--- a/.hgtags Fri Mar 15 17:02:24 2013 +0400
+++ b/.hgtags Fri Mar 15 16:39:07 2013 -0700
@@ -199,3 +199,6 @@
f1478a6d25fddd311a84dcbfac50824cc1858bdd jdk8-b75
f407160c280d1c5b00d314c535441ac26f195fee jdk8-b76
d17eb2e13e362085e866d46235314c50cc4661cc jdk8-b77
+6d3dcd34b5b962ea1ef9eed0dafdee9e812401bc jdk8-b78
+a1313a8d90d17d363a3b2a645dc4030ec204b168 jdk8-b79
+3fa21fbf9be7e6b482af43aacb6a09acfa30bdb6 jdk8-b80
--- a/.hgtags-top-repo Fri Mar 15 17:02:24 2013 +0400
+++ b/.hgtags-top-repo Fri Mar 15 16:39:07 2013 -0700
@@ -199,3 +199,6 @@
2a713921952cbd77a1e699626976cb6cdfe3e57e jdk8-b75
278af9fc67e7eba2884936b49ec07345f423aabb jdk8-b76
3933eebc659d58c597aa8cb4b3e58f2250ce3e1a jdk8-b77
+fd1a5574cf68af24bfd52decc37ac6361afb278a jdk8-b78
+91d35211e74464dca5edf9b66ab01d0d0d8cded7 jdk8-b79
+907a926d3c96472f357617b48b6b968ea855c23c jdk8-b80
--- a/README Fri Mar 15 17:02:24 2013 +0400
+++ b/README Fri Mar 15 16:39:07 2013 -0700
@@ -1,45 +1,40 @@
README:
This file should be located at the top of the OpenJDK Mercurial root
- repository. This root repository will include a "make" directory,
- and a Makefile for building the entire OpenJDK.
- A full OpenJDK repository set (forest) should also include the following
- 6 nested repositories:
+ repository. A full OpenJDK repository set (forest) should also include
+ the following 6 nested repositories:
"jdk", "hotspot", "langtools", "corba", "jaxws" and "jaxp".
- There are also several source downloads for the jax* repositories that
- will be needed.
- This one root repository can be obtained with something like:
-
+ The root repository can be obtained with something like:
hg clone http://hg.openjdk.java.net/jdk8/jdk8 openjdk8
- To make sure you have all the nested repositories, you can run the
- get_source.sh script located in the same respository as this file:
-
+ You can run the get_source.sh script located in the root repository to get
+ the other needed repositories:
cd openjdk8 && sh ./get_source.sh
People unfamiliar with Mercurial should read the first few chapters of
the Mercurial book: http://hgbook.red-bean.com/read/
- See http://openjdk.java.net/ for more information about the OpenJDK.
+ See http://openjdk.java.net/ for more information about OpenJDK.
Simple Build Instructions:
0. Get the necessary system software/packages installed on your system, see
- http://hg.openjdk.java.net/jdk8/build/raw-file/tip/README-builds.html
+ http://hg.openjdk.java.net/jdk8/jdk8/raw-file/tip/README-builds.html
- 1. If you don't have a jdk6 installed, download and install a JDK 6 from
+ 1. If you don't have a jdk7u7 or newer jdk, download and install it from
http://java.sun.com/javase/downloads/index.jsp
- Set the environment variable ALT_BOOTDIR to the location of JDK 6.
+ Add the /bin directory of this installation to your PATH environment
+ variable.
- 2. Check the sanity of doing a build with your current system:
- make sanity
- See README-builds.html if you run into problems.
+ 2. Configure the build:
+ bash ./configure
- 3. Do a complete build of the OpenJDK:
+ 3. Build the OpenJDK:
make all
- The resulting JDK image should be found in build/*/j2sdk-image
+ The resulting JDK image should be found in build/*/images/j2sdk-image
where make is GNU make 3.81 or newer, /usr/bin/make on Linux usually
-is 3.81 or newer.
+is 3.81 or newer. Note that on Solaris, GNU make is called "gmake".
-Complete details are available in README-builds.html.
+Complete details are available in the file:
+ http://hg.openjdk.java.net/jdk8/jdk8/raw-file/tip/README-builds.html
--- a/README-builds.html Fri Mar 15 17:02:24 2013 +0400
+++ b/README-builds.html Fri Mar 15 16:39:07 2013 -0700
@@ -3,14 +3,15 @@
<head>
<title>OpenJDK Build README</title>
</head>
- <body style="background-color:lightcyan">
+ <body style="background-color:aquamarine">
+
<!-- ====================================================== -->
<table width="100%">
<tr>
<td align="center">
<img alt="OpenJDK"
src="http://openjdk.java.net/images/openjdk.png"
- width=256 />
+ width=256>
</td>
</tr>
<tr>
@@ -19,109 +20,116 @@
</td>
</tr>
</table>
- <!-- ------------------------------------------------------ -->
+
+ <!-- ====================================================== -->
<hr>
<h2><a name="introduction">Introduction</a></h2>
<blockquote>
- <p>
- This README file contains build instructions for the
- <a href="http://openjdk.java.net" target="_blank">OpenJDK</a>.
- Building the source code for the
- OpenJDK
- requires
- a certain degree of technical expertise.
+ This README file contains build instructions for the
+ <a href="http://openjdk.java.net" target="_blank">OpenJDK</a>.
+ Building the source code for the
+ OpenJDK
+ requires
+ a certain degree of technical expertise.
+
+ <!-- ====================================================== -->
+ <h3>!!!!!!!!!!!!!!! THIS IS A MAJOR RE-WRITE of this document. !!!!!!!!!!!!!</h3>
+ <blockquote>
+ Some Headlines:
+ <ul>
+ <li>
+ The build is now a "<code>configure && make</code>" style build
+ </li>
+ <li>
+ Any GNU make 3.81 or newer should work
+ </li>
+ <li>
+ The build should scale, i.e. more processors should
+ cause the build to be done in less wall-clock time
+ </li>
+ <li>
+ Nested or recursive make invocations have been significantly
+ reduced, as has the total fork/exec or spawning
+ of sub processes during the build
+ </li>
+ <li>
+ Windows MKS usage is no longer supported
+ </li>
+ <li>
+ Windows Visual Studio <code>vsvars*.bat</code> and
+ <code>vcvars*.bat</code> files are run automatically
+ </li>
+ <li>
+ Ant is no longer used when building the OpenJDK
+ </li>
+ <li>
+ Use of ALT_* environment variables for configuring the
+ build is no longer supported
+ </li>
+ </ul>
+ </blockquote>
</blockquote>
- <!-- ------------------------------------------------------ -->
+
+ <!-- ====================================================== -->
<hr>
<h2><a name="contents">Contents</a></h2>
<blockquote>
<ul>
<li><a href="#introduction">Introduction</a></li>
+
<li><a href="#hg">Use of Mercurial</a>
<ul>
<li><a href="#get_source">Getting the Source</a></li>
+ <li><a href="#repositories">Repositories</a></li>
</ul>
</li>
- <li><a href="#MBE">Minimum Build Environments</a></li>
- <li><a href="#SDBE">Specific Developer Build Environments</a>
+
+ <li><a href="#building">Building</a>
<ul>
- <li><a href="#fedora">Fedora Linux</a> </li>
- <li><a href="#centos">CentOS Linux</a> </li>
- <li><a href="#debian">Debian GNU/Linux</a></li>
- <li><a href="#ubuntu">Ubuntu Linux</a> </li>
- <li><a href="#opensuse">OpenSUSE</a></li>
- <li><a href="#mandriva">Mandriva</a></li>
- <li><a href="#opensolaris">OpenSolaris</a></li>
- </ul>
- </li>
- <li><a href="#directories">Source Directory Structure</a>
- <ul>
- <li><a href="#drops">Managing the Source Drops</a></li>
+ <li><a href="#setup">System Setup</a>
+ <ul>
+ <li><a href="#linux">Linux</a></li>
+ <li><a href="#solaris">Solaris</a></li>
+ <li><a href="#macosx">Mac OS X</a></li>
+ <li><a href="#windows">Windows</a></li>
+ </ul>
+ </li>
+ <li><a href="#configure">Configure</a></li>
+ <li><a href="#make">Make</a></li>
</ul>
</li>
- <li><a href="#building">Build Information</a>
+ <li><a href="#testing">Testing</a></li>
+ </ul>
+ <hr>
+ <ul>
+ <li><a href="#hints">Appendix A: Hints and Tips</a>
<ul>
- <li><a href="#gmake">GNU Make (<tt><i>gmake</i></tt>)</a> </li>
- <li><a href="#linux">Basic Linux System Setup</a> </li>
- <li><a href="#solaris">Basic Solaris System Setup</a> </li>
- <li><a href="#windows">Basic Windows System Setup</a> </li>
- <li><a href="#macosx">Basic Mac OS X System Setup</a></li>
- <li><a href="#dependencies">Build Dependencies</a>
- <ul>
- <li><a href="#bootjdk">Bootstrap JDK</a> </li>
- <li><a href="#importjdk">Optional Import JDK</a> </li>
- <li><a href="#ant">Ant 1.7.1</a> </li>
- <li><a href="#cacerts">Certificate Authority File (cacert)</a> </li>
- <li><a href="#compilers">Compilers</a>
- <ul>
- <li><a href="#msvc32">Microsoft Visual Studio Professional/Express for 32 bit</a> </li>
- <li><a href="#msvc64">Microsoft Visual Studio Professional for 64 bit</a> </li>
- <li><a href="#mssdk64">Microsoft Windows SDK for 64 bit</a> </li>
- <li><a href="#gcc">Linux gcc/binutils</a> </li>
- <li><a href="#studio">Sun Studio</a> </li>
- </ul>
- </li>
- <li><a href="#zip">Zip and Unzip</a> </li>
- <li><a href="#freetype">FreeType2 Fonts</a> </li>
- <li>Linux and Solaris:
- <ul>
- <li><a href="#cups">CUPS Include files</a> </li>
- <li><a href="#xrender">XRender Include files</a></li>
- </ul>
- </li>
- <li>Linux only:
- <ul>
- <li><a href="#alsa">ALSA files</a> </li>
- </ul>
- </li>
- <li>Windows only:
- <ul>
- <li>Unix Command Tools (<a href="#cygwin">CYGWIN</a>) <strong>or</strong></li>
- <li>Minimalist GNU for Windows (<a href="#msys">MinGW/MSYS</a>)</li>
- <li><a href="#dxsdk">DirectX 9.0 SDK</a> </li>
- </ul>
- </li>
- </ul>
- </li>
+ <li><a href="#faq">FAQ</a></li>
+ <li><a href="#performance">Build Performance Tips</a></li>
+ <li><a href="#troubleshooting">Troubleshooting</a></li>
</ul>
</li>
- <li><a href="#creating">Creating the Build</a> </li>
- <li><a href="#testing">Testing the Build</a> </li>
- <li><a href="#variables">Environment/Make Variables</a></li>
- <li><a href="#troubleshooting">Troubleshooting</a></li>
- <li><a href="#newbuild">The New Build</a></li>
+ <li><a href="#gmake">Appendix B: GNU Make Information</a></li>
+ <li><a href="#buildenvironments">Appendix C: Build Environments</a></li>
+
+ <!-- Leave out
+ <li><a href="#mapping">Appendix D: Mapping Old Builds to the New Builds</a></li>
+ -->
+
</ul>
</blockquote>
- <!-- ------------------------------------------------------ -->
+ <!-- ====================================================== -->
<hr>
<h2><a name="hg">Use of Mercurial</a></h2>
<blockquote>
The OpenJDK sources are maintained with the revision control system
<a href="http://mercurial.selenic.com/wiki/Mercurial">Mercurial</a>.
If you are new to Mercurial, please see the
- <a href="http://mercurial.selenic.com/wiki/BeginnersGuides">Beginner Guides</a>
- or refer to the <a href="http://hgbook.red-bean.com/">Mercurial Book</a>.
+ <a href="http://mercurial.selenic.com/wiki/BeginnersGuides">
+ Beginner Guides</a>
+ or refer to the <a href="http://hgbook.red-bean.com/">
+ Mercurial Book</a>.
The first few chapters of the book provide an excellent overview of
Mercurial, what it is and how it works.
<br>
@@ -130,578 +138,1631 @@
Developer Guide: Installing and Configuring Mercurial</a>
section for more information.
- <!-- ------------------------------------------------------ -->
<h3><a name="get_source">Getting the Source</a></h3>
<blockquote>
To get the entire set of OpenJDK Mercurial repositories
- use the script <code>get_source.sh</code> located in the root repository:
+ use the script <code>get_source.sh</code> located in the
+ root repository:
<blockquote>
- <tt>
- hg clone http://hg.openjdk.java.net/jdk8/jdk8 <i>YourOpenJDK</i>
- <br>cd <i>YourOpenJDK</i>
- <br>sh ./get_source.sh
- </tt>
+ <code>
+ hg clone http://hg.openjdk.java.net/jdk8/jdk8
+ <i>YourOpenJDK</i>
+ <br>
+ cd <i>YourOpenJDK</i>
+ <br>
+ bash ./get_source.sh
+ </code>
+ </blockquote>
+ Once you have all the repositories, keep in mind that each
+ repository is it's own independent repository.
+ You can also re-run <code>./get_source.sh</code> anytime to
+ pull over all the latest changesets in all the repositories.
+ This set of nested repositories has been given the term
+ "forest" and there are various ways to apply the same
+ <code>hg</code> command to each of the repositories.
+ For example, the script <code>make/scripts/hgforest.sh</code>
+ can be used to repeat the same <code>hg</code>
+ command on every repository, e.g.
+ <blockquote>
+ <code>
+ cd <i>YourOpenJDK</i>
+ <br>
+ bash ./make/scripts/hgforest.sh status
+ </code>
</blockquote>
- Once you have all the repositories, the
- script <tt>make/scripts/hgforest.sh</tt>
- can be used to repeat the same <tt>hg</tt>
- command on every repository in the forest, e.g.
- <blockquote>
- <tt>
- cd <i>YourOpenJDK</i>
- <br>sh ./make/scripts/hgforest.sh pull -u
- </tt>
- </blockquote>
+ </blockquote>
+
+ <h3><a name="repositories">Repositories</a></h3>
+ <blockquote>
+ <p>The set of repositories and what they contain:</p>
+ <table border="1">
+ <thead>
+ <tr>
+ <th>Repository</th>
+ <th>Contains</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>
+ . (root)
+ </td>
+ <td>
+ common configure and makefile logic
+ </td>
+ </tr>
+ <tr>
+ <td>
+ hotspot
+ </td>
+ <td>
+ source code and make files for building
+ the OpenJDK Hotspot Virtual Machine
+ </td>
+ </tr>
+ <tr>
+ <td>
+ langtools
+ </td>
+ <td>
+ source code for the OpenJDK javac and language tools
+ </td>
+ </tr>
+ <tr>
+ <td>
+ jdk
+ </td>
+ <td>
+ source code and make files for building
+ the OpenJDK runtime libraries and misc files
+ </td>
+ </tr>
+ <tr>
+ <td>
+ jaxp
+ </td>
+ <td>
+ source code for the OpenJDK JAXP functionality
+ </td>
+ </tr>
+ <tr>
+ <td>
+ jaxws
+ </td>
+ <td>
+ source code for the OpenJDK JAX-WS functionality
+ </td>
+ </tr>
+ <tr>
+ <td>
+ corba
+ </td>
+ <td>
+ source code for the OpenJDK Corba functionality
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </blockquote>
+
+ <h3><a name="guidelines">Repository Source Guidelines</a></h3>
+ <blockquote>
+ There are some very basic guidelines:
+ <ul>
+ <li>
+ Use of whitespace in source files
+ (.java, .c, .h, .cpp, and .hpp files)
+ is restricted.
+ No TABs, no trailing whitespace on lines, and files
+ should not terminate in more than one blank line.
+ </li>
+ <li>
+ Files with execute permissions should not be added
+ to the source repositories.
+ </li>
+ <li>
+ All generated files need to be kept isolated from
+ the files
+ maintained or managed by the source control system.
+ The standard area for generated files is the top level
+ <code>build/</code> directory.
+ </li>
+ <li>
+ The default build process should be to build the product
+ and nothing else, in one form, e.g. a product (optimized),
+ debug (non-optimized, -g plus assert logic), or
+ fastdebug (optimized, -g plus assert logic).
+ </li>
+ <li>
+ The <tt>.hgignore</tt> file in each repository
+ must exist and should
+ include <tt>^build/</tt>, <tt>^dist/</tt> and
+ optionally any
+ <tt>nbproject/private</tt> directories.
+ <strong>It should NEVER</strong> include
+ anything in the
+ <tt>src/</tt> or <tt>test/</tt>
+ or any managed directory area of a repository.
+ </li>
+ <li>
+ Directory names and file names should never contain
+ blanks or
+ non-printing characters.
+ </li>
+ <li>
+ Generated source or binary files should NEVER be added to
+ the repository (that includes <tt>javah</tt> output).
+ There are some exceptions to this rule, in particular
+ with some of the generated configure scripts.
+ </li>
+ <li>
+ Files not needed for typical building
+ or testing of the repository
+ should not be added to the repository.
+ </li>
+ </ul>
</blockquote>
</blockquote>
- <!-- ------------------------------------------------------ -->
+ <!-- ====================================================== -->
<hr>
- <h2><a name="MBE">Minimum Build Environments</a></h2>
- <blockquote>
- This file often describes specific requirements for what we call the
- "minimum build environments" (MBE) for this
- specific release of the JDK,
- Building with the MBE will generate the most compatible
- bits that install on, and run correctly on, the most variations
- of the same base OS and hardware architecture.
- These usually represent what is often called the
- least common denominator platforms.
- It is understood that most developers will NOT be using these
- specific platforms, and in fact creating these specific platforms
- may be difficult due to the age of some of this software.
- <p>
- The minimum OS and C/C++ compiler versions needed for building the
- OpenJDK:
- <p>
- <table border="1">
- <thead>
- <tr>
- <th>Base OS and Architecture</th>
- <th>OS</th>
- <th>C/C++ Compiler</th>
- <th>BOOT JDK</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>Linux X86 (32-bit)</td>
- <td>Fedora 9</td>
- <td>gcc 4.3 </td>
- <td>JDK 6u18</td>
- </tr>
- <tr>
- <td>Linux X64 (64-bit)</td>
- <td>Fedora 9</td>
- <td>gcc 4.3 </td>
- <td>JDK 6u18</td>
- </tr>
- <tr>
- <td>Solaris SPARC (32-bit)</td>
- <td>Solaris 10 Update 6</td>
- <td>Sun Studio 12 Update 1 + patches</td>
- <td>JDK 6u18</td>
- </tr>
- <tr>
- <td>Solaris SPARCV9 (64-bit)</td>
- <td>Solaris 10 Update 6</td>
- <td>Sun Studio 12 Update 1 + patches</td>
- <td>JDK 6u18</td>
- </tr>
- <tr>
- <td>Solaris X86 (32-bit)</td>
- <td>Solaris 10 Update 6</td>
- <td>Sun Studio 12 Update 1 + patches</td>
- <td>JDK 6u18</td>
- </tr>
- <tr>
- <td>Solaris X64 (64-bit)</td>
- <td>Solaris 10 Update 6</td>
- <td>Sun Studio 12 Update 1 + patches</td>
- <td>JDK 6u18</td>
- </tr>
- <tr>
- <td>Windows X86 (32-bit)</td>
- <td>Windows XP</td>
- <td>Microsoft Visual Studio C++ 2010 Professional Edition</td>
- <td>JDK 6u18</td>
- </tr>
- <tr>
- <td>Windows X64 (64-bit)</td>
- <td>Windows Server 2003 - Enterprise x64 Edition</td>
- <td>Microsoft Visual Studio C++ 2010 Professional Edition</td>
- <td>JDK 6u18</td>
- </tr>
- <tr>
- <td>Mac OS X X64 (64-bit)</td>
- <td>Mac OS X 10.7.3 "Lion"</td>
- <td>XCode 4.1 or later</td>
- <td>Java for OS X Lion Update 1</td>
- </tr>
- </tbody>
- </table>
- <p>
- These same sources do indeed build on many more systems than the
- above older generation systems, again the above is just a minimum.
- <p>
- Compilation problems with newer or different C/C++ compilers is a
- common problem.
- Similarly, compilation problems related to changes to the
- <tt>/usr/include</tt> or system header files is also a
- common problem with newer or unreleased OS versions.
- Please report these types of problems as bugs so that they
- can be dealt with accordingly.
- </blockquote>
- <!-- ------------------------------------------------------ -->
- <hr>
- <h2><a name="SDBE">Specific Developer Build Environments</a></h2>
- <blockquote>
- We won't be listing all the possible environments, but
- we will try to provide what information we have available to us.
- </blockquote>
- <!-- ------------------------------------------------------ -->
- <h3><a name="fedora">Fedora</a></h3>
+ <h2><a name="building">Building</a></h2>
<blockquote>
- <h4>Fedora 9</h4>
- <p>
- <blockquote>
- After installing <a href="http://fedoraproject.org">Fedora</a> 9
- you need to install several build dependencies. The simplest
- way to do it is to execute the following commands as user
- <tt>root</tt>:
- <p/>
- <code>yum-builddep java-1.6.0-openjdk</code>
- <p/>
- <code>yum install gcc gcc-c++</code>
- <p/>
- In addition, it's necessary to set a few environment variables for the build:
-
- <p/>
- <code>export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-openjdk</code>
- </blockquote>
- <h4>Fedora 10</h4>
- <p>
+ The very first step in building the OpenJDK is making sure the
+ system itself has everything it needs to do OpenJDK builds.
+ Once a system is setup, it generally doesn't need to be done again.
+ <br>
+ Building the OpenJDK is now done with running a
+ <a href="#configure"><code>configure</code></a>
+ script which will try and find and verify you have everything
+ you need, followed by running
+ <a href="#gmake"><code>make</code></a>, e.g.
<blockquote>
- After installing <a href="http://fedoraproject.org">Fedora</a> 10
- you need to install several build dependencies. The simplest
- way to do it is to execute the following commands as user
- <tt>root</tt>:
- <p/>
- <code>yum-builddep java-1.6.0-openjdk</code>
- <p/>
- <code>yum install gcc gcc-c++</code>
- <p/>
- In addition, it's necessary to set a few environment variables for the build:
-
- <p/>
- <code>export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-openjdk</code>
- </blockquote>
- <h4>Fedora 11</h4>
- <p>
- <blockquote>
- After installing <a href="http://fedoraproject.org">Fedora</a> 11
- you need to install several build dependencies. The simplest
- way to do it is to execute the following commands as user
- <tt>root</tt>:
- <p/>
- <code>yum-builddep java-1.6.0-openjdk</code>
- <p/>
- <code>yum install gcc gcc-c++</code>
- <p/>
- In addition, it's necessary to set a few environment variables for the build:
-
- <p/>
- <code>export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-openjdk</code>
+ <b>
+ <code>
+ bash ./configure<br>
+ make all
+ </code>
+ </b>
</blockquote>
- </blockquote>
- <!-- ------------------------------------------------------ -->
- <h3><a name="centos">CentOS 5.5</a></h3>
- <blockquote>
- After installing
- <a href="http://www.centos.org/">CentOS 5.5</a>
- you need to make sure you have
- the following Development bundles installed:
+ Where possible the <code>configure</code> script will attempt to located the
+ various components in the default locations or via component
+ specific variable settings.
+ When the normal defaults fail or components cannot be found,
+ additional <code>configure</code> options may be necessary to help <code>configure</code>
+ find the necessary tools for the build, or you may need to
+ re-visit the setup of your system due to missing software
+ packages.
+ <br>
+ <strong>NOTE:</strong> The <code>configure</code> script
+ file does not have
+ execute permissions and will need to be explicitly run with
+ <code>bash</code>,
+ see the <a href="#guidelines">source guidelines</a>.
+
+ <!-- ====================================================== -->
+ <hr>
+ <h3><a name="setup">System Setup</a></h3>
<blockquote>
+ Before even attempting to use a system to build the OpenJDK
+ there are some very basic system setups needed.
+ For all systems:
<ul>
- <li>Development Libraries</li>
- <li>Development Tools</li>
- <li>Java Development</li>
- <li>X Software Development (Including XFree86-devel)</li>
+ <li>
+ Be sure the GNU make utility is version 3.81 or newer,
+ e.g. run "<code>make -version</code>"
+ </li>
+ <li>
+ Install a
+ <a name="bootjdk">Bootstrap JDK</a>
+ <br>
+ All OpenJDK builds require access to a previously released
+ JDK, this is often called a bootstrap JDK.
+ Currently, for this JDK release we require
+ JDK 7 Update 7 or newer.
+ The JDK 7 binaries can be downloaded from Oracle's
+ <a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html"
+ target="_blank">JDK 7 download site</a>.
+ For build performance reasons
+ is very important that this bootstrap JDK be made available
+ on the local disk of the machine doing the build.
+ You should add its <code>bin</code> directory
+ to the <code>PATH</code> environment variable.
+ If <code>configure</code> has any issues finding this JDK, you may
+ need to use the <code>configure</code> option
+ <code>--with-boot-jdk</code>.
+ </li>
+ <li>
+ Insure that GNU make, the Bootstrap JDK,
+ and the compilers are all
+ in your PATH environment variable
+ </li>
</ul>
- </blockquote>
- <p>
- Plus the following packages:
- <blockquote>
- <ul>
- <li>cups devel: Cups Development Package</li>
- <li>alsa devel: Alsa Development Package</li>
- <li>ant: Ant Package</li>
- <li>Xi devel: libXi.so Development Package</li>
- </ul>
+ And for specific systems:
+ <table border="1">
+ <thead>
+ <tr>
+ <th>Linux</th>
+ <th>Solaris</th>
+ <th>Windows</th>
+ <th>Mac OS X</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>
+ Install all the software development
+ packages needed including
+ <a href="#alsa">alsa</a>,
+ <a href="#freetype">freetype</a>,
+ <a href="#cups">cups</a>, and
+ <a href="#xrender">xrender</a>.
+ <br>
+ See
+ <a href="#SDBE">specific system packages</a>.
+ </td>
+ <td>
+ Install all the software development
+ packages needed including
+ <a href="#studio">Studio Compilers</a>,
+ <a href="#freetype">freetype</a>,
+ <a href="#cups">cups</a>, and
+ <a href="#xrender">xrender</a>.
+ <br>
+ See
+ <a href="#SDBE">specific system packages</a>.
+ </td>
+ <td>
+ <ul>
+ <li>
+ Install one of
+ <a href="#cygwin">CYGWIN</a> or
+ <a href="#msys">MinGW/MSYS</a>
+ </li>
+ <li>
+ Install
+ <a href="#vs2010">Visual Studio 2010</a>
+ </li>
+ <li>
+ Install the
+ <a href="#dxsdk">Microsoft DirectX SDK</a>
+ </li>
+ </ul>
+ </td>
+ <td>
+ Install
+ <a href="https://developer.apple.com/xcode/">XCode 4.5.2</a>
+ and also install the "Command line tools" found under the
+ preferences pane "Downloads"
+ </td>
+ </tr>
+ </tbody>
+ </table>
+
+ <h4><a name="linux">Linux</a></h4>
+ <blockquote>
+ With Linux, try and favor the system packages over
+ building your own
+ or getting packages from other areas.
+ Most Linux builds should be possible with the system's
+ available packages.
+ <br>
+ Note that some Linux systems have a habit of pre-populating
+ your environment variables for you, for example <code>JAVA_HOME</code>
+ might get pre-defined for you to refer to the JDK installed on
+ your Linux system.
+ You will need to unset <code>JAVA_HOME</code>.
+ It's a good idea to run <code>env</code> and verify the
+ environment variables you are getting from the default system
+ settings make sense for building the OpenJDK.
+
+ </blockquote>
+
+ <h4><a name="solaris">Solaris</a></h4>
+ <blockquote>
+ <h5><a name="studio">Studio Compilers</a></h5>
+ <blockquote>
+ At a minimum, the
+ <a href="http://www.oracle.com/technetwork/server-storage/solarisstudio/downloads/index.htm" target="_blank">
+ Studio 12 Update 1 Compilers</a>
+ (containing version 5.10 of the C and C++ compilers) is required,
+ including specific patches.
+ <p>
+ The Solaris SPARC patch list is:
+ <ul>
+ <li>
+ 118683-05: SunOS 5.10: Patch for profiling libraries and assembler
+ </li>
+ <li>
+ 119963-21: SunOS 5.10: Shared library patch for C++
+ </li>
+ <li>
+ 120753-08: SunOS 5.10: Microtasking libraries (libmtsk) patch
+ </li>
+ <li>
+ 128228-09: Sun Studio 12 Update 1: Patch for Sun C++ Compiler
+ </li>
+ <li>
+ 141860-03: Sun Studio 12 Update 1: Patch for Compiler Common patch for Sun C C++ F77 F95
+ </li>
+ <li>
+ 141861-05: Sun Studio 12 Update 1: Patch for Sun C Compiler
+ </li>
+ <li>
+ 142371-01: Sun Studio 12.1 Update 1: Patch for dbx
+ </li>
+ <li>
+ 143384-02: Sun Studio 12 Update 1: Patch for debuginfo handling
+ </li>
+ <li>
+ 143385-02: Sun Studio 12 Update 1: Patch for Compiler Common patch for Sun C C++ F77 F95
+ </li>
+ <li>
+ 142369-01: Sun Studio 12.1: Patch for Performance Analyzer Tools
+ </li>
+ </ul>
+ <p>
+ The Solaris X86 patch list is:
+ <ul>
+ <li>
+ 119961-07: SunOS 5.10_x86, x64, Patch for profiling libraries and assembler
+ </li>
+ <li>
+ 119964-21: SunOS 5.10_x86: Shared library patch for C++_x86
+ </li>
+ <li>
+ 120754-08: SunOS 5.10_x86: Microtasking libraries (libmtsk) patch
+ </li>
+ <li>
+ 141858-06: Sun Studio 12 Update 1_x86: Sun Compiler Common patch for x86 backend
+ </li>
+ <li>
+ 128229-09: Sun Studio 12 Update 1_x86: Patch for C++ Compiler
+ </li>
+ <li>
+ 142363-05: Sun Studio 12 Update 1_x86: Patch for C Compiler
+ </li>
+ <li>
+ 142368-01: Sun Studio 12.1_x86: Patch for Performance Analyzer Tools
+ </li>
+ </ul>
+ <p>
+ Place the <code>bin</code> directory in <code>PATH</code>.
+ <p>
+ The Oracle Solaris Studio Express compilers at:
+ <a href="http://www.oracle.com/technetwork/server-storage/solarisstudio/downloads/index-jsp-142582.html" target="_blank">
+ Oracle Solaris Studio Express Download site</a>
+ are also an option, although these compilers have not
+ been extensively used yet.
+ </blockquote>
+
+ </blockquote> <!-- Solaris -->
+
+ <h4><a name="windows">Windows</a></h4>
+ <blockquote>
+
+ <h5><a name="toolkit">Windows Unix Toolkit</a></h5>
+ <blockquote>
+ Building on Windows requires a Unix-like environment, notably a
+ Unix-like shell.
+ There are several such environments available of which
+ <a href="http://www.cygwin.com/">Cygwin</a> and
+ <a href="http://www.mingw.org/wiki/MSYS">MinGW/MSYS</a> are
+ currently supported for
+ the OpenJDK build. One of the differences of these
+ systems from standard Windows tools is the way
+ they handle Windows path names, particularly path names which contain
+ spaces, backslashes as path separators and possibly drive letters.
+ Depending
+ on the use case and the specifics of each environment these path
+ problems can
+ be solved by a combination of quoting whole paths, translating
+ backslashes to
+ forward slashes, escaping backslashes with additional backslashes and
+ translating the path names to their
+ <a href="http://en.wikipedia.org/wiki/8.3_filename">
+ "8.3" version</a>.
+
+ <h6><a name="cygwin">CYGWIN</a></h6>
+ <blockquote>
+ CYGWIN is an open source, Linux-like environment which tries to emulate
+ a complete POSIX layer on Windows. It tries to be smart about path names
+ and can usually handle all kinds of paths if they are correctly quoted
+ or escaped although internally it maps drive letters <code><drive>:</code>
+ to a virtual directory <code>/cygdrive/<drive></code>.
+ <p>
+ You can always use the <code>cygpath</code> utility to map pathnames with spaces
+ or the backslash character into the <code>C:/</code> style of pathname
+ (called 'mixed'), e.g. <code>cygpath -s -m "<i>path</i>"</code>.
+ </p>
+ <p>
+ Note that the use of CYGWIN creates a unique problem with regards to
+ setting <a href="#path"><code>PATH</code></a>. Normally on Windows
+ the <code>PATH</code> variable contains directories
+ separated with the ";" character (Solaris and Linux use ":").
+ With CYGWIN, it uses ":", but that means that paths like "C:/path"
+ cannot be placed in the CYGWIN version of <code>PATH</code> and
+ instead CYGWIN uses something like <code>/cygdrive/c/path</code>
+ which CYGWIN understands, but only CYGWIN understands.
+ </p>
+ <p>
+ The OpenJDK build requires CYGWIN version 1.7.16 or newer.
+ Information about CYGWIN can
+ be obtained from the CYGWIN website at
+ <a href="http://www.cygwin.com" target="_blank">www.cygwin.com</a>.
+ </p>
+ <p>
+ By default CYGWIN doesn't install all the tools required for building
+ the OpenJDK.
+ Along with the default installation, you need to install
+ the following tools.
+ <blockquote>
+ <table border="1">
+ <thead>
+ <tr>
+ <td>Binary Name</td>
+ <td>Category</td>
+ <td>Package</td>
+ <td>Description</td>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>ar.exe</td>
+ <td>Devel</td>
+ <td>binutils</td>
+ <td>
+ The GNU assembler, linker and binary utilities
+ </td>
+ </tr>
+ <tr>
+ <td>make.exe</td>
+ <td>Devel</td>
+ <td>make</td>
+ <td>
+ The GNU version of the 'make' utility built for CYGWIN
+ </td>
+ </tr>
+ <tr>
+ <td>m4.exe</td>
+ <td>Interpreters</td>
+ <td>m4</td>
+ <td>
+ GNU implementation of the traditional Unix macro
+ processor
+ </td>
+ </tr>
+ <tr>
+ <td>cpio.exe</td>
+ <td>Utils</td>
+ <td>cpio</td>
+ <td>
+ A program to manage archives of files
+ </td>
+ </tr>
+ <tr>
+ <td>gawk.exe</td>
+ <td>Utils</td>
+ <td>awk</td>
+ <td>
+ Pattern-directed scanning and processing language
+ </td>
+ </tr>
+ <tr>
+ <td>file.exe</td>
+ <td>Utils</td>
+ <td>file</td>
+ <td>
+ Determines file type using 'magic' numbers
+ </td>
+ </tr>
+ <tr>
+ <td>zip.exe</td>
+ <td>Archive</td>
+ <td>zip</td>
+ <td>
+ Package and compress (archive) files
+ </td>
+ </tr>
+ <tr>
+ <td>unzip.exe</td>
+ <td>Archive</td>
+ <td>unzip</td>
+ <td>
+ Extract compressed files in a ZIP archive
+ </td>
+ </tr>
+ <tr>
+ <td>free.exe</td>
+ <td>System</td>
+ <td>procps</td>
+ <td>
+ Display amount of free and used memory in the system
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </blockquote>
+ Note that the CYGWIN software can conflict with other non-CYGWIN
+ software on your Windows system.
+ CYGWIN provides a
+ <a href="http://cygwin.com/faq/faq.using.html" target="_blank">FAQ</a> for
+ known issues and problems, of particular interest is the
+ section on
+ <a href="http://cygwin.com/faq/faq.using.html#faq.using.bloda" target="_blank">
+ BLODA (applications that interfere with CYGWIN)</a>.
+ </blockquote>
+
+ <h6><a name="msys">MinGW/MSYS</a></h6>
+ <blockquote>
+ MinGW ("Minimalist GNU for Windows") is a collection of free Windows
+ specific header files and import libraries combined with GNU toolsets that
+ allow one to produce native Windows programs that do not rely on any
+ 3rd-party C runtime DLLs. MSYS is a supplement to MinGW which allows building
+ applications and programs which rely on traditional UNIX tools to
+ be present. Among others this includes tools like <code>bash</code>
+ and <code>make</code>.
+ See <a href="http://www.mingw.org/wiki/MSYS" target="_blank">MinGW/MSYS</a>
+ for more information.
+ <p>
+ Like Cygwin, MinGW/MSYS can handle different types of path formats. They
+ are internally converted to paths with forward slashes and drive letters
+ <code><drive>:</code> replaced by a virtual
+ directory <code>/<drive></code>. Additionally, MSYS automatically
+ detects binaries compiled for the MSYS environment and feeds them with the
+ internal, Unix-style path names. If native Windows applications are called
+ from within MSYS programs their path arguments are automatically converted
+ back to Windows style path names with drive letters and backslashes as
+ path separators. This may cause problems for Windows applications which
+ use forward slashes as parameter separator (e.g. <code>cl /nologo /I</code>)
+ because MSYS may wrongly <a href="http://mingw.org/wiki/Posix_path_conversion">
+ replace such parameters by drive letters</a>.
+ </p>
+ <p>
+ In addition to the tools which will be installed
+ by default, you have
+ to manually install the
+ <code>msys-zip</code> and
+ <code>msys-unzip</code> packages.
+ This can be easily done with the MinGW command line installer:
+ <blockquote>
+ <code>mingw-get.exe install msys-zip</code>
+ <br>
+ <code>mingw-get.exe install msys-unzip</code>
+ </blockquote>
+ </blockquote>
+
+ </blockquote>
+
+ <h5><a name="vs2010">Visual Studio 2010 Compilers</a></h5>
+ <blockquote>
+ <p>
+ The 32-bit and 64-bit OpenJDK Windows build requires
+ Microsoft Visual Studio C++ 2010 (VS2010) Professional
+ Edition or Express compiler.
+ The compiler and other tools are expected to reside
+ in the location defined by the variable
+ <code>VS100COMNTOOLS</code> which
+ is set by the Microsoft Visual Studio installer.
+ </p>
+ <p>
+ Only the C++ part of VS2010 is needed.
+ Try to let the installation go to the default
+ install directory.
+ Always reboot your system after installing VS2010.
+ The system environment variable VS100COMNTOOLS
+ should be
+ set in your environment.
+ </p>
+ <p>
+ Make sure that TMP and TEMP are also set
+ in the environment
+ and refer to Windows paths that exist,
+ like <code>C:\temp</code>,
+ not <code>/tmp</code>, not <code>/cygdrive/c/temp</code>,
+ and not <code>C:/temp</code>.
+ <code>C:\temp</code> is just an example,
+ it is assumed that this area is
+ private to the user, so by default
+ after installs you should
+ see a unique user path in these variables.
+ </p>
+ </blockquote>
+
+
+ </blockquote> <!-- Windows -->
+
+ <h4><a name="macosx">Mac OS X</a></h4>
+ <blockquote>
+ Make sure you get the right XCode version.
+ </blockquote> <!-- Mac OS X -->
+
</blockquote>
- <p>
- The freetype 2.3 packages don't seem to be available,
- but the freetype 2.3 sources can be downloaded, built,
- and installed easily enough from
- <a href="http://downloads.sourceforge.net/freetype">
- the freetype site</a>.
- Build and install with something like:
+
+ <!-- ====================================================== -->
+ <hr>
+ <h3><a name="configure">Configure</a></h3>
<blockquote>
- <tt>./configure && make && sudo -u root make install</tt>
+ The basic invocation of the <code>configure</code> script
+ looks like:
+ <blockquote>
+ <b><code>bash ./configure [<i>options</i>]</code></b>
+ </blockquote>
+ This will create an output directory containing the
+ "configuration" and setup an area for the build result.
+ This directory typically looks like:
+ <blockquote>
+ <b><code>build/linux-x64-normal-server-release</code></b>
+ </blockquote>
+ <code>configure</code> will try to figure out what system you are running on
+ and where all necessary build components are.
+ If you have all prerequisites for building installed,
+ it should find everything.
+ If it fails to detect any component automatically,
+ it will exit and inform you about the problem.
+ When this happens, read more below in
+ <a href="#configureoptions">the <code>configure</code> options</a>.
+ <p>
+ Some examples:
+ </p>
+ <table border="1">
+ <thead>
+ <tr>
+ <th>Description</th>
+ <th>Configure Command Line</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>Windows 32bit build with freetype specified</td>
+ <td>
+ <code>bash ./configure --with-freetype=/cygdrive/c/freetype-i586 --with-target-bits=32</code>
+ </td>
+ </tr>
+ <tr>
+ <td>Debug 64bit Build</td>
+ <td>
+ <code>bash ./configure --enable-debug --with-target-bits=64</code>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+
+ <!-- ====================================================== -->
+ <h4><a name="configureoptions">Configure Options</a></h4>
+ <blockquote>
+ Complete details on all the OpenJDK <code>configure</code> options can
+ be seen with:
+ <blockquote>
+ <b><code>bash ./configure --help=short</code></b>
+ </blockquote>
+ Use <code>-help</code> to see all the <code>configure</code> options
+ available.
+
+ You can generate any number of different configurations,
+ e.g. debug, release, 32, 64, etc.
+
+ Some of the more commonly used <code>configure</code> options are:
+
+ <table border="1">
+ <thead>
+ <tr>
+ <th width="300">OpenJDK Configure Option</th>
+ <th>Description</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><b><code>--enable-debug</code></b></td>
+ <td>
+ set the debug level to fastdebug (this is a shorthand for
+ <code>--with-debug-level=fastdebug</code>)
+ </td>
+ </tr>
+ <tr>
+ <td><b><code>--with-alsa=</code></b><i>path</i></td>
+ <td>
+ select the location of the
+ <a name="alsa">Advanced Linux Sound Architecture (ALSA)</a>
+ <br>
+ Version 0.9.1 or newer of the ALSA files are
+ required for building the OpenJDK on Linux.
+ These Linux files are usually available from an "alsa"
+ of "libasound"
+ development package,
+ and it's highly recommended that you try and use
+ the package provided by the particular version of Linux that
+ you are using.
+ </td>
+ </tr>
+ <tr>
+ <td><b><code>--with-boot-jdk=</code></b><i>path</i></td>
+ <td>
+ select the <a href="#bootjdk">Bootstrap JDK</a>
+ </td>
+ </tr>
+ <tr>
+ <td><b><code>--with-boot-jdk-jvmargs=</code></b>"<i>args</i>"</td>
+ <td>
+ provide the JVM options to be used to run the
+ <a href="#bootjdk">Bootstrap JDK</a>
+ </td>
+ </tr>
+ <tr>
+ <td><b><code>--with-cacerts=</code></b><i>path</i></td>
+ <td>
+ select the path to the cacerts file.
+ <br>
+ See <a href="http://en.wikipedia.org/wiki/Certificate_Authority" target="_blank">
+ http://en.wikipedia.org/wiki/Certificate_Authority</a>
+ for a better understanding of the Certificate Authority (CA).
+ A certificates file named "cacerts"
+ represents a system-wide keystore with CA certificates.
+ In JDK and JRE
+ binary bundles, the "cacerts" file contains root CA certificates from
+ several public CAs (e.g., VeriSign, Thawte, and Baltimore).
+ The source contain a cacerts file
+ without CA root certificates.
+ Formal JDK builders will need to secure
+ permission from each public CA and include the certificates into their
+ own custom cacerts file.
+ Failure to provide a populated cacerts file
+ will result in verification errors of a certificate chain during runtime.
+ By default an empty cacerts file is provided and that should be
+ fine for most JDK developers.
+ </td>
+ </tr>
+ <tr>
+ <td><b><code>--with-cups=</code></b><i>path</i></td>
+ <td>
+ select the CUPS install location
+ <br>
+ The
+ <a name="cups">Common UNIX Printing System (CUPS) Headers</a>
+ are required for building the
+ OpenJDK on Solaris and Linux.
+ The Solaris header files can be obtained by installing
+ the package <strong>SFWcups</strong> from the Solaris Software
+ Companion CD/DVD, these often will be installed into the
+ directory <code>/opt/sfw/cups</code>.
+ <br>
+ The CUPS header files can always be downloaded from
+ <a href="http://www.cups.org" target="_blank">www.cups.org</a>.
+ </td>
+ </tr>
+ <tr>
+ <td><b><code>--with-cups-include=</code></b><i>path</i></td>
+ <td>
+ select the CUPS include directory location
+ </td>
+ </tr>
+ <tr>
+ <td><b><code>--with-debug-level=</code></b><i>level</i></td>
+ <td>
+ select the debug information level of release,
+ fastdebug, or slowdebug
+ </td>
+ </tr>
+ <tr>
+ <td><b><code>--with-dev-kit=</code></b><i>path</i></td>
+ <td>
+ select location of the compiler install or
+ developer install location
+ </td>
+ </tr>
+ <tr>
+ <td><b><code>--with-dxsdk=</code></b><i>path</i></td>
+ <td>
+ select location of the Windows Direct X SDK install
+ <br>
+ The <a name="dxsdk">Microsoft DirectX 9.0 SDK</a>
+ header files and libraries
+ from the Summer 2004 edition
+ are required for building OpenJDK.
+ This SDK can be downloaded from
+ <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=FD044A42-9912-42A3-9A9E-D857199F888E&displaylang=en" target="_blank">
+ Microsoft DirectX 9.0 SDK (Summer 2004)</a>.
+ If the link above becomes obsolete, the SDK can be found from
+ <a href="http://download.microsoft.com" target="_blank">the Microsoft Download Site</a>
+ (search with "DirectX 9.0 SDK Update Summer 2004").
+ Installation usually will set the environment variable
+ <code>DXSDK_DIR</code> to it's install location.
+ </td>
+ </tr>
+ <tr>
+ <td><b><code>--with-freetype=</code></b><i>path</i></td>
+ <td>
+ select the freetype files to use.
+ <br>
+ Expecting the
+ <a name="freetype">freetype</a> libraries under
+ <code>lib/</code> and the
+ headers under <code>include/</code>.
+ <br>
+ Version 2.3 or newer of FreeType is required.
+ On Unix systems required files can be available as part of your
+ distribution (while you still may need to upgrade them).
+ Note that you need development version of package that
+ includes both the FreeType library and header files.
+ <br>
+ You can always download latest FreeType version from the
+ <a href="http://www.freetype.org" target="_blank">FreeType website</a>.
+ <br>
+ Building the freetype 2 libraries from scratch is also possible,
+ however on Windows refer to the
+ <a href="http://freetype.freedesktop.org/wiki/FreeType_DLL">
+ Windows FreeType DLL build instructions</a>.
+ <br>
+ Note that by default FreeType is built with byte code hinting
+ support disabled due to licensing restrictions.
+ In this case, text appearance and metrics are expected to
+ differ from Sun's official JDK build.
+ See
+ <a href="http://freetype.sourceforge.net/freetype2/index.html">
+ the SourceForge FreeType2 Home Page
+ </a>
+ for more information.
+ </td>
+ </tr>
+ <tr>
+ <td><b><code>--with-import-hotspot=</code></b><i>path</i></td>
+ <td>
+ select the location to find hotspot
+ binaries from a previous build to avoid building
+ hotspot
+ </td>
+ </tr>
+ <tr>
+ <td><b><code>--with-target-bits=</code></b><i>arg</i></td>
+ <td>
+ select 32 or 64 bit build
+ </td>
+ </tr>
+ <tr>
+ <td><b><code>--with-jvm-variants=</code></b><i>variants</i></td>
+ <td>
+ select the JVM variants to build from, comma
+ separated list that can include:
+ server, client, kernel, zero and zeroshark
+ </td>
+ </tr>
+ <tr>
+ <td><b><code>--with-memory-size=</code></b><i>size</i></td>
+ <td>
+ select the RAM size that GNU make will think
+ this system has
+ </td>
+ </tr>
+ <tr>
+ <td><a name="msvcrNN"><b><code>--with-msvcr-dll=</code></b><i>path</i></a></td>
+ <td>
+ select the <code>msvcr100.dll</code>
+ file to include in the
+ Windows builds (C/C++ runtime library for
+ Visual Studio).
+ <br>
+ This is usually picked up automatically
+ from the redist
+ directories of Visual Studio 2010.
+ </td>
+ </tr>
+ <tr>
+ <td><b><code>--with-num-cores=</code></b><i>cores</i></td>
+ <td>
+ select the number of cores to use (processor
+ count or CPU count)
+ </td>
+ </tr>
+ <tr>
+ <td><b><code>--with-x=</code></b><i>path</i></td>
+ <td>
+ select the location of the X11 and xrender files.
+ <br>
+ The
+ <a name="xrender">XRender Extension Headers</a>
+ are required for building the
+ OpenJDK on Solaris and Linux.
+ <br>
+ The Linux header files are usually available from a "Xrender"
+ development package, it's recommended that you try and use
+ the package provided by the particular distribution of Linux that
+ you are using.
+ <br>
+ The Solaris XRender header files is
+ included with the other X11 header files
+ in the package <strong>SFWxwinc</strong>
+ on new enough versions of
+ Solaris and will be installed in
+ <code>/usr/X11/include/X11/extensions/Xrender.h</code> or
+ <code>/usr/openwin/share/include/X11/extensions/Xrender.h</code>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </blockquote>
+
</blockquote>
- <p>
- Mercurial packages could not be found easily, but a Google
- search should find ones, and they usually include Python if
- it's needed.
- </blockquote>
- <!-- ------------------------------------------------------ -->
- <h3><a name="debian">Debian</a></h3>
- <blockquote>
- <h4>Debian 5.0 (Lenny)</h4>
- <p>
+
+ <!-- ====================================================== -->
+ <hr>
+ <h3><a name="make">Make</a></h3>
<blockquote>
- After installing <a href="http://debian.org">Debian</a> 5
- you need to install several build dependencies.
- The simplest way to install the build dependencies is to
- execute the following commands as user <tt>root</tt>:
- <p/>
- <code>aptitude build-dep openjdk-6</code>
- <p/>
- <code>aptitude install openjdk-6-jdk libmotif-dev</code>
- <p/>
- In addition, it's necessary to set a few environment variables for the build:
- <p/>
- <code>export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-6-openjdk</code>
+ The basic invocation of the <code>make</code> utility
+ looks like:
+ <blockquote>
+ <b><code>make all</code></b>
+ </blockquote>
+ This will start the build to the output directory containing the
+ "configuration" that was created by the <code>configure</code>
+ script. Run <code>make help</code> for more information on
+ the available targets.
+ <br>
+ There are some of the make targets that
+ are of general interest:
+ <table border="1">
+ <thead>
+ <tr>
+ <th>Make Target</th>
+ <th>Description</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><i>empty</i></td>
+ <td>build everything but no images</td>
+ </tr>
+ <tr>
+ <td><b><code>all</code></b></td>
+ <td>build everything including images</td>
+ </tr>
+ <tr>
+ <td><b><code>all-conf</code></b></td>
+ <td>build all configurations</td>
+ </tr>
+ <tr>
+ <td><b><code>images</code></b></td>
+ <td>create complete j2sdk and j2re images</td>
+ </tr>
+ <tr>
+ <td><b><code>install</code></b></td>
+ <td>install the generated images locally,
+ typically in <code>/usr/local</code></td>
+ </tr>
+ <tr>
+ <td><b><code>clean</code></b></td>
+ <td>remove all files generated by make,
+ but not those generated by <code>configure</code></td>
+ </tr>
+ <tr>
+ <td><b><code>dist-clean</code></b></td>
+ <td>remove all files generated by both
+ and <code>configure</code> (basically killing the configuration)</td>
+ </tr>
+ <tr>
+ <td><b><code>help</code></b></td>
+ <td>give some help on using <code>make</code>,
+ including some interesting make targets</td>
+ </tr>
+ </tbody>
+ </table>
</blockquote>
</blockquote>
+
<!-- ====================================================== -->
- <h3><a name="ubuntu">Ubuntu</a></h3>
- <blockquote>
- <h4>Ubuntu 8.04</h4>
- <p>
- <blockquote>
- After installing <a href="http://ubuntu.org">Ubuntu</a> 8.04
- you need to install several build dependencies.
- <p/>
- First, you need to enable the universe repository in the
- Software Sources application and reload the repository
- information. The Software Sources application is available
- under the System/Administration menu.
- <p/>
- The simplest way to install the build dependencies is to
- execute the following commands:
- <p/>
- <code>sudo aptitude build-dep openjdk-6</code>
- <p/>
- <code>sudo aptitude install openjdk-6-jdk</code>
- <p/>
- In addition, it's necessary to set a few environment variables for the build:
- <p/>
- <code>export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-6-openjdk</code>
- </blockquote>
- <h4>Ubuntu 8.10</h4>
- <p>
- <blockquote>
- After installing <a href="http://ubuntu.org">Ubuntu</a> 8.10
- you need to install several build dependencies. The simplest
- way to do it is to execute the following commands:
- <p/>
- <code>sudo aptitude build-dep openjdk-6</code>
- <p/>
- <code>sudo aptitude install openjdk-6-jdk</code>
- <p/>
- In addition, it's necessary to set a few environment variables for the build:
- <p/>
- <code>export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-6-openjdk</code>
- </blockquote>
- <h4>Ubuntu 9.04</h4>
- <p>
- <blockquote>
- After installing <a href="http://ubuntu.org">Ubuntu</a> 9.04
- you need to install several build dependencies. The simplest
- way to do it is to execute the following commands:
- <p/>
- <code>sudo aptitude build-dep openjdk-6</code>
- <p/>
- <code>sudo aptitude install openjdk-6-jdk</code>
- <p/>
- In addition, it's necessary to set a few environment variables for the build:
- <p/>
- <code>export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-6-openjdk</code>
- </blockquote>
- </blockquote>
- <!-- ====================================================== -->
- <h3><a name="opensuse">OpenSUSE</a></h3>
+ <hr>
+ <h2><a name="testing">Testing</a></h2>
<blockquote>
- <h4>OpenSUSE 11.1</h4>
- <p>
- <blockquote>
- After installing <a href="http://opensuse.org">OpenSUSE</a> 11.1
- you need to install several build dependencies.
- The simplest way to install the build dependencies is to
- execute the following commands:
- <p/>
- <code>sudo zypper source-install -d java-1_6_0-openjdk</code>
- <p/>
- <code>sudo zypper install make</code>
- <p/>
- In addition, it is necessary to set a few environment variables for the build:
- <p/>
- <code>export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-1.6.0-openjdk</code>
- <p/>
- Finally, you need to unset the <code>JAVA_HOME</code> environment variable:
- <p/>
- <code>export -n JAVA_HOME</code>
- </blockquote>
- </blockquote>
- <!-- ====================================================== -->
- <h3><a name="mandriva">Mandriva</a></h3>
- <blockquote>
- <h4>Mandriva Linux One 2009 Spring</h4>
- <p>
+ When the build is completed, you should see the generated
+ binaries and associated files in the <code>j2sdk-image</code>
+ directory in the output directory.
+ In particular, the
+ <code>build/<i>*</i>/images/j2sdk-image/bin</code>
+ directory should contain executables for the
+ OpenJDK tools and utilities for that configuration.
+ The testing tool <code>jtreg</code> will be needed
+ and can be found at:
+ <a href="http://openjdk.java.net/jtreg/" target="_blank">
+ the jtreg site</a>.
+ The provided regression tests in the repositories
+ can be run with the command:
<blockquote>
- After installing <a href="http://mandriva.org">Mandriva</a> Linux One 2009 Spring
- you need to install several build dependencies.
- The simplest way to install the build dependencies is to
- execute the following commands as user <tt>root</tt>:
- <p/>
- <code>urpmi java-1.6.0-openjdk-devel ant make gcc gcc-c++ freetype-devel zip unzip libcups2-devel libxrender1-devel libalsa2-devel libstc++-static-devel libxtst6-devel libxi-devel</code>
- <p/>
- In addition, it is necessary to set a few environment variables for the build:
- <p/>
- <code>export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-1.6.0-openjdk</code>
- </blockquote>
- </blockquote>
- <!-- ====================================================== -->
- <h3><a name="opensolaris">OpenSolaris</a></h3>
- <blockquote>
- <h4>OpenSolaris 2009.06</h4>
- <p>
- <blockquote>
- After installing <a href="http://opensolaris.org">OpenSolaris</a> 2009.06
- you need to install several build dependencies.
- The simplest way to install the build dependencies is to
- execute the following commands:
- <p/>
- <code>pfexec pkg install SUNWgmake SUNWj6dev SUNWant sunstudioexpress SUNWcups SUNWzip SUNWunzip SUNWxwhl SUNWxorg-headers SUNWaudh SUNWfreetype2</code>
- <p/>
- In addition, it is necessary to set a few environment variables for the build:
- <p/>
- <code>export LANG=C ALT_COMPILER_PATH=/opt/SunStudioExpress/bin/ ALT_CUPS_HEADERS_PATH=/usr/include/</code>
- <p/>
- Finally, you need to make sure that the build process can find the Sun Studio compilers:
- <p/>
- <code>export PATH=$PATH:/opt/SunStudioExpress/bin/</code>
+ <code><b>cd test && make PRODUCT_HOME=`pwd`/../build/*/images/j2sdk-image all</b></code>
</blockquote>
</blockquote>
- <!-- ------------------------------------------------------ -->
+
+ <!-- ====================================================== -->
+ <!-- ====================================================== -->
+ <!-- ====================================================== -->
+ <!-- ====================================================== -->
+ <!-- ====================================================== -->
+ <!-- ====================================================== -->
+ <!-- ====================================================== -->
+ <!-- ====================================================== -->
+ <!-- ====================================================== -->
+
+ <!-- ====================================================== -->
<hr>
- <h2><a name="directories">Source Directory Structure</a></h2>
+ <h2><a name="hints">Appendix A: Hints and Tips</a></h2>
<blockquote>
- <p>
- The source code for the OpenJDK is delivered in a set of
- directories:
- <tt>hotspot</tt>,
- <tt>langtools</tt>,
- <tt>corba</tt>,
- <tt>jaxws</tt>,
- <tt>jaxp</tt>,
- and
- <tt>jdk</tt>.
- The <tt>hotspot</tt> directory contains the source code and make
- files for building the OpenJDK Hotspot Virtual Machine.
- The <tt>langtools</tt> directory contains the source code and make
- files for building the OpenJDK javac and language tools.
- The <tt>corba</tt> directory contains the source code and make
- files for building the OpenJDK Corba files.
- The <tt>jaxws</tt> directory contains the source code and make
- files for building the OpenJDK JAXWS files.
- The <tt>jaxp</tt> directory contains the source code and make
- files for building the OpenJDK JAXP files.
- The <tt>jdk</tt> directory contains the source code and make files for
- building the OpenJDK runtime libraries and misc files.
- The top level <tt>Makefile</tt>
- is used to build the entire OpenJDK.
+
+ <h3><a name="faq">FAQ</a></h3>
+ <blockquote>
- <h3><a name="drops">Managing the Source Drops</a></h3>
- <blockquote>
+ <p>
+ <b>Q:</b> The <code>configure</code> file looks horrible!
+ How are you going to edit it?
+ <br>
+ <b>A:</b> The <code>configure</code> file is generated (think
+ "compiled") by the autoconf tools. The source code is
+ in <code>configure.ac</code> various .m4 files in common/autoconf,
+ which are
+ much more readable.
+ </p>
+
<p>
- The repositories <tt>jaxp</tt> and <tt>jaxws</tt> actually
- do not contain the sources for JAXP or JAX-WS.
- These products have their own open source procedures at their
- <a href="http://jaxp.java.net/">JAXP</a> and
- <a href="http://jax-ws.java.net/">JAX-WS</a> home pages.
- The OpenJDK project does need access to these sources to build
- a complete JDK image because JAXP and JAX-WS are part of the JDK.
- The current process for delivery of the JAXP and JAX-WS sources
- involves so called "source drop bundles" downloaded from a public
- website.
- There are many reasons for this current mechanism, and it is
- understood that this is not ideal for the open source community.
- It is possible this process could change in the future.
+ <b>Q:</b>
+ Why is the <code>configure</code> file checked in,
+ if it is generated?
<br>
- <b>NOTE:</b> The <a href="http://download.java.net/openjdk/jdk8/">
- Complete OpenJDK Source Bundles</a> <u>will</u> contain the JAXP and
- JAX-WS sources.
+ <b>A:</b>
+ If it was not generated, every user would need to have the autoconf
+ tools installed, and re-generate the <code>configure</code> file
+ as the first step.
+ Our goal is to minimize the work needed to be done by the user
+ to start building OpenJDK, and to minimize
+ the number of external dependencies required.
</p>
- <h4><a name="dropcreation">Creation of New Source Drop Bundles</a></h4>
+ <p>
+ <b>Q:</b>
+ Do you require a specific version of autoconf for regenerating
+ <code>configure</code>?
+ <br>
+ <b>A:</b>
+ Currently, no, but this will likely be the case when things have
+ settled down a bit more. (The reason for this is to avoid
+ large spurious changes in <code>configure</code>
+ in commits that made small changes to <code>configure.ac</code>).
+ </p>
+
+ <p>
+ <b>Q:</b>
+ What are the files in <code>common/makefiles/support/*</code> for?
+ They look like gibberish.
+ <br>
+ <b>A:</b>
+ They are a somewhat ugly hack to compensate for command line length
+ limitations on certain platforms (Windows, Solaris).
+ Due to a combination of limitations in make and the shell,
+ command lines containing too many files will not work properly.
+ These
+ helper files are part of an elaborate hack that will compress the
+ command line in the makefile and then uncompress it safely.
+ We're
+ not proud of it, but it does fix the problem.
+ If you have any better suggestions, we're all ears! :-)
+ </p>
+
+ <p>
+ <b>Q:</b>
+ I want to see the output of the commands that make runs,
+ like in the old build. How do I do that?
+ <br>
+ <b>A:</b>
+ You specify the <code>LOG</code> variable to make. There are
+ several log levels:
+ </p>
<blockquote>
- <ol>
+ <ul>
<li>
- The JAXP or JAX-WS team prepares a new zip bundle,
- places a copy in a public download area on java.net,
- sends us a link and a list of CRs (Change Request Numbers).
- The older download bundles should not be deleted.
- It is the responsibility of the JAXP and JAX-WS team to
- place the proper GPL legal notices on the sources
- and do any filtering or java re-packaging for the
- OpenJDK instances of these classes.
+ <b><code>warn</code></b> — Default and very quiet.
</li>
<li>
- The OpenJDK team copies this new bundle into shared
- area (e.g. <tt>/java/devtools/share/jdk8-drops</tt>).
- Older bundles are never deleted so we retain the history.
+ <b><code>info</code></b> — Shows more progress information
+ than warn.
</li>
<li>
- The OpenJDK team edits the ant property file
- <tt>jaxp/jaxp.properties</tt> or
- <tt>jaxws/jaxws.properties</tt> to update the
- base URL, the zip bundle name, and the MD5 checksum
- of the zip bundle
- (on Solaris: <tt>sum -c md5 <i>bundlename</i></tt>)
+ <b><code>debug</code></b> — Echos all command lines and
+ prints all macro calls for compilation definitions.
</li>
<li>
- OpenJDK team reviews and commits those changes with the
- given CRs.
+ <b><code>trace</code></b> — Echos all $(shell) command
+ lines as well.
</li>
- </ol>
+ </ul>
</blockquote>
- <h4><a name="dropusage">Using Source Drop Bundles</a></h4>
+ <p>
+ <b>Q:</b>
+ When do I have to re-run <code>configure</code>?
+ <br>
+ <b>A:</b>
+ Normally you will run <code>configure</code> only once for creating a
+ configuration.
+ You need to re-run configuration only if you want to change any
+ configuration options,
+ or if you pull down changes to the <code>configure</code> script.
+ </p>
+
+ <p>
+ <b>Q:</b>
+ I have added a new source file. Do I need to modify the makefiles?
+ <br>
+ <b>A:</b>
+ Normally, no. If you want to create e.g. a new native
+ library,
+ you will need to modify the makefiles. But for normal file
+ additions or removals, no changes are needed. There are certan
+ exceptions for some native libraries where the source files are spread
+ over many directories which also contain courses for other
+ libraries. In these cases it was simply easier to create include lists
+ rather thane excludes.
+ </p>
+
+ <p>
+ <b>Q:</b>
+ When I run <code>configure --help</code>, I see many strange options,
+ like <code>--dvidir</code>. What is this?
+ <br>
+ <b>A:</b>
+ Configure provides a slew of options by default, to all projects
+ that use autoconf. Most of them are not used in OpenJDK,
+ so you can safely ignore them. To list only OpenJDK specific features,
+ use <code>configure --help=short</code> instead.
+ </p>
+
+ <p>
+ <b>Q:</b>
+ <code>configure</code> provides OpenJDK-specific features such as
+ <code>--enable-jigsaw</code> or <code>--with-builddeps-server</code>
+ that are not described in this document. What about those?
+ <br>
+ <b>A:</b>
+ Try them out if you like! But be aware that most of these are
+ experimental features.
+ Many of them don't do anything at all at the moment; the option
+ is just a placeholder. Other depends on
+ pieces of code or infrastructure that is currently
+ not ready for prime time.
+ </p>
+
+ <p>
+ <b>Q:</b>
+ How will you make sure you don't break anything?
+ <br>
+ <b>A:</b>
+ We have a script that compares the result of the new build system
+ with the result of the old. For most part, we aim for (and achieve)
+ byte-by-byte identical output. There are however technical issues
+ with e.g. native binaries, which might differ in a byte-by-byte
+ comparison, even
+ when building twice with the old build system.
+ For these, we compare relevant aspects
+ (e.g. the symbol table and file size).
+ Note that we still don't have 100%
+ equivalence, but we're close.
+ </p>
+
+ <p>
+ <b>Q:</b>
+ I noticed this thing X in the build that looks very broken by design.
+ Why don't you fix it?
+ <br>
+ <b>A:</b>
+ Our goal is to produce a build output that is as close as
+ technically possible to the old build output.
+ If things were weird in the old build,
+ they will be weird in the new build.
+ Often, things were weird before due to obscurity,
+ but in the new build system the weird stuff comes up to the surface.
+ The plan is to attack these things at a later stage,
+ after the new build system is established.
+ </p>
+
+ <p>
+ <b>Q:</b>
+ The code in the new build system is not that well-structured.
+ Will you fix this?
+ <br>
+ <b>A:</b>
+ Yes! The new build system has grown bit by bit as we converted
+ the old system. When all of the old build system is converted,
+ we can take a step back and clean up the structure of the new build
+ system. Some of this we plan to do before replacing the old build
+ system and some will need to wait until after.
+ </p>
+
+ <p>
+ <b>Q:</b> What is @GenerateNativeHeaders?
+ <br>
+ <b>A:</b>
+ To speed up compilation, we added a flag to javac which makes it
+ do the job of javah as well, as a by-product; that is, generating
+ native .h header files. These files are only generated
+ if a class contains native methods. However, sometimes
+ a class contains no native method,
+ but still contains constants that native code needs to use.
+ The new GenerateNativeHeaders annotation tells javac to
+ force generation of a
+ header file in these cases. (We don't want to generate
+ native headers for all classes that contains constants
+ but no native methods, since
+ that would slow down the compilation process needlessly.)
+ </p>
+
+ <p>
+ <b>Q:</b>
+ Is anything able to use the results of the new build's default make target?
+ <br>
+ <b>A:</b>
+ Yes, this is the minimal (or roughly minimal)
+ set of compiled output needed for a developer to actually
+ execute the newly built JDK. The idea is that in an incremental
+ development fashion, when doing a normal make,
+ you should only spend time recompiling what's changed
+ (making it purely incremental) and only do the work that's
+ needed to actually run and test your code.
+ The packaging stuff that is part of the <code>images</code>
+ target is not needed for a normal developer who wants to
+ test his new code. Even if it's quite fast, it's still unnecessary.
+ We're targeting sub-second incremental rebuilds! ;-)
+ (Or, well, at least single-digit seconds...)
+ </p>
+
+ <p>
+ <b>Q:</b>
+ I usually set a specific environment variable when building,
+ but I can't find the equivalent in the new build.
+ What should I do?
+ <br>
+ <b>A:</b>
+ It might very well be that we have missed to add support for
+ an option that was actually used from outside the build system.
+ Email us and we will
+ add support for it!
+ </p>
+
+ </blockquote>
+
+ <h3><a name="performance">Build Performance Tips</a></h3>
+ <blockquote>
+
+ <p>Building OpenJDK requires a lot of horsepower.
+ Some of the build tools can be adjusted to utilize more or less
+ of resources such as
+ parallel threads and memory.
+ The <code>configure</code> script analyzes your system and selects reasonable
+ values for such options based on your hardware.
+ If you encounter resource problems, such as out of memory conditions,
+ you can modify the detected values with:</p>
+
+ <ul>
+ <li>
+ <b><code>--with-num-cores</code></b>
+ —
+ number of cores in the build system,
+ e.g. <code>--with-num-cores=8</code>
+ </li>
+ <li>
+ <b><code>--with-memory-size</code></b>
+ — memory (in MB) available in the build system,
+ e.g. <code>--with-memory-size=1024</code>
+ </li>
+ </ul>
+
+ <p>It might also be necessary to specify the JVM arguments passed
+ to the Bootstrap JDK, using e.g.
+ <code>--with-boot-jdk-jvmargs="-Xmx8G -enableassertions"</code>.
+ Doing this will override the default JVM arguments
+ passed to the Bootstrap JDK.</p>
+
+
+ <p>One of the top goals of the new build system is to improve the
+ build performance and decrease the time needed to build. This will
+ soon also apply to the java compilation when the Smart Javac wrapper
+ is making its way into jdk8. It can be tried in the build-infra
+ repository already. You are likely to find that the new build system
+ is faster than the old one even without this feature.</p>
+
+ <p>At the end of a successful execution of <code>configure</code>,
+ you will get a performance summary,
+ indicating how well the build will perform. Here you will
+ also get performance hints.
+ If you want to build fast, pay attention to those!</p>
+
+ <h4>Building with ccache</h4>
+
+ <p>A simple way to radically speed up compilation of native code
+ (typically hotspot and native libraries in JDK) is to install
+ ccache. This will cache and reuse prior compilation results, if the
+ source code is unchanged. However, ccache versions prior to 3.1.4
+ does not work correctly with the precompiled headers used in
+ OpenJDK. So if your platform supports ccache at 3.1.4 or later, we
+ highly recommend installing it. This is currently only supported on
+ linux.</p>
+
+ <h4>Building on local disk</h4>
+
+ <p>If you are using network shares, e.g. via NFS, for your source code,
+ make sure the build directory is situated on local disk.
+ The performance
+ penalty is extremely high for building on a network share,
+ close to unusable.</p>
+
+ <h4>Building only one JVM</h4>
+
+ <p>The old build builds multiple JVMs on 32-bit systems (client and
+ server; and on Windows kernel as well). In the new build we have
+ changed this default to only build server when it's available. This
+ improves build times for those not interested in multiple JVMs. To
+ mimic the old behavior on platforms that support it,
+ use <code>--with-jvm-variants=client,server</code>.</p>
+
+ <h4>Selecting the number of cores to build on</h4>
+
+ <p>By default, <code>configure</code> will analyze your machine and run the make
+ process in parallel with as many threads as you have cores. This
+ behavior can be overridden, either "permanently" (on a <code>configure</code>
+ basis) using <code>--with-num-cores=N</code> or for a single build
+ only (on a make basis), using <code>make JOBS=N</code>.</p>
+
+ <p>If you want to make a slower build just this time, to save some CPU
+ power for other processes, you can run
+ e.g. <code>make JOBS=2</code>. This will force the makefiles
+ to only run 2 parallel processes, or even <code>make JOBS=1</code>
+ which will disable parallelism.</p>
+
+ <p>If you want to have it the other way round, namely having slow
+ builds default and override with fast if you're
+ impatient, you should call <code>configure</code> with
+ <code>--with-num-cores=2</code>, making 2 the default.
+ If you want to run with more
+ cores, run <code>make JOBS=8</code></p>
+
+ </blockquote>
+
+ <h3><a name="troubleshooting">Troubleshooting</a></h3>
+ <blockquote>
+
+ <h4>Solving build problems</h4>
+
<blockquote>
- <p>
- The ant scripts that build <tt>jaxp</tt> and <tt>jaxws</tt>
- will attempt to locate these zip bundles from the directory
- in the environment variable
- <tt><a href="#ALT_DROPS_DIR">ALT_DROPS_DIR</a></tt>.
- The checksums protect from getting the wrong, corrupted, or
- improperly modified sources.
- Once the sources are made available, the population will not
- happen again unless a <tt>make clobber</tt> is requested
- or the <tt>jaxp/drop/</tt> or <tt>jaxws/drop/</tt>
- directory is explicitly deleted.
- <br>
- <b>NOTE:</b> The default Makefile and ant script behavior
- is to NOT download these bundles from the public http site.
- In general, doing downloads
- during the build process is not advised, it creates too much
- unpredictability in the build process.
- However, you can use <tt>make ALLOW_DOWNLOADS=true</tt> to
- tell the ant script that the download of the zip bundle is
- acceptable.
- </p>
- <p>
- The recommended procedure for keeping a cache of these
- source bundles would be to download them once, place them
- in a directory outside the repositories, and then set
- <tt><a href="#ALT_DROPS_DIR">ALT_DROPS_DIR</a></tt> to refer
- to that directory.
- These drop bundles do change occasionally, so the newer
- bundles may need to be added to this area from time to time.
- </p>
+ If the build fails (and it's not due to a compilation error in
+ a source file you've changed), the first thing you should do
+ is to re-run the build with more verbosity.
+ Do this by adding <code>LOG=debug</code> to your make command line.
+ <br>
+ The build log (with both stdout and stderr intermingled,
+ basically the same as you see on your console) can be found as
+ <code>build.log</code> in your build directory.
+ <br>
+ You can ask for help on build problems with the new build system
+ on either the
+ <a href="http://mail.openjdk.java.net/mailman/listinfo/build-dev">
+ build-dev</a>
+ or the
+ <a href="http://mail.openjdk.java.net/mailman/listinfo/build-infra-dev">
+ build-infra-dev</a>
+ mailing lists. Please include the relevant parts
+ of the build log.
+ <br>
+ A build can fail for any number of reasons.
+ Most failures
+ are a result of trying to build in an environment in which all the
+ pre-build requirements have not been met.
+ The first step in
+ troubleshooting a build failure is to recheck that you have satisfied
+ all the pre-build requirements for your platform.
+ Scanning the <code>configure</code> log is a good first step, making
+ sure that what it found makes sense for your system.
+ Look for strange error messages or any difficulties that
+ <code>configure</code> had in finding things.
+ <br>
+ Some of the more common problems with builds are briefly
+ described
+ below, with suggestions for remedies.
+ <ul>
+ <li>
+ <b>Corrupted Bundles on Windows:</b>
+ <blockquote>
+ Some virus scanning software has been known to
+ corrupt the
+ downloading of zip bundles.
+ It may be necessary to disable the 'on access' or
+ 'real time'
+ virus scanning features to prevent this corruption.
+ This type of "real time" virus scanning can also
+ slow down the
+ build process significantly.
+ Temporarily disabling the feature, or excluding the build
+ output directory may be necessary to get correct and
+ faster builds.
+ </blockquote>
+ </li>
+ <li>
+ <b>Slow Builds:</b>
+ <blockquote>
+ If your build machine seems to be overloaded from too many
+ simultaneous C++ compiles, try setting the
+ <code>JOBS=1</code> on the <code>make</code> command line.
+ Then try increasing the count slowly to an acceptable
+ level for your system. Also:
+ <blockquote>
+ Creating the javadocs can be very slow,
+ if you are running
+ javadoc, consider skipping that step.
+ <br>
+ Faster CPUs, more RAM, and a faster DISK usually helps.
+ The VM build tends to be CPU intensive
+ (many C++ compiles),
+ and the rest of the JDK will often be disk intensive.
+ <br>
+ Faster compiles are possible using a tool called
+ <a href="http://ccache.samba.org/" target="_blank">ccache</a>.
+ </blockquote>
+ </blockquote>
+ </li>
+ <li>
+ <b>File time issues:</b>
+ <blockquote>
+ If you see warnings that refer to file time stamps, e.g.
+ <blockquote>
+ <i>Warning message:</i><code>
+ File `xxx' has modification time in
+ the future.</code>
+ <br>
+ <i>Warning message:</i> <code> Clock skew detected.
+ Your build may
+ be incomplete.</code>
+ </blockquote>
+ These warnings can occur when the clock on the build
+ machine is out of
+ sync with the timestamps on the source files.
+ Other errors, apparently
+ unrelated but in fact caused by the clock skew,
+ can occur along with
+ the clock skew warnings.
+ These secondary errors may tend to obscure the
+ fact that the true root cause of the problem
+ is an out-of-sync clock.
+ <p>
+ If you see these warnings, reset the clock on the
+ build
+ machine, run "<code><i>gmake</i> clobber</code>"
+ or delete the directory
+ containing the build output, and restart the
+ build from the beginning.
+ </blockquote>
+ </li>
+ <li>
+ <b>Error message:
+ <code>Trouble writing out table to disk</code></b>
+ <blockquote>
+ Increase the amount of swap space on your build machine.
+ This could be caused by overloading the system and
+ it may be necessary to use:
+ <blockquote>
+ <code>make JOBS=1</code>
+ </blockquote>
+ to reduce the load on the system.
+ </blockquote>
+ </li>
+ <li>
+ <b>Error Message:
+ <code>libstdc++ not found:</code></b>
+ <blockquote>
+ This is caused by a missing libstdc++.a library.
+ This is installed as part of a specific package
+ (e.g. libstdc++.so.devel.386).
+ By default some 64-bit Linux versions (e.g. Fedora)
+ only install the 64-bit version of the libstdc++ package.
+ Various parts of the JDK build require a static
+ link of the C++ runtime libraries to allow for maximum
+ portability of the built images.
+ </blockquote>
+ </li>
+ <li>
+ <b>Linux Error Message:
+ <code>cannot restore segment prot after reloc</code></b>
+ <blockquote>
+ This is probably an issue with SELinux (See
+ <a href="http://en.wikipedia.org/wiki/SELinux" target="_blank">
+ http://en.wikipedia.org/wiki/SELinux</a>).
+ Parts of the VM is built without the <code>-fPIC</code> for
+ performance reasons.
+ <p>
+ To completely disable SELinux:
+ <ol>
+ <li><code>$ su root</code></li>
+ <li><code># system-config-securitylevel</code></li>
+ <li><code>In the window that appears, select the SELinux tab</code></li>
+ <li><code>Disable SELinux</code></li>
+ </ol>
+ <p>
+ Alternatively, instead of completely disabling it you could
+ disable just this one check.
+ <ol>
+ <li>Select System->Administration->SELinux Management</li>
+ <li>In the SELinux Management Tool which appears,
+ select "Boolean" from the menu on the left</li>
+ <li>Expand the "Memory Protection" group</li>
+ <li>Check the first item, labeled
+ "Allow all unconfined executables to use
+ libraries requiring text relocation ..."</li>
+ </ol>
+ </blockquote>
+ </li>
+ <li>
+ <b>Windows Error Messages:</b>
+ <br>
+ <code>*** fatal error - couldn't allocate heap, ... </code>
+ <br>
+ <code>rm fails with "Directory not empty"</code>
+ <br>
+ <code>unzip fails with "cannot create ... Permission denied"</code>
+ <br>
+ <code>unzip fails with "cannot create ... Error 50"</code>
+ <br>
+ <blockquote>
+ The CYGWIN software can conflict with other non-CYGWIN
+ software. See the CYGWIN FAQ section on
+ <a href="http://cygwin.com/faq/faq.using.html#faq.using.bloda" target="_blank">
+ BLODA (applications that interfere with CYGWIN)</a>.
+ </blockquote>
+ </li>
+ <li>
+ <b>Windows Error Message: <code>spawn failed</code></b>
+ <blockquote>
+ Try rebooting the system, or there could be some kind of
+ issue with the disk or disk partition being used.
+ Sometimes it comes with a "Permission Denied" message.
+ </blockquote>
+ </li>
+ </ul>
</blockquote>
- </blockquote>
- </blockquote>
- <!-- ------------------------------------------------------ -->
+
+ </blockquote> <!-- Troubleshooting -->
+
+ </blockquote> <!-- Appendix A -->
+
+ <!-- ====================================================== -->
<hr>
- <h2><a name="building">Build Information</a></h2>
+ <h2><a name="gmake">Appendix B: GNU make</a></h2>
<blockquote>
- Building the OpenJDK
- is done with a <a href="#gmake">GNU <tt>make</tt></a> command line
- and various
- environment or make variable settings that direct the makefile rules
- to where various components have been installed.
- Where possible the makefiles will attempt to located the various
- components in the default locations or any component specific
- variable settings.
- When the normal defaults fail or components cannot be found,
- the various
- <tt>ALT_*</tt> variables (alternates)
- can be used to help the makefiles locate components.
- <p>
- Refer to the bash/sh/ksh setup file
- <tt>jdk/make/jdk_generic_profile.sh</tt>
- if you need help in setting up your environment variables.
- A build could be as simple as:
- <blockquote>
- <pre><tt>
- bash
- . jdk/make/jdk_generic_profile.sh
- <a href="#gmake"><tt>make</tt></a> sanity && <a href="#gmake"><tt>make</tt></a>
- </tt></pre>
- </blockquote>
- <p>
- Of course ksh or sh would work too.
- But some customization will probably be necessary.
- The <tt>sanity</tt> rule will make some basic checks on build
- dependencies and generate appropriate warning messages
- regarding missing, out of date, or newer than expected components
- found on your system.
- </blockquote>
- <!-- ------------------------------------------------------ -->
- <hr>
- <h3><a name="gmake">GNU make (<tt><i>gmake</i></tt>)</a></h3>
- <blockquote>
+
The Makefiles in the OpenJDK are only valid when used with the
- GNU version of the utility command <tt>make</tt>
- (<tt><i>gmake</i></tt>).
+ GNU version of the utility command <code>make</code>
+ (usually called <code>gmake</code> on Solaris).
A few notes about using GNU make:
<ul>
<li>
You need GNU make version 3.81 or newer.
- </li>
- <li>
- Place the location of the GNU make binary in the <tt>PATH</tt>.
+ If the GNU make utility on your systems is not
+ 3.81 or newer,
+ see <a href="#buildgmake">"Building GNU make"</a>.
</li>
<li>
- <strong>Linux:</strong>
- The <tt>/usr/bin/make</tt> should be 3.81 or newer
- and should work fine for you.
- If this version is not 3.81 or newer,
- see the <a href="#buildgmake">"Building GNU make"</a> section.
+ Place the location of the GNU make binary in the
+ <code>PATH</code>.
</li>
<li>
<strong>Solaris:</strong>
- Do NOT use <tt>/usr/bin/make</tt> on Solaris.
+ Do NOT use <code>/usr/bin/make</code> on Solaris.
If your Solaris system has the software
- from the Solaris Companion CD installed,
- you should try and use <tt>gmake</tt>
- which will be located in either the <tt>/opt/sfw/bin</tt> or
- <tt>/usr/sfw/bin</tt> directory.
- In more recent versions of Solaris GNU make might be found
- at <tt>/usr/bin/gmake</tt>.<br>
- <b>NOTE:</b> It is very likely that this <tt>gmake</tt>
- could be 3.80, you need 3.81, in which case,
- see the <a href="#buildgmake">"Building GNU make"</a> section.
+ from the Solaris Developer Companion CD installed,
+ you should try and use <code>gmake</code>
+ which will be located in either the
+ <code>/usr/bin</code>, <code>/opt/sfw/bin</code> or
+ <code>/usr/sfw/bin</code> directory.
</li>
<li>
<strong>Windows:</strong>
- Make sure you start your build inside a bash/sh/ksh shell and are
- using a <tt>make.exe</tt> utility built for that environment.<br/>
- <strong>MKS</strong> builds need a native Windows version of GNU make
- (see <a href="#buildgmake">Building GNU make</a>).<br/>
- <strong>Cygwin</strong> builds need
- a make version which was specially compiled for the Cygwin environment
- (see <a href="#buildgmake">Building GNU make</a>). <strong>WARNING:</strong>
- the OpenJDK build with the make utility provided by Cygwin will <strong>not</strong>
- work because it does not support drive letters in paths. Make sure that
- your version of make will be found before the Cygwins default make by
- setting an appropriate <tt>PATH</tt> environment variable or by removing
- Cygwin's make after you built your own make version.<br/>
- <strong>MinGW/MSYS</strong> builds can use the default make which
- comes with the environment.
+ Make sure you start your build inside a bash shell.
+ </li>
+ <li>
+ <strong>Mac OS X:</strong>
+ The XCode "command line tools" must be installed on your Mac.
</li>
</ul>
<p>
@@ -714,1539 +1775,728 @@
<a href="http://ftp.gnu.org/pub/gnu/make/" target="_blank">
ftp.gnu.org/pub/gnu/make/</a>.
</p>
- <!-- ------------------------------------------------------ -->
- <h4><a name="buildgmake">Building GNU make</a></h4>
+
+ <h3><a name="buildgmake">Building GNU make</a></h3>
<blockquote>
- First step is to get the GNU make 3.81 (or newer) source from
+ First step is to get the GNU make 3.81 or newer source from
<a href="http://ftp.gnu.org/pub/gnu/make/" target="_blank">
ftp.gnu.org/pub/gnu/make/</a>.
- Building is a little different depending on the OS and unix toolset
- on Windows:
- <ul>
- <li>
- <strong>Linux:</strong>
- <tt>./configure && make</tt>
- </li>
- <li>
- <strong>Solaris:</strong>
- <tt>./configure && gmake CC=gcc</tt>
- </li>
- <li>
- <strong>Windows for CYGWIN:</strong><br/>
- <tt>./configure</tt><br/>
- Add the line <tt>#define HAVE_CYGWIN_SHELL 1</tt> to the end of <tt>config.h</tt><br/>
- <tt>make</tt><br/>
- <br/>
- This should produce <tt>make.exe</tt> in the current directory.
- </li>
- <li>
- <strong>Windows for MKS:</strong><br/>
- Edit <tt>config.h.W32</tt> and uncomment the line <tt>#define HAVE_MKS_SHELL 1</tt><br/>
- Set the environment for your native compiler (e.g. by calling:<br/>
- <tt>"C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /Release /xp /x64)</tt>
- <tt>nmake -f NMakefile.win32</tt>
- <br/>
- This should produce <tt>WinDebug/make.exe</tt> and <tt>WinRel/make.exe</tt>
- <br/>
- If you get the error: <tt>NMAKE : fatal error U1045: spawn failed : Permission denied</tt>
- you have to set the <tt>Read & execute</tt> permission for the file <tt>subproc.bat</tt>.
- </li>
- </ul>
- </blockquote>
- </blockquote>
- <!-- ------------------------------------------------------ -->
- <hr>
- <h3><a name="linux">Basic Linux System Setup</a></h3>
- <blockquote>
- <strong>i586 only:</strong>
- The minimum recommended hardware for building the Linux version
- is a Pentium class processor or better, at least 256 MB of RAM, and
- approximately 1.5 GB of free disk space.
- <p>
- <strong>X64 only:</strong>
- The minimum recommended hardware for building the Linux
- version is an AMD Opteron class processor, at least 512 MB of RAM, and
- approximately 4 GB of free disk space.
- <p>
- The build will use the tools contained in
- <tt>/bin</tt> and
- <tt>/usr/bin</tt>
- of a standard installation of the Linux operating environment.
- You should ensure that these directories are in your
- <tt>PATH</tt>.
- <p>
- Note that some Linux systems have a habit of pre-populating
- your environment variables for you, for example <tt>JAVA_HOME</tt>
- might get pre-defined for you to refer to the JDK installed on
- your Linux system.
- You will need to unset <tt>JAVA_HOME</tt>.
- It's a good idea to run <tt>env</tt> and verify the
- environment variables you are getting from the default system
- settings make sense for building the
- OpenJDK.
- </blockquote>
- <!-- ------------------------------------------------------ -->
- <h4><a name="linux_checklist">Basic Linux Check List</a></h4>
- <blockquote>
- <ol>
- <li>
- Install the
- <a href="#bootjdk">Bootstrap JDK</a>, set
- <tt><a href="#ALT_BOOTDIR">ALT_BOOTDIR</a></tt>.
- </li>
- <li>
- <a href="#importjdk">Optional Import JDK</a>, set
- <tt><a href="#ALT_JDK_IMPORT_PATH">ALT_JDK_IMPORT_PATH</a></tt>.
- </li>
- <li>
- Install or upgrade the <a href="#freetype">FreeType development
- package</a>.
- </li>
- <li>
- Install
- <a href="#ant">Ant 1.7.1 or newer</a>,
- make sure it is in your PATH.
- </li>
- </ol>
- </blockquote>
- <!-- ------------------------------------------------------ -->
- <hr>
- <h3><a name="solaris">Basic Solaris System Setup</a></h3>
- <blockquote>
- The minimum recommended hardware for building the
- Solaris SPARC version is an UltraSPARC with 512 MB of RAM.
- For building
- the Solaris x86 version, a Pentium class processor or better and at
- least 512 MB of RAM are recommended.
- Approximately 1.4 GB of free disk
- space is needed for a 32-bit build.
- <p>
- If you are building the 64-bit version, you should
- run the command "isainfo -v" to verify that you have a
- 64-bit installation, it should say <tt>sparcv9</tt> or
- <tt>amd64</tt>.
- An additional 7 GB of free disk space is needed
- for a 64-bit build.
- <p>
- The build uses the tools contained in <tt>/usr/ccs/bin</tt>
- and <tt>/usr/bin</tt> of a standard developer or full installation of
- the Solaris operating environment.
- <p>
- Solaris patches specific to the JDK can be downloaded from the
- <a href="http://sunsolve.sun.com/show.do?target=patches/JavaSE" target="_blank">
- SunSolve JDK Solaris patches download page</a>.
- You should ensure that the latest patch cluster for
- your version of the Solaris operating environment has also
- been installed.
- </blockquote>
- <!-- ------------------------------------------------------ -->
- <h4><a name="solaris_checklist">Basic Solaris Check List</a></h4>
- <blockquote>
- <ol>
- <li>
- Install the
- <a href="#bootjdk">Bootstrap JDK</a>, set
- <tt><a href="#ALT_BOOTDIR">ALT_BOOTDIR</a></tt>.
- </li>
- <li>
- <a href="#importjdk">Optional Import JDK</a>, set
- <tt><a href="#ALT_JDK_IMPORT_PATH">ALT_JDK_IMPORT_PATH</a></tt>.
- </li>
- <li>
- Install the
- <a href="#studio">Sun Studio Compilers</a>, set
- <a href="#ALT_COMPILER_PATH"><tt>ALT_COMPILER_PATH</tt></a>.
- </li>
- <li>
- Install the
- <a href="#cups">CUPS Include files</a>, set
- <tt><a href="#ALT_CUPS_HEADERS_PATH">ALT_CUPS_HEADERS_PATH</a></tt>.
- </li>
- <li>
- Install the <a href="#xrender">XRender Include files</a>.
- </li>
- <li>
- Install
- <a href="#ant">Ant 1.7.1 or newer</a>,
- make sure it is in your PATH.
- </li>
- </ol>
- </blockquote>
- <!-- ------------------------------------------------------ -->
- <hr>
- <h3><a name="windows">Basic Windows System Setup</a></h3>
- <blockquote>
- <strong>i586 only:</strong>
- The minimum recommended hardware for building the 32-bit or X86
- Windows version is an Pentium class processor or better, at least
- 512 MB of RAM, and approximately 600 MB of free disk space.
- <strong>
- NOTE: The Windows build machines need to use the
- file system NTFS.
- Build machines formatted to FAT32 will not work
- because FAT32 doesn't support case-sensitivity in file names.
- </strong>
- <p>
- <strong>X64 only:</strong>
- The minimum recommended hardware for building
- the Windows X64 version is an AMD Opteron class processor, at least 1
- GB of RAM, and approximately 10 GB of free disk space.
- </blockquote>
- <!-- ------------------------------------------------------ -->
- <h4><a name="paths">Windows Paths</a></h4>
- <blockquote>
- <strong>Windows:</strong>
- Note that GNU make, the shell and other Unix-tools required during the build
- do not tolerate the Windows habit
- of having spaces in pathnames or the use of the <tt>\</tt>characters in pathnames.
- Luckily on most Windows systems, you can use <tt>/</tt>instead of <tt>\</tt>, and
- there is always a short <a href="http://en.wikipedia.org/wiki/8.3_filename">
- "8.3" pathname</a> without spaces for any path that contains spaces.
- Unfortunately, this short pathname is somewhat dynamic (i.e. dependant on the
- other files and directories inside a given directory) and can not be
- algorithmicly calculated by only looking at a specific path name.
- <p>
- The makefiles will try to translate any pathnames supplied
- to it into the <tt>C:/</tt> style automatically.
- </p>
- <p>
- Special care has to be taken if native Windows applications
- like <tt>nmake</tt> or <tt>cl</tt> are called with file arguments processed
- by Unix-tools like <tt>make</tt> or <tt>sh</tt>!
- </p>
- </blockquote>
- <!-- ------------------------------------------------------ -->
- <h4><a name="paths">Windows build environments</a></h4>
- <blockquote>
- Building on Windows requires a Unix-like environment, notably a Unix-like shell.
- There are several such environments available of which
- <a href="http://www.mkssoftware.com/products/tk/ds_tkdev.asp">MKS</a>,
- <a href="http://www.cygwin.com/">Cygwin</a> and
- <a href="http://www.mingw.org/wiki/MSYS">MinGW/MSYS</a> are currently supported for
- the OpenJDK build. One of the differences of these three systems is the way
- they handle Windows path names, particularly path names which contain
- spaces, backslashes as path separators and possibly drive letters. Depending
- on the use case and the specifics of each environment these path problems can
- be solved by a combination of quoting whole paths, translating backslashes to
- forward slashes, escaping backslashes with additional backslashes and
- translating the path names to their <a href="http://en.wikipedia.org/wiki/8.3_filename">
- "8.3" version</a>.
- <p>
- As of this writing (MKS ver. 9.4, Cygwin ver. 1.7.9, MinGW/MSYS 1.0.17),
- MKS builds are known to be the fastest Windows builds while MingGW/MSYS
- builds are slightly slower (about 10%) than MKS builds and Cygwin builds
- require nearly twice the time (about 180%) of MKS builds (e.g. on a
- DualCore i7 notebook with 8GB of RAM, HDD and 64-bit Windows 7 operating system
- the complete OpenJDK 8 product build takes about 49min with MKS, 54min with
- MinGW/MSYS and 88min with Cygwin).
- </p>
- <p>
- Mixing tools from the different Unix emulation environments is not a good
- idea and will probably not work!
- </p>
- <p>
- <strong>MKS:</strong> is a commercial product which includes
- all the Unix utilities which are required to build the OpenJDK except GNU
- make. In pre-OpenJDK times it was the only supported build environment on
- Windows. The MKS tools support Windows paths with drive letters and
- forward slashes as path separator. Paths in environment variables like (for
- example) <tt>PATH</tt> are separated by semicolon '<tt>;</tt>'.
- </p>
- <p>
- Recent versions of MKS provide the <tt>dosname</tt> utility to convert paths
- with spaces to short (8.3) path names,e .g.
- <tt>dosname -s "<i>path</i>"</tt>.
- </p>
- <p>
- If you are using the MKS environment, you need a native Windows version
- of Gnu make <a href="#buildgmake">which you can easily build yourself</a>.
- </p>
- <p>
- <strong>Cygwin:</strong>
- is an open source, Linux-like environment which tries to emulate
- a complete POSIX layer on Windows. It tries to be smart about path names
- and can usually handle all kinds of paths if they are correctly quoted
- or escaped although internally it maps drive letters <tt><drive>:</tt>
- to a virtual directory <tt>/cygdrive/<drive></tt>.
- </p>
- <p>
- You can always use the <tt>cygpath</tt> utility to map pathnames with spaces
- or the backslash character into the <tt>C:/</tt> style of pathname
- (called 'mixed'), e.g. <tt>cygpath -s -m "<i>path</i>"</tt>.
- </p>
- <p>
- Note that the use of CYGWIN creates a unique problem with regards to
- setting <a href="#path"><tt>PATH</tt></a>. Normally on Windows
- the <tt>PATH</tt> variable contains directories
- separated with the ";" character (Solaris and Linux use ":").
- With CYGWIN, it uses ":", but that means that paths like "C:/path"
- cannot be placed in the CYGWIN version of <tt>PATH</tt> and
- instead CYGWIN uses something like <tt>/cygdrive/c/path</tt>
- which CYGWIN understands, but only CYGWIN understands.
- </p>
- <p>
- If you are using the Cygwin environment, you need to
- <a href="#buildgmake">compile your own version</a>
- of GNU make because the default Cygwin make can not handle drive letters in paths.
- </p>
- <p>
- <strong>MinGW/MSYS:</strong>
- MinGW ("Minimalist GNU for Windows") is a collection of free Windows
- specific header files and import libraries combined with GNU toolsets that
- allow one to produce native Windows programs that do not rely on any
- 3rd-party C runtime DLLs. MSYS is a supplement to MinGW which allows building
- applications and programs which rely on traditional UNIX tools to
- be present. Among others this includes tools like <tt>bash</tt> and <tt>make</tt>.
- </p>
- <p>
- Like Cygwin, MinGW/MSYS can handle different types of path formats. They
- are internally converted to paths with forward slashes and drive letters
- <tt><drive>:</tt> replaced by a virtual
- directory <tt>/<drive></tt>. Additionally, MSYS automatically
- detects binaries compiled for the MSYS environment and feeds them with the
- internal, Unix-style path names. If native Windows applications are called
- from within MSYS programs their path arguments are automatically converted
- back to Windows style path names with drive letters and backslashes as
- path separators. This may cause problems for Windows applications which
- use forward slashes as parameter separator (e.g. <tt>cl /nologo /I</tt>)
- because MSYS may wrongly <a href="http://mingw.org/wiki/Posix_path_conversion">
- replace such parameters by drive letters</a>.
- </p>
- <p>
- If you are using the MinGW/MSYS system you can use the default make
- version supplied by the environment.
- </p>
- </blockquote>
- <!-- ------------------------------------------------------ -->
- <h4><a name="windows_checklist">Basic Windows Check List</a></h4>
- <blockquote>
- <ol>
- <li>
- Install one of the
- <a href="#cygwin">CYGWIN</a>, <a href="#msys">MinGW/MSYS</a> or
- <a href="http://www.mkssoftware.com/products/tk/ds_tkdev.asp">MKS</a> environments.
- </li>
- <li>
- Install the
- <a href="#bootjdk">Bootstrap JDK</a>, set
- <tt><a href="#ALT_BOOTDIR">ALT_BOOTDIR</a></tt>.
- </li>
- <li>
- <a href="#importjdk">Optional Import JDK</a>, set
- <tt><a href="#ALT_JDK_IMPORT_PATH">ALT_JDK_IMPORT_PATH</a></tt>.
- </li>
- <li>
- Install the
- <a href="#msvc32">Microsoft Visual Studio Compilers</a>).
- </li>
- <li>
- Setup all environment variables for compilers
- (see <a href="#msvc32">compilers</a>).
- </li>
- <li>
- Install
- <a href="#dxsdk">Microsoft DirectX SDK</a>.
- </li>
- <li>
- Install
- <a href="#ant">Ant 1.7.1 or newer</a>,
- make sure it is in your PATH and set
- <tt><a href="#ANT_HOME">ANT_HOME</a></tt>.
- </li>
- </ol>
- </blockquote>
- <!-- ------------------------------------------------------ -->
- <hr>
- <h3><a name="macosx">Basic Mac OS X System Setup</a></h3>
- <blockquote>
- <strong>X64 only:</strong>
- The minimum recommended hardware for building
- the Mac OS X version is any 64-bit capable Intel processor, at least 2
- GB of RAM, and approximately 3 GB of free disk space. You should also
- have OS X Lion 10.7.3 installed.
- </blockquote>
- <!-- ------------------------------------------------------ -->
-
- <h4><a name="macosx_checklist">Basic Mac OS X Check List</a></h4>
- <blockquote>
- <ol>
- <li>
- Install <a href="https://developer.apple.com/xcode/">XCode 4.1</a> or newer.
- If you install XCode 4.3 or newer, make sure you also install
- "Command line tools" found under the preferences pane "Downloads".
- </li>
- <li>
- Install <a href="http://support.apple.com/kb/dl1421" target="_blank">"Java for OS X Lion Update 1"</a>,
- set <tt><a href="#ALT_BOOTDIR">ALT_BOOTDIR</a> to <code>`/usr/libexec/java_home -v 1.6`</code></tt>
- </li>
- <li>
- <a href="#importjdk">Optional Import JDK</a>, set
- <tt><a href="#ALT_JDK_IMPORT_PATH">ALT_JDK_IMPORT_PATH</a></tt>.
- </li>
- </ol>
- </blockquote>
- <!-- ------------------------------------------------------ -->
- <hr>
- <h3><a name="dependencies">Build Dependencies</a></h3>
- <blockquote>
- Depending on the platform, the OpenJDK build process has some basic
- dependencies on components not part of the OpenJDK sources.
- Some of these are specific to a platform, some even specific to
- an architecture.
- Each dependency will have a set of ALT variables that can be set
- to tell the makefiles where to locate the component.
- In most cases setting these ALT variables may not be necessary
- and the makefiles will find defaults on the system in standard
- install locations or through component specific variables.
- <!-- ------------------------------------------------------ -->
- <h4><a name="bootjdk">Bootstrap JDK</a></h4>
- <blockquote>
- All OpenJDK builds require access to the previously released
- JDK 6, this is often called a bootstrap JDK.
- The JDK 6 binaries can be downloaded from Sun's
- <a href="http://java.sun.com/javase/downloads/index.jsp"
- target="_blank">JDK 6 download site</a>.
- For build performance reasons
- is very important that this bootstrap JDK be made available on the
- local disk of the machine doing the build.
- You should always set
- <tt><a href="#ALT_BOOTDIR">ALT_BOOTDIR</a></tt>
- to point to the location of
- the bootstrap JDK installation, this is the directory pathname
- that contains a <tt>bin, lib, and include</tt>
- It's also a good idea to also place its <tt>bin</tt> directory
- in the <tt>PATH</tt> environment variable, although it's
- not required.
- <p>
- <strong>Solaris:</strong>
- Some pre-installed JDK images may be available to you in the
- directory <tt>/usr/jdk/instances</tt>.
- If you don't set
- <tt><a href="#ALT_BOOTDIR">ALT_BOOTDIR</a></tt>
- the makefiles will look in that location for a JDK it can use.
- </blockquote>
- <!-- ------------------------------------------------------ -->
- <h4><a name="importjdk">Optional Import JDK</a></h4>
- <blockquote>
- The <tt><a href="#ALT_JDK_IMPORT_PATH">ALT_JDK_IMPORT_PATH</a></tt>
- setting is only needed if you are not building the entire
- JDK. For example, if you have built the entire JDK once, and
- wanted to avoid repeatedly building the Hotspot VM, you could
- set this to the location of the previous JDK install image
- and the build will copy the needed files from this import area.
- </blockquote>
- <!-- ------------------------------------------------------ -->
- <h4><a name="ant">Ant</a></h4>
- <blockquote>
- All OpenJDK builds require access to least Ant 1.7.1.
- The Ant tool is available from the
- <a href="http://archive.apache.org/dist/ant/binaries/apache-ant-1.7.1-bin.zip" target="_blank">
- Ant 1.7.1 archive download site</a>.
- You should always make sure <tt>ant</tt> is in your PATH, and
- on Windows you may also need to set
- <tt><a href="#ANT_HOME">ANT_HOME</a></tt>
- to point to the location of
- the Ant installation, this is the directory pathname
- that contains a <tt>bin and lib</tt>.
- <br>
- <b>WARNING:</b> Ant versions used from IDE tools like NetBeans
- or installed via system packages may not operate the same
- as the one obtained from the Ant download bundles.
- These system and IDE installers sometimes choose to change
- the ant installation enough to cause differences.
- </blockquote>
- <!-- ------------------------------------------------------ -->
- <h4><a name="cacerts">Certificate Authority File (cacert)</a></h4>
- <blockquote>
- See <a href="http://en.wikipedia.org/wiki/Certificate_Authority" target="_blank">
- http://en.wikipedia.org/wiki/Certificate_Authority</a>
- for a better understanding of the Certificate Authority (CA).
- A certificates file named "cacerts"
- represents a system-wide keystore with CA certificates.
- In JDK and JRE
- binary bundles, the "cacerts" file contains root CA certificates from
- several public CAs (e.g., VeriSign, Thawte, and Baltimore).
- The source contain a cacerts file
- without CA root certificates.
- Formal JDK builders will need to secure
- permission from each public CA and include the certificates into their
- own custom cacerts file.
- Failure to provide a populated cacerts file
- will result in verification errors of a certificate chain during runtime.
- The variable
- <tt><a href="#ALT_CACERTS_FILE">ALT_CACERTS_FILE</a></tt>
- can be used to override the default location of the
- cacerts file that will get placed in your build.
- By default an empty cacerts file is provided and that should be
- fine for most JDK developers.
- </blockquote>
- <!-- ------------------------------------------------------ -->
- <h4><a name="compilers">Compilers</a></h4>
- <blockquote>
- <strong><a name="gcc">Linux gcc/binutils</a></strong>
+ Building is a little different depending on the OS but is
+ basically done with:
<blockquote>
- The GNU gcc compiler version should be 4.3 or newer.
- The compiler used should be the default compiler installed
- in <tt>/usr/bin</tt>.
- </blockquote>
- <strong><a name="studio">Solaris: Sun Studio</a></strong>
- <blockquote>
- At a minimum, the
- <a href="http://www.oracle.com/technetwork/server-storage/solarisstudio/downloads/index.htm" target="_blank">
- Sun Studio 12 Update 1 Compilers</a>
- (containing version 5.10 of the C and C++ compilers) is required,
- including specific patches.
- <p>
- The Solaris SPARC patch list is:
- <ul>
- <li>
- 118683-05: SunOS 5.10: Patch for profiling libraries and assembler
- </li>
- <li>
- 119963-21: SunOS 5.10: Shared library patch for C++
- </li>
- <li>
- 120753-08: SunOS 5.10: Microtasking libraries (libmtsk) patch
- </li>
- <li>
- 128228-09: Sun Studio 12 Update 1: Patch for Sun C++ Compiler
- </li>
- <li>
- 141860-03: Sun Studio 12 Update 1: Patch for Compiler Common patch for Sun C C++ F77 F95
- </li>
- <li>
- 141861-05: Sun Studio 12 Update 1: Patch for Sun C Compiler
- </li>
- <li>
- 142371-01: Sun Studio 12.1 Update 1: Patch for dbx
- </li>
- <li>
- 143384-02: Sun Studio 12 Update 1: Patch for debuginfo handling
- </li>
- <li>
- 143385-02: Sun Studio 12 Update 1: Patch for Compiler Common patch for Sun C C++ F77 F95
- </li>
- <li>
- 142369-01: Sun Studio 12.1: Patch for Performance Analyzer Tools
- </li>
- </ul>
- <p>
- The Solaris X86 patch list is:
- <ul>
- <li>
- 119961-07: SunOS 5.10_x86, x64, Patch for profiling libraries and assembler
- </li>
- <li>
- 119964-21: SunOS 5.10_x86: Shared library patch for C++_x86
- </li>
- <li>
- 120754-08: SunOS 5.10_x86: Microtasking libraries (libmtsk) patch
- </li>
- <li>
- 141858-06: Sun Studio 12 Update 1_x86: Sun Compiler Common patch for x86 backend
- </li>
- <li>
- 128229-09: Sun Studio 12 Update 1_x86: Patch for C++ Compiler
- </li>
- <li>
- 142363-05: Sun Studio 12 Update 1_x86: Patch for C Compiler
- </li>
- <li>
- 142368-01: Sun Studio 12.1_x86: Patch for Performance Analyzer Tools
- </li>
- </ul>
- <p>
- Set
- <a href="#ALT_COMPILER_PATH"><tt>ALT_COMPILER_PATH</tt></a>
- to point to the location of
- the compiler binaries, and place this location in the <tt>PATH</tt>.
- <p>
- The Oracle Solaris Studio Express compilers at:
- <a href="http://developers.sun.com/sunstudio/downloads/express.jsp" target="_blank">
- Oracle Solaris Studio Express Download site</a>
- are also an option, although these compilers have not
- been extensively used yet.
- </blockquote>
- <strong><a name="msvc32">Windows i586: Microsoft Visual Studio 2010 Compilers</a></strong>
- <blockquote>
- <p>
- <b>BEGIN WARNING</b>: JDK 7 has transitioned to
- use the newest VS2010 Microsoft compilers.
- No other compilers are known to build the entire JDK,
- including non-open portions.
- Visual Studio 2010 Express compilers are now able to build all the
- open source repositories, but this is 32 bit only. To build 64 bit
- Windows binaries use the the 7.1 Windows SDK.
- <b>END WARNING.</b>
- <p>
- The 32-bit OpenJDK Windows build requires
- Microsoft Visual Studio C++ 2010 (VS2010) Professional
- Edition or Express compiler.
- The compiler and other tools are expected to reside
- in the location defined by the variable
- <tt>VS100COMNTOOLS</tt> which
- is set by the Microsoft Visual Studio installer.
- <p>
- Once the compiler is installed,
- it is recommended that you run <tt>VCVARS32.BAT</tt>
- to set the compiler environment variables
- <tt>INCLUDE</tt>,
- <tt>LIB</tt>, and
- <tt>PATH</tt>
- prior to building the
- OpenJDK.
- The above environment variables <b>MUST</b> be set.
- This compiler also contains the Windows SDK v 7.0a,
- which is an update to the Windows 7 SDK.
- <p>
- <b>WARNING:</b> Make sure you check out the
- <a href="#cygwin">CYGWIN link.exe WARNING</a>.
- The path <tt>/usr/bin</tt> must be after the path to the
- Visual Studio product.
- </blockquote>
- <strong><a name="msvc64">Windows x64: Microsoft Visual Studio 2010 Professional Compiler</a></strong>
- <blockquote>
- For <b>X64</b>, the set up is much the same as 32 bit
- except that you run <tt>amd64\VCVARS64.BAT</tt>
- to set the compiler environment variables.
- Previously 64 bit builds had to use the 64 bit compiler in
- an unbundled Windows SDK but this is no longer necessary if
- you have VS2010 Professional.
- </blockquote>
- <strong><a name="mssdk64">Windows x64: Microsoft Windows 7.1 SDK 64 bit compilers.</a></strong>
- For a free alternative for 64 bit builds, use the 7.1 SDK.
- Microsoft say that to set up your paths for this run
- <pre>
- c:\Program Files\Microsoft SDKs\Windows\v7.1\bin\setenv.cmd /x64.
- </pre>
- What was tested is just directly setting up LIB, INCLUDE,
- PATH and based on the installation directories using the
- DOS short name appropriate for the system, (you will
- need to set them for yours, not just blindly copy this) eg :
- <pre>
- set VSINSTALLDIR=c:\PROGRA~2\MICROS~1.0
- set WindowsSdkDir=c:\PROGRA~1\MICROS~1\Windows\v7.1
- set PATH=%VSINSTALLDIR%\vc\bin\amd64;%VSINSTALLDIR%\Common7\IDE;%WindowsSdkDir%\bin;%PATH%
- set INCLUDE=%VSINSTALLDIR%\vc\include;%WindowsSdkDir%\include
- set LIB=%VSINSTALLDIR%\vc\lib\amd64;%WindowsSdkDir%\lib\x64
- </pre>
- <strong><a name="llvmgcc">OS X Lion 10.7.3: LLVM GCC</a></strong>
- <blockquote>
- LLVM GCC is bundled with XCode. The version should be at least 4.2.1.
+ <code>bash ./configure</code>
+ <br>
+ <code>make</code>
</blockquote>
</blockquote>
- <!-- ------------------------------------------------------ -->
- <h4><a name="zip">Zip and Unzip</a></h4>
- <blockquote>
- Version 2.2 (November 3rd 1997) or newer of the zip utility
- and version 5.12 or newer of the unzip utility is needed
- to build the JDK.
- With Solaris, Linux, and Windows CYGWIN, the zip and unzip
- utilities installed on the system should be fine.
- Information and the source code for
- ZIP.EXE and UNZIP.EXE is available on the
- <a href="http://www.info-zip.org"
- target="_blank">info-zip web site</a>.
- </blockquote>
- <!-- ------------------------------------------------------ -->
- <h4><a name="cups">Common UNIX Printing System (CUPS) Headers (Solaris & Linux)</a></h4>
- <blockquote>
- <strong>Solaris:</strong>
- CUPS header files are required for building the
- OpenJDK on Solaris.
- The Solaris header files can be obtained by installing
- the package <strong>SFWcups</strong> from the Solaris Software
- Companion CD/DVD, these often will be installed into
- <tt>/opt/sfw/cups</tt>.
- <p>
- <strong>Linux:</strong>
- CUPS header files are required for building the
- OpenJDK on Linux.
- The Linux header files are usually available from a "cups"
- development package, it's recommended that you try and use
- the package provided by the particular version of Linux that
- you are using.
- <p>
- The CUPS header files can always be downloaded from
- <a href="http://www.cups.org" target="_blank">www.cups.org</a>.
- The variable
- <tt><a href="#ALT_CUPS_HEADERS_PATH">ALT_CUPS_HEADERS_PATH</a></tt>
- can be used to override the default location of the
- CUPS Header files.
- </blockquote>
- <!-- ------------------------------------------------------ -->
- <h4><a name="xrender">XRender Extension Headers (Solaris & Linux)</a></h4>
- <blockquote>
- <p>
- <strong>Solaris:</strong>
- XRender header files are required for building the
- OpenJDK on Solaris.
- The XRender header file is included with the other X11 header files
- in the package <strong>SFWxwinc</strong> on new enough versions of
- Solaris and will be installed in
- <tt>/usr/X11/include/X11/extensions/Xrender.h</tt> or
- <tt>/usr/openwin/share/include/X11/extensions/Xrender.h</tt>
- </p><p>
- <strong>Linux:</strong>
- XRender header files are required for building the
- OpenJDK on Linux.
- The Linux header files are usually available from a "Xrender"
- development package, it's recommended that you try and use
- the package provided by the particular distribution of Linux that
- you are using.
- </p>
- </blockquote>
- <!-- ------------------------------------------------------ -->
- <h4><a name="freetype">FreeType 2</a></h4>
- <blockquote>
- Version 2.3 or newer of FreeType is required for building the OpenJDK.
- On Unix systems required files can be available as part of your
- distribution (while you still may need to upgrade them).
- Note that you need development version of package that
- includes both FreeType library and header files.
- <p>
- You can always download latest FreeType version from the
- <a href="http://www.freetype.org" target="_blank">FreeType website</a>.
- <p>
- Makefiles will try to pick FreeType from /usr/lib and /usr/include.
- In case it is installed elsewhere you will need to set environment
- variables
- <tt><a href="#ALT_FREETYPE_LIB_PATH">ALT_FREETYPE_LIB_PATH</a></tt>
- and
- <tt><a href="#ALT_FREETYPE_HEADERS_PATH">ALT_FREETYPE_HEADERS_PATH</a></tt>
- to refer to place where library and header files are installed.
- <p>
- Building the freetype 2 libraries from scratch is also possible,
- however on Windows refer to the
- <a href="http://freetype.freedesktop.org/wiki/FreeType_DLL">
- Windows FreeType DLL build instructions</a>.
- <p>
- Note that by default FreeType is built with byte code hinting
- support disabled due to licensing restrictions.
- In this case, text appearance and metrics are expected to
- differ from Sun's official JDK build.
- See
- <a href="http://freetype.sourceforge.net/freetype2/index.html">
- the SourceForge FreeType2 Home Page
- </a>
- for more information.
- </blockquote>
- <!-- ------------------------------------------------------ -->
- <h4><a name="alsa">Advanced Linux Sound Architecture (ALSA) (Linux only)</a></h4>
- <blockquote>
- <strong>Linux only:</strong>
- Version 0.9.1 or newer of the ALSA files are
- required for building the OpenJDK on Linux.
- These Linux files are usually available from an "alsa"
- of "libasound"
- development package, it's highly recommended that you try and use
- the package provided by the particular version of Linux that
- you are using.
- The makefiles will check this emit a sanity error if it is
- missing or the wrong version.
- <p>
- In particular, older Linux systems will likely not have the
- right version of ALSA installed, for example
- Redhat AS 2.1 U2 and SuSE 8.1 do not include a sufficiently
- recent ALSA distribution.
- On rpm-based systems, you can see if ALSA is installed by
- running this command:
- <pre>
- <tt>rpm -qa | grep alsa</tt>
- </pre>
- Both <tt>alsa</tt> and <tt>alsa-devel</tt> packages are needed.
- <p>
- If your distribution does not come with ALSA, and you can't
- find ALSA packages built for your particular system,
- you can try to install the pre-built ALSA rpm packages from
- <a href="http://www.freshrpms.net/" target="_blank">
- <tt>www.freshrpms.net</tt></a>.
- Note that installing a newer ALSA could
- break sound output if an older version of ALSA was previously
- installed on the system, but it will enable JDK compilation.
- <blockquote>
- Installation: execute as root<br>
- [i586]: <code>rpm -Uv --force alsa-lib-devel-0.9.1-rh61.i386.rpm</code><br>
- [x64]: <code>rpm -Uv --force alsa-lib-devel-0.9.8-amd64.x86_64.rpm</code><br>
- Uninstallation:<br>
- [i586]: <code>rpm -ev alsa-lib-devel-0.9.1-rh61</code><br>
- [x64]:<code>rpm -ev alsa-lib-devel-0.9.8-amd64</code><br>
- Make sure that you do not link to the static library
- (<tt>libasound.a</tt>),
- by verifying that the dynamic library (<tt>libasound.so</tt>) is
- correctly installed in <tt>/usr/lib</tt>.
- </blockquote>
- As a last resort you can go to the
- <a href="http://www.alsa-project.org" target="_blank">
- Advanced Linux Sound Architecture Site</a> and build it from
- source.
- <blockquote>
- Download driver and library
- source tarballs from
- <a href="http://www.alsa-project.org" target="_blank">ALSA's homepage</a>.
- As root, execute the following
- commands (you may need to adapt the version number):
- <pre>
- <tt>
- $ tar xjf alsa-driver-0.9.1.tar.bz2
- $ cd alsa-driver-0.9.1
- $ ./configure
- $ make install
- $ cd ..
- $ tar xjf alsa-lib-0.9.1.tar.bz2
- $ cd alsa-lib-0.9.1
- $ ./configure
- $ make install
- </tt>
- </pre>
- Should one of the above steps fail, refer to the documentation on
- ALSA's home page.
- </blockquote>
- Note that this is a minimum install that enables
- building the JDK platform. To actually use ALSA sound drivers, more
- steps are necessary as outlined in the documentation on ALSA's homepage.
- <p>
- ALSA can be uninstalled by executing <tt>make uninstall</tt> first in
- the <tt>alsa-lib-0.9.1</tt> directory and then in
- <tt>alsa-driver-0.9.1</tt>.
- </blockquote>
- There are no ALT* variables to change the assumed locations of ALSA,
- the makefiles will expect to find the ALSA include files and library at:
- <tt>/usr/include/alsa</tt> and <tt>/usr/lib/libasound.so</tt>.
- </blockquote>
- <!-- ------------------------------------------------------ -->
- <h4>Windows Specific Dependencies</h4>
- <blockquote>
- <strong>Unix Command Tools (<a name="cygwin">CYGWIN</a>)</strong>
- <blockquote>
- The OpenJDK requires access to a set of unix command tools
- on Windows which can be supplied by
- <a href="http://www.cygwin.com" target="_blank">CYGWIN</a>.
- <p>
- The OpenJDK build requires CYGWIN version 1.5.12 or newer.
- Information about CYGWIN can
- be obtained from the CYGWIN website at
- <a href="http://www.cygwin.com" target="_blank">www.cygwin.com</a>.
- <p>
- By default CYGWIN doesn't install all the tools required for building
- the OpenJDK.
- Along with the default installation, you need to install
- the following tools.
- <blockquote>
- <table border="1">
- <thead>
- <tr>
- <td>Binary Name</td>
- <td>Category</td>
- <td>Package</td>
- <td>Description</td>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>ar.exe</td>
- <td>Devel</td>
- <td>binutils</td>
- <td>The GNU assembler, linker and binary
- utilities</td>
- </tr>
- <tr>
- <td>make.exe</td>
- <td>Devel</td>
- <td>make</td>
- <td>The GNU version of the 'make' utility built for CYGWIN.<br>
- <b>NOTE</b>: the Cygwin make can not be used to build the
- OpenJDK. You only need it to build your own version of make
- (see <a href="#gmake">the GNU make section</a>)</td>
- </tr>
- <tr>
- <td>m4.exe</td>
- <td>Interpreters</td>
- <td>m4</td>
- <td>GNU implementation of the traditional Unix macro
- processor</td>
- </tr>
- <tr>
- <td>cpio.exe</td>
- <td>Utils</td>
- <td>cpio</td>
- <td>A program to manage archives of files</td>
- </tr>
- <tr>
- <td>gawk.exe</td>
- <td>Utils</td>
- <td>awk</td>
- <td>Pattern-directed scanning and processing language</td>
- </tr>
- <tr>
- <td>file.exe</td>
- <td>Utils</td>
- <td>file</td>
- <td>Determines file type using 'magic' numbers</td>
- </tr>
- <tr>
- <td>zip.exe</td>
- <td>Archive</td>
- <td>zip</td>
- <td>Package and compress (archive) files</td>
- </tr>
- <tr>
- <td>unzip.exe</td>
- <td>Archive</td>
- <td>unzip</td>
- <td>Extract compressed files in a ZIP archive</td>
- </tr>
- <tr>
- <td>free.exe</td>
- <td>System</td>
- <td>procps</td>
- <td>Display amount of free and used memory in the system</td>
- </tr>
- </tbody>
- </table>
- </blockquote>
- <p>
- Note that the CYGWIN software can conflict with other non-CYGWIN
- software on your Windows system.
- CYGWIN provides a
- <a href="http://cygwin.com/faq/faq.using.html" target="_blank">FAQ</a> for
- known issues and problems, of particular interest is the
- section on
- <a href="http://cygwin.com/faq/faq.using.html#faq.using.bloda" target="_blank">
- BLODA (applications that interfere with CYGWIN)</a>.
- <p>
- <b>WARNING:</b>
- Be very careful with <b><tt>link.exe</tt></b>, it will conflict
- with the Visual Studio version. You need the Visual Studio
- version of <tt>link.exe</tt>, not the CYGWIN one.
- So it's important that the Visual Studio paths in PATH preceed
- the CYGWIN path <tt>/usr/bin</tt>.
- </blockquote>
- <strong> Minimalist GNU for Windows (<a name="msys">MinGW/MSYS</a>)</strong>
- <blockquote>
- Alternatively, the set of unix command tools for the OpenJDK build on
- Windows can be supplied by
- <a href="http://www.mingw.org/wiki/MSYS" target="_blank">MinGW/MSYS</a>.
- <p>
- In addition to the tools which will be installed by default, you have
- to manually install the <tt>msys-zip</tt> and <tt>msys-unzip</tt> packages.
- This can be easily done with the MinGW command line installer:<br/>
- <tt><br/>
- mingw-get.exe install msys-zip<br/>
- mingw-get.exe install msys-unzip<br/>
- </tt>
- </p>
- </blockquote>
- <strong><a name="dxsdk">Microsoft DirectX 9.0 SDK header files and libraries</a></strong>
- <blockquote>
- Microsoft DirectX 9.0 SDK (Summer 2004)
- headers are required for building
- OpenJDK.
- This SDK can be downloaded from
- <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=FD044A42-9912-42A3-9A9E-D857199F888E&displaylang=en" target="_blank">
- Microsoft DirectX 9.0 SDK (Summer 2004)</a>.
- If the link above becomes obsolete, the SDK can be found from
- <a href="http://download.microsoft.com" target="_blank">the Microsoft Download Site</a>
- (search with "DirectX 9.0 SDK Update Summer 2004").
- The location of this SDK can be set with
- <tt><a href="#ALT_DXSDK_PATH">ALT_DXSDK_PATH</a></tt>
- but it's normally found via the DirectX environment variable
- <tt>DXSDK_DIR</tt>.
- </blockquote>
- <strong><a name="msvcrNN"><tt>MSVCR100.DLL</tt></a></strong>
- <blockquote>
- The OpenJDK build requires access to a redistributable
- <tt>MSVCR100.DLL</tt>.
- This is usually picked up automatically from the redist
- directories of Visual Studio 2010.
- If this cannot be found set the
- <a href="#ALT_MSVCRNN_DLL_PATH"><tt>ALT_MSVCRNN_DLL_PATH</tt></a>
- variable to the location of this file.
- <p>
- </blockquote>
- </blockquote>
- <!-- ------------------------------------------------------ -->
+
+ </blockquote> <!-- Appendix B -->
+
+ <!-- ====================================================== -->
<hr>
- <h2><a name="creating">Creating the Build</a></h2>
- <blockquote>
- Once a machine is setup to build the OpenJDK,
- the steps to create the build are fairly simple.
- The various ALT settings can either be made into variables
- or can be supplied on the
- <a href="#gmake"><tt><i>gmake</i></tt></a>
- command.
- <ol>
- <li>Use the sanity rule to double check all the ALT settings:
- <blockquote>
- <tt>
- <i>gmake</i>
- sanity
- [ARCH_DATA_MODEL=<i>32 or 64</i>]
- [other "ALT_" overrides]
- </tt>
- </blockquote>
- </li>
- <li>Start the build with the command:
- <blockquote>
- <tt>
- <i>gmake</i>
- [ARCH_DATA_MODEL=<i>32 or 64</i>]
- [ALT_OUTPUTDIR=<i>output_directory</i>]
- [other "ALT_" overrides]
- </tt>
- </blockquote>
- </li>
- </ol>
- <p>
- <strong>Solaris:</strong>
- Note that ARCH_DATA_MODEL is really only needed on Solaris to
- indicate you want to built the 64-bit version.
- And before the Solaris 64-bit binaries can be used, they
- must be merged with the binaries from a separate 32-bit build.
- The merged binaries may then be used in either 32-bit or 64-bit mode, with
- the selection occurring at runtime
- with the <tt>-d32</tt> or <tt>-d64</tt> options.
- </blockquote>
- <!-- ------------------------------------------------------ -->
- <hr>
- <h2><a name="testing">Testing the Build</a></h2>
- <blockquote>
- When the build is completed, you should see the generated
- binaries and associated files in the <tt>j2sdk-image</tt>
- directory in the output directory.
- The default output directory is
- <tt>build/<i>platform</i></tt>,
- where <tt><i>platform</i></tt> is one of
- <blockquote>
- <ul>
- <li><tt>solaris-sparc</tt></li>
- <li><tt>solaris-sparcv9</tt></li>
- <li><tt>solaris-i586</tt></li>
- <li><tt>solaris-amd64</tt></li>
- <li><tt>linux-i586</tt></li>
- <li><tt>linux-amd64</tt></li>
- <li><tt>windows-i586</tt></li>
- <li><tt>windows-amd64</tt></li>
- </ul>
- </blockquote>
- In particular, the
- <tt>build/<i>platform</i>/j2sdk-image/bin</tt>
- directory should contain executables for the
- OpenJDK tools and utilities.
- <p>
- You can test that the build completed properly by using the build
- to run the various demos that you will find in the
- <tt>build/<i>platform</i>/j2sdk-image/demo</tt>
- directory.
- <p>
- The provided regression tests can be run with the <tt>jtreg</tt>
- utility from
- <a href="http://openjdk.java.net/jtreg/" target="_blank">the jtreg site</a>.
- </blockquote>
- <!-- ------------------------------------------------------ -->
- <hr>
- <h2><a name="variables">Environment/Make Variables</a></h2>
- <p>
- Some of the
- environment or make variables (just called <b>variables</b> in this
- document) that can impact the build are:
+ <h2><a name="buildenvironments">Appendix C: Build Environments</a></h2>
<blockquote>
- <dl>
- <dt><a name="path"><tt>PATH</tt></a> </dt>
- <dd>Typically you want to set the <tt>PATH</tt> to include:
- <ul>
- <li>The location of the GNU make binary</li>
- <li>The location of the Bootstrap JDK <tt>java</tt>
- (see <a href="#bootjdk">Bootstrap JDK</a>)</li>
- <li>The location of the C/C++ compilers
- (see <a href="#compilers"><tt>compilers</tt></a>)</li>
- <li>The location or locations for the Unix command utilities
- (e.g. <tt>/usr/bin</tt>)</li>
- </ul>
- </dd>
- <dt><tt>MILESTONE</tt> </dt>
- <dd>
- The milestone name for the build (<i>e.g.</i>"beta").
- The default value is "internal".
- </dd>
- <dt><tt>BUILD_NUMBER</tt> </dt>
- <dd>
- The build number for the build (<i>e.g.</i> "b27").
- The default value is "b00".
- </dd>
- <dt><a name="arch_data_model"><tt>ARCH_DATA_MODEL</tt></a></dt>
- <dd>The <tt>ARCH_DATA_MODEL</tt> variable
- is used to specify whether the build is to generate 32-bit or 64-bit
- binaries.
- The Solaris build supports either 32-bit or 64-bit builds, but
- Windows and Linux will support only one, depending on the specific
- OS being used.
- Normally, setting this variable is only necessary on Solaris.
- Set <tt>ARCH_DATA_MODEL</tt> to <tt>32</tt> for generating 32-bit binaries,
- or to <tt>64</tt> for generating 64-bit binaries.
- </dd>
- <dt><a name="ALT_BOOTDIR"><tt>ALT_BOOTDIR</tt></a></dt>
- <dd>
- The location of the bootstrap JDK installation.
- See <a href="#bootjdk">Bootstrap JDK</a> for more information.
- You should always install your own local Bootstrap JDK and
- always set <tt>ALT_BOOTDIR</tt> explicitly.
- </dd>
- <dt><a name="ALT_JDK_IMPORT_PATH"><tt>ALT_JDK_IMPORT_PATH</tt></a></dt>
- <dd>
- The location of a previously built JDK installation.
- See <a href="#importjdk">Optional Import JDK</a> for more information.
- </dd>
- <dt><a name="ALT_OUTPUTDIR"><tt>ALT_OUTPUTDIR</tt></a> </dt>
- <dd>
- An override for specifying the (absolute) path of where the
- build output is to go.
- The default output directory will be build/<i>platform</i>.
- </dd>
- <dt><a name="ALT_COMPILER_PATH"><tt>ALT_COMPILER_PATH</tt></a> </dt>
- <dd>
- The location of the C/C++ compiler.
- The default varies depending on the platform.
- </dd>
- <dt><tt><a name="ALT_CACERTS_FILE">ALT_CACERTS_FILE</a></tt></dt>
- <dd>
- The location of the <a href="#cacerts">cacerts</a> file.
- The default will refer to
- <tt>jdk/src/share/lib/security/cacerts</tt>.
- </dd>
- <dt><a name="ALT_CUPS_HEADERS_PATH"><tt>ALT_CUPS_HEADERS_PATH</tt></a> </dt>
- <dd>
- The location of the CUPS header files.
- See <a href="#cups">CUPS information</a> for more information.
- If this path does not exist the fallback path is
- <tt>/usr/include</tt>.
- </dd>
- <dt><a name="ALT_FREETYPE_LIB_PATH"><tt>ALT_FREETYPE_LIB_PATH</tt></a></dt>
- <dd>
- The location of the FreeType shared library.
- See <a href="#freetype">FreeType information</a> for details.
- </dd>
- <dt><a name="ALT_FREETYPE_HEADERS_PATH"><tt>ALT_FREETYPE_HEADERS_PATH</tt></a></dt>
- <dd>
- The location of the FreeType header files.
- See <a href="#freetype">FreeType information</a> for details.
- </dd>
- <dt><a name="ALT_JDK_DEVTOOLS_PATH"><tt>ALT_JDK_DEVTOOLS_PATH</tt></a></dt>
- <dd>
- The default root location of the devtools.
- The default value is
- <tt>$(ALT_SLASH_JAVA)/devtools</tt>.
- </dd>
- <dt><tt><a name="ALT_DEVTOOLS_PATH">ALT_DEVTOOLS_PATH</a></tt> </dt>
- <dd>
- The location of tools like the
- <a href="#zip"><tt>zip</tt> and <tt>unzip</tt></a>
- binaries, but might also contain the GNU make utility
- (<tt><i>gmake</i></tt>).
- So this area is a bit of a grab bag, especially on Windows.
- The default value depends on the platform and
- Unix Commands being used.
- On Linux the default will be
- <tt>$(ALT_JDK_DEVTOOLS_PATH)/linux/bin</tt>,
- on Solaris
- <tt>$(ALT_JDK_DEVTOOLS_PATH)/<i>{sparc,i386}</i>/bin</tt>,
- and on Windows with CYGWIN
- <tt>/usr/bin</tt>.
- </dd>
- <dt><tt><a name="ALT_DROPS_DIR">ALT_DROPS_DIR</a></tt> </dt>
- <dd>
- The location of any source drop bundles
- (see <a href="#drops">Managing the Source Drops</a>).
- The default will be
- <tt>$(ALT_JDK_DEVTOOLS_PATH)/share/jdk8-drops</tt>.
- </dd>
- <dt><a name="ALT_UNIXCCS_PATH"><tt>ALT_UNIXCCS_PATH</tt></a></dt>
- <dd>
- <strong>Solaris only:</strong>
- An override for specifying where the Unix CCS
- command set are located.
- The default location is <tt>/usr/ccs/bin</tt>
- </dd>
- <dt><a name="ALT_SLASH_JAVA"><tt>ALT_SLASH_JAVA</tt></a></dt>
- <dd>
- The default root location for many of the ALT path locations
- of the following ALT variables.
- The default value is
- <tt>"/java"</tt> on Solaris and Linux,
- <tt>"J:"</tt> on Windows.
- </dd>
- <dt><a name="ALT_BUILD_JDK_IMPORT_PATH"><tt>ALT_BUILD_JDK_IMPORT_PATH</tt></a></dt>
- <dd>
- These are useful in managing builds on multiple platforms.
- The default network location for all of the import JDK images
- for all platforms.
- If <tt><a href="#ALT_JDK_IMPORT_PATH">ALT_JDK_IMPORT_PATH</a></tt>
- is not set, this directory will be used and should contain
- the following directories:
- <tt>solaris-sparc</tt>,
- <tt>solaris-i586</tt>,
- <tt>solaris-sparcv9</tt>,
- <tt>solaris-amd64</tt>,
- <tt>linux-i586</tt>,
- <tt>linux-amd64</tt>,
- <tt>windows-i586</tt>,
- and
- <tt>windows-amd64</tt>.
- Where each of these directories contain the import JDK image
- for that platform.
- </dd>
- <dt><a name="ALT_OPENWIN_HOME"><tt>ALT_OPENWIN_HOME</tt></a></dt>
- <dd>
- The top-level directory of the libraries and include files for the platform's
- graphical programming environment. The default location is platform specific.
- For example, on Linux it defaults to <tt>/usr/X11R6/</tt>.
- </dd>
- <dt><strong>Windows specific:</strong></dt>
- <dd>
- <dl>
- <dt><a name="ALT_WINDOWSSDKDIR"><tt>ALT_WINDOWSSDKDIR</tt></a> </dt>
- <dd>
- The location of the
- Microsoft Windows SDK where some tools will be
- located.
- The default is whatever WINDOWSSDKDIR is set to
- (or WindowsSdkDir) or the path
- <br>
- <tt>c:\Program Files\Microsoft SDKs\Windows\v7.0a</tt>
- </dd>
- <dt><tt><a name="ALT_DXSDK_PATH">ALT_DXSDK_PATH</a></tt> </dt>
- <dd>
- The location of the
- <a href="#dxsdk">Microsoft DirectX 9 SDK</a>.
- The default will be to try and use the DirectX environment
- variable <tt>DXSDK_DIR</tt>,
- failing that, look in <tt>C:/DXSDK</tt>.
- </dd>
- <dt><tt><a name="ALT_MSVCRNN_DLL_PATH">ALT_MSVCRNN_DLL_PATH</a></tt> </dt>
- <dd>
- The location of the
- <a href="#msvcrNN"><tt>MSVCR100.DLL</tt></a>.
- </dd>
- </dl>
- </dd>
- <dt><strong>Cross-Compilation Support:</strong></dt>
- <dd>
- <dl>
- <dt><a name="CROSS_COMPILE_ARCH"><tt>CROSS_COMPILE_ARCH</tt></a> </dt>
- <dd>
- Set to the target architecture of a cross-compilation build. If set, this
- variable is used to signify that we are cross-compiling. The expectation
- is that <a href="#ALT_COMPILER_PATH"><tt>ALT_COMPILER_PATH</tt></a> is set
- to point to the cross-compiler and that any cross-compilation specific flags
- are passed using <a href="#EXTRA_CFLAGS"><tt>EXTRA_CFLAGS</tt></a>.
- The <a href="#ALT_OPENWIN_HOME"><tt>ALT_OPENWIN_HOME</tt></a> variable should
- also be set to point to the graphical header files (e.g. X11) provided with
- the cross-compiler.
- When cross-compiling we skip execution of any demos etc that may be built, and
- also skip binary-file verification.
- </dd>
- <dt><tt><a name="EXTRA_CFLAGS">EXTRA_CFLAGS</a></tt> </dt>
- <dd>
- Used to pass cross-compilation options to the cross-compiler.
- These are added to the <tt>CFLAGS</tt> and <tt>CXXFLAGS</tt> variables.
- </dd>
- <dt><tt><a name="USE_ONLY_BOOTDIR_TOOLS">USE_ONLY_BOOTDIR_TOOLS</a></tt> </dt>
- <dd>
- Used primarily for cross-compilation builds (and always set in that case)
- this variable indicates that tools from the boot JDK should be used during
- the build process, not the tools (<tt>javac</tt>, <tt>javah</tt>, <tt>jar</tt>)
- just built (which can't execute on the build host).
- </dd>
- <dt><tt><a name="HOST_CC">HOST_CC</a></tt> </dt>
- <dd>
- The location of the C compiler to generate programs to run on the build host.
- Some parts of the build generate programs that are then compiled and executed
- to produce other parts of the build. Normally the primary C compiler is used
- to do this, but when cross-compiling that would be the cross-compiler and the
- resulting program could not be executed.
- On Linux this defaults to <tt>/usr/bin/gcc</tt>; on other platforms it must be
- set explicitly.
- </dd>
- </dl>
- <dt><strong>Specialized Build Options:</strong></dt>
- <dd>
- Some build variables exist to support specialized build environments and/or specialized
- build products. Their use is only supported in those contexts:
- <dl>
- <dt><tt><a name="BUILD_CLIENT_ONLY">BUILD_CLIENT_ONLY</a></tt> </dt>
- <dd>
- Indicates this build will only contain the Hotspot client VM. In addition to
- controlling the Hotspot build target, it ensures that we don't try to copy
- any server VM files/directories, and defines a default <tt>jvm.cfg</tt> file
- suitable for a client-only environment. Using this in a 64-bit build will
- generate a sanity warning as 64-bit client builds are not directly supported.
- </dd>
- <dt><tt><a name="BUILD_HEADLESS_ONLY"></a>BUILD_HEADLESS_ONLY</tt> </dt>
- <dd>
- Used when the build environment has no graphical capabilities at all. This
- excludes building anything that requires graphical libraries to be available.
- </dd>
- <dt><tt><a name="JAVASE_EMBEDDED"></a>JAVASE_EMBEDDED</tt> </dt>
- <dd>
- Used to indicate this is a build of the Oracle Java SE Embedded product.
- This will enable the directives included in the SE-Embedded specific build
- files.
- </dd>
- <dt><tt><a name="LIBZIP_CAN_USE_MMAP">LIBZIP_CAN_USE_MMAP</a></tt> </dt>
- <dd>
- If set to false, disables the use of mmap by the zip utility. Otherwise,
- mmap will be used.
- </dd>
- <dt><tt><a name="COMPRESS_JARS"></a>COMPRESS_JARS</tt> </dt>
- <dd>
- If set to true, causes certain jar files that would otherwise be built without
- compression, to use compression.
- </dd>
- </dl>
- </dd>
- </dl>
- </blockquote>
- <!-- ------------------------------------------------------ -->
+
+ <h3><a name="MBE">Minimum Build Environments</a></h3>
+ <blockquote>
+ This file often describes specific requirements for what we
+ call the
+ "minimum build environments" (MBE) for this
+ specific release of the JDK.
+ What is listed below is what the Oracle Release
+ Engineering Team will use to build the Oracle JDK product.
+ Building with the MBE will hopefully generate the most compatible
+ bits that install on, and run correctly on, the most variations
+ of the same base OS and hardware architecture.
+ In some cases, these represent what is often called the
+ least common denominator, but each Operating System has different
+ aspects to it.
+ <p>
+ In all cases, the Bootstrap JDK version minimum is critical,
+ we cannot guarantee builds will work with older Bootstrap JDK's.
+ Also in all cases, more RAM and more processors is better,
+ the minimums listed below are simply recommendations.
+ <p>
+ With Solaris and Mac OS X, the version listed below is the
+ oldest release we can guarantee builds and works, and the
+ specific version of the compilers used could be critical.
+ <p>
+ With Windows the critical aspect is the Visual Studio compiler
+ used, which due to it's runtime, generally dictates what Windows
+ systems can do the builds and where the resulting bits can
+ be used.<br>
+ <b>NOTE: We expect a change here off these older Windows OS releases
+ and to a 'less older' one, probably Windows 2008R2 X64.</b>
+ <p>
+ With Linux, it was just a matter of picking a
+ stable distribution that is a good representative for Linux
+ in general.<br>
+ <b>NOTE: We expect a change here from Fedora 9 to something else,
+ but it has not been completely determined yet, possibly
+ Ubuntu 12.04 X64, unbiased community feedback would be welcome on
+ what a good choice would be here.</b>
+ <p>
+ It is understood that most developers will NOT be using these
+ specific versions, and in fact creating these specific versions
+ may be difficult due to the age of some of this software.
+ It is expected that developers are more often using the more
+ recent releases and distributions of these operating systems.
+ <p>
+ Compilation problems with newer or different C/C++ compilers is a
+ common problem.
+ Similarly, compilation problems related to changes to the
+ <code>/usr/include</code> or system header files is also a
+ common problem with older, newer, or unreleased OS versions.
+ Please report these types of problems as bugs so that they
+ can be dealt with accordingly.
+ </p>
+ <table border="1">
+ <thead>
+ <tr>
+ <th>Base OS and Architecture</th>
+ <th>OS</th>
+ <th>C/C++ Compiler</th>
+ <th>Bootstrap JDK</th>
+ <th>Processors</th>
+ <th>RAM Minimum</th>
+ <th>DISK Needs</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>Linux X86 (32-bit) and X64 (64-bit)</td>
+ <td>Fedora 9</td>
+ <td>gcc 4.3 </td>
+ <td>JDK 7u7</td>
+ <td>2 or more</td>
+ <td>1 GB</td>
+ <td>6 GB</td>
+ </tr>
+ <tr>
+ <td>Solaris SPARC (32-bit) and SPARCV9 (64-bit)</td>
+ <td>Solaris 10 Update 6</td>
+ <td>Studio 12 Update 1 + patches</td>
+ <td>JDK 7u7</td>
+ <td>4 or more</td>
+ <td>4 GB</td>
+ <td>8 GB</td>
+ </tr>
+ <tr>
+ <td>Solaris X86 (32-bit) and X64 (64-bit)</td>
+ <td>Solaris 10 Update 6</td>
+ <td>Studio 12 Update 1 + patches</td>
+ <td>JDK 7u7</td>
+ <td>4 or more</td>
+ <td>4 GB</td>
+ <td>8 GB</td>
+ </tr>
+ <tr>
+ <td>Windows X86 (32-bit)</td>
+ <td>Windows XP</td>
+ <td>Microsoft Visual Studio C++ 2010 Professional Edition</td>
+ <td>JDK 7u7</td>
+ <td>2 or more</td>
+ <td>2 GB</td>
+ <td>6 GB</td>
+ </tr>
+ <tr>
+ <td>Windows X64 (64-bit)</td>
+ <td>Windows Server 2003 - Enterprise x64 Edition</td>
+ <td>Microsoft Visual Studio C++ 2010 Professional Edition</td>
+ <td>JDK 7u7</td>
+ <td>2 or more</td>
+ <td>2 GB</td>
+ <td>6 GB</td>
+ </tr>
+ <tr>
+ <td>Mac OS X X64 (64-bit)</td>
+ <td>Mac OS X 10.7 "Lion"</td>
+ <td>XCode 4.5.2 or newer</td>
+ <td>JDK 7u7</td>
+ <td>2 or more</td>
+ <td>4 GB</td>
+ <td>6 GB</td>
+ </tr>
+ </tbody>
+ </table>
+ </blockquote>
+
+ <!-- ====================================================== -->
+ <hr>
+ <h3><a name="SDBE">Specific Developer Build Environments</a></h3>
+ <blockquote>
+ We won't be listing all the possible environments, but
+ we will try to provide what information we have available to us.
+ <p>
+ <strong>NOTE: The community can help out by updating
+ this part of the document.
+ </strong>
+
+ <h4><a name="fedora">Fedora</a></h4>
+ <blockquote>
+ After installing the latest
+ <a href="http://fedoraproject.org">Fedora</a>
+ you need to install several build dependencies.
+ The simplest way to do it is to execute the
+ following commands as user <code>root</code>:
+ <blockquote>
+ <code>yum-builddep java-1.7.0-openjdk</code>
+ <br>
+ <code>yum install gcc gcc-c++</code>
+ </blockquote>
+ <p>
+ In addition, it's necessary to set a few environment
+ variables for the build:
+ <blockquote>
+ <code>export LANG=C</code>
+ <br>
+ <code>export PATH="/usr/lib/jvm/java-openjdk/bin:${PATH}"</code>
+ </blockquote>
+ </blockquote>
+
+
+ <h4><a name="centos">CentOS 5.5</a></h4>
+ <blockquote>
+ After installing
+ <a href="http://www.centos.org/">CentOS 5.5</a>
+ you need to make sure you have
+ the following Development bundles installed:
+ <blockquote>
+ <ul>
+ <li>Development Libraries</li>
+ <li>Development Tools</li>
+ <li>Java Development</li>
+ <li>X Software Development (Including XFree86-devel)</li>
+ </ul>
+ </blockquote>
+ <p>
+ Plus the following packages:
+ <blockquote>
+ <ul>
+ <li>cups devel: Cups Development Package</li>
+ <li>alsa devel: Alsa Development Package</li>
+ <li>Xi devel: libXi.so Development Package</li>
+ </ul>
+ </blockquote>
+ <p>
+ The freetype 2.3 packages don't seem to be available,
+ but the freetype 2.3 sources can be downloaded, built,
+ and installed easily enough from
+ <a href="http://downloads.sourceforge.net/freetype">
+ the freetype site</a>.
+ Build and install with something like:
+ <blockquote>
+ <code>bash ./configure</code>
+ <br>
+ <code>make</code>
+ <br>
+ <code>sudo -u root make install</code>
+ </blockquote>
+ <p>
+ Mercurial packages could not be found easily, but a Google
+ search should find ones, and they usually include Python if
+ it's needed.
+ </blockquote>
+
+ <h4><a name="debian">Debian 5.0 (Lenny)</a></h4>
+ <blockquote>
+ After installing <a href="http://debian.org">Debian</a> 5
+ you need to install several build dependencies.
+ The simplest way to install the build dependencies is to
+ execute the following commands as user <code>root</code>:
+ <blockquote>
+ <code>aptitude build-dep openjdk-7</code>
+ <br>
+ <code>aptitude install openjdk-7-jdk libmotif-dev</code>
+ </blockquote>
+ <p>
+ In addition, it's necessary to set a few environment
+ variables for the build:
+ <blockquote>
+ <code>export LANG=C</code>
+ <br>
+ <code>export PATH="/usr/lib/jvm/java-7-openjdk/bin:${PATH}"</code>
+ </blockquote>
+ </blockquote>
+
+ <h4><a name="ubuntu">Ubuntu 12.04</a></h4>
+ <blockquote>
+ After installing <a href="http://ubuntu.org">Ubuntu</a> 12.04
+ you need to install several build dependencies. The simplest
+ way to do it is to execute the following commands:
+ <blockquote>
+ <code>sudo aptitude build-dep openjdk-7</code>
+ <br>
+ <code>sudo aptitude install openjdk-7-jdk</code>
+ </blockquote>
+ <p>
+ In addition, it's necessary to set a few environment
+ variables for the build:
+ <blockquote>
+ <code>export LANG=C</code>
+ <br>
+ <code>export PATH="/usr/lib/jvm/java-7-openjdk/bin:${PATH}"</code>
+ </blockquote>
+ </blockquote>
+
+ <h4><a name="opensuse">OpenSUSE 11.1</a></h4>
+ <blockquote>
+ After installing <a href="http://opensuse.org">OpenSUSE</a> 11.1
+ you need to install several build dependencies.
+ The simplest way to install the build dependencies is to
+ execute the following commands:
+ <blockquote>
+ <code>sudo zypper source-install -d java-1_7_0-openjdk</code>
+ <br>
+ <code>sudo zypper install make</code>
+ </blockquote>
+ <p>
+ In addition, it is necessary to set a few environment
+ variables for the build:
+ <blockquote>
+ <code>export LANG=C</code>
+ <br>
+ <code>export PATH="/usr/lib/jvm/java-1.7.0-openjdk/bin:$[PATH}"</code>
+ </blockquote>
+ <p>
+ Finally, you need to unset the <code>JAVA_HOME</code>
+ environment variable:
+ <blockquote>
+ <code>export -n JAVA_HOME</code>
+ </blockquote>
+ </blockquote>
+
+ <h4><a name="mandriva">Mandriva Linux One 2009 Spring</a></h4>
+ <blockquote>
+ After installing <a href="http://mandriva.org">Mandriva</a>
+ Linux One 2009 Spring
+ you need to install several build dependencies.
+ The simplest way to install the build dependencies is to
+ execute the following commands as user <code>root</code>:
+ <blockquote>
+ <code>urpmi java-1.7.0-openjdk-devel make gcc gcc-c++
+ freetype-devel zip unzip libcups2-devel libxrender1-devel
+ libalsa2-devel libstc++-static-devel libxtst6-devel
+ libxi-devel</code>
+ </blockquote>
+ <p>
+ In addition, it is necessary to set a few environment
+ variables for the build:
+ <blockquote>
+ <code>export LANG=C</code>
+ <br>
+ <code>export PATH="/usr/lib/jvm/java-1.7.0-openjdk/bin:${PATH}"</code>
+ </blockquote>
+ </blockquote>
+
+ <h4><a name="opensolaris">OpenSolaris 2009.06</a></h4>
+ <blockquote>
+ After installing <a href="http://opensolaris.org">OpenSolaris</a> 2009.06
+ you need to install several build dependencies.
+ The simplest way to install the build dependencies is to
+ execute the following commands:
+ <blockquote>
+ <code>pfexec pkg install SUNWgmake SUNWj7dev
+ sunstudioexpress SUNWcups SUNWzip SUNWunzip SUNWxwhl
+ SUNWxorg-headers SUNWaudh SUNWfreetype2</code>
+ </blockquote>
+ <p>
+ In addition, it is necessary to set a few environment
+ variables for the build:
+ <blockquote>
+ <code>export LANG=C</code>
+ <br>
+ <code>export PATH="/opt/SunStudioExpress/bin:${PATH}"</code>
+ </blockquote>
+ </blockquote>
+
+ </blockquote>
+
+ </blockquote> <!-- Appendix C -->
+
+ <!-- ====================================================== -->
+
+ <!-- Leave out Appendix D --
+
+<hr>
+<h2><a name="mapping">Appendix D: Mapping Old to New</a></h2>
+<blockquote>
+ <p>This table will help you convert some idioms of the old build
+ system to the new build system.</p>
+ <table summary="Cheat sheet for converting from old to new build system">
+ <tr valign="top">
+ <th>In the old build system, you used to...</th>
+ <th>In the new build system, you should ...</th>
+ </tr>
+ <tr valign="top">
+ <td>run <code>make sanity</code></td>
+ <td>run <code>bash ./configure</code></td>
+ </tr>
+ <tr valign="top">
+ <td>set <code>ALT_OUTPUTDIR=build/my-special-output</code></td>
+ <td>before building the first time:
+ <br>
+ <code>cd build/my-special-output</code>
+ <br>
+ <code>bash ../../configure</code>
+ <br>
+ to build:
+ <br>
+ <code>cd build/my-special-output</code>
+ <br>
+ <code>make</code>
+ </td>
+ </tr>
+ <tr valign="top">
+ <td>set <code>ALT_BOOTDIR=/opt/java/jdk7</code></td>
+ <td>run <code>configure --with-boot-jdk=/opt/java/jdk7</code></td>
+ </tr>
+ <tr valign="top">
+ <td>run <code>make ARCH_DATA_MODEL=32</code></td>
+ <td>run <code>configure --with-target-bits=32</code></td>
+ </tr>
+ <tr valign="top">
+ <td>set <code>BUILD_CLIENT_ONLY=true</code></td>
+ <td>run <code>configure --with-jvm-variants=client</code></td>
+ </tr>
+ <tr valign="top">
+ <td>set <code>ALT_FREETYPE_LIB_PATH=/opt/freetype/lib</code>
+ and <code>ALT_FREETYPE_HEADERS_PATH=/opt/freetype/include</code></td>
+ <td>run <code>configure --with-freetype=/opt/freetype</code></td>
+ </tr>
+ <tr valign="top">
+ <td>set <code>ALT_CUPS_HEADERS_PATH=/opt/cups/include</code></td>
+ <td>run <code>configure --with-cups=/opt/cups</code></td>
+ </tr>
+ <tr valign="top">
+ <td>set <code>ALT_OPENWIN_HOME=/opt/X11R6</code></td>
+ <td>run <code>configure --with-x=/opt/X11R6</code></td>
+ </tr>
+ <tr valign="top">
+ <td>set <code>ALT_MSVCRNN_DLL_PATH=c:/vc_redist</code></td>
+ <td>run <code>configure --with-msvcr100dll=/cygdrive/c/vc_redist</code></td>
+ </tr>
+ <tr valign="top">
+ <td>set <code>ALT_COMPILER_PATH=/opt/my-gcc/bin/gcc</code></td>
+ <td>run <code>CC=/opt/my-gcc/bin/gcc configure</code>
+ or <code>CXX=/opt/my-gcc/bin/g++ configure</code>
+ </td>
+ </tr>
+ <tr valign="top">
+ <td>set <code>BUILD_HEADLESS_ONLY=true</code></td>
+ <td>run <code>configure --disable-headful</code></td>
+ </tr>
+ <tr valign="top">
+ <td>set <code>ALT_DEVTOOLS_PATH=/opt/mytools</code></td>
+ <td>just run <code>configure</code>,
+ your tools should be detected automatically.
+ If you have an unusual configuration,
+ add the tools directory to your <code>PATH</code>.
+ </td>
+ </tr>
+ <tr valign="top">
+ <td>set <code>ALT_DROPS_DIR=/home/user/dropdir</code></td>
+ <td>source drops are not used anymore</td>
+ </tr>
+ <tr valign="top">
+ <td>set <code>USE_ONLY_BOOTDIR_TOOLS=true</code></td>
+ <td>not needed, <code>configure</code> should always do the Right Thing automatically</td>
+ </tr>
+ <tr valign="top">
+ <td>set <code>ALT_JDK_IMPORT_PATH=/opt/java/import-jdk</code>
+ or <code>ALT_BUILD_JDK_IMPORT_PATH=/opt/java/import-jdk</code>
+ </td>
+ <td>Importing JDKs is no longer possible,
+ but hotspot can be imported using
+ <code>--with-import-hotspot</code>.
+ Documentation on how to achieve a
+ similar solution will come soon!
+ </td>
+ </tr>
+ <tr valign="top">
+ <td>set <code>EXTRA_CFLAGS=-Xfoo</code></td>
+ <td>run <code>CFLAGS=-Xfoo configure</code></td>
+ </tr>
+ <tr valign="top">
+ <td>set <code>CROSS_COMPILE_ARCH=i586</code></td>
+ <td>see <a href="#sec7.3"> section 7.3, Cross-compilation</a></td>
+ </tr>
+ <tr valign="top">
+ <td>set <code>SKIP_BOOT_CYCLE=false</code></td>
+ <td>Run <code>make bootcycle-images</code>.</td>
+ </tr>
+ </table>
+
+ <h3><a name="variables">Environment/Make Variables</a></h3>
+ <p>
+ Some of the
+ environment or make variables (just called <b>variables</b> in this
+ document) that can impact the build are:
+ <blockquote>
+ <dl>
+ <dt><a name="path"><code>PATH</code></a> </dt>
+ <dd>Typically you want to set the <code>PATH</code> to include:
+ <ul>
+ <li>The location of the GNU make binary</li>
+ <li>The location of the Bootstrap JDK <code>java</code>
+ (see <a href="#bootjdk">Bootstrap JDK</a>)</li>
+ <li>The location of the C/C++ compilers
+ (see <a href="#compilers"><code>compilers</code></a>)</li>
+ <li>The location or locations for the Unix command utilities
+ (e.g. <code>/usr/bin</code>)</li>
+ </ul>
+ </dd>
+ <dt><code>MILESTONE</code> </dt>
+ <dd>
+ The milestone name for the build (<i>e.g.</i>"beta").
+ The default value is "internal".
+ </dd>
+ <dt><code>BUILD_NUMBER</code> </dt>
+ <dd>
+ The build number for the build (<i>e.g.</i> "b27").
+ The default value is "b00".
+ </dd>
+ <dt><a name="arch_data_model"><code>ARCH_DATA_MODEL</code></a></dt>
+ <dd>The <code>ARCH_DATA_MODEL</code> variable
+ is used to specify whether the build is to generate 32-bit or 64-bit
+ binaries.
+ The Solaris build supports either 32-bit or 64-bit builds, but
+ Windows and Linux will support only one, depending on the specific
+ OS being used.
+ Normally, setting this variable is only necessary on Solaris.
+ Set <code>ARCH_DATA_MODEL</code> to <code>32</code> for generating 32-bit binaries,
+ or to <code>64</code> for generating 64-bit binaries.
+ </dd>
+ <dt><a name="ALT_BOOTDIR"><code>ALT_BOOTDIR</code></a></dt>
+ <dd>
+ The location of the bootstrap JDK installation.
+ See <a href="#bootjdk">Bootstrap JDK</a> for more information.
+ You should always install your own local Bootstrap JDK and
+ always set <code>ALT_BOOTDIR</code> explicitly.
+ </dd>
+ <dt><a name="ALT_OUTPUTDIR"><code>ALT_OUTPUTDIR</code></a> </dt>
+ <dd>
+ An override for specifying the (absolute) path of where the
+ build output is to go.
+ The default output directory will be build/<i>platform</i>.
+ </dd>
+ <dt><a name="ALT_COMPILER_PATH"><code>ALT_COMPILER_PATH</code></a> </dt>
+ <dd>
+ The location of the C/C++ compiler.
+ The default varies depending on the platform.
+ </dd>
+ <dt><code><a name="ALT_CACERTS_FILE">ALT_CACERTS_FILE</a></code></dt>
+ <dd>
+ The location of the <a href="#cacerts">cacerts</a> file.
+ The default will refer to
+ <code>jdk/src/share/lib/security/cacerts</code>.
+ </dd>
+ <dt><a name="ALT_CUPS_HEADERS_PATH"><code>ALT_CUPS_HEADERS_PATH</code></a> </dt>
+ <dd>
+ The location of the CUPS header files.
+ See <a href="#cups">CUPS information</a> for more information.
+ If this path does not exist the fallback path is
+ <code>/usr/include</code>.
+ </dd>
+ <dt><a name="ALT_FREETYPE_LIB_PATH"><code>ALT_FREETYPE_LIB_PATH</code></a></dt>
+ <dd>
+ The location of the FreeType shared library.
+ See <a href="#freetype">FreeType information</a> for details.
+ </dd>
+ <dt><a name="ALT_FREETYPE_HEADERS_PATH"><code>ALT_FREETYPE_HEADERS_PATH</code></a></dt>
+ <dd>
+ The location of the FreeType header files.
+ See <a href="#freetype">FreeType information</a> for details.
+ </dd>
+ <dt><a name="ALT_JDK_DEVTOOLS_PATH"><code>ALT_JDK_DEVTOOLS_PATH</code></a></dt>
+ <dd>
+ The default root location of the devtools.
+ The default value is
+ <code>$(ALT_SLASH_JAVA)/devtools</code>.
+ </dd>
+ <dt><code><a name="ALT_DEVTOOLS_PATH">ALT_DEVTOOLS_PATH</a></code> </dt>
+ <dd>
+ The location of tools like the
+ <a href="#zip"><code>zip</code> and <code>unzip</code></a>
+ binaries, but might also contain the GNU make utility
+ (<code><i>gmake</i></code>).
+ So this area is a bit of a grab bag, especially on Windows.
+ The default value depends on the platform and
+ Unix Commands being used.
+ On Linux the default will be
+ <code>$(ALT_JDK_DEVTOOLS_PATH)/linux/bin</code>,
+ on Solaris
+ <code>$(ALT_JDK_DEVTOOLS_PATH)/<i>{sparc,i386}</i>/bin</code>,
+ and on Windows with CYGWIN
+ <code>/usr/bin</code>.
+ </dd>
+ <dt><a name="ALT_UNIXCCS_PATH"><code>ALT_UNIXCCS_PATH</code></a></dt>
+ <dd>
+ <strong>Solaris only:</strong>
+ An override for specifying where the Unix CCS
+ command set are located.
+ The default location is <code>/usr/ccs/bin</code>
+ </dd>
+ <dt><a name="ALT_SLASH_JAVA"><code>ALT_SLASH_JAVA</code></a></dt>
+ <dd>
+ The default root location for many of the ALT path locations
+ of the following ALT variables.
+ The default value is
+ <code>"/java"</code> on Solaris and Linux,
+ <code>"J:"</code> on Windows.
+ </dd>
+
+ <dt><a name="ALT_OPENWIN_HOME"><code>ALT_OPENWIN_HOME</code></a></dt>
+ <dd>
+ The top-level directory of the libraries and include files
+ for the platform's
+ graphical programming environment.
+ The default location is platform specific.
+ For example, on Linux it defaults to <code>/usr/X11R6/</code>.
+ </dd>
+ <dt><strong>Windows specific:</strong></dt>
+ <dd>
+ <dl>
+ <dt><a name="ALT_WINDOWSSDKDIR"><code>ALT_WINDOWSSDKDIR</code></a> </dt>
+ <dd>
+ The location of the
+ Microsoft Windows SDK where some tools will be
+ located.
+ The default is whatever WINDOWSSDKDIR is set to
+ (or WindowsSdkDir) or the path
+ <br>
+ <code>c:\Program Files\Microsoft SDKs\Windows\v7.0a</code>
+ </dd>
+ <dt><code><a name="ALT_DXSDK_PATH">ALT_DXSDK_PATH</a></code> </dt>
+ <dd>
+ The location of the
+ <a href="#dxsdk">Microsoft DirectX 9 SDK</a>.
+ The default will be to try and use the DirectX environment
+ variable <code>DXSDK_DIR</code>,
+ failing that, look in <code>C:/DXSDK</code>.
+ </dd>
+ <dt><code><a name="ALT_MSVCRNN_DLL_PATH">ALT_MSVCRNN_DLL_PATH</a></code> </dt>
+ <dd>
+ The location of the
+ <a href="#msvcrNN"><code>MSVCR100.DLL</code></a>.
+ </dd>
+ </dl>
+ </dd>
+ <dt><strong>Cross-Compilation Support:</strong></dt>
+ <dd>
+ <dl>
+ <dt><a name="CROSS_COMPILE_ARCH"><code>CROSS_COMPILE_ARCH</code></a> </dt>
+ <dd>
+ Set to the target architecture of a
+ cross-compilation build. If set, this
+ variable is used to signify that we are
+ cross-compiling. The expectation
+ is that
+ <a href="#ALT_COMPILER_PATH"><code>ALT_COMPILER_PATH</code></a>
+ is set
+ to point to the cross-compiler and that any
+ cross-compilation specific flags
+ are passed using
+ <a href="#EXTRA_CFLAGS"><code>EXTRA_CFLAGS</code></a>.
+ The <a href="#ALT_OPENWIN_HOME"><code>ALT_OPENWIN_HOME</code></a>
+ variable should
+ also be set to point to the graphical header files
+ (e.g. X11) provided with
+ the cross-compiler.
+ When cross-compiling we skip execution of any demos
+ etc that may be built, and
+ also skip binary-file verification.
+ </dd>
+ <dt><code><a name="EXTRA_CFLAGS">EXTRA_CFLAGS</a></code> </dt>
+ <dd>
+ Used to pass cross-compilation options to the
+ cross-compiler.
+ These are added to the <code>CFLAGS</code>
+ and <code>CXXFLAGS</code> variables.
+ </dd>
+ <dt><code><a name="USE_ONLY_BOOTDIR_TOOLS">USE_ONLY_BOOTDIR_TOOLS</a></code> </dt>
+ <dd>
+ Used primarily for cross-compilation builds
+ (and always set in that case)
+ this variable indicates that tools from the
+ boot JDK should be used during
+ the build process, not the tools
+ (<code>javac</code>, <code>javah</code>, <code>jar</code>)
+ just built (which can't execute on the build host).
+ </dd>
+ <dt><code><a name="HOST_CC">HOST_CC</a></code> </dt>
+ <dd>
+ The location of the C compiler to generate programs
+ to run on the build host.
+ Some parts of the build generate programs that are
+ then compiled and executed
+ to produce other parts of the build. Normally the
+ primary C compiler is used
+ to do this, but when cross-compiling that would be
+ the cross-compiler and the
+ resulting program could not be executed.
+ On Linux this defaults to <code>/usr/bin/gcc</code>;
+ on other platforms it must be
+ set explicitly.
+ </dd>
+ </dl>
+ <dt><strong>Specialized Build Options:</strong></dt>
+ <dd>
+ Some build variables exist to support specialized build
+ environments and/or specialized
+ build products. Their use is only supported in those contexts:
+ <dl>
+ <dt><code><a name="BUILD_CLIENT_ONLY">BUILD_CLIENT_ONLY</a></code> </dt>
+ <dd>
+ Indicates this build will only contain the
+ Hotspot client VM. In addition to
+ controlling the Hotspot build target,
+ it ensures that we don't try to copy
+ any server VM files/directories,
+ and defines a default <code>jvm.cfg</code> file
+ suitable for a client-only environment.
+ Using this in a 64-bit build will
+ generate a sanity warning as 64-bit client
+ builds are not directly supported.
+ </dd>
+ <dt><code><a name="BUILD_HEADLESS_ONLY"></a>BUILD_HEADLESS_ONLY</code> </dt>
+ <dd>
+ Used when the build environment has no graphical
+ capabilities at all. This
+ excludes building anything that requires graphical
+ libraries to be available.
+ </dd>
+ <dt><code><a name="JAVASE_EMBEDDED"></a>JAVASE_EMBEDDED</code> </dt>
+ <dd>
+ Used to indicate this is a build of the Oracle
+ Java SE Embedded product.
+ This will enable the directives included in the
+ SE-Embedded specific build
+ files.
+ </dd>
+ <dt><code><a name="LIBZIP_CAN_USE_MMAP">LIBZIP_CAN_USE_MMAP</a></code> </dt>
+ <dd>
+ If set to false, disables the use of mmap by the
+ zip utility. Otherwise,
+ mmap will be used.
+ </dd>
+ <dt><code><a name="COMPRESS_JARS"></a>COMPRESS_JARS</code> </dt>
+ <dd>
+ If set to true, causes certain jar files that
+ would otherwise be built without
+ compression, to use compression.
+ </dd>
+ </dl>
+ </dd>
+ </dl>
+ </blockquote>
+
+</blockquote> <!-- Appendix D -->
+
+ <!-- ====================================================== -->
<hr>
- <h2><a name="hints">Hints and Tips</a></h2>
- <blockquote>
- You don't have to use all these hints and tips, and in fact people do actually
- build with systems that contradict these, but they might prove to be
- helpful to some.
- <ul>
- <li>
- If <tt>make sanity</tt> does not work, find out why, fix that
- before going any further. Or at least understand what the
- complaints are from it.
- </li>
- <li>
- JDK: Keep in mind that you are building a JDK, but you need
- a JDK (BOOTDIR JDK) to build this JDK.
- </li>
- <li>
- Ant: The ant utility is a java application and besides having
- ant available to you, it's important that ant finds the right
- java to run with. Make sure you can type <tt>ant -version</tt>
- and get clean results with no error messages.
- </li>
- <li>
- Linux: Try and favor the system packages over building your own
- or getting packages from other areas.
- Most Linux builds should be possible with the system's
- available packages.
- </li>
- <li>
- Solaris: Typically you will need to get compilers on your systems
- and occasionally GNU make 3.81 if a gmake binary is not available.
- The gmake binary might not be 3.81, be careful.
- </li>
- <li>
- Windows VS2010:
- <ul>
- <li>
- Only the C++ part of VS2010 is needed.
- Try to let the installation go to the default install directory.
- Always reboot your system after installing VS2010.
- The system environment variable VS100COMNTOOLS should be
- set in your environment.
- </li>
- <li>
- Make sure that TMP and TEMP are also set in the environment
- and refer to Windows paths that exist, like <tt>C:\temp</tt>,
- not <tt>/tmp</tt>, not <tt>/cygdrive/c/temp</tt>, and not <tt>C:/temp</tt>.
- <tt>C:\temp</tt> is just an example, it is assumed that this area is
- private to the user, so by default after installs you should
- see a unique user path in these variables.
- </li>
- <li>
- You need to use vsvars32.bat or vsvars64.bat to get the
- PATH, INCLUDE, LIB, LIBPATH, and WINDOWSSDKDIR
- variables set in your shell environment.
- These bat files are not easy to use from a shell environment.
- However, there is a script placed in the root jdk8 repository called
- vsvars.sh that can help, it should only be done once in a shell
- that will be doing the build, e.g.<br>
- <tt>sh ./make/scripts/vsvars.sh -v10 > settings<br>
- eval `cat settings`</tt><br>
- Or just <tt>eval `sh ./make/scripts/vsvars.sh -v10`</tt>.
- </li>
- </ul>
- </li>
- <li>
- Windows: PATH order is critical, see the
- <a href="#paths">paths</a> section for more information.
- </li>
- <li>
- Windows 64bit builds: Use ARCH_DATA_MODEL=64.
- </li>
- </ul>
- </blockquote>
- <!-- ------------------------------------------------------ -->
+ <p>End of OpenJDK README-builds.html document.<br>Please come again!
<hr>
- <h2><a name="troubleshooting">Troubleshooting</a></h2>
- <blockquote>
- A build can fail for any number of reasons.
- Most failures
- are a result of trying to build in an environment in which all the
- pre-build requirements have not been met.
- The first step in
- troubleshooting a build failure is to recheck that you have satisfied
- all the pre-build requirements for your platform.
- Look for the check list of the platform you are building on in the
- <a href="#contents">Table of Contents</a>.
- <p>
- You can validate your build environment by using the <tt>sanity</tt>
- target.
- Any errors listed
- will stop the build from starting, and any warnings may result in
- a flawed product build.
- We strongly encourage you to evaluate every
- sanity check warning and fix it if required, before you proceed
- further with your build.
- <p>
- Some of the more common problems with builds are briefly described
- below, with suggestions for remedies.
- <ul>
- <li>
- <b>Corrupted Bundles on Windows:</b>
- <blockquote>
- Some virus scanning software has been known to corrupt the
- downloading of zip bundles.
- It may be necessary to disable the 'on access' or 'real time'
- virus scanning features to prevent this corruption.
- This type of "real time" virus scanning can also slow down the
- build process significantly.
- Temporarily disabling the feature, or excluding the build
- output directory may be necessary to get correct and faster builds.
- </blockquote>
- </li>
- <li>
- <b>Slow Builds:</b>
- <blockquote>
- If your build machine seems to be overloaded from too many
- simultaneous C++ compiles, try setting the <tt>HOTSPOT_BUILD_JOBS</tt>
- variable to <tt>1</tt> (if you're using a multiple CPU
- machine, setting it to more than the the number of CPUs is probably
- not a good idea).
- <p>
- Creating the javadocs can be very slow, if you are running
- javadoc, consider skipping that step.
- <p>
- Faster hardware and more RAM always helps too.
- The VM build tends to be CPU intensive (many C++ compiles),
- and the rest of the JDK will often be disk intensive.
- <p>
- Faster compiles are possible using a tool called
- <a href="http://ccache.samba.org/" target="_blank">ccache</a>.
- </blockquote>
- </li>
- <li>
- <b>File time issues:</b>
- <blockquote>
- If you see warnings that refer to file time stamps, e.g.
- <blockquote>
- <i>Warning message:</i><tt> File `xxx' has modification time in
- the future.</tt>
- <br>
- <i>Warning message:</i> <tt> Clock skew detected. Your build may
- be incomplete.</tt>
- </blockquote>
- These warnings can occur when the clock on the build machine is out of
- sync with the timestamps on the source files. Other errors, apparently
- unrelated but in fact caused by the clock skew, can occur along with
- the clock skew warnings. These secondary errors may tend to obscure the
- fact that the true root cause of the problem is an out-of-sync clock.
- For example, an out-of-sync clock has been known to cause an old
- version of javac to be used to compile some files, resulting in errors
- when the pre-1.4 compiler ran across the new <tt>assert</tt> keyword
- in the 1.4 source code.
- <p>
- If you see these warnings, reset the clock on the build
- machine, run "<tt><i>gmake</i> clobber</tt>" or delete the directory
- containing the build output, and restart the build from the beginning.
- </blockquote>
- </li>
- <li>
- <b>Error message: <tt>Trouble writing out table to disk</tt></b>
- <blockquote>
- Increase the amount of swap space on your build machine.
- </blockquote>
- </li>
- <li>
- <b>Error Message: <tt>libstdc++ not found:</tt></b>
- <blockquote>
- This is caused by a missing libstdc++.a library.
- This is installed as part of a specific package
- (e.g. libstdc++.so.devel.386).
- By default some 64-bit Linux versions (e.g. Fedora)
- only install the 64-bit version of the libstdc++ package.
- Various parts of the JDK build require a static
- link of the C++ runtime libraries to allow for maximum
- portability of the built images.
- </blockquote>
- </li>
- <li>
- <b>Error Message: <tt>cannot restore segment prot after reloc</tt></b>
- <blockquote>
- This is probably an issue with SELinux (See
- <a href="http://en.wikipedia.org/wiki/SELinux" target="_blank">
- http://en.wikipedia.org/wiki/SELinux</a>).
- Parts of the VM is built without the <tt>-fPIC</tt> for
- performance reasons.
- <p>
- To completely disable SELinux:
- <ol>
- <li><tt>$ su root</tt></li>
- <li><tt># system-config-securitylevel</tt></li>
- <li><tt>In the window that appears, select the SELinux tab</tt></li>
- <li><tt>Disable SELinux</tt></li>
- </ol>
- <p>
- Alternatively, instead of completely disabling it you could
- disable just this one check.
- <ol>
- <li>Select System->Administration->SELinux Management</li>
- <li>In the SELinux Management Tool which appears,
- select "Boolean" from the menu on the left</li>
- <li>Expand the "Memory Protection" group</li>
- <li>Check the first item, labeled
- "Allow all unconfined executables to use libraries requiring text relocation ..."</li>
- </ol>
- </blockquote>
- </li>
- <li>
- <b>Windows Error Messages:</b><br>
- <tt>*** fatal error - couldn't allocate heap, ... </tt><br>
- <tt>rm fails with "Directory not empty"</tt><br>
- <tt>unzip fails with "cannot create ... Permission denied"</tt><br>
- <tt>unzip fails with "cannot create ... Error 50"</tt><br>
- <blockquote>
- The CYGWIN software can conflict with other non-CYGWIN
- software. See the CYGWIN FAQ section on
- <a href="http://cygwin.com/faq/faq.using.html#faq.using.bloda" target="_blank">
- BLODA (applications that interfere with CYGWIN)</a>.
- </blockquote>
- </li>
- <li>
- <b>Windows Error Message: <tt>spawn failed</tt></b>
- <blockquote>
- Try rebooting the system, or there could be some kind of
- issue with the disk or disk partition being used.
- Sometimes it comes with a "Permission Denied" message.
- </blockquote>
- </li>
- </ul>
- </blockquote>
- <!-- ------------------------------------------------------ -->
- <hr>
- <h2><a name="newbuild">The New Build</a></h2>
- <blockquote>
- The <a href="http://openjdk.java.net/projects/build-infra/">
- Build Infrastructure project</a> is working on a new
- build. For information on how to try it out, please see the
- <a href="http://openjdk.java.net/projects/build-infra/guide.html">
- Build Infra User Guide</a>
- </blockquote>
- <hr>
+
</body>
</html>
--- a/common/autoconf/build-performance.m4 Fri Mar 15 17:02:24 2013 +0400
+++ b/common/autoconf/build-performance.m4 Fri Mar 15 16:39:07 2013 -0700
@@ -47,10 +47,6 @@
FOUND_CORES=yes
fi
- # For c/c++ code we run twice as many concurrent build
- # jobs than we have cores, otherwise we will stall on io.
- CONCURRENT_BUILD_JOBS=`expr $NUM_CORES \* 2`
-
if test "x$FOUND_CORES" = xyes; then
AC_MSG_RESULT([$NUM_CORES])
else
@@ -98,32 +94,62 @@
AC_DEFUN_ONCE([BPERF_SETUP_BUILD_CORES],
[
-# How many cores do we have on this build system?
-AC_ARG_WITH(num-cores, [AS_HELP_STRING([--with-num-cores],
+ # How many cores do we have on this build system?
+ AC_ARG_WITH(num-cores, [AS_HELP_STRING([--with-num-cores],
[number of cores in the build system, e.g. --with-num-cores=8 @<:@probed@:>@])])
-if test "x$with_num_cores" = x; then
+ if test "x$with_num_cores" = x; then
# The number of cores were not specified, try to probe them.
BPERF_CHECK_CORES
-else
+ else
NUM_CORES=$with_num_cores
- CONCURRENT_BUILD_JOBS=`expr $NUM_CORES \* 2`
-fi
-AC_SUBST(NUM_CORES)
-AC_SUBST(CONCURRENT_BUILD_JOBS)
+ fi
+ AC_SUBST(NUM_CORES)
])
AC_DEFUN_ONCE([BPERF_SETUP_BUILD_MEMORY],
[
-# How much memory do we have on this build system?
-AC_ARG_WITH(memory-size, [AS_HELP_STRING([--with-memory-size],
+ # How much memory do we have on this build system?
+ AC_ARG_WITH(memory-size, [AS_HELP_STRING([--with-memory-size],
[memory (in MB) available in the build system, e.g. --with-memory-size=1024 @<:@probed@:>@])])
-if test "x$with_memory_size" = x; then
+ if test "x$with_memory_size" = x; then
# The memory size was not specified, try to probe it.
BPERF_CHECK_MEMORY_SIZE
-else
+ else
MEMORY_SIZE=$with_memory_size
-fi
-AC_SUBST(MEMORY_SIZE)
+ fi
+ AC_SUBST(MEMORY_SIZE)
+])
+
+AC_DEFUN_ONCE([BPERF_SETUP_BUILD_JOBS],
+[
+ # Provide a decent default number of parallel jobs for make depending on
+ # number of cores, amount of memory and machine architecture.
+ AC_ARG_WITH(jobs, [AS_HELP_STRING([--with-jobs],
+ [number of parallel jobs to let make run @<:@calculated based on cores and memory@:>@])])
+ if test "x$with_jobs" = x; then
+ # Number of jobs was not specified, calculate.
+ AC_MSG_CHECKING([for appropriate number of jobs to run in parallel])
+ # Approximate memory in GB, rounding up a bit.
+ memory_gb=`expr $MEMORY_SIZE / 1100`
+ # Pick the lowest of memory in gb and number of cores.
+ if test "$memory_gb" -lt "$NUM_CORES"; then
+ JOBS="$memory_gb"
+ else
+ JOBS="$NUM_CORES"
+ # On bigger machines, leave some room for other processes to run
+ if test "$JOBS" -gt "4"; then
+ JOBS=`expr $JOBS '*' 90 / 100`
+ fi
+ fi
+ # Cap number of jobs to 16
+ if test "$JOBS" -gt "16"; then
+ JOBS=16
+ fi
+ AC_MSG_RESULT([$JOBS])
+ else
+ JOBS=$with_jobs
+ fi
+ AC_SUBST(JOBS)
])
AC_DEFUN([BPERF_SETUP_CCACHE],
--- a/common/autoconf/configure.ac Fri Mar 15 17:02:24 2013 +0400
+++ b/common/autoconf/configure.ac Fri Mar 15 16:39:07 2013 -0700
@@ -204,6 +204,7 @@
BPERF_SETUP_BUILD_CORES
BPERF_SETUP_BUILD_MEMORY
+BPERF_SETUP_BUILD_JOBS
# Setup smart javac (after cores and memory have been setup)
BPERF_SETUP_SMART_JAVAC
--- a/common/autoconf/generated-configure.sh Fri Mar 15 17:02:24 2013 +0400
+++ b/common/autoconf/generated-configure.sh Fri Mar 15 16:39:07 2013 -0700
@@ -609,8 +609,8 @@
ENABLE_SJAVAC
SJAVAC_SERVER_CORES
SJAVAC_SERVER_JAVA
+JOBS
MEMORY_SIZE
-CONCURRENT_BUILD_JOBS
NUM_CORES
SALIB_NAME
HOTSPOT_MAKE_ARGS
@@ -649,7 +649,7 @@
CXXFLAGS_JDKLIB
CFLAGS_JDKEXE
CFLAGS_JDKLIB
-MACOSX_REQUIRED_VERSION
+MACOSX_VERSION_MIN
PACKAGE_PATH
LEGACY_EXTRA_LDFLAGS
LEGACY_EXTRA_CXXFLAGS
@@ -733,6 +733,8 @@
BUILD_CXX
BUILD_CC
MSVCR_DLL
+DXSDK_INCLUDE_PATH
+DXSDK_LIB_PATH
VS_PATH
VS_LIB
VS_INCLUDE
@@ -993,6 +995,9 @@
with_override_jdk
with_import_hotspot
with_msvcr_dll
+with_dxsdk
+with_dxsdk_lib
+with_dxsdk_include
with_extra_cflags
with_extra_cxxflags
with_extra_ldflags
@@ -1010,6 +1015,7 @@
with_stdc__lib
with_num_cores
with_memory_size
+with_jobs
with_sjavac_server_java
with_sjavac_server_cores
enable_sjavac
@@ -1743,6 +1749,11 @@
source
--with-msvcr-dll copy this msvcr100.dll into the built JDK (Windows
only) [probed]
+ --with-dxsdk the DirectX SDK (Windows only) [probed]
+ --with-dxsdk-lib the DirectX SDK lib directory (Windows only)
+ [probed]
+ --with-dxsdk-include the DirectX SDK include directory (Windows only)
+ [probed]
--with-extra-cflags extra flags to be used when compiling jdk c-files
--with-extra-cxxflags extra flags to be used when compiling jdk c++-files
--with-extra-ldflags extra flags to be used when linking jdk
@@ -1768,6 +1779,8 @@
--with-num-cores=8 [probed]
--with-memory-size memory (in MB) available in the build system, e.g.
--with-memory-size=1024 [probed]
+ --with-jobs number of parallel jobs to let make run [calculated
+ based on cores and memory]
--with-sjavac-server-java
use this java binary for running the sjavac
background server [Boot JDK java]
@@ -3337,6 +3350,8 @@
+
+
#
# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -3723,6 +3738,10 @@
+# Setup the DXSDK paths
+
+
+
@@ -3732,7 +3751,7 @@
#CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1361218904
+DATE_WHEN_GENERATED=1363150186
###############################################################################
#
@@ -16955,6 +16974,432 @@
fi
+
+
+# Check whether --with-dxsdk was given.
+if test "${with_dxsdk+set}" = set; then :
+ withval=$with_dxsdk;
+fi
+
+
+# Check whether --with-dxsdk-lib was given.
+if test "${with_dxsdk_lib+set}" = set; then :
+ withval=$with_dxsdk_lib;
+fi
+
+
+# Check whether --with-dxsdk-include was given.
+if test "${with_dxsdk_include+set}" = set; then :
+ withval=$with_dxsdk_include;
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DirectX SDK" >&5
+$as_echo_n "checking for DirectX SDK... " >&6; }
+
+ if test "x$with_dxsdk" != x; then
+ dxsdk_path="$with_dxsdk"
+ elif test "x$DXSDK_DIR" != x; then
+ dxsdk_path="$DXSDK_DIR"
+ elif test -d "C:/DXSDK"; then
+ dxsdk_path="C:/DXSDK"
+ else
+ as_fn_error $? "Could not find the DirectX SDK" "$LINENO" 5
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dxsdk_path" >&5
+$as_echo "$dxsdk_path" >&6; }
+
+ if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
+
+ # Input might be given as Windows format, start by converting to
+ # unix format.
+ path="$dxsdk_path"
+ new_path=`$CYGPATH -u "$path"`
+
+ # Cygwin tries to hide some aspects of the Windows file system, such that binaries are
+ # named .exe but called without that suffix. Therefore, "foo" and "foo.exe" are considered
+ # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
+ # "foo.exe" is OK but "foo" is an error.
+ #
+ # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # It is also a way to make sure we got the proper file name for the real test later on.
+ test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
+ if test "x$test_shortpath" = x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The path of dxsdk_path, which resolves as \"$path\", is invalid." >&5
+$as_echo "$as_me: The path of dxsdk_path, which resolves as \"$path\", is invalid." >&6;}
+ as_fn_error $? "Cannot locate the the path of dxsdk_path" "$LINENO" 5
+ fi
+
+ # Call helper function which possibly converts this using DOS-style short mode.
+ # If so, the updated path is stored in $new_path.
+
+ input_path="$new_path"
+ # Check if we need to convert this using DOS-style short mode. If the path
+ # contains just simple characters, use it. Otherwise (spaces, weird characters),
+ # take no chances and rewrite it.
+ # Note: m4 eats our [], so we need to use [ and ] instead.
+ has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-._/a-zA-Z0-9]`
+ if test "x$has_forbidden_chars" != x; then
+ # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
+ shortmode_path=`$CYGPATH -s -m -a "$input_path"`
+ path_after_shortmode=`$CYGPATH -u "$shortmode_path"`
+ if test "x$path_after_shortmode" != "x$input_to_shortpath"; then
+ # Going to short mode and back again did indeed matter. Since short mode is
+ # case insensitive, let's make it lowercase to improve readability.
+ shortmode_path=`$ECHO "$shortmode_path" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ # Now convert it back to Unix-stile (cygpath)
+ input_path=`$CYGPATH -u "$shortmode_path"`
+ new_path="$input_path"
+ fi
+ fi
+
+ test_cygdrive_prefix=`$ECHO $input_path | $GREP ^/cygdrive/`
+ if test "x$test_cygdrive_prefix" = x; then
+ # As a simple fix, exclude /usr/bin since it's not a real path.
+ if test "x`$ECHO $new_path | $GREP ^/usr/bin/`" = x; then
+ # The path is in a Cygwin special directory (e.g. /home). We need this converted to
+ # a path prefixed by /cygdrive for fixpath to work.
+ new_path="$CYGWIN_ROOT_PATH$input_path"
+ fi
+ fi
+
+
+ if test "x$path" != "x$new_path"; then
+ dxsdk_path="$new_path"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting dxsdk_path to \"$new_path\"" >&5
+$as_echo "$as_me: Rewriting dxsdk_path to \"$new_path\"" >&6;}
+ fi
+
+ elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
+
+ path="$dxsdk_path"
+ has_colon=`$ECHO $path | $GREP ^.:`
+ new_path="$path"
+ if test "x$has_colon" = x; then
+ # Not in mixed or Windows style, start by that.
+ new_path=`cmd //c echo $path`
+ fi
+
+
+ input_path="$new_path"
+ # Check if we need to convert this using DOS-style short mode. If the path
+ # contains just simple characters, use it. Otherwise (spaces, weird characters),
+ # take no chances and rewrite it.
+ # Note: m4 eats our [], so we need to use [ and ] instead.
+ has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-_/:a-zA-Z0-9]`
+ if test "x$has_forbidden_chars" != x; then
+ # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
+ new_path=`cmd /c "for %A in (\"$input_path\") do @echo %~sA"|$TR \\\\\\\\ / | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ fi
+
+
+ windows_path="$new_path"
+ if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
+ unix_path=`$CYGPATH -u "$windows_path"`
+ new_path="$unix_path"
+ elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
+ unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'`
+ new_path="$unix_path"
+ fi
+
+ if test "x$path" != "x$new_path"; then
+ dxsdk_path="$new_path"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting dxsdk_path to \"$new_path\"" >&5
+$as_echo "$as_me: Rewriting dxsdk_path to \"$new_path\"" >&6;}
+ fi
+
+ # Save the first 10 bytes of this path to the storage, so fixpath can work.
+ all_fixpath_prefixes=("${all_fixpath_prefixes[@]}" "${new_path:0:10}")
+
+ else
+ # We're on a posix platform. Hooray! :)
+ path="$dxsdk_path"
+
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of dxsdk_path, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ has_space=`$ECHO "$path" | $GREP " "`
+ if test "x$has_space" != x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The path of dxsdk_path, which resolves as \"$path\", is invalid." >&5
+$as_echo "$as_me: The path of dxsdk_path, which resolves as \"$path\", is invalid." >&6;}
+ as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
+ fi
+ fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DirectX SDK lib dir" >&5
+$as_echo_n "checking for DirectX SDK lib dir... " >&6; }
+ if test "x$with_dxsdk_lib" != x; then
+ DXSDK_LIB_PATH="$with_dxsdk_lib"
+ elif test "x$OPENJDK_TARGET_CPU" = "xx86_64"; then
+ DXSDK_LIB_PATH="$dxsdk_path/Lib/x64"
+ else
+ DXSDK_LIB_PATH="$dxsdk_path/Lib"
+ fi
+ # dsound.lib is linked to in jsoundds
+ if test ! -f "$DXSDK_LIB_PATH/dsound.lib"; then
+ as_fn_error $? "Invalid DirectX SDK lib dir" "$LINENO" 5
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DXSDK_LIB_PATH" >&5
+$as_echo "$DXSDK_LIB_PATH" >&6; }
+
+ if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
+
+ # Input might be given as Windows format, start by converting to
+ # unix format.
+ path="$DXSDK_LIB_PATH"
+ new_path=`$CYGPATH -u "$path"`
+
+ # Cygwin tries to hide some aspects of the Windows file system, such that binaries are
+ # named .exe but called without that suffix. Therefore, "foo" and "foo.exe" are considered
+ # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
+ # "foo.exe" is OK but "foo" is an error.
+ #
+ # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # It is also a way to make sure we got the proper file name for the real test later on.
+ test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
+ if test "x$test_shortpath" = x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The path of DXSDK_LIB_PATH, which resolves as \"$path\", is invalid." >&5
+$as_echo "$as_me: The path of DXSDK_LIB_PATH, which resolves as \"$path\", is invalid." >&6;}
+ as_fn_error $? "Cannot locate the the path of DXSDK_LIB_PATH" "$LINENO" 5
+ fi
+
+ # Call helper function which possibly converts this using DOS-style short mode.
+ # If so, the updated path is stored in $new_path.
+
+ input_path="$new_path"
+ # Check if we need to convert this using DOS-style short mode. If the path
+ # contains just simple characters, use it. Otherwise (spaces, weird characters),
+ # take no chances and rewrite it.
+ # Note: m4 eats our [], so we need to use [ and ] instead.
+ has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-._/a-zA-Z0-9]`
+ if test "x$has_forbidden_chars" != x; then
+ # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
+ shortmode_path=`$CYGPATH -s -m -a "$input_path"`
+ path_after_shortmode=`$CYGPATH -u "$shortmode_path"`
+ if test "x$path_after_shortmode" != "x$input_to_shortpath"; then
+ # Going to short mode and back again did indeed matter. Since short mode is
+ # case insensitive, let's make it lowercase to improve readability.
+ shortmode_path=`$ECHO "$shortmode_path" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ # Now convert it back to Unix-stile (cygpath)
+ input_path=`$CYGPATH -u "$shortmode_path"`
+ new_path="$input_path"
+ fi
+ fi
+
+ test_cygdrive_prefix=`$ECHO $input_path | $GREP ^/cygdrive/`
+ if test "x$test_cygdrive_prefix" = x; then
+ # As a simple fix, exclude /usr/bin since it's not a real path.
+ if test "x`$ECHO $new_path | $GREP ^/usr/bin/`" = x; then
+ # The path is in a Cygwin special directory (e.g. /home). We need this converted to
+ # a path prefixed by /cygdrive for fixpath to work.
+ new_path="$CYGWIN_ROOT_PATH$input_path"
+ fi
+ fi
+
+
+ if test "x$path" != "x$new_path"; then
+ DXSDK_LIB_PATH="$new_path"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting DXSDK_LIB_PATH to \"$new_path\"" >&5
+$as_echo "$as_me: Rewriting DXSDK_LIB_PATH to \"$new_path\"" >&6;}
+ fi
+
+ elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
+
+ path="$DXSDK_LIB_PATH"
+ has_colon=`$ECHO $path | $GREP ^.:`
+ new_path="$path"
+ if test "x$has_colon" = x; then
+ # Not in mixed or Windows style, start by that.
+ new_path=`cmd //c echo $path`
+ fi
+
+
+ input_path="$new_path"
+ # Check if we need to convert this using DOS-style short mode. If the path
+ # contains just simple characters, use it. Otherwise (spaces, weird characters),
+ # take no chances and rewrite it.
+ # Note: m4 eats our [], so we need to use [ and ] instead.
+ has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-_/:a-zA-Z0-9]`
+ if test "x$has_forbidden_chars" != x; then
+ # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
+ new_path=`cmd /c "for %A in (\"$input_path\") do @echo %~sA"|$TR \\\\\\\\ / | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ fi
+
+
+ windows_path="$new_path"
+ if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
+ unix_path=`$CYGPATH -u "$windows_path"`
+ new_path="$unix_path"
+ elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
+ unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'`
+ new_path="$unix_path"
+ fi
+
+ if test "x$path" != "x$new_path"; then
+ DXSDK_LIB_PATH="$new_path"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting DXSDK_LIB_PATH to \"$new_path\"" >&5
+$as_echo "$as_me: Rewriting DXSDK_LIB_PATH to \"$new_path\"" >&6;}
+ fi
+
+ # Save the first 10 bytes of this path to the storage, so fixpath can work.
+ all_fixpath_prefixes=("${all_fixpath_prefixes[@]}" "${new_path:0:10}")
+
+ else
+ # We're on a posix platform. Hooray! :)
+ path="$DXSDK_LIB_PATH"
+
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of DXSDK_LIB_PATH, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ has_space=`$ECHO "$path" | $GREP " "`
+ if test "x$has_space" != x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The path of DXSDK_LIB_PATH, which resolves as \"$path\", is invalid." >&5
+$as_echo "$as_me: The path of DXSDK_LIB_PATH, which resolves as \"$path\", is invalid." >&6;}
+ as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
+ fi
+ fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DirectX SDK include dir" >&5
+$as_echo_n "checking for DirectX SDK include dir... " >&6; }
+ if test "x$with_dxsdk_include" != x; then
+ DXSDK_INCLUDE_PATH="$with_dxsdk_include"
+ else
+ DXSDK_INCLUDE_PATH="$dxsdk_path/Include"
+ fi
+ # dsound.h is included in jsoundds
+ if test ! -f "$DXSDK_INCLUDE_PATH/dsound.h"; then
+ as_fn_error $? "Invalid DirectX SDK lib dir" "$LINENO" 5
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DXSDK_INCLUDE_PATH" >&5
+$as_echo "$DXSDK_INCLUDE_PATH" >&6; }
+
+ if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
+
+ # Input might be given as Windows format, start by converting to
+ # unix format.
+ path="$DXSDK_INCLUDE_PATH"
+ new_path=`$CYGPATH -u "$path"`
+
+ # Cygwin tries to hide some aspects of the Windows file system, such that binaries are
+ # named .exe but called without that suffix. Therefore, "foo" and "foo.exe" are considered
+ # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
+ # "foo.exe" is OK but "foo" is an error.
+ #
+ # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # It is also a way to make sure we got the proper file name for the real test later on.
+ test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
+ if test "x$test_shortpath" = x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The path of DXSDK_INCLUDE_PATH, which resolves as \"$path\", is invalid." >&5
+$as_echo "$as_me: The path of DXSDK_INCLUDE_PATH, which resolves as \"$path\", is invalid." >&6;}
+ as_fn_error $? "Cannot locate the the path of DXSDK_INCLUDE_PATH" "$LINENO" 5
+ fi
+
+ # Call helper function which possibly converts this using DOS-style short mode.
+ # If so, the updated path is stored in $new_path.
+
+ input_path="$new_path"
+ # Check if we need to convert this using DOS-style short mode. If the path
+ # contains just simple characters, use it. Otherwise (spaces, weird characters),
+ # take no chances and rewrite it.
+ # Note: m4 eats our [], so we need to use [ and ] instead.
+ has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-._/a-zA-Z0-9]`
+ if test "x$has_forbidden_chars" != x; then
+ # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
+ shortmode_path=`$CYGPATH -s -m -a "$input_path"`
+ path_after_shortmode=`$CYGPATH -u "$shortmode_path"`
+ if test "x$path_after_shortmode" != "x$input_to_shortpath"; then
+ # Going to short mode and back again did indeed matter. Since short mode is
+ # case insensitive, let's make it lowercase to improve readability.
+ shortmode_path=`$ECHO "$shortmode_path" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ # Now convert it back to Unix-stile (cygpath)
+ input_path=`$CYGPATH -u "$shortmode_path"`
+ new_path="$input_path"
+ fi
+ fi
+
+ test_cygdrive_prefix=`$ECHO $input_path | $GREP ^/cygdrive/`
+ if test "x$test_cygdrive_prefix" = x; then
+ # As a simple fix, exclude /usr/bin since it's not a real path.
+ if test "x`$ECHO $new_path | $GREP ^/usr/bin/`" = x; then
+ # The path is in a Cygwin special directory (e.g. /home). We need this converted to
+ # a path prefixed by /cygdrive for fixpath to work.
+ new_path="$CYGWIN_ROOT_PATH$input_path"
+ fi
+ fi
+
+
+ if test "x$path" != "x$new_path"; then
+ DXSDK_INCLUDE_PATH="$new_path"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting DXSDK_INCLUDE_PATH to \"$new_path\"" >&5
+$as_echo "$as_me: Rewriting DXSDK_INCLUDE_PATH to \"$new_path\"" >&6;}
+ fi
+
+ elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
+
+ path="$DXSDK_INCLUDE_PATH"
+ has_colon=`$ECHO $path | $GREP ^.:`
+ new_path="$path"
+ if test "x$has_colon" = x; then
+ # Not in mixed or Windows style, start by that.
+ new_path=`cmd //c echo $path`
+ fi
+
+
+ input_path="$new_path"
+ # Check if we need to convert this using DOS-style short mode. If the path
+ # contains just simple characters, use it. Otherwise (spaces, weird characters),
+ # take no chances and rewrite it.
+ # Note: m4 eats our [], so we need to use [ and ] instead.
+ has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-_/:a-zA-Z0-9]`
+ if test "x$has_forbidden_chars" != x; then
+ # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
+ new_path=`cmd /c "for %A in (\"$input_path\") do @echo %~sA"|$TR \\\\\\\\ / | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ fi
+
+
+ windows_path="$new_path"
+ if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
+ unix_path=`$CYGPATH -u "$windows_path"`
+ new_path="$unix_path"
+ elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
+ unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'`
+ new_path="$unix_path"
+ fi
+
+ if test "x$path" != "x$new_path"; then
+ DXSDK_INCLUDE_PATH="$new_path"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting DXSDK_INCLUDE_PATH to \"$new_path\"" >&5
+$as_echo "$as_me: Rewriting DXSDK_INCLUDE_PATH to \"$new_path\"" >&6;}
+ fi
+
+ # Save the first 10 bytes of this path to the storage, so fixpath can work.
+ all_fixpath_prefixes=("${all_fixpath_prefixes[@]}" "${new_path:0:10}")
+
+ else
+ # We're on a posix platform. Hooray! :)
+ path="$DXSDK_INCLUDE_PATH"
+
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of DXSDK_INCLUDE_PATH, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ has_space=`$ECHO "$path" | $GREP " "`
+ if test "x$has_space" != x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The path of DXSDK_INCLUDE_PATH, which resolves as \"$path\", is invalid." >&5
+$as_echo "$as_me: The path of DXSDK_INCLUDE_PATH, which resolves as \"$path\", is invalid." >&6;}
+ as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
+ fi
+ fi
+
+
+
+
+ LDFLAGS_JDK="$LDFLAGS_JDK -libpath:$DXSDK_LIB_PATH"
+
fi
@@ -28242,10 +28687,17 @@
fi
if test "x$OPENJDK_TARGET_OS" = xmacosx; then
CCXXFLAGS_JDK="$CCXXFLAGS_JDK -DMACOSX -D_ALLBSD_SOURCE"
- # Adding these macros will make it an error to link to mac APIs newer than OS version 10.7
- MACOSX_REQUIRED_VERSION=1070
-
- CCXXFLAGS_JDK="$CCXXFLAGS_JDK -DMAC_OS_X_VERSION_MAX_ALLOWED=\$(MACOSX_REQUIRED_VERSION) -DMAC_OS_X_VERSION_MIN_REQUIRED=\$(MACOSX_REQUIRED_VERSION)"
+ # Setting these parameters makes it an error to link to macosx APIs that are
+ # newer than the given OS version and makes the linked binaries compatible even
+ # if built on a newer version of the OS.
+ # The expected format is X.Y.Z
+ MACOSX_VERSION_MIN=10.7.0
+
+ # The macro takes the version with no dots, ex: 1070
+ # Let the flags variables get resolved in make for easier override on make
+ # command line.
+ CCXXFLAGS_JDK="$CCXXFLAGS_JDK -DMAC_OS_X_VERSION_MAX_ALLOWED=\$(subst .,,\$(MACOSX_VERSION_MIN)) -mmacosx-version-min=\$(MACOSX_VERSION_MIN)"
+ LDFLAGS_JDK="$LDFLAGS_JDK -mmacosx-version-min=\$(MACOSX_VERSION_MIN)"
fi
if test "x$OPENJDK_TARGET_OS" = xbsd; then
CCXXFLAGS_JDK="$CCXXFLAGS_JDK -DBSD -D_ALLBSD_SOURCE"
@@ -31226,14 +31678,14 @@
###############################################################################
-# How many cores do we have on this build system?
+ # How many cores do we have on this build system?
# Check whether --with-num-cores was given.
if test "${with_num_cores+set}" = set; then :
withval=$with_num_cores;
fi
-if test "x$with_num_cores" = x; then
+ if test "x$with_num_cores" = x; then
# The number of cores were not specified, try to probe them.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for number of cores" >&5
@@ -31259,10 +31711,6 @@
FOUND_CORES=yes
fi
- # For c/c++ code we run twice as many concurrent build
- # jobs than we have cores, otherwise we will stall on io.
- CONCURRENT_BUILD_JOBS=`expr $NUM_CORES \* 2`
-
if test "x$FOUND_CORES" = xyes; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $NUM_CORES" >&5
$as_echo "$NUM_CORES" >&6; }
@@ -31274,22 +31722,20 @@
fi
-else
+ else
NUM_CORES=$with_num_cores
- CONCURRENT_BUILD_JOBS=`expr $NUM_CORES \* 2`
-fi
-
-
-
-
-# How much memory do we have on this build system?
+ fi
+
+
+
+ # How much memory do we have on this build system?
# Check whether --with-memory-size was given.
if test "${with_memory_size+set}" = set; then :
withval=$with_memory_size;
fi
-if test "x$with_memory_size" = x; then
+ if test "x$with_memory_size" = x; then
# The memory size was not specified, try to probe it.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for memory size" >&5
@@ -31329,9 +31775,45 @@
$as_echo "$as_me: WARNING: This might seriously impact build performance!" >&2;}
fi
-else
+ else
MEMORY_SIZE=$with_memory_size
-fi
+ fi
+
+
+
+ # Provide a decent default number of parallel jobs for make depending on
+ # number of cores, amount of memory and machine architecture.
+
+# Check whether --with-jobs was given.
+if test "${with_jobs+set}" = set; then :
+ withval=$with_jobs;
+fi
+
+ if test "x$with_jobs" = x; then
+ # Number of jobs was not specified, calculate.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for appropriate number of jobs to run in parallel" >&5
+$as_echo_n "checking for appropriate number of jobs to run in parallel... " >&6; }
+ # Approximate memory in GB, rounding up a bit.
+ memory_gb=`expr $MEMORY_SIZE / 1100`
+ # Pick the lowest of memory in gb and number of cores.
+ if test "$memory_gb" -lt "$NUM_CORES"; then
+ JOBS="$memory_gb"
+ else
+ JOBS="$NUM_CORES"
+ # On bigger machines, leave some room for other processes to run
+ if test "$JOBS" -gt "4"; then
+ JOBS=`expr $JOBS '*' 90 / 100`
+ fi
+ fi
+ # Cap number of jobs to 16
+ if test "$JOBS" -gt "16"; then
+ JOBS=16
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JOBS" >&5
+$as_echo "$JOBS" >&6; }
+ else
+ JOBS=$with_jobs
+ fi
@@ -33159,7 +33641,7 @@
printf "\n"
printf "Build performance summary:\n"
-printf "* Cores to use: $NUM_CORES\n"
+printf "* Cores to use: $JOBS\n"
printf "* Memory limit: $MEMORY_SIZE MB\n"
printf "* ccache status: $CCACHE_STATUS\n"
printf "\n"
--- a/common/autoconf/help.m4 Fri Mar 15 17:02:24 2013 +0400
+++ b/common/autoconf/help.m4 Fri Mar 15 16:39:07 2013 -0700
@@ -174,7 +174,7 @@
printf "\n"
printf "Build performance summary:\n"
-printf "* Cores to use: $NUM_CORES\n"
+printf "* Cores to use: $JOBS\n"
printf "* Memory limit: $MEMORY_SIZE MB\n"
printf "* ccache status: $CCACHE_STATUS\n"
printf "\n"
--- a/common/autoconf/hotspot-spec.gmk.in Fri Mar 15 17:02:24 2013 +0400
+++ b/common/autoconf/hotspot-spec.gmk.in Fri Mar 15 16:39:07 2013 -0700
@@ -80,7 +80,7 @@
HOTSPOT_MAKE_ARGS:=@HOTSPOT_MAKE_ARGS@ @STATIC_CXX_SETTING@
# This is used from the libjvm build for C/C++ code.
-HOTSPOT_BUILD_JOBS:=@CONCURRENT_BUILD_JOBS@
+HOTSPOT_BUILD_JOBS:=$(JOBS)
# Control wether Hotspot runs Queens test after building
TEST_IN_BUILD=@TEST_IN_BUILD@
--- a/common/autoconf/spec.gmk.in Fri Mar 15 17:02:24 2013 +0400
+++ b/common/autoconf/spec.gmk.in Fri Mar 15 16:39:07 2013 -0700
@@ -260,6 +260,9 @@
# the sjavac server log files.
SJAVAC_SERVER_DIR:=@SJAVAC_SERVER_DIR@
+# Number of parallel jobs to use for compilation
+JOBS?=@JOBS@
+
# The OpenJDK makefiles should be changed to using the standard
# configure output ..._CFLAGS and ..._LIBS. In the meantime we
# extract the information here.
@@ -282,8 +285,12 @@
X_LIBS:=@X_LIBS@
OPENWIN_HOME:=@OPENWIN_HOME@
+# DirectX SDK
+DXSDK_LIB_PATH=@DXSDK_LIB_PATH@
+DXSDK_INCLUDE_PATH=@DXSDK_INCLUDE_PATH@
+
# The lowest required version of macosx to enforce compatiblity for
-MACOSX_REQUIRED_VERSION=@MACOSX_REQUIRED_VERSION@
+MACOSX_VERSION_MIN=@MACOSX_VERSION_MIN@
# There are two types: CC or CL
# CC is gcc and others behaving reasonably similar.
--- a/common/autoconf/toolchain.m4 Fri Mar 15 17:02:24 2013 +0400
+++ b/common/autoconf/toolchain.m4 Fri Mar 15 16:39:07 2013 -0700
@@ -176,6 +176,7 @@
[
if test "x$OPENJDK_TARGET_OS" = "xwindows"; then
TOOLCHAIN_SETUP_VISUAL_STUDIO_ENV
+ TOOLCHAIN_SETUP_DXSDK
fi
AC_SUBST(MSVCR_DLL)
@@ -876,10 +877,17 @@
fi
if test "x$OPENJDK_TARGET_OS" = xmacosx; then
CCXXFLAGS_JDK="$CCXXFLAGS_JDK -DMACOSX -D_ALLBSD_SOURCE"
- # Adding these macros will make it an error to link to mac APIs newer than OS version 10.7
- MACOSX_REQUIRED_VERSION=1070
- AC_SUBST(MACOSX_REQUIRED_VERSION)
- CCXXFLAGS_JDK="$CCXXFLAGS_JDK -DMAC_OS_X_VERSION_MAX_ALLOWED=\$(MACOSX_REQUIRED_VERSION) -DMAC_OS_X_VERSION_MIN_REQUIRED=\$(MACOSX_REQUIRED_VERSION)"
+ # Setting these parameters makes it an error to link to macosx APIs that are
+ # newer than the given OS version and makes the linked binaries compatible even
+ # if built on a newer version of the OS.
+ # The expected format is X.Y.Z
+ MACOSX_VERSION_MIN=10.7.0
+ AC_SUBST(MACOSX_VERSION_MIN)
+ # The macro takes the version with no dots, ex: 1070
+ # Let the flags variables get resolved in make for easier override on make
+ # command line.
+ CCXXFLAGS_JDK="$CCXXFLAGS_JDK -DMAC_OS_X_VERSION_MAX_ALLOWED=\$(subst .,,\$(MACOSX_VERSION_MIN)) -mmacosx-version-min=\$(MACOSX_VERSION_MIN)"
+ LDFLAGS_JDK="$LDFLAGS_JDK -mmacosx-version-min=\$(MACOSX_VERSION_MIN)"
fi
if test "x$OPENJDK_TARGET_OS" = xbsd; then
CCXXFLAGS_JDK="$CCXXFLAGS_JDK -DBSD -D_ALLBSD_SOURCE"
--- a/common/autoconf/toolchain_windows.m4 Fri Mar 15 17:02:24 2013 +0400
+++ b/common/autoconf/toolchain_windows.m4 Fri Mar 15 16:39:07 2013 -0700
@@ -262,3 +262,61 @@
AC_MSG_RESULT([$MSVCR_DLL])
BASIC_FIXUP_PATH(MSVCR_DLL)
])
+
+
+# Setup the DXSDK paths
+AC_DEFUN([TOOLCHAIN_SETUP_DXSDK],
+[
+ AC_ARG_WITH(dxsdk, [AS_HELP_STRING([--with-dxsdk],
+ [the DirectX SDK (Windows only) @<:@probed@:>@])])
+ AC_ARG_WITH(dxsdk-lib, [AS_HELP_STRING([--with-dxsdk-lib],
+ [the DirectX SDK lib directory (Windows only) @<:@probed@:>@])])
+ AC_ARG_WITH(dxsdk-include, [AS_HELP_STRING([--with-dxsdk-include],
+ [the DirectX SDK include directory (Windows only) @<:@probed@:>@])])
+
+ AC_MSG_CHECKING([for DirectX SDK])
+
+ if test "x$with_dxsdk" != x; then
+ dxsdk_path="$with_dxsdk"
+ elif test "x$DXSDK_DIR" != x; then
+ dxsdk_path="$DXSDK_DIR"
+ elif test -d "C:/DXSDK"; then
+ dxsdk_path="C:/DXSDK"
+ else
+ AC_MSG_ERROR([Could not find the DirectX SDK])
+ fi
+ AC_MSG_RESULT([$dxsdk_path])
+ BASIC_FIXUP_PATH(dxsdk_path)
+
+ AC_MSG_CHECKING([for DirectX SDK lib dir])
+ if test "x$with_dxsdk_lib" != x; then
+ DXSDK_LIB_PATH="$with_dxsdk_lib"
+ elif test "x$OPENJDK_TARGET_CPU" = "xx86_64"; then
+ DXSDK_LIB_PATH="$dxsdk_path/Lib/x64"
+ else
+ DXSDK_LIB_PATH="$dxsdk_path/Lib"
+ fi
+ # dsound.lib is linked to in jsoundds
+ if test ! -f "$DXSDK_LIB_PATH/dsound.lib"; then
+ AC_MSG_ERROR([Invalid DirectX SDK lib dir])
+ fi
+ AC_MSG_RESULT([$DXSDK_LIB_PATH])
+ BASIC_FIXUP_PATH(DXSDK_LIB_PATH)
+
+ AC_MSG_CHECKING([for DirectX SDK include dir])
+ if test "x$with_dxsdk_include" != x; then
+ DXSDK_INCLUDE_PATH="$with_dxsdk_include"
+ else
+ DXSDK_INCLUDE_PATH="$dxsdk_path/Include"
+ fi
+ # dsound.h is included in jsoundds
+ if test ! -f "$DXSDK_INCLUDE_PATH/dsound.h"; then
+ AC_MSG_ERROR([Invalid DirectX SDK lib dir])
+ fi
+ AC_MSG_RESULT([$DXSDK_INCLUDE_PATH])
+ BASIC_FIXUP_PATH(DXSDK_INCLUDE_PATH)
+
+ AC_SUBST(DXSDK_LIB_PATH)
+ AC_SUBST(DXSDK_INCLUDE_PATH)
+ LDFLAGS_JDK="$LDFLAGS_JDK -libpath:$DXSDK_LIB_PATH"
+])
--- a/common/makefiles/JavaCompilation.gmk Fri Mar 15 17:02:24 2013 +0400
+++ b/common/makefiles/JavaCompilation.gmk Fri Mar 15 16:39:07 2013 -0700
@@ -501,7 +501,7 @@
$(ECHO) Compiling $1
($$($1_JVM) $$($1_SJAVAC) \
$$($1_REMOTE) \
- -j $(NUM_CORES) \
+ -j $(JOBS) \
--permit-unidentified-artifacts \
--permit-sources-without-package \
--compare-found-sources $$($1_BIN)/_the.batch.tmp \
--- a/common/makefiles/Main.gmk Fri Mar 15 17:02:24 2013 +0400
+++ b/common/makefiles/Main.gmk Fri Mar 15 16:39:07 2013 -0700
@@ -58,9 +58,6 @@
# Setup number of jobs to use. -jN is unfortunately not available for us to parse from the command line,
# hence this workaround.
-ifeq ($(JOBS),)
- JOBS=$(NUM_CORES)
-endif
MAKE_ARGS:=$(MAKE_ARGS) -j$(JOBS)
### Main targets
--- a/corba/.hgtags Fri Mar 15 17:02:24 2013 +0400
+++ b/corba/.hgtags Fri Mar 15 16:39:07 2013 -0700
@@ -199,3 +199,6 @@
d4e68ce17795601017ac2f952baad7272942c36e jdk8-b75
58be6ca3c0603882a1ec478724e337aac85e0da0 jdk8-b76
35684a40c5845782324dbcc9ac8969528020ff61 jdk8-b77
+27d6368ae8ba570c31c2f0e696d39c99fa2f4538 jdk8-b78
+e41fb1aa0329767b2737303c994e38bede1baa07 jdk8-b79
+5f3d4a6bdd027a1631d97e2dfff63fd5e46987a4 jdk8-b80
--- a/hotspot/.hgtags Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/.hgtags Fri Mar 15 16:39:07 2013 -0700
@@ -316,3 +316,9 @@
412d722168bc23f8e6d98995202728678561417f hs25-b18
cdb46031e7184d37301288f5719121a63c7054b5 jdk8-b77
9f19f4a7d48a4ebe7f616b6068971ea5f8b075fa hs25-b19
+d5e12e7d2f719144d84903d9151455661c47b476 jdk8-b78
+555ec35a250783110aa070dbc8a8603f6cabe41f hs25-b20
+6691814929b606fe0e7954fd6e485dd876505c83 jdk8-b79
+df5396524152118535c36da5801d828b560d19a2 hs25-b21
+4a198b201f3ce84433fa94a3ca65d061473e7c4c jdk8-b80
+dd6350b4abc4a6c19c89dd982cc0e4f3d119885c hs25-b22
--- a/hotspot/agent/make/Makefile Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/agent/make/Makefile Fri Mar 15 16:39:07 2013 -0700
@@ -19,7 +19,7 @@
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
-#
+#
#
# This guards against adding broken .java files to the directory
@@ -42,8 +42,6 @@
sun.jvm.hotspot \
sun.jvm.hotspot.asm \
sun.jvm.hotspot.asm.sparc \
-sun.jvm.hotspot.bugspot \
-sun.jvm.hotspot.bugspot.tree \
sun.jvm.hotspot.c1 \
sun.jvm.hotspot.ci \
sun.jvm.hotspot.code \
@@ -84,7 +82,6 @@
sun.jvm.hotspot.gc_interface \
sun.jvm.hotspot.interpreter \
sun.jvm.hotspot.jdi \
-sun.jvm.hotspot.livejvm \
sun.jvm.hotspot.memory \
sun.jvm.hotspot.opto \
sun.jvm.hotspot.oops \
@@ -130,8 +127,6 @@
sun/jvm/hotspot/*.java \
sun/jvm/hotspot/asm/*.java \
sun/jvm/hotspot/asm/sparc/*.java \
-sun/jvm/hotspot/bugspot/*.java \
-sun/jvm/hotspot/bugspot/tree/*.java \
sun/jvm/hotspot/c1/*.java \
sun/jvm/hotspot/ci/*.java \
sun/jvm/hotspot/code/*.java \
@@ -168,7 +163,6 @@
sun/jvm/hotspot/gc_implementation/shared/*.java \
sun/jvm/hotspot/interpreter/*.java \
sun/jvm/hotspot/jdi/*.java \
-sun/jvm/hotspot/livejvm/*.java \
sun/jvm/hotspot/memory/*.java \
sun/jvm/hotspot/oops/*.java \
sun/jvm/hotspot/opto/*.java \
@@ -205,7 +199,7 @@
sun/jvm/hotspot/utilities/memo/*.java \
sun/jvm/hotspot/utilities/soql/*.java \
com/sun/java/swing/action/*.java \
-com/sun/java/swing/ui/*.java
+com/sun/java/swing/ui/*.java
#END FILELIST
ifneq "x$(ALT_BOOTDIR)" "x"
@@ -231,7 +225,7 @@
OUTPUT_DIR = $(BUILD_DIR)/classes
DOC_DIR = $(BUILD_DIR)/doc
-# gnumake 3.78.1 does not accept the *s,
+# gnumake 3.78.1 does not accept the *s,
# so use the shell to expand them
ALLFILES := $(patsubst %,$(SRC_DIR)/%,$(FILELIST))
ALLFILES := $(shell /bin/ls $(ALLFILES))
@@ -303,7 +297,7 @@
cscope: $(ALLFILES)
rm -f java.files
echo $(ALLFILES) > java.files
- cscope -b -i java.files -f java.out
+ cscope -b -i java.files -f java.out
rm -f java.files
.PHONY: sa.jar
--- a/hotspot/agent/make/bugspot.bat Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-REM
-REM Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved.
-REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-REM
-REM This code is free software; you can redistribute it and/or modify it
-REM under the terms of the GNU General Public License version 2 only, as
-REM published by the Free Software Foundation.
-REM
-REM This code is distributed in the hope that it will be useful, but WITHOUT
-REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-REM version 2 for more details (a copy is included in the LICENSE file that
-REM accompanied this code).
-REM
-REM You should have received a copy of the GNU General Public License version
-REM 2 along with this work; if not, write to the Free Software Foundation,
-REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-REM
-REM Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-REM or visit www.oracle.com if you need additional information or have any
-REM questions.
-REM
-REM
-
-java -showversion -cp ..\build\classes;..\src\share\lib\js.jar;.\sa.jar;lib\js.jar sun.jvm.hotspot.bugspot.Main
--- a/hotspot/agent/make/marks_notes.html Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/agent/make/marks_notes.html Fri Mar 15 16:39:07 2013 -0700
@@ -26,14 +26,12 @@
<ul>
<li><code>java -cp classes sun.jvm.hotspot.HSDB</code>
- <li><code>java -cp classes sun.jvm.hotspot.bugspot.Main</code>
</ul>
<h2>Feedback</h2>
<p>
Refactoring of package hierarchy. All user interface components should be in
- the ui package. Perhaps: sun.jvm.hotspot.ui.hsdb.Main for the HSDB and
- sun.jvm.hotspot.ui.bugspot.Main for BugSpot.
+ the ui package. Perhaps: sun.jvm.hotspot.ui.hsdb.Main for the HSDB.
<p>
The src\share\vm\agent area seems like a workspace so it should be organized like
one. In particular, I'd like to suggest the following directory layout:<br>
@@ -47,7 +45,7 @@
</ul>
<p>
- Seems like there is a lot of redundant functionality. Between the HSDB and BugSpot. Perhaps
+ Seems like there is a lot of redundant functionality. Perhaps
this can be consolidated with a <code>javax.swing.Actions</code> architecture.
<h2>Tasklist</h2>
@@ -55,11 +53,7 @@
<p>
<b>Stack memory pane</b>:
It's one of the more useful JVM debugging tools in the SA. However, it
- doesn't support any interaction with the text; the Memory Panel in BugSpot
- was written afterward (with help from Shannon) and implements proper
- selection, scrolling, and drag-and-drop, but no annotations. I'm not sure how
- to integrate the annotations with the JTable that's being used for the memory
- view; if you have suggestions here please let me know.
+ doesn't support any interaction with the text.
<p>
<b>Integrations with the NetBeans architecture (plug in).</b> See the
<a href="http://openide.netbeans.org">Netbeans Open APIs homepage</a>
--- a/hotspot/agent/src/os/bsd/MacosxDebuggerLocal.m Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/agent/src/os/bsd/MacosxDebuggerLocal.m Fri Mar 15 16:39:07 2013 -0700
@@ -38,6 +38,8 @@
#import <dlfcn.h>
#import <limits.h>
#import <errno.h>
+#import <sys/types.h>
+#import <sys/ptrace.h>
jboolean debug = JNI_FALSE;
@@ -158,7 +160,7 @@
CHECK_EXCEPTION_(0);
unsigned long alignedAddress;
- unsigned long alignedLength;
+ unsigned long alignedLength = 0;
kern_return_t result;
vm_offset_t *pages;
int *mapped;
@@ -430,6 +432,73 @@
return (jint) usable_tid;
}
+
+static bool ptrace_continue(pid_t pid, int signal) {
+ // pass the signal to the process so we don't swallow it
+ int res;
+ if ((res = ptrace(PT_CONTINUE, pid, (caddr_t)1, signal)) < 0) {
+ fprintf(stderr, "attach: ptrace(PT_CONTINUE, %d) failed with %d\n", pid, res);
+ return false;
+ }
+ return true;
+}
+
+// waits until the ATTACH has stopped the process
+// by signal SIGSTOP
+static bool ptrace_waitpid(pid_t pid) {
+ int ret;
+ int status;
+ while (true) {
+ // Wait for debuggee to stop.
+ ret = waitpid(pid, &status, 0);
+ if (ret >= 0) {
+ if (WIFSTOPPED(status)) {
+ // Any signal will stop the thread, make sure it is SIGSTOP. Otherwise SIGSTOP
+ // will still be pending and delivered when the process is DETACHED and the process
+ // will go to sleep.
+ if (WSTOPSIG(status) == SIGSTOP) {
+ // Debuggee stopped by SIGSTOP.
+ return true;
+ }
+ if (!ptrace_continue(pid, WSTOPSIG(status))) {
+ fprintf(stderr, "attach: Failed to correctly attach to VM. VM might HANG! [PTRACE_CONT failed, stopped by %d]\n", WSTOPSIG(status));
+ return false;
+ }
+ } else {
+ fprintf(stderr, "attach: waitpid(): Child process exited/terminated (status = 0x%x)\n", status);
+ return false;
+ }
+ } else {
+ switch (errno) {
+ case EINTR:
+ continue;
+ break;
+ case ECHILD:
+ fprintf(stderr, "attach: waitpid() failed. Child process pid (%d) does not exist \n", pid);
+ break;
+ case EINVAL:
+ fprintf(stderr, "attach: waitpid() failed. Invalid options argument.\n");
+ break;
+ default:
+ fprintf(stderr, "attach: waitpid() failed. Unexpected error %d\n",errno);
+ break;
+ }
+ return false;
+ }
+ }
+}
+
+// attach to a process/thread specified by "pid"
+static bool ptrace_attach(pid_t pid) {
+ int res;
+ if ((res = ptrace(PT_ATTACH, pid, 0, 0)) < 0) {
+ fprintf(stderr, "ptrace(PT_ATTACH, %d) failed with %d\n", pid, res);
+ return false;
+ } else {
+ return ptrace_waitpid(pid);
+ }
+}
+
/*
* Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
* Method: attach0
@@ -445,7 +514,8 @@
else
debug = JNI_FALSE;
if (debug) printf("attach0 called for jpid=%d\n", (int)jpid);
-
+
+ // get the task from the pid
kern_return_t result;
task_t gTask = 0;
result = task_for_pid(mach_task_self(), jpid, &gTask);
@@ -455,6 +525,13 @@
}
putTask(env, this_obj, gTask);
+ // use ptrace to stop the process
+ // on os x, ptrace only needs to be called on the process, not the individual threads
+ if (ptrace_attach(jpid) != true) {
+ mach_port_deallocate(mach_task_self(), gTask);
+ THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the process");
+ }
+
id symbolicator = nil;
id jrsSymbolicator = objc_lookUpClass("JRSSymbolicator");
if (jrsSymbolicator != nil) {
@@ -486,6 +563,21 @@
if (debug) printf("detach0 called\n");
task_t gTask = getTask(env, this_obj);
+
+ // detach from the ptraced process causing it to resume execution
+ int pid;
+ kern_return_t k_res;
+ k_res = pid_for_task(gTask, &pid);
+ if (k_res != KERN_SUCCESS) {
+ fprintf(stderr, "detach: pid_for_task(%d) failed (%d)\n", pid, k_res);
+ }
+ else {
+ int res = ptrace(PT_DETACH, pid, 0, 0);
+ if (res < 0) {
+ fprintf(stderr, "detach: ptrace(PT_DETACH, %d) failed (%d)\n", pid, res);
+ }
+ }
+
mach_port_deallocate(mach_task_self(), gTask);
id symbolicator = getSymbolicator(env, this_obj);
if (symbolicator != nil) {
@@ -538,7 +630,7 @@
/* Couldn't find entry point. error_message should contain some
* platform dependent error message.
*/
- THROW_NEW_DEBUGGER_EXCEPTION(error_message);
+ THROW_NEW_DEBUGGER_EXCEPTION_(error_message, (jlong)func);
}
return (jlong)func;
}
--- a/hotspot/agent/src/os/bsd/libproc_impl.c Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/agent/src/os/bsd/libproc_impl.c Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -91,6 +91,14 @@
}
}
+void print_error(const char* format,...) {
+ va_list alist;
+ va_start(alist, format);
+ fputs("ERROR: ", stderr);
+ vfprintf(stderr, format, alist);
+ va_end(alist);
+}
+
bool is_debug() {
return _libsaproc_debug;
}
--- a/hotspot/agent/src/os/bsd/libproc_impl.h Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/agent/src/os/bsd/libproc_impl.h Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -107,6 +107,7 @@
int pathmap_open(const char* name);
void print_debug(const char* format,...);
+void print_error(const char* format,...);
bool is_debug();
typedef bool (*thread_info_callback)(struct ps_prochandle* ph, pthread_t pid, lwpid_t lwpid);
--- a/hotspot/agent/src/os/bsd/ps_proc.c Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/agent/src/os/bsd/ps_proc.c Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -129,42 +129,66 @@
return (errno == 0)? true: false;
}
+static bool ptrace_continue(pid_t pid, int signal) {
+ // pass the signal to the process so we don't swallow it
+ if (ptrace(PTRACE_CONT, pid, NULL, signal) < 0) {
+ print_debug("ptrace(PTRACE_CONT, ..) failed for %d\n", pid);
+ return false;
+ }
+ return true;
+}
+
+// waits until the ATTACH has stopped the process
+// by signal SIGSTOP
+static bool ptrace_waitpid(pid_t pid) {
+ int ret;
+ int status;
+ do {
+ // Wait for debuggee to stop.
+ ret = waitpid(pid, &status, 0);
+ if (ret >= 0) {
+ if (WIFSTOPPED(status)) {
+ // Any signal will stop the thread, make sure it is SIGSTOP. Otherwise SIGSTOP
+ // will still be pending and delivered when the process is DETACHED and the process
+ // will go to sleep.
+ if (WSTOPSIG(status) == SIGSTOP) {
+ // Debuggee stopped by SIGSTOP.
+ return true;
+ }
+ if (!ptrace_continue(pid, WSTOPSIG(status))) {
+ print_error("Failed to correctly attach to VM. VM might HANG! [PTRACE_CONT failed, stopped by %d]\n", WSTOPSIG(status));
+ return false;
+ }
+ } else {
+ print_debug("waitpid(): Child process exited/terminated (status = 0x%x)\n", status);
+ return false;
+ }
+ } else {
+ switch (errno) {
+ case EINTR:
+ continue;
+ break;
+ case ECHILD:
+ print_debug("waitpid() failed. Child process pid (%d) does not exist \n", pid);
+ break;
+ case EINVAL:
+ print_debug("waitpid() failed. Invalid options argument.\n");
+ break;
+ default:
+ print_debug("waitpid() failed. Unexpected error %d\n",errno);
+ }
+ return false;
+ }
+ } while(true);
+}
+
// attach to a process/thread specified by "pid"
static bool ptrace_attach(pid_t pid) {
if (ptrace(PT_ATTACH, pid, NULL, 0) < 0) {
print_debug("ptrace(PTRACE_ATTACH, ..) failed for %d\n", pid);
return false;
} else {
- int ret;
- int status;
- do {
- // Wait for debuggee to stop.
- ret = waitpid(pid, &status, 0);
- if (ret >= 0) {
- if (WIFSTOPPED(status)) {
- // Debuggee stopped.
- return true;
- } else {
- print_debug("waitpid(): Child process exited/terminated (status = 0x%x)\n", status);
- return false;
- }
- } else {
- switch (errno) {
- case EINTR:
- continue;
- break;
- case ECHILD:
- print_debug("waitpid() failed. Child process pid (%d) does not exist \n", pid);
- break;
- case EINVAL:
- print_debug("waitpid() failed. Invalid options argument.\n");
- break;
- default:
- print_debug("waitpid() failed. Unexpected error %d\n",errno);
- }
- return false;
- }
- } while(true);
+ return ptrace_waitpid(pid);
}
}
--- a/hotspot/agent/src/os/linux/LinuxDebuggerLocal.c Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/agent/src/os/linux/LinuxDebuggerLocal.c Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,13 @@
#include <jni.h>
#include "libproc.h"
+#include <elf.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <limits.h>
+
#if defined(x86_64) && !defined(amd64)
#define amd64 1
#endif
@@ -154,6 +161,39 @@
}
}
+
+/*
+ * Verify that a named ELF binary file (core or executable) has the same
+ * bitness as ourselves.
+ * Throw an exception if there is a mismatch or other problem.
+ *
+ * If we proceed using a mismatched debugger/debuggee, the best to hope
+ * for is a missing symbol, the worst is a crash searching for debug symbols.
+ */
+void verifyBitness(JNIEnv *env, const char *binaryName) {
+ int fd = open(binaryName, O_RDONLY);
+ if (fd < 0) {
+ THROW_NEW_DEBUGGER_EXCEPTION("cannot open binary file");
+ }
+ unsigned char elf_ident[EI_NIDENT];
+ int i = read(fd, &elf_ident, sizeof(elf_ident));
+ close(fd);
+
+ if (i < 0) {
+ THROW_NEW_DEBUGGER_EXCEPTION("cannot read binary file");
+ }
+#ifndef _LP64
+ if (elf_ident[EI_CLASS] == ELFCLASS64) {
+ THROW_NEW_DEBUGGER_EXCEPTION("debuggee is 64 bit, use 64-bit java for debugger");
+ }
+#else
+ if (elf_ident[EI_CLASS] != ELFCLASS64) {
+ THROW_NEW_DEBUGGER_EXCEPTION("debuggee is 32 bit, use 32 bit java for debugger");
+ }
+#endif
+}
+
+
/*
* Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal
* Method: attach0
@@ -162,6 +202,12 @@
JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_attach0__I
(JNIEnv *env, jobject this_obj, jint jpid) {
+ // For bitness checking, locate binary at /proc/jpid/exe
+ char buf[PATH_MAX];
+ snprintf((char *) &buf, PATH_MAX, "/proc/%d/exe", jpid);
+ verifyBitness(env, (char *) &buf);
+ CHECK_EXCEPTION;
+
struct ps_prochandle* ph;
if ( (ph = Pgrab(jpid)) == NULL) {
THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the process");
@@ -187,6 +233,9 @@
coreName_cstr = (*env)->GetStringUTFChars(env, coreName, &isCopy);
CHECK_EXCEPTION;
+ verifyBitness(env, execName_cstr);
+ CHECK_EXCEPTION;
+
if ( (ph = Pgrab_core(execName_cstr, coreName_cstr)) == NULL) {
(*env)->ReleaseStringUTFChars(env, execName, execName_cstr);
(*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr);
--- a/hotspot/agent/src/os/linux/libproc_impl.c Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/agent/src/os/linux/libproc_impl.c Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -92,6 +92,14 @@
}
}
+void print_error(const char* format,...) {
+ va_list alist;
+ va_start(alist, format);
+ fputs("ERROR: ", stderr);
+ vfprintf(stderr, format, alist);
+ va_end(alist);
+}
+
bool is_debug() {
return _libsaproc_debug;
}
--- a/hotspot/agent/src/os/linux/libproc_impl.h Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/agent/src/os/linux/libproc_impl.h Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -105,6 +105,7 @@
int pathmap_open(const char* name);
void print_debug(const char* format,...);
+void print_error(const char* format,...);
bool is_debug();
typedef bool (*thread_info_callback)(struct ps_prochandle* ph, pthread_t pid, lwpid_t lwpid);
--- a/hotspot/agent/src/os/linux/ps_proc.c Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/agent/src/os/linux/ps_proc.c Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <signal.h>
#include <errno.h>
#include <sys/ptrace.h>
#include "libproc_impl.h"
@@ -142,46 +143,71 @@
}
+static bool ptrace_continue(pid_t pid, int signal) {
+ // pass the signal to the process so we don't swallow it
+ if (ptrace(PTRACE_CONT, pid, NULL, signal) < 0) {
+ print_debug("ptrace(PTRACE_CONT, ..) failed for %d\n", pid);
+ return false;
+ }
+ return true;
+}
+
+// waits until the ATTACH has stopped the process
+// by signal SIGSTOP
+static bool ptrace_waitpid(pid_t pid) {
+ int ret;
+ int status;
+ while (true) {
+ // Wait for debuggee to stop.
+ ret = waitpid(pid, &status, 0);
+ if (ret == -1 && errno == ECHILD) {
+ // try cloned process.
+ ret = waitpid(pid, &status, __WALL);
+ }
+ if (ret >= 0) {
+ if (WIFSTOPPED(status)) {
+ // Any signal will stop the thread, make sure it is SIGSTOP. Otherwise SIGSTOP
+ // will still be pending and delivered when the process is DETACHED and the process
+ // will go to sleep.
+ if (WSTOPSIG(status) == SIGSTOP) {
+ // Debuggee stopped by SIGSTOP.
+ return true;
+ }
+ if (!ptrace_continue(pid, WSTOPSIG(status))) {
+ print_error("Failed to correctly attach to VM. VM might HANG! [PTRACE_CONT failed, stopped by %d]\n", WSTOPSIG(status));
+ return false;
+ }
+ } else {
+ print_debug("waitpid(): Child process exited/terminated (status = 0x%x)\n", status);
+ return false;
+ }
+ } else {
+ switch (errno) {
+ case EINTR:
+ continue;
+ break;
+ case ECHILD:
+ print_debug("waitpid() failed. Child process pid (%d) does not exist \n", pid);
+ break;
+ case EINVAL:
+ print_debug("waitpid() failed. Invalid options argument.\n");
+ break;
+ default:
+ print_debug("waitpid() failed. Unexpected error %d\n",errno);
+ break;
+ }
+ return false;
+ }
+ }
+}
+
// attach to a process/thread specified by "pid"
static bool ptrace_attach(pid_t pid) {
if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) < 0) {
print_debug("ptrace(PTRACE_ATTACH, ..) failed for %d\n", pid);
return false;
} else {
- int ret;
- int status;
- do {
- // Wait for debuggee to stop.
- ret = waitpid(pid, &status, 0);
- if (ret == -1 && errno == ECHILD) {
- // try cloned process.
- ret = waitpid(pid, &status, __WALL);
- }
- if (ret >= 0) {
- if (WIFSTOPPED(status)) {
- // Debuggee stopped.
- return true;
- } else {
- print_debug("waitpid(): Child process exited/terminated (status = 0x%x)\n", status);
- return false;
- }
- } else {
- switch (errno) {
- case EINTR:
- continue;
- break;
- case ECHILD:
- print_debug("waitpid() failed. Child process pid (%d) does not exist \n", pid);
- break;
- case EINVAL:
- print_debug("waitpid() failed. Invalid options argument.\n");
- break;
- default:
- print_debug("waitpid() failed. Unexpected error %d\n",errno);
- }
- return false;
- }
- } while(true);
+ return ptrace_waitpid(pid);
}
}
--- a/hotspot/agent/src/os/win32/windbg/sawindbg.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/agent/src/os/win32/windbg/sawindbg.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -372,8 +372,7 @@
We are attaching to a process in 'read-only' mode. i.e., we do not want to
put breakpoints, suspend/resume threads etc. For read-only JDI and HSDB kind of
- usage this should suffice. We are not intending to use this for full-fledged
- ProcessControl implementation to be used with BugSpotAgent.
+ usage this should suffice.
Please refer to DEBUG_ATTACH_NONINVASIVE mode source comments from dbgeng.h.
In this mode, debug engine does not call DebugActiveProrcess. i.e., we are not
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/asm/amd64/AMD64FloatRegister.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.asm.amd64;
-
-import sun.jvm.hotspot.asm.Register;
-import sun.jvm.hotspot.utilities.Assert;
-
-public class AMD64FloatRegister extends Register {
-
- public AMD64FloatRegister(int number) {
- super(number);
- }
-
- public int getNumber() {
- return number;
- }
-
- public int getNumberOfRegisters() {
- return AMD64FloatRegisters.getNumRegisters();
- }
-
- public boolean isFloat() {
- return true;
- }
-
- public boolean isFramePointer() {
- return false;
- }
-
- public boolean isStackPointer() {
- return false;
- }
-
- public boolean isValid() {
- return number >= 0 && number < AMD64FloatRegisters.getNumRegisters();
- }
-
- public String toString() {
- return AMD64FloatRegisters.getRegisterName(number);
- }
-
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/bugspot/BugSpot.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1536 +0,0 @@
-/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.bugspot;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.io.*;
-import java.net.*;
-import java.util.*;
-import javax.swing.*;
-import javax.swing.filechooser.*;
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.cdbg.*;
-import sun.jvm.hotspot.debugger.posix.*;
-import sun.jvm.hotspot.debugger.windbg.*;
-import sun.jvm.hotspot.livejvm.*;
-import sun.jvm.hotspot.memory.*;
-import sun.jvm.hotspot.oops.*;
-import sun.jvm.hotspot.runtime.*;
-import sun.jvm.hotspot.ui.*;
-import sun.jvm.hotspot.utilities.*;
-
-/** The BugSpot component. This is embeddable in an application by
- virtue of its being a JComponent. It (currently) requires the use
- of a menu bar which can be fetched via getMenuBar(). This is
- intended ultimately to replace HSDB. */
-
-public class BugSpot extends JPanel {
- public BugSpot() {
- super();
- Runtime.getRuntime().addShutdownHook(new java.lang.Thread() {
- public void run() {
- detachDebugger();
- }
- });
- }
-
- /** Turn on or off MDI (Multiple Document Interface) mode. When MDI
- is enabled, the BugSpot component contains a JDesktopPane and all
- windows are JInternalFrames. When disabled, only the menu bar is
- relevant. */
- public void setMDIMode(boolean onOrOff) {
- mdiMode = onOrOff;
- }
-
- /** Indicates whether MDI mode is enabled. */
- public boolean getMDIMode() {
- return mdiMode;
- }
-
- /** Build user interface widgets. This must be called before adding
- the BugSpot component to its parent. */
- public void build() {
- setLayout(new BorderLayout());
-
- menuBar = new JMenuBar();
-
- attachMenuItems = new java.util.ArrayList();
- detachMenuItems = new java.util.ArrayList();
- debugMenuItems = new java.util.ArrayList();
- suspendDebugMenuItems = new java.util.ArrayList();
- resumeDebugMenuItems = new java.util.ArrayList();
-
- //
- // File menu
- //
-
- JMenu menu = createMenu("File", 'F', 0);
- JMenuItem item;
- item = createMenuItem("Open source file...",
- new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- openSourceFile();
- }
- },
- KeyEvent.VK_O, InputEvent.CTRL_MASK,
- 'O', 0);
- menu.add(item);
- detachMenuItems.add(item);
-
- menu.addSeparator();
-
- item = createMenuItem("Attach to process...",
- new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- showAttachDialog();
- }
- },
- 'A', 0);
- menu.add(item);
- attachMenuItems.add(item);
-
- item = createMenuItem("Detach",
- new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- detach();
- }
- },
- 'D', 0);
- menu.add(item);
- detachMenuItems.add(item);
-
- // Disable detach menu items at first
- setMenuItemsEnabled(detachMenuItems, false);
-
- menu.addSeparator();
-
- menu.add(createMenuItem("Exit",
- new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- detach();
- System.exit(0);
- }
- },
- 'x', 1));
-
- menuBar.add(menu);
-
- //
- // Debug menu
- //
-
- debugMenu = createMenu("Debug", 'D', 0);
- item = createMenuItem("Go",
- new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- if (!attached) return;
- if (!isSuspended()) return;
- resume();
- }
- },
- KeyEvent.VK_F5, 0,
- 'G', 0);
- debugMenu.add(item);
- resumeDebugMenuItems.add(item);
-
- item = createMenuItem("Break",
- new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- if (!attached) {
- System.err.println("Not attached");
- return;
- }
- if (isSuspended()) {
- System.err.println("Already suspended");
- return;
- }
- suspend();
- }
- },
- 'B', 0);
- debugMenu.add(item);
- suspendDebugMenuItems.add(item);
-
- debugMenu.addSeparator();
-
- item = createMenuItem("Threads...",
- new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- showThreadsDialog();
- }
- },
- 'T', 0);
- debugMenu.add(item);
- debugMenuItems.add(item);
- // FIXME: belongs under "View -> Debug Windows"
- item = createMenuItem("Memory",
- new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- showMemoryDialog();
- }
- },
- 'M', 0);
- debugMenu.add(item);
- debugMenuItems.add(item);
-
- debugMenu.setEnabled(false);
- menuBar.add(debugMenu);
-
- if (mdiMode) {
- desktop = new JDesktopPane();
- add(desktop, BorderLayout.CENTER);
- }
-
- fixedWidthFont = GraphicsUtilities.lookupFont("Courier");
-
- debugEventTimer = new javax.swing.Timer(100, new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- pollForDebugEvent();
- }
- });
- }
-
- public JMenuBar getMenuBar() {
- return menuBar;
- }
-
- public void showAttachDialog() {
- setMenuItemsEnabled(attachMenuItems, false);
- final FrameWrapper attachDialog = newFrame("Attach to process");
- attachDialog.getContentPane().setLayout(new BorderLayout());
- attachDialog.setClosable(true);
- attachDialog.setResizable(true);
-
- JPanel panel = new JPanel();
- panel.setLayout(new BorderLayout());
- panel.setBorder(GraphicsUtilities.newBorder(5));
- attachDialog.setBackground(panel.getBackground());
-
- JPanel listPanel = new JPanel();
- listPanel.setLayout(new BorderLayout());
- final ProcessListPanel plist = new ProcessListPanel(getLocalDebugger());
- panel.add(plist, BorderLayout.CENTER);
- JCheckBox check = new JCheckBox("Update list continuously");
- check.addItemListener(new ItemListener() {
- public void itemStateChanged(ItemEvent e) {
- if (e.getStateChange() == ItemEvent.SELECTED) {
- plist.start();
- } else {
- plist.stop();
- }
- }
- });
- listPanel.add(plist, BorderLayout.CENTER);
- listPanel.add(check, BorderLayout.SOUTH);
- panel.add(listPanel, BorderLayout.CENTER);
- attachDialog.getContentPane().add(panel, BorderLayout.CENTER);
- attachDialog.setClosingActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- plist.stop();
- setMenuItemsEnabled(attachMenuItems, true);
- }
- });
-
- ActionListener attacher = new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- plist.stop();
- attachDialog.setVisible(false);
- removeFrame(attachDialog);
- ProcessInfo info = plist.getSelectedProcess();
- if (info != null) {
- attach(info.getPid());
- }
- }
- };
-
- Box hbox = Box.createHorizontalBox();
- hbox.add(Box.createGlue());
- JButton button = new JButton("OK");
- button.addActionListener(attacher);
- hbox.add(button);
- hbox.add(Box.createHorizontalStrut(20));
- button = new JButton("Cancel");
- button.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- plist.stop();
- attachDialog.setVisible(false);
- removeFrame(attachDialog);
- setMenuItemsEnabled(attachMenuItems, true);
- }
- });
- hbox.add(button);
- hbox.add(Box.createGlue());
- panel = new JPanel();
- panel.setBorder(GraphicsUtilities.newBorder(5));
- panel.add(hbox);
-
- attachDialog.getContentPane().add(panel, BorderLayout.SOUTH);
-
- addFrame(attachDialog);
- attachDialog.pack();
- attachDialog.setSize(400, 300);
- GraphicsUtilities.centerInContainer(attachDialog.getComponent(),
- getParentDimension(attachDialog.getComponent()));
- attachDialog.setVisible(true);
- }
-
- public void showThreadsDialog() {
- final FrameWrapper threadsDialog = newFrame("Threads");
- threadsDialog.getContentPane().setLayout(new BorderLayout());
- threadsDialog.setClosable(true);
- threadsDialog.setResizable(true);
-
- ThreadListPanel threads = new ThreadListPanel(getCDebugger(), getAgent().isJavaMode());
- threads.addListener(new ThreadListPanel.Listener() {
- public void setFocus(ThreadProxy thread, JavaThread jthread) {
- setCurrentThread(thread);
- // FIXME: print this to GUI, bring some windows to foreground
- System.err.println("Focus changed to thread " + thread);
- }
- });
- threads.setBorder(GraphicsUtilities.newBorder(5));
- threadsDialog.getContentPane().add(threads);
- addFrame(threadsDialog);
- threadsDialog.pack();
- GraphicsUtilities.reshapeToAspectRatio(threadsDialog.getComponent(),
- 3.0f,
- 0.9f,
- getParentDimension(threadsDialog.getComponent()));
- GraphicsUtilities.centerInContainer(threadsDialog.getComponent(),
- getParentDimension(threadsDialog.getComponent()));
- threadsDialog.setVisible(true);
- }
-
- public void showMemoryDialog() {
- final FrameWrapper memoryDialog = newFrame("Memory");
- memoryDialog.getContentPane().setLayout(new BorderLayout());
- memoryDialog.setClosable(true);
- memoryDialog.setResizable(true);
-
- memoryDialog.getContentPane().add(new MemoryViewer(getDebugger(),
- (getDebugger().getMachineDescription().getAddressSize() == 8)),
- BorderLayout.CENTER);
- addFrame(memoryDialog);
- memoryDialog.pack();
- GraphicsUtilities.reshapeToAspectRatio(memoryDialog.getComponent(),
- 1.0f,
- 0.7f,
- getParentDimension(memoryDialog.getComponent()));
- GraphicsUtilities.centerInContainer(memoryDialog.getComponent(),
- getParentDimension(memoryDialog.getComponent()));
- memoryDialog.setVisible(true);
- }
-
- /** Changes the editor factory this debugger uses to display source
- code. Specified factory may be null, in which case the default
- factory is used. */
- public void setEditorFactory(EditorFactory fact) {
- if (fact != null) {
- editorFact = fact;
- } else {
- editorFact = new DefaultEditorFactory();
- }
- }
-
- //----------------------------------------------------------------------
- // Internals only below this point
- //
-
- private WorkerThread workerThread;
- private boolean mdiMode;
- private JVMDebugger localDebugger;
- private BugSpotAgent agent = new BugSpotAgent();
- private JMenuBar menuBar;
- /** List <JMenuItem> */
- private java.util.List attachMenuItems;
- private java.util.List detachMenuItems;
- private java.util.List debugMenuItems;
- private java.util.List suspendDebugMenuItems;
- private java.util.List resumeDebugMenuItems;
- private FrameWrapper stackFrame;
- private VariablePanel localsPanel;
- private StackTracePanel stackTracePanel;
- private FrameWrapper registerFrame;
- private RegisterPanel registerPanel;
- // Used for mixed-language stack traces
- private Map threadToJavaThreadMap;
-
- private JMenu debugMenu;
-
- // MDI mode only: desktop pane
- private JDesktopPane desktop;
-
- // Attach/detach state
- private boolean attached;
-
- // Suspension (combined Java/C++) state
- private boolean suspended;
-
- // Fixed-width font
- private Font fixedWidthFont;
-
- // Breakpoint setting
- // Maps Strings to List/*<LineNumberInfo>*/
- private Map sourceFileToLineNumberInfoMap;
- // Maps Strings (file names) to Sets of Integers (line numbers)
- private Map fileToBreakpointMap;
-
- // Debug events
- private javax.swing.Timer debugEventTimer;
-
- // Java debug events
- private boolean javaEventPending;
-
- static class BreakpointResult {
- private boolean success;
- private boolean set;
- private int lineNo;
- private String why;
-
- /** For positive results */
- BreakpointResult(boolean success, boolean set, int lineNo) {
- this(success, set, lineNo, null);
- }
-
- /** For negative results */
- BreakpointResult(boolean success, boolean set, int lineNo, String why) {
- this.success = success;
- this.set = set;
- this.lineNo = lineNo;
- this.why = why;
- }
-
- public boolean succeeded() {
- return success;
- }
-
- public boolean set() {
- return set;
- }
-
- /** Line at which the breakpoint was actually set; only valid if
- succeeded() returns true */
- public int getLine() {
- return lineNo;
- }
-
- public String getWhy() {
- return why;
- }
- }
-
-
- // Editors for source code. File name-to-Editor mapping.
- private Map editors;
- private EditorFactory editorFact = new DefaultEditorFactory();
- private EditorCommands editorComm = new EditorCommands() {
- public void windowClosed(Editor editor) {
- editors.remove(editor.getSourceFileName());
- }
-
- public void toggleBreakpointAtLine(Editor editor, int lineNumber) {
- // FIXME: handle "lazy" breakpoints where the source file has
- // been opened with some other mechanism (File -> Open) and we
- // don't have debug information pointing to that file yet
- // FIXME: NOT FINISHED
-
- BreakpointResult res =
- handleBreakpointToggle(editor, lineNumber);
- if (res.succeeded()) {
- if (res.set()) {
- editor.showBreakpointAtLine(res.getLine());
- } else {
- editor.clearBreakpointAtLine(res.getLine());
- }
- } else {
- String why = res.getWhy();
- if (why == null) {
- why = "";
- } else {
- why = ": " + why;
- }
- showMessageDialog("Unable to toggle breakpoint" + why,
- "Unable to toggle breakpoint",
- JOptionPane.WARNING_MESSAGE);
- }
- }
- };
-
- private void attach(final int pid) {
- try {
- getAgent().attach(pid);
- setMenuItemsEnabled(detachMenuItems, true);
- setMenuItemsEnabled(suspendDebugMenuItems, false);
- setMenuItemsEnabled(resumeDebugMenuItems, true);
- debugMenu.setEnabled(true);
- attached = true;
- suspended = true;
-
- if (getAgent().isJavaMode()) {
- System.err.println("Java HotSpot(TM) virtual machine detected.");
- } else {
- System.err.println("(No Java(TM) virtual machine detected)");
- }
-
- // Set up editor map
- editors = new HashMap();
-
- // Initialize breakpoints
- fileToBreakpointMap = new HashMap();
-
- // Create combined stack trace and local variable panel
- JPanel framePanel = new JPanel();
- framePanel.setLayout(new BorderLayout());
- framePanel.setBorder(GraphicsUtilities.newBorder(5));
- localsPanel = new VariablePanel();
- JTabbedPane tab = new JTabbedPane();
- tab.addTab("Locals", localsPanel);
- tab.setTabPlacement(JTabbedPane.BOTTOM);
- framePanel.add(tab, BorderLayout.CENTER);
- JPanel stackPanel = new JPanel();
- stackPanel.setLayout(new BoxLayout(stackPanel, BoxLayout.X_AXIS));
- stackPanel.add(new JLabel("Context:"));
- stackPanel.add(Box.createHorizontalStrut(5));
- stackTracePanel = new StackTracePanel();
- stackTracePanel.addListener(new StackTracePanel.Listener() {
- public void frameChanged(CFrame fr, JavaVFrame jfr) {
- setCurrentFrame(fr, jfr);
- }
- });
- stackPanel.add(stackTracePanel);
- framePanel.add(stackPanel, BorderLayout.NORTH);
- stackFrame = newFrame("Stack");
- stackFrame.getContentPane().setLayout(new BorderLayout());
- stackFrame.getContentPane().add(framePanel, BorderLayout.CENTER);
- stackFrame.setResizable(true);
- stackFrame.setClosable(false);
- addFrame(stackFrame);
- stackFrame.setSize(400, 200);
- GraphicsUtilities.moveToInContainer(stackFrame.getComponent(), 0.0f, 1.0f, 0, 20);
- stackFrame.setVisible(true);
-
- // Create register panel
- registerPanel = new RegisterPanel();
- registerPanel.setFont(fixedWidthFont);
- registerFrame = newFrame("Registers");
- registerFrame.getContentPane().setLayout(new BorderLayout());
- registerFrame.getContentPane().add(registerPanel, BorderLayout.CENTER);
- addFrame(registerFrame);
- registerFrame.setResizable(true);
- registerFrame.setClosable(false);
- registerFrame.setSize(225, 200);
- GraphicsUtilities.moveToInContainer(registerFrame.getComponent(),
- 1.0f, 0.0f, 0, 0);
- registerFrame.setVisible(true);
-
- resetCurrentThread();
- } catch (DebuggerException e) {
- final String errMsg = formatMessage(e.getMessage(), 80);
- setMenuItemsEnabled(attachMenuItems, true);
- showMessageDialog("Unable to connect to process ID " + pid + ":\n\n" + errMsg,
- "Unable to Connect",
- JOptionPane.WARNING_MESSAGE);
- getAgent().detach();
- }
- }
-
- private synchronized void detachDebugger() {
- if (!attached) {
- return;
- }
- if (isSuspended()) {
- resume(); // Necessary for JVMDI resumption
- }
- getAgent().detach();
- // FIXME: clear out breakpoints (both Java and C/C++) from target
- // process
- sourceFileToLineNumberInfoMap = null;
- fileToBreakpointMap = null;
- threadToJavaThreadMap = null;
- editors = null;
- attached = false;
- }
-
- private synchronized void detach() {
- detachDebugger();
- setMenuItemsEnabled(attachMenuItems, true);
- setMenuItemsEnabled(detachMenuItems, false);
- debugMenu.setEnabled(false);
- if (mdiMode) {
- // FIXME: is this sufficient, or will I have to do anything else
- // to the components to kill them off? What about WorkerThreads?
- desktop.removeAll();
- desktop.invalidate();
- desktop.validate();
- desktop.repaint();
- }
- // FIXME: keep track of all windows and close them even in non-MDI
- // mode
- debugEventTimer.stop();
- }
-
- // Returns a Debugger for processes on the local machine. This is
- // only used to fetch the process list.
- private Debugger getLocalDebugger() {
- if (localDebugger == null) {
- String os = PlatformInfo.getOS();
- String cpu = PlatformInfo.getCPU();
-
- if (os.equals("win32")) {
- if (!cpu.equals("x86")) {
- throw new DebuggerException("Unsupported CPU \"" + cpu + "\" for Windows");
- }
-
- localDebugger = new WindbgDebuggerLocal(new MachineDescriptionIntelX86(), true);
- } else if (os.equals("linux")) {
- if (!cpu.equals("x86")) {
- throw new DebuggerException("Unsupported CPU \"" + cpu + "\" for Linux");
- }
-
- // FIXME: figure out how to specify path to debugger module
- throw new RuntimeException("FIXME: figure out how to specify path to debugger module");
- // localDebugger = new PosixDebuggerLocal(new MachineDescriptionIntelX86(), true);
- } else {
- // FIXME: port to Solaris
- throw new DebuggerException("Unsupported OS \"" + os + "\"");
- }
-
- // FIXME: we require that the primitive type sizes be configured
- // in order to use basic functionality in class Address such as
- // the fetching of floating-point values. There are a lot of
- // assumptions in the current code that Java floats and doubles
- // are of equivalent size to C values. The configurability of the
- // primitive type sizes hasn't seemed necessary and in this kind
- // of debugging scenario (namely, debugging arbitrary C++
- // processes) it appears difficult to support that kind of
- // flexibility.
- localDebugger.configureJavaPrimitiveTypeSizes(1, 1, 2, 8, 4, 4, 8, 2);
- }
-
- return localDebugger;
- }
-
- private BugSpotAgent getAgent() {
- return agent;
- }
-
- private Debugger getDebugger() {
- return getAgent().getDebugger();
- }
-
- private CDebugger getCDebugger() {
- return getAgent().getCDebugger();
- }
-
- private void resetCurrentThread() {
- setCurrentThread((ThreadProxy) getCDebugger().getThreadList().get(0));
- }
-
- private void setCurrentThread(ThreadProxy t) {
- // Create stack trace
- // FIXME: add ability to intermix C/Java frames
- java.util.List trace = new ArrayList();
- CFrame fr = getCDebugger().topFrameForThread(t);
- while (fr != null) {
- trace.add(new StackTraceEntry(fr, getCDebugger()));
- try {
- fr = fr.sender(t);
- } catch (AddressException e) {
- e.printStackTrace();
- showMessageDialog("Error while walking stack; stack trace will be truncated\n(see console for details)",
- "Error walking stack",
- JOptionPane.WARNING_MESSAGE);
- fr = null;
- }
- }
- JavaThread jthread = javaThreadForProxy(t);
- if (jthread != null) {
- // Java mode, and we have a Java thread.
- // Find all Java frames on the stack. We currently do this in a
- // manner which involves minimal interaction between the Java
- // and C/C++ debugging systems: any C frame which has a PC in an
- // unknown location (i.e., not in any DSO) is assumed to be a
- // Java frame. We merge stack segments of unknown frames with
- // segments of Java frames beginning with native methods.
- java.util.List javaTrace = new ArrayList();
- VFrame vf = jthread.getLastJavaVFrameDbg();
- while (vf != null) {
- if (vf.isJavaFrame()) {
- javaTrace.add(new StackTraceEntry((JavaVFrame) vf));
- vf = vf.sender();
- }
- }
- // Merge stack traces
- java.util.List mergedTrace = new ArrayList();
- int c = 0;
- int j = 0;
- while (c < trace.size()) {
- StackTraceEntry entry = (StackTraceEntry) trace.get(c);
- if (entry.isUnknownCFrame()) {
- boolean gotJavaFrame = false;
- while (j < javaTrace.size()) {
- StackTraceEntry javaEntry = (StackTraceEntry) javaTrace.get(j);
- JavaVFrame jvf = javaEntry.getJavaFrame();
- Method m = jvf.getMethod();
- if (!m.isNative() || !gotJavaFrame) {
- gotJavaFrame = true;
- mergedTrace.add(javaEntry);
- ++j;
- } else {
- break; // Reached native method; have intervening C frames
- }
- }
- if (gotJavaFrame) {
- // Skip this sequence of unknown frames, as we've
- // successfully identified it as Java frames
- while (c < trace.size() && entry.isUnknownCFrame()) {
- ++c;
- if (c < trace.size()) {
- entry = (StackTraceEntry) trace.get(c);
- }
- }
- continue;
- }
- }
- // If we get here, we either have an unknown frame we didn't
- // know how to categorize or we have a known C frame. Add it
- // to the trace.
- mergedTrace.add(entry);
- ++c;
- }
- trace = mergedTrace;
- }
- stackTracePanel.setTrace(trace);
-
- registerPanel.update(t);
- }
-
- private void setCurrentFrame(CFrame fr, JavaVFrame jfr) {
- localsPanel.clear();
-
- if (fr != null) {
- localsPanel.update(fr);
-
- // FIXME: load source file if we can find it, otherwise display disassembly
- LoadObject lo = getCDebugger().loadObjectContainingPC(fr.pc());
- if (lo != null) {
- CDebugInfoDataBase db = lo.getDebugInfoDataBase();
- if (db != null) {
- LineNumberInfo info = db.lineNumberForPC(fr.pc());
- if (info != null) {
- System.err.println("PC " + fr.pc() + ": Source file \"" +
- info.getSourceFileName() +
- "\", line number " +
- info.getLineNumber() +
- ", PC range [" +
- info.getStartPC() +
- ", " +
- info.getEndPC() +
- ")");
- // OK, here we go...
- showLineNumber(null, info.getSourceFileName(), info.getLineNumber());
- } else {
- System.err.println("(No line number information for PC " + fr.pc() + ")");
- // Dump line number information for database
- db.iterate(new LineNumberVisitor() {
- public void doLineNumber(LineNumberInfo info) {
- System.err.println(" Source file \"" +
- info.getSourceFileName() +
- "\", line number " +
- info.getLineNumber() +
- ", PC range [" +
- info.getStartPC() +
- ", " +
- info.getEndPC() +
- ")");
- }
- });
- }
- }
- }
- } else {
- if (Assert.ASSERTS_ENABLED) {
- Assert.that(jfr != null, "Must have either C or Java frame");
- }
- localsPanel.update(jfr);
- // See whether we can locate source file and line number
- // FIXME: infer pathmap entries from user's locating of this
- // source file
- // FIXME: figure out what to do for native methods. Possible to
- // go to line number for the native method declaration?
- Method m = jfr.getMethod();
- Symbol sfn = ((InstanceKlass) m.getMethodHolder()).getSourceFileName();
- if (sfn != null) {
- int bci = jfr.getBCI();
- int lineNo = m.getLineNumberFromBCI(bci);
- if (lineNo >= 0) {
- // FIXME: show disassembly otherwise
- showLineNumber(packageName(m.getMethodHolder().getName().asString()),
- sfn.asString(), lineNo);
- }
- }
- }
- }
-
- private String packageName(String str) {
- int idx = str.lastIndexOf('/');
- if (idx < 0) {
- return "";
- }
- return str.substring(0, idx).replace('/', '.');
- }
-
- private JavaThread javaThreadForProxy(ThreadProxy t) {
- if (!getAgent().isJavaMode()) {
- return null;
- }
- if (threadToJavaThreadMap == null) {
- threadToJavaThreadMap = new HashMap();
- Threads threads = VM.getVM().getThreads();
- for (JavaThread thr = threads.first(); thr != null; thr = thr.next()) {
- threadToJavaThreadMap.put(thr.getThreadProxy(), thr);
- }
- }
- return (JavaThread) threadToJavaThreadMap.get(t);
- }
-
- private static JMenu createMenu(String name, char mnemonic, int mnemonicPos) {
- JMenu menu = new JMenu(name);
- menu.setMnemonic(mnemonic);
- menu.setDisplayedMnemonicIndex(mnemonicPos);
- return menu;
- }
-
- private static JMenuItem createMenuItem(String name, ActionListener l) {
- JMenuItem item = new JMenuItem(name);
- item.addActionListener(l);
- return item;
- }
-
- private static JMenuItem createMenuItemInternal(String name, ActionListener l, int accelerator, int modifiers) {
- JMenuItem item = createMenuItem(name, l);
- item.setAccelerator(KeyStroke.getKeyStroke(accelerator, modifiers));
- return item;
- }
-
- private static JMenuItem createMenuItem(String name, ActionListener l, int accelerator) {
- return createMenuItemInternal(name, l, accelerator, 0);
- }
-
- private static JMenuItem createMenuItem(String name, ActionListener l, char mnemonic, int mnemonicPos) {
- JMenuItem item = createMenuItem(name, l);
- item.setMnemonic(mnemonic);
- item.setDisplayedMnemonicIndex(mnemonicPos);
- return item;
- }
-
- private static JMenuItem createMenuItem(String name,
- ActionListener l,
- int accelerator,
- int acceleratorMods,
- char mnemonic,
- int mnemonicPos) {
- JMenuItem item = createMenuItemInternal(name, l, accelerator, acceleratorMods);
- item.setMnemonic(mnemonic);
- item.setDisplayedMnemonicIndex(mnemonicPos);
- return item;
- }
-
- /** Punctuates the given string with \n's where necessary to not
- exceed the given number of characters per line. Strips
- extraneous whitespace. */
- private static String formatMessage(String message, int charsPerLine) {
- StringBuffer buf = new StringBuffer(message.length());
- StringTokenizer tokenizer = new StringTokenizer(message);
- int curLineLength = 0;
- while (tokenizer.hasMoreTokens()) {
- String tok = tokenizer.nextToken();
- if (curLineLength + tok.length() > charsPerLine) {
- buf.append('\n');
- curLineLength = 0;
- } else {
- if (curLineLength != 0) {
- buf.append(' ');
- ++curLineLength;
- }
- }
- buf.append(tok);
- curLineLength += tok.length();
- }
- return buf.toString();
- }
-
- private void setMenuItemsEnabled(java.util.List items, boolean enabled) {
- for (Iterator iter = items.iterator(); iter.hasNext(); ) {
- ((JMenuItem) iter.next()).setEnabled(enabled);
- }
- }
-
- private void showMessageDialog(final String message, final String title, final int jOptionPaneKind) {
- SwingUtilities.invokeLater(new Runnable() {
- public void run() {
- if (mdiMode) {
- JOptionPane.showInternalMessageDialog(desktop, message, title, jOptionPaneKind);
- } else {
- JOptionPane.showMessageDialog(null, message, title, jOptionPaneKind);
- }
- }
- });
- }
-
- private FrameWrapper newFrame(String title) {
- if (mdiMode) {
- return new JInternalFrameWrapper(new JInternalFrame(title));
- } else {
- return new JFrameWrapper(new JFrame(title));
- }
- }
-
- private void addFrame(FrameWrapper frame) {
- if (mdiMode) {
- desktop.add(frame.getComponent());
- }
- }
-
- private void removeFrame(FrameWrapper frame) {
- if (mdiMode) {
- desktop.remove(frame.getComponent());
- desktop.invalidate();
- desktop.validate();
- desktop.repaint();
- }
- // FIXME: do something when not in MDI mode
- }
-
- private Dimension getParentDimension(Component c) {
- if (mdiMode) {
- return desktop.getSize();
- } else {
- return Toolkit.getDefaultToolkit().getScreenSize();
- }
- }
-
- // Default editor implementation
- class DefaultEditor implements Editor {
- private DefaultEditorFactory factory;
- private FrameWrapper editorFrame;
- private String filename;
- private SourceCodePanel code;
- private boolean shown;
- private Object userData;
-
- public DefaultEditor(DefaultEditorFactory fact, String filename, final EditorCommands comm) {
- this.filename = filename;
- this.factory = fact;
- editorFrame = newFrame(filename);
- code = new SourceCodePanel();
- // FIXME: when font changes, change font in editors as well
- code.setFont(fixedWidthFont);
- editorFrame.getContentPane().add(code);
- editorFrame.setClosable(true);
- editorFrame.setResizable(true);
- editorFrame.setClosingActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- comm.windowClosed(DefaultEditor.this);
- removeFrame(editorFrame);
- editorFrame.dispose();
- factory.editorClosed(DefaultEditor.this);
- }
- });
- editorFrame.setActivatedActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- factory.makeEditorCurrent(DefaultEditor.this);
- code.requestFocus();
- }
- });
- code.setEditorCommands(comm, this);
- }
-
- public boolean openFile() { return code.openFile(filename); }
- public String getSourceFileName() { return filename; }
- public int getCurrentLineNumber() { return code.getCurrentLineNumber(); }
- public void showLineNumber(int lineNo) {
- if (!shown) {
- addFrame(editorFrame);
- GraphicsUtilities.reshapeToAspectRatio(editorFrame.getComponent(),
- 1.0f,
- 0.85f,
- getParentDimension(editorFrame.getComponent()));
- editorFrame.setVisible(true);
- shown = true;
- }
- code.showLineNumber(lineNo);
- editorFrame.toFront();
- }
- public void highlightLineNumber(int lineNo) { code.highlightLineNumber(lineNo); }
- public void showBreakpointAtLine(int lineNo) { code.showBreakpointAtLine(lineNo); }
- public boolean hasBreakpointAtLine(int lineNo) { return code.hasBreakpointAtLine(lineNo); }
- public void clearBreakpointAtLine(int lineNo) { code.clearBreakpointAtLine(lineNo); }
- public void clearBreakpoints() { code.clearBreakpoints(); }
- public void setUserData(Object o) { userData = o; }
- public Object getUserData() { return userData; }
- public void toFront() { editorFrame.toFront();
- factory.makeEditorCurrent(this); }
- }
-
- class DefaultEditorFactory implements EditorFactory {
- private LinkedList/*<Editor>*/ editors = new LinkedList();
-
- public Editor openFile(String filename, EditorCommands commands) {
- DefaultEditor editor = new DefaultEditor(this, filename, editorComm);
- if (!editor.openFile()) {
- return null;
- }
- return editor;
- }
-
- public Editor getCurrentEditor() {
- if (editors.isEmpty()) {
- return null;
- }
- return (Editor) editors.getFirst();
- }
-
- void editorClosed(Editor editor) {
- editors.remove(editor);
- }
-
- void makeEditorCurrent(Editor editor) {
- editors.remove(editor);
- editors.addFirst(editor);
- }
- }
-
- // Helper class for loading .java files; show only those with
- // correct file name which are also in the correct package
- static class JavaFileFilter extends javax.swing.filechooser.FileFilter {
- private String packageName;
- private String fileName;
-
- JavaFileFilter(String packageName, String fileName) {
- this.packageName = packageName;
- this.fileName = fileName;
- }
-
- public boolean accept(File f) {
- if (f.isDirectory()) {
- return true;
- }
- // This rejects most files
- if (!f.getName().equals(fileName)) {
- return false;
- }
- // Ensure selected file is in the correct package
- PackageScanner scanner = new PackageScanner();
- String pkg = scanner.scan(f);
- if (!pkg.equals(packageName)) {
- return false;
- }
- return true;
- }
-
- public String getDescription() { return "Java source files"; }
- }
-
- // Auxiliary information used only for Java source files
- static class JavaUserData {
- private String packageName; // External format
- private String sourceFileName;
-
- /** Source file name is equivalent to that found in the .java
- file; i.e., not a full path */
- JavaUserData(String packageName, String sourceFileName) {
- this.packageName = packageName;
- this.sourceFileName = sourceFileName;
- }
-
- String packageName() { return packageName; }
- String sourceFileName() { return sourceFileName; }
- }
-
- // Opens a source file. This makes it available for the setting of
- // lazy breakpoints.
- private void openSourceFile() {
- JFileChooser chooser = new JFileChooser();
- chooser.setDialogTitle("Open source code file");
- chooser.setMultiSelectionEnabled(false);
- if (chooser.showOpenDialog(null) != JFileChooser.APPROVE_OPTION) {
- return;
- }
- File chosen = chooser.getSelectedFile();
- if (chosen == null) {
- return;
- }
-
- // See whether we have a Java source file. If so, derive a package
- // name for it.
- String path = chosen.getPath();
- String name = null;
- JavaUserData data = null;
- if (path.endsWith(".java")) {
- PackageScanner scanner = new PackageScanner();
- String pkg = scanner.scan(chosen);
- // Now knowing both the package name and file name, we can put
- // this in the editor map and use it for setting breakpoints
- // later
- String fileName = chosen.getName();
- name = pkg + "." + fileName;
- data = new JavaUserData(pkg, fileName);
- } else {
- // FIXME: need pathmap mechanism
- name = path;
- }
- Editor editor = (Editor) editors.get(name);
- if (editor == null) {
- editor = editorFact.openFile(path, editorComm);
- if (editor == null) {
- showMessageDialog("Unable to open file \"" + path + "\" -- unexpected error.",
- "Unable to open file",
- JOptionPane.WARNING_MESSAGE);
- return;
- }
- editors.put(name, editor);
- if (data != null) {
- editor.setUserData(data);
- }
- } else {
- editor.toFront();
- }
- editor.showLineNumber(1);
- // Show breakpoints as well if we have any for this file
- Set set = (Set) fileToBreakpointMap.get(editor.getSourceFileName());
- if (set != null) {
- for (Iterator iter = set.iterator(); iter.hasNext(); ) {
- editor.showBreakpointAtLine(((Integer) iter.next()).intValue());
- }
- }
- }
-
- // Package name may be null, in which case the file is assumed to be
- // a C source file. Otherwise it is assumed to be a Java source file
- // and certain filtering rules will be applied.
- private void showLineNumber(String packageName, String fileName, int lineNumber) {
- String name;
- if (packageName == null) {
- name = fileName;
- } else {
- name = packageName + "." + fileName;
- }
- Editor editor = (Editor) editors.get(name);
- if (editor == null) {
- // See whether file exists
- File file = new File(fileName);
- String realFileName = fileName;
- if (!file.exists()) {
- // User must specify path to file
- JFileChooser chooser = new JFileChooser();
- chooser.setDialogTitle("Please locate " + fileName);
- chooser.setMultiSelectionEnabled(false);
- if (packageName != null) {
- chooser.setFileFilter(new JavaFileFilter(packageName, fileName));
- }
- int res = chooser.showOpenDialog(null);
- if (res != JFileChooser.APPROVE_OPTION) {
- // FIXME: show disassembly instead
- return;
- }
- // FIXME: would like to infer more from the selection; i.e.,
- // a pathmap leading up to this file
- File chosen = chooser.getSelectedFile();
- if (chosen == null) {
- return;
- }
- realFileName = chosen.getPath();
- }
- // Now instruct editor factory to open file
- editor = editorFact.openFile(realFileName, editorComm);
- if (editor == null) {
- showMessageDialog("Unable to open file \"" + realFileName + "\" -- unexpected error.",
- "Unable to open file",
- JOptionPane.WARNING_MESSAGE);
- return;
- }
- // Got an editor; put it in map
- editors.put(name, editor);
- // If Java source file, add additional information for later
- if (packageName != null) {
- editor.setUserData(new JavaUserData(packageName, fileName));
- }
- }
- // Got editor; show line
- editor.showLineNumber(lineNumber);
- editor.highlightLineNumber(lineNumber);
- // Show breakpoints as well if we have any for this file
- Set set = (Set) fileToBreakpointMap.get(editor.getSourceFileName());
- if (set != null) {
- for (Iterator iter = set.iterator(); iter.hasNext(); ) {
- editor.showBreakpointAtLine(((Integer) iter.next()).intValue());
- }
- }
- }
-
- //
- // Suspend/resume
- //
-
- private boolean isSuspended() {
- return suspended;
- }
-
- private synchronized void suspend() {
- setMenuItemsEnabled(resumeDebugMenuItems, true);
- setMenuItemsEnabled(suspendDebugMenuItems, false);
- BugSpotAgent agent = getAgent();
- if (agent.canInteractWithJava() && !agent.isJavaSuspended()) {
- agent.suspendJava();
- }
- agent.suspend();
- // FIXME: call VM.getVM().fireVMSuspended()
- resetCurrentThread();
- debugEventTimer.stop();
- suspended = true;
- }
-
- private synchronized void resume() {
- // Note: we don't wipe out the cached state like the
- // sourceFileToLineNumberInfoMap since it is too expensive to
- // recompute. Instead we recompute it if any DLLs are loaded or
- // unloaded.
- threadToJavaThreadMap = null;
- setMenuItemsEnabled(resumeDebugMenuItems, false);
- setMenuItemsEnabled(suspendDebugMenuItems, true);
- registerPanel.clear();
- // FIXME: call VM.getVM().fireVMResumed()
- BugSpotAgent agent = getAgent();
- agent.resume();
- if (agent.canInteractWithJava()) {
- if (agent.isJavaSuspended()) {
- agent.resumeJava();
- }
- if (javaEventPending) {
- javaEventPending = false;
- // Clear it out before resuming polling for events
- agent.javaEventContinue();
- }
- }
- agent.enableJavaInteraction();
- suspended = false;
- debugEventTimer.start();
- }
-
- //
- // Breakpoints
- //
-
- private synchronized BreakpointResult handleBreakpointToggle(Editor editor, int lineNumber) {
- // Currently we only use user data in editors to indicate Java
- // source files. If this changes then this code will need to
- // change.
- JavaUserData data = (JavaUserData) editor.getUserData();
- String filename = editor.getSourceFileName();
- if (data == null) {
- // C/C++ code
- // FIXME: as noted above in EditorCommands.toggleBreakpointAtLine,
- // this needs more work to handle "lazy" breakpoints in files
- // which we don't know about in the debug information yet
- CDebugger dbg = getCDebugger();
- ProcessControl prctl = dbg.getProcessControl();
- if (prctl == null) {
- return new BreakpointResult(false, false, 0, "Process control not enabled");
- }
- boolean mustSuspendAndResume = (!prctl.isSuspended());
- try {
- if (mustSuspendAndResume) {
- prctl.suspend();
- }
- // Search debug info for all DSOs
- LineNumberInfo info = getLineNumberInfo(filename, lineNumber);
- if (info != null) {
- Set bpset = (Set) fileToBreakpointMap.get(filename);
- if (bpset == null) {
- bpset = new HashSet();
- fileToBreakpointMap.put(filename, bpset);
- }
- Integer key = new Integer(info.getLineNumber());
- if (bpset.contains(key)) {
- // Clear breakpoint at this line's PC
- prctl.clearBreakpoint(info.getStartPC());
- bpset.remove(key);
- return new BreakpointResult(true, false, info.getLineNumber());
- } else {
- // Set breakpoint at this line's PC
- System.err.println("Setting breakpoint at PC " + info.getStartPC());
- prctl.setBreakpoint(info.getStartPC());
- bpset.add(key);
- return new BreakpointResult(true, true, info.getLineNumber());
- }
- } else {
- return new BreakpointResult(false, false, 0, "No debug information for this source file and line");
- }
- } finally {
- if (mustSuspendAndResume) {
- prctl.resume();
- }
- }
- } else {
- BugSpotAgent agent = getAgent();
- if (!agent.canInteractWithJava()) {
- String why;
- if (agent.isJavaInteractionDisabled()) {
- why = "Can not toggle Java breakpoints while stopped because\nof C/C++ debug events (breakpoints, single-stepping)";
- } else {
- why = "Could not talk to SA's JVMDI module to enable Java\nprogramming language breakpoints (run with -Xdebug -Xrunsa)";
- }
- return new BreakpointResult(false, false, 0, why);
- }
- Set bpset = (Set) fileToBreakpointMap.get(filename);
- if (bpset == null) {
- bpset = new HashSet();
- fileToBreakpointMap.put(filename, bpset);
- }
- boolean mustResumeAndSuspend = isSuspended();
- try {
- if (mustResumeAndSuspend) {
- agent.resume();
- }
- ServiceabilityAgentJVMDIModule.BreakpointToggleResult res =
- getAgent().toggleJavaBreakpoint(data.sourceFileName(),
- data.packageName(),
- lineNumber);
- if (res.getSuccess()) {
- Integer key = new Integer(res.getLineNumber());
- boolean addRemRes = false;
- if (res.getWasSet()) {
- addRemRes = bpset.add(key);
- System.err.println("Setting breakpoint at " + res.getMethodName() + res.getMethodSignature() +
- ", bci " + res.getBCI() + ", line " + res.getLineNumber());
- } else {
- addRemRes = bpset.remove(key);
- System.err.println("Clearing breakpoint at " + res.getMethodName() + res.getMethodSignature() +
- ", bci " + res.getBCI() + ", line " + res.getLineNumber());
- }
- if (Assert.ASSERTS_ENABLED) {
- Assert.that(addRemRes, "Inconsistent Java breakpoint state with respect to target process");
- }
- return new BreakpointResult(true, res.getWasSet(), res.getLineNumber());
- } else {
- return new BreakpointResult(false, false, 0, res.getErrMsg());
- }
- } finally {
- if (mustResumeAndSuspend) {
- agent.suspend();
- resetCurrentThread();
- }
- }
- }
- }
-
- // Must call only when suspended
- private LineNumberInfo getLineNumberInfo(String filename, int lineNumber) {
- Map map = getSourceFileToLineNumberInfoMap();
- java.util.List infos = (java.util.List) map.get(filename);
- if (infos == null) {
- return null;
- }
- // Binary search for line number
- return searchLineNumbers(infos, lineNumber, 0, infos.size());
- }
-
- // Must call only when suspended
- private Map getSourceFileToLineNumberInfoMap() {
- if (sourceFileToLineNumberInfoMap == null) {
- // Build from debug info
- java.util.List loadObjects = getCDebugger().getLoadObjectList();
- final Map map = new HashMap();
- for (Iterator iter = loadObjects.iterator(); iter.hasNext(); ) {
- LoadObject lo = (LoadObject) iter.next();
- CDebugInfoDataBase db = lo.getDebugInfoDataBase();
- if (db != null) {
- db.iterate(new LineNumberVisitor() {
- public void doLineNumber(LineNumberInfo info) {
- String name = info.getSourceFileName();
- if (name != null) {
- java.util.List val = (java.util.List) map.get(name);
- if (val == null) {
- val = new ArrayList();
- map.put(name, val);
- }
- val.add(info);
- }
- }
- });
- }
- }
- // Sort all lists
- for (Iterator iter = map.values().iterator(); iter.hasNext(); ) {
- java.util.List list = (java.util.List) iter.next();
- Collections.sort(list, new Comparator() {
- public int compare(Object o1, Object o2) {
- LineNumberInfo l1 = (LineNumberInfo) o1;
- LineNumberInfo l2 = (LineNumberInfo) o2;
- int n1 = l1.getLineNumber();
- int n2 = l2.getLineNumber();
- if (n1 < n2) return -1;
- if (n1 == n2) return 0;
- return 1;
- }
- });
- }
- sourceFileToLineNumberInfoMap = map;
- }
- return sourceFileToLineNumberInfoMap;
- }
-
- private LineNumberInfo searchLineNumbers(java.util.List infoList, int lineNo, int lowIdx, int highIdx) {
- if (highIdx < lowIdx) return null;
- if (lowIdx == highIdx) {
- // Base case: see whether start PC is less than or equal to addr
- if (checkLineNumber(infoList, lineNo, lowIdx)) {
- return (LineNumberInfo) infoList.get(lowIdx);
- } else {
- return null;
- }
- } else if (lowIdx == highIdx - 1) {
- if (checkLineNumber(infoList, lineNo, lowIdx)) {
- return (LineNumberInfo) infoList.get(lowIdx);
- } else if (checkLineNumber(infoList, lineNo, highIdx)) {
- return (LineNumberInfo) infoList.get(highIdx);
- } else {
- return null;
- }
- }
- int midIdx = (lowIdx + highIdx) >> 1;
- LineNumberInfo info = (LineNumberInfo) infoList.get(midIdx);
- if (lineNo < info.getLineNumber()) {
- // Always move search down
- return searchLineNumbers(infoList, lineNo, lowIdx, midIdx);
- } else if (lineNo == info.getLineNumber()) {
- return info;
- } else {
- // Move search up
- return searchLineNumbers(infoList, lineNo, midIdx, highIdx);
- }
- }
-
- private boolean checkLineNumber(java.util.List infoList, int lineNo, int idx) {
- LineNumberInfo info = (LineNumberInfo) infoList.get(idx);
- return (info.getLineNumber() >= lineNo);
- }
-
- //
- // Debug events
- //
-
- private synchronized void pollForDebugEvent() {
- ProcessControl prctl = getCDebugger().getProcessControl();
- if (prctl == null) {
- return;
- }
- DebugEvent ev = prctl.debugEventPoll();
- if (ev != null) {
- DebugEvent.Type t = ev.getType();
- if (t == DebugEvent.Type.LOADOBJECT_LOAD ||
- t == DebugEvent.Type.LOADOBJECT_UNLOAD) {
- // Conservatively clear cached debug info state
- sourceFileToLineNumberInfoMap = null;
- // FIXME: would be very useful to have "stop on load/unload"
- // events
- // FIXME: must do work at these events to implement lazy
- // breakpoints
- prctl.debugEventContinue();
- } else if (t == DebugEvent.Type.BREAKPOINT) {
- // Note: Visual C++ only notifies on breakpoints it doesn't
- // know about
-
- // FIXME: put back test
- // if (!prctl.isBreakpointSet(ev.getPC())) {
- showMessageDialog("Breakpoint reached at PC " + ev.getPC(),
- "Breakpoint reached",
- JOptionPane.INFORMATION_MESSAGE);
- // }
- agent.disableJavaInteraction();
- suspend();
- prctl.debugEventContinue();
- } else if (t == DebugEvent.Type.SINGLE_STEP) {
- agent.disableJavaInteraction();
- suspend();
- prctl.debugEventContinue();
- } else if (t == DebugEvent.Type.ACCESS_VIOLATION) {
- showMessageDialog("Access violation attempting to " +
- (ev.getWasWrite() ? "write" : "read") +
- " address " + ev.getAddress() +
- " at PC " + ev.getPC(),
- "Access Violation",
- JOptionPane.WARNING_MESSAGE);
- agent.disableJavaInteraction();
- suspend();
- prctl.debugEventContinue();
- } else {
- String info = "Unknown debug event encountered";
- if (ev.getUnknownEventDetail() != null) {
- info = info + ": " + ev.getUnknownEventDetail();
- }
- showMessageDialog(info, "Unknown debug event", JOptionPane.INFORMATION_MESSAGE);
- suspend();
- prctl.debugEventContinue();
- }
- return;
- }
-
- // No C++ debug event; poll for Java debug event
- if (getAgent().canInteractWithJava()) {
- if (!javaEventPending) {
- if (getAgent().javaEventPending()) {
- suspend();
- // This does a lot of work and we want to have the page
- // cache available to us as it runs
- sun.jvm.hotspot.livejvm.Event jev = getAgent().javaEventPoll();
- if (jev != null) {
- javaEventPending = true;
- if (jev.getType() == sun.jvm.hotspot.livejvm.Event.Type.BREAKPOINT) {
- BreakpointEvent bpev = (BreakpointEvent) jev;
- showMessageDialog("Breakpoint reached in method\n" +
- bpev.methodID().method().externalNameAndSignature() +
- ",\nbci " + bpev.location(),
- "Breakpoint reached",
- JOptionPane.INFORMATION_MESSAGE);
- } else if (jev.getType() == sun.jvm.hotspot.livejvm.Event.Type.EXCEPTION) {
- ExceptionEvent exev = (ExceptionEvent) jev;
- showMessageDialog(exev.exception().getKlass().getName().asString() +
- "\nthrown in method\n" +
- exev.methodID().method().externalNameAndSignature() +
- "\nat BCI " + exev.location(),
- "Exception thrown",
- JOptionPane.INFORMATION_MESSAGE);
- } else {
- Assert.that(false, "Should not reach here");
- }
- }
- }
- }
- }
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/bugspot/BugSpotAgent.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,799 +0,0 @@
-/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.bugspot;
-
-import java.io.PrintStream;
-import java.net.*;
-import java.rmi.*;
-import sun.jvm.hotspot.*;
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.bsd.*;
-import sun.jvm.hotspot.debugger.proc.*;
-import sun.jvm.hotspot.debugger.cdbg.*;
-import sun.jvm.hotspot.debugger.windbg.*;
-import sun.jvm.hotspot.debugger.linux.*;
-import sun.jvm.hotspot.debugger.sparc.*;
-import sun.jvm.hotspot.debugger.remote.*;
-import sun.jvm.hotspot.livejvm.*;
-import sun.jvm.hotspot.memory.*;
-import sun.jvm.hotspot.oops.*;
-import sun.jvm.hotspot.runtime.*;
-import sun.jvm.hotspot.types.*;
-import sun.jvm.hotspot.utilities.*;
-
-/** <P> This class wraps the basic functionality for connecting to the
- * target process or debug server. It makes it simple to start up the
- * debugging system. </P>
- *
- * <P> This agent (as compared to the HotSpotAgent) can connect to
- * and interact with arbitrary processes. If the target process
- * happens to be a HotSpot JVM, the Java debugging features of the
- * Serviceability Agent are enabled. Further, if the Serviceability
- * Agent's JVMDI module is loaded into the target VM, interaction
- * with the live Java program is possible, specifically the catching
- * of exceptions and setting of breakpoints. </P>
- *
- * <P> The BugSpot debugger requires that the underlying Debugger
- * support C/C++ debugging via the CDebugger interface. </P>
- *
- * <P> FIXME: especially with the addition of remote debugging, this
- * has turned into a mess; needs rethinking. </P> */
-
-public class BugSpotAgent {
-
- private JVMDebugger debugger;
- private MachineDescription machDesc;
- private TypeDataBase db;
-
- private String os;
- private String cpu;
- private String fileSep;
-
- // The system can work in several ways:
- // - Attaching to local process
- // - Attaching to local core file
- // - Connecting to remote debug server
- // - Starting debug server for process
- // - Starting debug server for core file
-
- // These are options for the "client" side of things
- private static final int PROCESS_MODE = 0;
- private static final int CORE_FILE_MODE = 1;
- private static final int REMOTE_MODE = 2;
- private int startupMode;
-
- // This indicates whether we are really starting a server or not
- private boolean isServer;
-
- // All possible required information for connecting
- private int pid;
- private String executableName;
- private String coreFileName;
- private String debugServerID;
-
- // All needed information for server side
- private String serverID;
-
- // Indicates whether we are attached to a HotSpot JVM or not
- private boolean javaMode;
-
- // Indicates whether we have process control over a live HotSpot JVM
- // or not; non-null if so.
- private ServiceabilityAgentJVMDIModule jvmdi;
- // While handling C breakpoints interactivity with the Java program
- // is forbidden. Too many invariants are broken while the target is
- // stopped at a C breakpoint to risk making JVMDI calls.
- private boolean javaInteractionDisabled;
-
- private String[] jvmLibNames;
- private String[] saLibNames;
-
- // FIXME: make these configurable, i.e., via a dotfile; also
- // consider searching within the JDK from which this Java executable
- // comes to find them
- private static final String defaultDbxPathPrefix = "/net/jano.eng/export/disk05/hotspot/sa";
- private static final String defaultDbxSvcAgentDSOPathPrefix = "/net/jano.eng/export/disk05/hotspot/sa";
-
- private static final boolean DEBUG;
- static {
- DEBUG = System.getProperty("sun.jvm.hotspot.bugspot.BugSpotAgent.DEBUG")
- != null;
- }
-
- static void debugPrintln(String str) {
- if (DEBUG) {
- System.err.println(str);
- }
- }
-
- static void showUsage() {
- System.out.println(" You can also pass these -D options to java to specify where to find dbx and the \n" +
- " Serviceability Agent plugin for dbx:");
- System.out.println(" -DdbxPathName=<path-to-dbx-executable>\n" +
- " Default is derived from dbxPathPrefix");
- System.out.println(" or");
- System.out.println(" -DdbxPathPrefix=<xxx>\n" +
- " where xxx is the path name of a dir structure that contains:\n" +
- " <os>/<arch>/bin/dbx\n" +
- " The default is " + defaultDbxPathPrefix);
- System.out.println(" and");
- System.out.println(" -DdbxSvcAgentDSOPathName=<path-to-dbx-serviceability-agent-module>\n" +
- " Default is determined from dbxSvcAgentDSOPathPrefix");
- System.out.println(" or");
- System.out.println(" -DdbxSvcAgentDSOPathPrefix=<xxx>\n" +
- " where xxx is the pathname of a dir structure that contains:\n" +
- " <os>/<arch>/bin/lib/libsvc_agent_dbx.so\n" +
- " The default is " + defaultDbxSvcAgentDSOPathPrefix);
- }
-
- public BugSpotAgent() {
- // for non-server add shutdown hook to clean-up debugger in case
- // of forced exit. For remote server, shutdown hook is added by
- // DebugServer.
- Runtime.getRuntime().addShutdownHook(new java.lang.Thread(
- new Runnable() {
- public void run() {
- synchronized (BugSpotAgent.this) {
- if (!isServer) {
- detach();
- }
- }
- }
- }));
- }
-
- //--------------------------------------------------------------------------------
- // Accessors (once the system is set up)
- //
-
- public synchronized Debugger getDebugger() {
- return debugger;
- }
-
- public synchronized CDebugger getCDebugger() {
- return getDebugger().getCDebugger();
- }
-
- public synchronized ProcessControl getProcessControl() {
- return getCDebugger().getProcessControl();
- }
-
- public synchronized TypeDataBase getTypeDataBase() {
- return db;
- }
-
- /** Indicates whether the target process is suspended
- completely. Equivalent to getProcessControl().isSuspended(). */
- public synchronized boolean isSuspended() throws DebuggerException {
- return getProcessControl().isSuspended();
- }
-
- /** Suspends the target process completely. Equivalent to
- getProcessControl().suspend(). */
- public synchronized void suspend() throws DebuggerException {
- getProcessControl().suspend();
- }
-
- /** Resumes the target process completely. Equivalent to
- getProcessControl().suspend(). */
- public synchronized void resume() throws DebuggerException {
- getProcessControl().resume();
- }
-
- /** Indicates whether we are attached to a Java HotSpot virtual
- machine */
- public synchronized boolean isJavaMode() {
- return javaMode;
- }
-
- /** Temporarily disables interaction with the target process via
- JVMDI. This is done while the target process is stopped at a C
- breakpoint. Can be called even if the JVMDI agent has not been
- initialized. */
- public synchronized void disableJavaInteraction() {
- javaInteractionDisabled = true;
- }
-
- /** Re-enables interaction with the target process via JVMDI. This
- is done while the target process is continued past a C
- braekpoint. Can be called even if the JVMDI agent has not been
- initialized. */
- public synchronized void enableJavaInteraction() {
- javaInteractionDisabled = false;
- }
-
- /** Indicates whether Java interaction has been disabled */
- public synchronized boolean isJavaInteractionDisabled() {
- return javaInteractionDisabled;
- }
-
- /** Indicates whether we can talk to the Serviceability Agent's
- JVMDI module to be able to set breakpoints */
- public synchronized boolean canInteractWithJava() {
- return (jvmdi != null) && !javaInteractionDisabled;
- }
-
- /** Suspends all Java threads in the target process. Can only be
- called if we are attached to a HotSpot JVM and can connect to
- the SA's JVMDI module. Must not be called when the target
- process has been suspended with suspend(). */
- public synchronized void suspendJava() throws DebuggerException {
- if (!canInteractWithJava()) {
- throw new DebuggerException("Could not connect to SA's JVMDI module");
- }
- if (jvmdi.isSuspended()) {
- throw new DebuggerException("Target process already suspended via JVMDI");
- }
- jvmdi.suspend();
- }
-
- /** Resumes all Java threads in the target process. Can only be
- called if we are attached to a HotSpot JVM and can connect to
- the SA's JVMDI module. Must not be called when the target
- process has been suspended with suspend(). */
- public synchronized void resumeJava() throws DebuggerException {
- if (!canInteractWithJava()) {
- throw new DebuggerException("Could not connect to SA's JVMDI module");
- }
- if (!jvmdi.isSuspended()) {
- throw new DebuggerException("Target process already resumed via JVMDI");
- }
- jvmdi.resume();
- }
-
- /** Indicates whether the target process has been suspended at the
- Java language level via the SA's JVMDI module */
- public synchronized boolean isJavaSuspended() throws DebuggerException {
- return jvmdi.isSuspended();
- }
-
- /** Toggle a Java breakpoint at the given location. */
- public synchronized ServiceabilityAgentJVMDIModule.BreakpointToggleResult
- toggleJavaBreakpoint(String srcFileName,
- String pkgName,
- int lineNo) {
- if (!canInteractWithJava()) {
- throw new DebuggerException("Could not connect to SA's JVMDI module; can not toggle Java breakpoints");
- }
- return jvmdi.toggleBreakpoint(srcFileName, pkgName, lineNo);
- }
-
- /** Access to JVMDI module's eventPending */
- public synchronized boolean javaEventPending() throws DebuggerException {
- if (!canInteractWithJava()) {
- throw new DebuggerException("Could not connect to SA's JVMDI module; can not poll for Java debug events");
- }
- return jvmdi.eventPending();
- }
-
- /** Access to JVMDI module's eventPoll */
- public synchronized Event javaEventPoll() throws DebuggerException {
- if (!canInteractWithJava()) {
- throw new DebuggerException("Could not connect to SA's JVMDI module; can not poll for Java debug events");
- }
- return jvmdi.eventPoll();
- }
-
- /** Access to JVMDI module's eventContinue */
- public synchronized void javaEventContinue() throws DebuggerException {
- if (!canInteractWithJava()) {
- throw new DebuggerException("Could not connect to SA's JVMDI module; can not continue past Java debug events");
- }
- jvmdi.eventContinue();
- }
-
-
- // FIXME: add other accessors. For example, suspension and
- // resumption should be done through this interface, as well as
- // interaction with the live Java process such as breakpoint setting.
- // Probably should not expose the ServiceabilityAgentJVMDIModule
- // from this interface.
-
- //--------------------------------------------------------------------------------
- // Client-side operations
- //
-
- /** This attaches to a process running on the local machine. */
- public synchronized void attach(int processID)
- throws DebuggerException {
- if (debugger != null) {
- throw new DebuggerException("Already attached");
- }
- pid = processID;
- startupMode = PROCESS_MODE;
- isServer = false;
- go();
- }
-
- /** This opens a core file on the local machine */
- public synchronized void attach(String executableName, String coreFileName)
- throws DebuggerException {
- if (debugger != null) {
- throw new DebuggerException("Already attached");
- }
- if ((executableName == null) || (coreFileName == null)) {
- throw new DebuggerException("Both the core file name and executable name must be specified");
- }
- this.executableName = executableName;
- this.coreFileName = coreFileName;
- startupMode = CORE_FILE_MODE;
- isServer = false;
- go();
- }
-
- /** This attaches to a "debug server" on a remote machine; this
- remote server has already attached to a process or opened a
- core file and is waiting for RMI calls on the Debugger object to
- come in. */
- public synchronized void attach(String remoteServerID)
- throws DebuggerException {
- if (debugger != null) {
- throw new DebuggerException("Already attached to a process");
- }
- if (remoteServerID == null) {
- throw new DebuggerException("Debug server id must be specified");
- }
-
- debugServerID = remoteServerID;
- startupMode = REMOTE_MODE;
- isServer = false;
- go();
- }
-
- /** This should only be called by the user on the client machine,
- not the server machine */
- public synchronized boolean detach() throws DebuggerException {
- if (isServer) {
- throw new DebuggerException("Should not call detach() for server configuration");
- }
- return detachInternal();
- }
-
- //--------------------------------------------------------------------------------
- // Server-side operations
- //
-
- /** This attaches to a process running on the local machine and
- starts a debug server, allowing remote machines to connect and
- examine this process. uniqueID is used to uniquely identify the
- debuggee */
- public synchronized void startServer(int processID, String uniqueID)
- throws DebuggerException {
- if (debugger != null) {
- throw new DebuggerException("Already attached");
- }
- pid = processID;
- startupMode = PROCESS_MODE;
- isServer = true;
- serverID = uniqueID;
- go();
- }
-
- /** This attaches to a process running on the local machine and
- starts a debug server, allowing remote machines to connect and
- examine this process. */
- public synchronized void startServer(int processID)
- throws DebuggerException {
- startServer(processID, null);
- }
-
- /** This opens a core file on the local machine and starts a debug
- server, allowing remote machines to connect and examine this
- core file. uniqueID is used to uniquely identify the
- debuggee */
- public synchronized void startServer(String executableName, String coreFileName,
- String uniqueID)
- throws DebuggerException {
- if (debugger != null) {
- throw new DebuggerException("Already attached");
- }
- if ((executableName == null) || (coreFileName == null)) {
- throw new DebuggerException("Both the core file name and Java executable name must be specified");
- }
- this.executableName = executableName;
- this.coreFileName = coreFileName;
- startupMode = CORE_FILE_MODE;
- isServer = true;
- serverID = uniqueID;
- go();
- }
-
- /** This opens a core file on the local machine and starts a debug
- server, allowing remote machines to connect and examine this
- core file.*/
- public synchronized void startServer(String executableName, String coreFileName)
- throws DebuggerException {
- startServer(executableName, coreFileName, null);
- }
-
- /** This may only be called on the server side after startServer()
- has been called */
- public synchronized boolean shutdownServer() throws DebuggerException {
- if (!isServer) {
- throw new DebuggerException("Should not call shutdownServer() for client configuration");
- }
- return detachInternal();
- }
-
-
- //--------------------------------------------------------------------------------
- // Internals only below this point
- //
-
- private boolean detachInternal() {
- if (debugger == null) {
- return false;
- }
- if (canInteractWithJava()) {
- jvmdi.detach();
- jvmdi = null;
- }
- boolean retval = true;
- if (!isServer) {
- VM.shutdown();
- }
- // We must not call detach() if we are a client and are connected
- // to a remote debugger
- Debugger dbg = null;
- DebuggerException ex = null;
- if (isServer) {
- try {
- RMIHelper.unbind(serverID);
- }
- catch (DebuggerException de) {
- ex = de;
- }
- dbg = debugger;
- } else {
- if (startupMode != REMOTE_MODE) {
- dbg = debugger;
- }
- }
- if (dbg != null) {
- retval = dbg.detach();
- }
-
- debugger = null;
- machDesc = null;
- db = null;
- if (ex != null) {
- throw(ex);
- }
- return retval;
- }
-
- private void go() {
- setupDebugger();
- javaMode = setupVM();
- }
-
- private void setupDebugger() {
- if (startupMode != REMOTE_MODE) {
- //
- // Local mode (client attaching to local process or setting up
- // server, but not client attaching to server)
- //
-
- try {
- os = PlatformInfo.getOS();
- cpu = PlatformInfo.getCPU();
- }
- catch (UnsupportedPlatformException e) {
- throw new DebuggerException(e);
- }
- fileSep = System.getProperty("file.separator");
-
- if (os.equals("solaris")) {
- setupDebuggerSolaris();
- } else if (os.equals("win32")) {
- setupDebuggerWin32();
- } else if (os.equals("linux")) {
- setupDebuggerLinux();
- } else if (os.equals("bsd")) {
- setupDebuggerBsd();
- } else {
- // Add support for more operating systems here
- throw new DebuggerException("Operating system " + os + " not yet supported");
- }
- if (isServer) {
- RemoteDebuggerServer remote = null;
- try {
- remote = new RemoteDebuggerServer(debugger);
- }
- catch (RemoteException rem) {
- throw new DebuggerException(rem);
- }
- RMIHelper.rebind(serverID, remote);
- }
- } else {
- //
- // Remote mode (client attaching to server)
- //
-
- // Create and install a security manager
-
- // FIXME: currently commented out because we were having
- // security problems since we're "in the sun.* hierarchy" here.
- // Perhaps a permissive policy file would work around this. In
- // the long run, will probably have to move into com.sun.*.
-
- // if (System.getSecurityManager() == null) {
- // System.setSecurityManager(new RMISecurityManager());
- // }
-
- connectRemoteDebugger();
- }
- }
-
- private boolean setupVM() {
- // We need to instantiate a HotSpotTypeDataBase on both the client
- // and server machine. On the server it is only currently used to
- // configure the Java primitive type sizes (which we should
- // consider making constant). On the client it is used to
- // configure the VM.
-
- try {
- if (os.equals("solaris")) {
- db = new HotSpotTypeDataBase(machDesc, new HotSpotSolarisVtblAccess(debugger, jvmLibNames),
- debugger, jvmLibNames);
- } else if (os.equals("win32")) {
- db = new HotSpotTypeDataBase(machDesc, new Win32VtblAccess(debugger, jvmLibNames),
- debugger, jvmLibNames);
- } else if (os.equals("linux")) {
- db = new HotSpotTypeDataBase(machDesc, new LinuxVtblAccess(debugger, jvmLibNames),
- debugger, jvmLibNames);
- } else if (os.equals("bsd")) {
- db = new HotSpotTypeDataBase(machDesc, new BsdVtblAccess(debugger, jvmLibNames),
- debugger, jvmLibNames);
- } else {
- throw new DebuggerException("OS \"" + os + "\" not yet supported (no VtblAccess implemented yet)");
- }
- }
- catch (NoSuchSymbolException e) {
- e.printStackTrace();
- return false;
- }
-
- if (startupMode != REMOTE_MODE) {
- // Configure the debugger with the primitive type sizes just obtained from the VM
- debugger.configureJavaPrimitiveTypeSizes(db.getJBooleanType().getSize(),
- db.getJByteType().getSize(),
- db.getJCharType().getSize(),
- db.getJDoubleType().getSize(),
- db.getJFloatType().getSize(),
- db.getJIntType().getSize(),
- db.getJLongType().getSize(),
- db.getJShortType().getSize());
- }
-
- if (!isServer) {
- // Do not initialize the VM on the server (unnecessary, since it's
- // instantiated on the client)
- VM.initialize(db, debugger);
- }
-
- try {
- jvmdi = new ServiceabilityAgentJVMDIModule(debugger, saLibNames);
- if (jvmdi.canAttach()) {
- jvmdi.attach();
- jvmdi.setCommandTimeout(6000);
- debugPrintln("Attached to Serviceability Agent's JVMDI module.");
- // Jog VM to suspended point with JVMDI module
- resume();
- suspendJava();
- suspend();
- debugPrintln("Suspended all Java threads.");
- } else {
- debugPrintln("Could not locate SA's JVMDI module; skipping attachment");
- jvmdi = null;
- }
- } catch (Exception e) {
- e.printStackTrace();
- jvmdi = null;
- }
-
- return true;
- }
-
- //--------------------------------------------------------------------------------
- // OS-specific debugger setup/connect routines
- //
-
- //
- // Solaris
- //
-
- private void setupDebuggerSolaris() {
- setupJVMLibNamesSolaris();
- ProcDebuggerLocal dbg = new ProcDebuggerLocal(null, true);
- debugger = dbg;
- attachDebugger();
-
- // Set up CPU-dependent stuff
- if (cpu.equals("x86")) {
- machDesc = new MachineDescriptionIntelX86();
- } else if (cpu.equals("sparc")) {
- int addressSize = dbg.getRemoteProcessAddressSize();
- if (addressSize == -1) {
- throw new DebuggerException("Error occurred while trying to determine the remote process's address size");
- }
-
- if (addressSize == 32) {
- machDesc = new MachineDescriptionSPARC32Bit();
- } else if (addressSize == 64) {
- machDesc = new MachineDescriptionSPARC64Bit();
- } else {
- throw new DebuggerException("Address size " + addressSize + " is not supported on SPARC");
- }
- } else if (cpu.equals("amd64")) {
- machDesc = new MachineDescriptionAMD64();
- } else {
- throw new DebuggerException("Solaris only supported on sparc/sparcv9/x86/amd64");
- }
-
- dbg.setMachineDescription(machDesc);
- }
-
- private void connectRemoteDebugger() throws DebuggerException {
- RemoteDebugger remote =
- (RemoteDebugger) RMIHelper.lookup(debugServerID);
- debugger = new RemoteDebuggerClient(remote);
- machDesc = ((RemoteDebuggerClient) debugger).getMachineDescription();
- os = debugger.getOS();
- if (os.equals("solaris")) {
- setupJVMLibNamesSolaris();
- } else if (os.equals("win32")) {
- setupJVMLibNamesWin32();
- } else if (os.equals("linux")) {
- setupJVMLibNamesLinux();
- } else if (os.equals("bsd")) {
- setupJVMLibNamesBsd();
- } else {
- throw new RuntimeException("Unknown OS type");
- }
-
- cpu = debugger.getCPU();
- }
-
- private void setupJVMLibNamesSolaris() {
- jvmLibNames = new String[] { "libjvm.so", "libjvm_g.so", "gamma_g" };
- saLibNames = new String[] { "libsa.so", "libsa_g.so" };
- }
-
- //
- // Win32
- //
-
- private void setupDebuggerWin32() {
- setupJVMLibNamesWin32();
-
- if (cpu.equals("x86")) {
- machDesc = new MachineDescriptionIntelX86();
- } else if (cpu.equals("amd64")) {
- machDesc = new MachineDescriptionAMD64();
- } else if (cpu.equals("ia64")) {
- machDesc = new MachineDescriptionIA64();
- } else {
- throw new DebuggerException("Win32 supported under x86, amd64 and ia64 only");
- }
-
- // Note we do not use a cache for the local debugger in server
- // mode; it will be taken care of on the client side (once remote
- // debugging is implemented).
-
- debugger = new WindbgDebuggerLocal(machDesc, !isServer);
-
- attachDebugger();
- }
-
- private void setupJVMLibNamesWin32() {
- jvmLibNames = new String[] { "jvm.dll", "jvm_g.dll" };
- saLibNames = new String[] { "sa.dll", "sa_g.dll" };
- }
-
- //
- // Linux
- //
-
- private void setupDebuggerLinux() {
- setupJVMLibNamesLinux();
-
- if (cpu.equals("x86")) {
- machDesc = new MachineDescriptionIntelX86();
- } else if (cpu.equals("ia64")) {
- machDesc = new MachineDescriptionIA64();
- } else if (cpu.equals("amd64")) {
- machDesc = new MachineDescriptionAMD64();
- } else if (cpu.equals("sparc")) {
- if (LinuxDebuggerLocal.getAddressSize()==8) {
- machDesc = new MachineDescriptionSPARC64Bit();
- } else {
- machDesc = new MachineDescriptionSPARC32Bit();
- }
- } else {
- try {
- machDesc = (MachineDescription)
- Class.forName("sun.jvm.hotspot.debugger.MachineDescription" +
- cpu.toUpperCase()).newInstance();
- } catch (Exception e) {
- throw new DebuggerException("unsupported machine type");
- }
- }
-
-
- // Note we do not use a cache for the local debugger in server
- // mode; it will be taken care of on the client side (once remote
- // debugging is implemented).
-
- debugger = new LinuxDebuggerLocal(machDesc, !isServer);
- attachDebugger();
- }
-
- private void setupJVMLibNamesLinux() {
- // same as solaris
- setupJVMLibNamesSolaris();
- }
-
- //
- // BSD
- //
-
- private void setupDebuggerBsd() {
- setupJVMLibNamesBsd();
-
- if (cpu.equals("x86")) {
- machDesc = new MachineDescriptionIntelX86();
- } else if (cpu.equals("amd64") || (cpu.equals("x86_64"))) {
- machDesc = new MachineDescriptionAMD64();
- } else {
- throw new DebuggerException("Bsd only supported on x86/x86_64. Current arch: " + cpu);
- }
-
- // Note we do not use a cache for the local debugger in server
- // mode; it will be taken care of on the client side (once remote
- // debugging is implemented).
-
- debugger = new BsdDebuggerLocal(machDesc, !isServer);
- attachDebugger();
- }
-
- private void setupJVMLibNamesBsd() {
- // same as solaris
- setupJVMLibNamesSolaris();
- }
-
- /** Convenience routine which should be called by per-platform
- debugger setup. Should not be called when startupMode is
- REMOTE_MODE. */
- private void attachDebugger() {
- if (startupMode == PROCESS_MODE) {
- debugger.attach(pid);
- } else if (startupMode == CORE_FILE_MODE) {
- debugger.attach(executableName, coreFileName);
- } else {
- throw new DebuggerException("Should not call attach() for startupMode == " + startupMode);
- }
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/bugspot/JavaLineNumberInfo.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.bugspot;
-
-import sun.jvm.hotspot.oops.*;
-
-/** Wrapper class which describes line number information for Java
- class files. The line number table is converted into this
- representation on demand. These objects are then sorted by line
- number for fast lookup when setting breakpoints in a particular
- source file. */
-
-public class JavaLineNumberInfo {
- private InstanceKlass klass;
- private Method method;
- private int startBCI;
- private int lineNumber;
-
- public JavaLineNumberInfo(InstanceKlass klass,
- Method method,
- int startBCI,
- int lineNumber) {
- this.klass = klass;
- this.method = method;
- this.startBCI = startBCI;
- this.lineNumber = lineNumber;
- }
-
- public InstanceKlass getKlass() { return klass; }
- public Method getMethod() { return method; }
- public int getStartBCI() { return startBCI; }
- public int getLineNumber() { return lineNumber; }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/bugspot/Main.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.bugspot;
-
-import java.awt.*;
-import java.awt.event.*;
-import javax.swing.*;
-
-import sun.jvm.hotspot.ui.*;
-
-/** The main class for the BugSpot debugger. */
-
-public class Main {
- public static void main(String[] args) {
- JFrame frame = new JFrame("BugSpot");
- frame.setSize(800, 600);
- BugSpot db = new BugSpot();
- db.setMDIMode(true);
- db.build();
- frame.setJMenuBar(db.getMenuBar());
- frame.getContentPane().add(db);
- frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
-
- GraphicsUtilities.reshapeToAspectRatio(frame,
- 4.0f/3.0f, 0.85f, Toolkit.getDefaultToolkit().getScreenSize());
- GraphicsUtilities.centerInContainer(frame,
- Toolkit.getDefaultToolkit().getScreenSize());
- frame.setVisible(true);
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/bugspot/PCFinder.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-/*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.bugspot;
-
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.cdbg.*;
-
-/** Helper class for locating a program counter. Indicates the
- confidence of the find. */
-
-public class PCFinder {
- public static final int LOW_CONFIDENCE = 1;
- public static final int HIGH_CONFIDENCE = 2;
-
- public static class Info {
- private String name;
- private long offset;
- private int confidence;
-
- public Info(String name, long offset, int confidence) {
- this.name = name;
- this.offset = offset;
- this.confidence = confidence;
- }
-
- /** May be null */
- public String getName() { return name; }
-
- /** If this is -1, a symbol could not be found, and the offset
- should not be shown */
- public long getOffset() { return offset; }
-
- /** PCFinder.LOW_CONFIDENCE or PCFinder.HIGH_CONFIDENCE */
- public int getConfidence() { return confidence; }
- }
-
- /** Passed loadobject may be null in which case the returned Info
- object has low confidence */
- public static Info findPC(Address pc, LoadObject lo, CDebugger dbg) {
- if (lo == null) {
- return new Info(null, -1, LOW_CONFIDENCE);
- }
-
- // First try debug info
- BlockSym sym = lo.debugInfoForPC(pc);
- while (sym != null) {
- if (sym.isFunction()) {
- // Highest confidence
- return new Info(sym.toString(), pc.minus(sym.getAddress()), HIGH_CONFIDENCE);
- }
- }
-
- // Now try looking up symbol in loadobject
-
- // FIXME: must add support for mapfiles on Win32 and try looking
- // up there first if possible. Should we hide that behind
- // LoadObject.closestSymbolToPC and have the ClosestSymbol return
- // confidence? I think so. On Solaris there is no notion of a
- // mapfile, and the confidence for closestSymbolToPC will be high
- // instead of low.
-
- int confidence = HIGH_CONFIDENCE;
-
- ClosestSymbol cs = lo.closestSymbolToPC(pc);
- if (cs != null) {
- // FIXME: currently low confidence (only on Win32)
- return new Info(cs.getName() + "()", cs.getOffset(), LOW_CONFIDENCE);
- }
-
- // Unknown location
- return new Info(dbg.getNameOfFile(lo.getName()).toUpperCase() +
- "! " + pc + "()", -1, HIGH_CONFIDENCE);
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/bugspot/PackageScanner.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.bugspot;
-
-import java.io.*;
-
-/** Scans a .java file for the package that it is in. */
-
-public class PackageScanner {
-
- public PackageScanner() {
- }
-
- public String scan(String filename) {
- return scan(new File(filename));
- }
-
- /** Returns the String comprising the package name of the classes in
- this .java file. Returns the (non-null) empty string if any
- error occurs or if the classes are in the unnamed package. */
- public String scan(File file) {
- BufferedReader buf = null;
- String res = "";
- try {
- buf = new BufferedReader(new FileReader(file));
- StreamTokenizer tok = new StreamTokenizer(buf);
- tok.slashStarComments(true);
- tok.slashSlashComments(true);
- if (tok.nextToken() != StreamTokenizer.TT_WORD) {
- return res;
- }
- if (!tok.sval.equals("package")) {
- return res;
- }
- if (tok.nextToken() != StreamTokenizer.TT_WORD) {
- return res;
- }
- res = tok.sval;
- return res;
- } catch (FileNotFoundException e) {
- return res;
- } catch (IOException e) {
- return res;
- } finally {
- try {
- if (buf != null) {
- buf.close();
- }
- } catch (IOException e) {
- }
- }
- }
-
- public static void main(String[] args) {
- if (args.length != 1) {
- usage();
- }
-
- System.out.println(new PackageScanner().scan(args[0]));
- }
-
- private static void usage() {
- System.err.println("Usage: java PackageScanner <.java file name>");
- System.err.println("Prints package the .java file is in to stdout.");
- System.exit(1);
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/bugspot/RegisterPanel.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,173 +0,0 @@
-/*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.bugspot;
-
-import java.awt.*;
-import java.util.*;
-import javax.swing.*;
-import javax.swing.table.*;
-
-import sun.jvm.hotspot.debugger.*;
-
-/** Displays registers in a window. FIXME: this will need more work to
- understand and handle register windows. */
-
-public class RegisterPanel extends JPanel {
- private java.util.List/*<RegisterInfo>*/ registers;
- private AbstractTableModel dataModel;
- private boolean valid;
- private boolean editable;
- private String nullAddressString;
- private ThreadProxy curThread;
- private JTable table;
-
- static class RegisterInfo {
- private String name;
- private Address value;
-
- RegisterInfo(String name, Address value) {
- this.name = name;
- this.value = value;
- }
-
- String getName() { return name; }
- Address getValue() { return value; }
- }
-
- public RegisterPanel() {
- super();
-
- registers = new ArrayList();
-
- dataModel = new AbstractTableModel() {
- public int getColumnCount() { return 2; }
- public int getRowCount() { return registers.size(); }
- public String getColumnName(int col) {
- switch (col) {
- case 0:
- return "Register Name";
- case 1:
- return "Register Value";
- default:
- throw new RuntimeException("Index " + col + " out of bounds");
- }
- }
- public Object getValueAt(int row, int col) {
- RegisterInfo info = (RegisterInfo) registers.get(row);
-
- switch (col) {
- case 0:
- return info.getName();
- case 1:
- if (valid) {
- Address val = info.getValue();
- if (val != null) {
- return val;
- } else {
- return nullAddressString;
- }
- } else {
- return "-";
- }
- default:
- throw new RuntimeException("Index (" + col + ", " + row + ") out of bounds");
- }
- }
- public boolean isCellEditable(int row, int col) {
- if (col == 0) return false;
- if (!valid) return false;
- if (curThread == null) return false;
- if (!curThread.canSetContext()) return false;
-
- // FIXME: add listener to watch for register changes
- // return true;
- return false;
- }
- };
-
- // Build user interface
- setLayout(new BorderLayout());
- table = new JTable(dataModel);
- table.setCellSelectionEnabled(true);
- table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
- table.setDragEnabled(true);
- JTableHeader header = table.getTableHeader();
- header.setReorderingAllowed(false);
- JScrollPane scrollPane = new JScrollPane(table);
- add(scrollPane, BorderLayout.CENTER);
- }
-
-
- /** Updates the register panel with the register set from the
- specified thread. Call this when the process has been suspended
- and the current thread has been set. FIXME: this interface will
- need to change to support register windows. */
- public void update(ThreadProxy curThread) {
- this.curThread = curThread;
- ThreadContext context = curThread.getContext();
- editable = curThread.canSetContext();
- registers.clear();
- for (int i = 0; i < context.getNumRegisters(); i++) {
- String name = context.getRegisterName(i);
- Address addr = context.getRegisterAsAddress(i);
- if ((nullAddressString == null) && (addr != null)) {
- String addrStr = addr.toString();
- StringBuffer buf = new StringBuffer();
- buf.append("0x");
- int len = addrStr.length() - 2;
- for (int j = 0; j < len; j++) {
- buf.append("0");
- }
- nullAddressString = buf.toString();
- }
- registers.add(new RegisterInfo(name, addr));
- }
- valid = true;
- SwingUtilities.invokeLater(new Runnable() {
- public void run() {
- dataModel.fireTableDataChanged();
- }
- });
- }
-
- /** Clears the registers' values. Call this when the processs has
- been resumed. */
- public void clear() {
- valid = false;
- nullAddressString = null;
- SwingUtilities.invokeLater(new Runnable() {
- public void run() {
- dataModel.fireTableDataChanged();
- }
- });
- }
-
- public void setFont(Font font) {
- super.setFont(font);
- if (table != null) {
- table.setFont(font);
- }
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/bugspot/StackTraceEntry.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-/*
- * Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.bugspot;
-
-import sun.jvm.hotspot.debugger.cdbg.*;
-import sun.jvm.hotspot.oops.*;
-import sun.jvm.hotspot.runtime.*;
-
-/** This class describes a frame in a stack trace. It abstracts over
- C/C++ and Java frames. */
-
-public class StackTraceEntry {
- private CFrame cFrame;
- private CDebugger dbg;
- private JavaVFrame javaFrame;
- private String value; // What is displayed in a stack trace
- // For merging C and Java stack traces.
- // For more precise stack traces, should probably have a way to
- // convert a CFrame to a sun.jvm.hotspot.runtime.Frame. For now,
- // doing similar algorithm to jdbx (which does not have intimate
- // knowledge of the VM).
- private boolean isUnknownCFrame;
-
- public StackTraceEntry(CFrame cFrame, CDebugger dbg) {
- this.cFrame = cFrame;
- this.dbg = dbg;
- computeValue();
- }
-
- public StackTraceEntry(JavaVFrame javaFrame) {
- this.javaFrame = javaFrame;
- computeValue();
- }
-
- public boolean isCFrame() { return (cFrame != null); }
- public boolean isJavaFrame() { return (javaFrame != null); }
- public CFrame getCFrame() { return cFrame; }
- public JavaVFrame getJavaFrame() { return javaFrame; }
- public boolean isUnknownCFrame() { return isUnknownCFrame; }
- public String toString() {
- return value;
- }
-
- private void computeValue() {
- isUnknownCFrame = true;
- value = "<unknown>";
- if (cFrame != null) {
- PCFinder.Info info = PCFinder.findPC(cFrame.pc(), cFrame.loadObjectForPC(), dbg);
- if (info.getName() != null) {
- value = "(C) " + info.getName();
- isUnknownCFrame = false;
- if (info.getConfidence() == PCFinder.LOW_CONFIDENCE) {
- value = value + " (?)";
- }
- if (info.getOffset() >= 0) {
- value = value + " + 0x" + Long.toHexString(info.getOffset());
- }
- }
- } else if (javaFrame != null) {
- isUnknownCFrame = false;
- Method m = javaFrame.getMethod();
- value = "(J) " + m.externalNameAndSignature();
- }
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/bugspot/StackTracePanel.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,115 +0,0 @@
-/*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.bugspot;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.util.*;
-import javax.swing.*;
-import sun.jvm.hotspot.debugger.cdbg.*;
-import sun.jvm.hotspot.runtime.*;
-import sun.jvm.hotspot.ui.*;
-
-/** This panel contains a ListBox with all of the stack frames in a
- given thread. When a given entry is selected, an event is
- fired. */
-
-public class StackTracePanel extends JPanel {
- public interface Listener {
- public void frameChanged(CFrame fr, JavaVFrame jfr);
- }
-
- class Model extends AbstractListModel implements ComboBoxModel {
- private Object selectedItem;
- public Object getElementAt(int index) {
- if (trace == null) return null;
- return trace.get(index);
- }
- public int getSize() {
- if (trace == null) return 0;
- return trace.size();
- }
- public Object getSelectedItem() {
- return selectedItem;
- }
- public void setSelectedItem(Object item) {
- selectedItem = item;
- }
- public void dataChanged() {
- fireContentsChanged(this, 0, trace.size());
- }
- }
-
- private java.util.List trace;
- private Model model;
- private JComboBox list;
- private java.util.List listeners;
-
- public StackTracePanel() {
- super();
-
- model = new Model();
-
- // Build user interface
- setLayout(new BorderLayout());
- setBorder(GraphicsUtilities.newBorder(5));
- list = new JComboBox(model);
- list.setPrototypeDisplayValue("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZ");
- add(list, BorderLayout.CENTER);
-
- // Add selection listener
- list.addItemListener(new ItemListener() {
- public void itemStateChanged(ItemEvent e) {
- if (e.getStateChange() == ItemEvent.SELECTED) {
- fireFrameChanged();
- }
- }
- });
- }
-
- /** Takes a List of StackTraceEntry objects */
- public void setTrace(java.util.List trace) {
- this.trace = trace;
- model.dataChanged();
- list.setSelectedIndex(0);
- fireFrameChanged();
- }
-
- public void addListener(Listener listener) {
- if (listeners == null) {
- listeners = new ArrayList();
- }
- listeners.add(listener);
- }
-
- protected void fireFrameChanged() {
- if (listeners != null) {
- StackTraceEntry entry = (StackTraceEntry) trace.get(list.getSelectedIndex());
- for (Iterator iter = listeners.iterator(); iter.hasNext(); ) {
- ((Listener) iter.next()).frameChanged(entry.getCFrame(), entry.getJavaFrame());
- }
- }
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/bugspot/ThreadListPanel.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,237 +0,0 @@
-/*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.bugspot;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.util.*;
-import javax.swing.*;
-import javax.swing.table.*;
-
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.cdbg.*;
-import sun.jvm.hotspot.runtime.*;
-import sun.jvm.hotspot.ui.*;
-
-// NOTE: this class was not placed in sun.jvm.hotspot.ui to prevent
-// mixing components designed for C and C++ debugging with the ones
-// that work with the core serviceability agent functionality (which
-// does not require that the CDebugger interface be implemented).
-
-/** The ThreadListPanel is used for C and C++ debugging and can
- visualize all threads in the target process. The caller passes in
- a CDebugger attached to the target process and can request that
- JavaThreads' associations with these underlying threads be
- displayed; this option is only valid when attached to a HotSpot
- JVM and when the {@link sun.jvm.hotspot.runtime.VM} has been
- initialized. */
-
-public class ThreadListPanel extends JPanel {
- /** Listener which can be added to receive "Set Focus" events */
- public static interface Listener {
- /** ThreadProxy will always be provided; JavaThread will only be
- present if displayJavaThreads was specified in the constructor
- for the panel and the thread was a JavaThread. */
- public void setFocus(ThreadProxy thread, JavaThread jthread);
- }
-
- static class ThreadInfo {
- private ThreadProxy thread;
- // Distinguish between PC == null and no top frame
- private boolean gotPC;
- private Address pc;
- private String location;
- private JavaThread javaThread;
- private String javaThreadName;
-
- public ThreadInfo(ThreadProxy thread, CDebugger dbg, JavaThread jthread) {
- this.thread = thread;
- this.location = "<unknown>";
- CFrame fr = dbg.topFrameForThread(thread);
- if (fr != null) {
- gotPC = true;
- pc = fr.pc();
- PCFinder.Info info = PCFinder.findPC(pc, fr.loadObjectForPC(), dbg);
- if (info.getName() != null) {
- location = info.getName();
- if (info.getConfidence() == PCFinder.LOW_CONFIDENCE) {
- location = location + " (?)";
- }
- if (info.getOffset() < 0) {
- location = location + " + 0x" + Long.toHexString(info.getOffset());
- }
- }
- }
- if (jthread != null) {
- javaThread = jthread;
- javaThreadName = jthread.getThreadName();
- }
- }
-
- public ThreadProxy getThread() { return thread; }
- public boolean hasPC() { return gotPC; }
- public Address getPC() { return pc; }
- public String getLocation() { return location; }
- public boolean isJavaThread() { return (javaThread != null); }
- public JavaThread getJavaThread() { return javaThread; }
- public String getJavaThreadName() { return javaThreadName; }
- }
-
- // List<ThreadInfo>
- private java.util.List threadList;
- private JTable table;
- private AbstractTableModel dataModel;
- // List<Listener>
- private java.util.List listeners;
-
- /** Takes a CDebugger from which the thread list is queried.
- displayJavaThreads must only be set to true if the debugger is
- attached to a HotSpot JVM and if the VM has already been
- initialized. */
- public ThreadListPanel(CDebugger dbg, final boolean displayJavaThreads) {
- super();
-
- Map threadToJavaThreadMap = null;
- if (displayJavaThreads) {
- // Collect Java threads from virtual machine and insert them in
- // table for later querying
- threadToJavaThreadMap = new HashMap();
- Threads threads = VM.getVM().getThreads();
- for (JavaThread thr = threads.first(); thr != null; thr = thr.next()) {
- threadToJavaThreadMap.put(thr.getThreadProxy(), thr);
- }
- }
-
- java.util.List/*<ThreadProxy>*/ threads = dbg.getThreadList();
- threadList = new ArrayList(threads.size());
- for (Iterator iter = threads.iterator(); iter.hasNext(); ) {
- ThreadProxy thr = (ThreadProxy) iter.next();
- JavaThread jthr = null;
- if (displayJavaThreads) {
- jthr = (JavaThread) threadToJavaThreadMap.get(thr);
- }
- threadList.add(new ThreadInfo(thr, dbg, jthr));
- }
-
- // Thread ID, current PC, current symbol, Java Thread, [Java thread name]
- dataModel = new AbstractTableModel() {
- public int getColumnCount() { return (displayJavaThreads ? 5 : 3); }
- public int getRowCount() { return threadList.size(); }
- public String getColumnName(int col) {
- switch (col) {
- case 0:
- return "Thread ID";
- case 1:
- return "PC";
- case 2:
- return "Location";
- case 3:
- return "Java?";
- case 4:
- return "Java Thread Name";
- default:
- throw new RuntimeException("Index " + col + " out of bounds");
- }
- }
- public Object getValueAt(int row, int col) {
- ThreadInfo info = (ThreadInfo) threadList.get(row);
-
- switch (col) {
- case 0:
- return info.getThread();
- case 1:
- {
- if (info.hasPC()) {
- return info.getPC();
- }
- return "<no frames on stack>";
- }
- case 2:
- return info.getLocation();
- case 3:
- if (info.isJavaThread()) {
- return "Yes";
- } else {
- return "";
- }
- case 4:
- if (info.isJavaThread()) {
- return info.getJavaThreadName();
- } else {
- return "";
- }
- default:
- throw new RuntimeException("Index (" + col + ", " + row + ") out of bounds");
- }
- }
- };
-
- // Build user interface
- setLayout(new BorderLayout());
- table = new JTable(dataModel);
- table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
- JTableHeader header = table.getTableHeader();
- header.setReorderingAllowed(false);
- table.setRowSelectionAllowed(true);
- table.setColumnSelectionAllowed(false);
- JScrollPane scrollPane = new JScrollPane(table);
- add(scrollPane, BorderLayout.CENTER);
- if (threadList.size() > 0) {
- table.setRowSelectionInterval(0, 0);
- }
-
- JButton button = new JButton("Set Focus");
- button.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- int i = table.getSelectedRow();
- if (i < 0) {
- return;
- }
- ThreadInfo info = (ThreadInfo) threadList.get(i);
- for (Iterator iter = listeners.iterator(); iter.hasNext(); ) {
- ((Listener) iter.next()).setFocus(info.getThread(), info.getJavaThread());
- }
- }
- });
- JPanel focusPanel = new JPanel();
- focusPanel.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0));
- focusPanel.setLayout(new BoxLayout(focusPanel, BoxLayout.Y_AXIS));
- focusPanel.add(Box.createGlue());
- focusPanel.add(button);
- focusPanel.add(Box.createGlue());
- add(focusPanel, BorderLayout.EAST);
-
- // FIXME: make listener model for the debugger so if the user
- // specifies a mapfile for or path to a given DSO later we can
- // update our state
- }
-
- public void addListener(Listener l) {
- if (listeners == null) {
- listeners = new ArrayList();
- }
- listeners.add(l);
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/bugspot/VariablePanel.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,252 +0,0 @@
-/*
- * Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.bugspot;
-
-import java.awt.*;
-import javax.swing.*;
-import java.util.*;
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.cdbg.*;
-import sun.jvm.hotspot.bugspot.tree.*;
-import sun.jvm.hotspot.oops.*;
-import sun.jvm.hotspot.runtime.*;
-import sun.jvm.hotspot.ui.tree.*;
-import sun.jvm.hotspot.ui.treetable.*;
-
-/** Manages display of a set of local variables in a frame, or the
- contents of the "this" pointer */
-
-public class VariablePanel extends JPanel {
- private JTreeTable treeTable;
- private SimpleTreeTableModel model;
- private SimpleTreeGroupNode root;
-
- public VariablePanel() {
- super();
-
- model = new SimpleTreeTableModel();
- model.setValuesEditable(false);
- root = new SimpleTreeGroupNode();
- model.setRoot(root);
- treeTable = new JTreeTable(model);
- treeTable.setRootVisible(false);
- treeTable.setShowsRootHandles(true);
- treeTable.setShowsIcons(false);
- treeTable.setTreeEditable(false);
- treeTable.getTableHeader().setReorderingAllowed(false);
- treeTable.setCellSelectionEnabled(true);
- treeTable.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
- treeTable.setDragEnabled(true);
- JScrollPane sp = new JScrollPane(treeTable);
- sp.getViewport().setBackground(Color.white);
-
- setLayout(new BorderLayout());
- add(sp, BorderLayout.CENTER);
- }
-
- /** Clear the contents of this VariablePanel */
- public void clear() {
- root.removeAllChildren();
- model.fireTreeStructureChanged();
- }
-
- /** Update the contents of this VariablePanel from the given CFrame */
- public void update(CFrame fr) {
- // Collect locals
- CCollector coll = new CCollector();
- fr.iterateLocals(coll);
- update(coll);
- }
-
- /** Update the contents of this VariablePanel from the given JavaVFrame */
- public void update(JavaVFrame jfr) {
- Method m = jfr.getMethod();
- if (!m.hasLocalVariableTable()) {
- return;
- }
- int bci = jfr.getBCI();
- // Get local variable table
- LocalVariableTableElement[] locals = m.getLocalVariableTable();
- // Get locals as StackValueCollection
- StackValueCollection coll = jfr.getLocals();
- root.removeAllChildren();
- // See which locals are live
- for (int i = 0; i < locals.length; i++) {
- LocalVariableTableElement local = locals[i];
- if (local.getStartBCI() <= bci && bci < local.getStartBCI() + local.getLength()) {
- // Valid; add it
- SimpleTreeNode node = null;
- Symbol name = null;
- try {
- name = m.getConstants().getSymbolAt(local.getNameCPIndex());
- if (name == null) {
- System.err.println("Null name at slot " +
- local.getNameCPIndex() +
- " for local variable at slot " +
- local.getSlot());
- continue;
- }
- } catch (Exception e) {
- System.err.println("Unable to fetch name at slot " +
- local.getNameCPIndex() +
- " for local variable at slot " +
- local.getSlot());
- e.printStackTrace();
- continue;
- }
- sun.jvm.hotspot.oops.NamedFieldIdentifier f =
- new sun.jvm.hotspot.oops.NamedFieldIdentifier(name.asString());
- Symbol descriptor = null;
- try {
- descriptor = m.getConstants().getSymbolAt(local.getDescriptorCPIndex());
- } catch (Exception e) {
- System.err.println("Unable to fetch descriptor at slot " +
- local.getDescriptorCPIndex() +
- " for local variable " + f.getName() +
- " at slot " + local.getSlot());
- e.printStackTrace();
- continue;
- }
-
- if (descriptor != null) {
- switch (descriptor.getByteAt(0)) {
- case 'F': {
- node = new sun.jvm.hotspot.ui.tree.FloatTreeNodeAdapter(coll.floatAt(local.getSlot()), f, true);
- break;
- }
- case 'D': {
- node = new sun.jvm.hotspot.ui.tree.DoubleTreeNodeAdapter(coll.doubleAt(local.getSlot()), f, true);
- break;
- }
- case 'C': {
- node = new sun.jvm.hotspot.ui.tree.CharTreeNodeAdapter((char) coll.intAt(local.getSlot()), f, true);
- break;
- }
- case 'B':
- case 'S':
- case 'I': {
- node = new sun.jvm.hotspot.ui.tree.LongTreeNodeAdapter(coll.intAt(local.getSlot()), f, true);
- break;
- }
- case 'Z': {
- node = new sun.jvm.hotspot.ui.tree.BooleanTreeNodeAdapter(
- ((coll.intAt(local.getSlot()) != 0) ? true : false), f, true
- );
- break;
- }
- case 'J': {
- node = new sun.jvm.hotspot.ui.tree.LongTreeNodeAdapter(coll.longAt(local.getSlot()), f, true);
- break;
- }
- default: {
- try {
- node = new sun.jvm.hotspot.ui.tree.OopTreeNodeAdapter(
- VM.getVM().getObjectHeap().newOop(coll.oopHandleAt(local.getSlot())), f, true
- );
- } catch (AddressException e) {
- node = new sun.jvm.hotspot.ui.tree.FieldTreeNodeAdapter(f, true) {
- public int getChildCount() { return 0; }
- public SimpleTreeNode getChild(int i) { return null; }
- public boolean isLeaf() { return false; }
- public int getIndexOfChild(SimpleTreeNode child) { return 0; }
- public String getValue() {
- return "<Bad oop>";
- }
- };
- }
- break;
- }
- }
- if (node != null) {
- root.addChild(node);
- }
- }
- }
- }
-
- model.fireTreeStructureChanged();
- }
-
- /** Update the contents of this VariablePanel from the given "this"
- pointer of the given type */
- public void update(Address thisAddr, Type type) {
- // Collect fields
- CCollector coll = new CCollector();
- type.iterateObject(thisAddr, coll);
- update(coll);
- }
-
- private void update(CCollector coll) {
- root.removeAllChildren();
- for (int i = 0; i < coll.getNumChildren(); i++) {
- root.addChild(coll.getChild(i));
- }
- model.fireTreeStructureChanged();
- }
-
- static class CCollector extends DefaultObjectVisitor {
- private java.util.List children;
-
- public CCollector() {
- children = new ArrayList();
- }
-
- public int getNumChildren() {
- return children.size();
- }
-
- public SimpleTreeNode getChild(int i) {
- return (SimpleTreeNode) children.get(i);
- }
-
- public void doBit(sun.jvm.hotspot.debugger.cdbg.FieldIdentifier f, long val) {
- children.add(new sun.jvm.hotspot.bugspot.tree.LongTreeNodeAdapter(val, f, true));
- }
- public void doInt(sun.jvm.hotspot.debugger.cdbg.FieldIdentifier f, long val) {
- children.add(new sun.jvm.hotspot.bugspot.tree.LongTreeNodeAdapter(val, f, true));
- }
- public void doEnum(sun.jvm.hotspot.debugger.cdbg.FieldIdentifier f, long val, String enumName) {
- children.add(new sun.jvm.hotspot.bugspot.tree.EnumTreeNodeAdapter(enumName, val, f, true));
- }
- public void doFloat(sun.jvm.hotspot.debugger.cdbg.FieldIdentifier f, float val) {
- children.add(new sun.jvm.hotspot.bugspot.tree.FloatTreeNodeAdapter(val, f, true));
- }
- public void doDouble(sun.jvm.hotspot.debugger.cdbg.FieldIdentifier f, double val) {
- children.add(new sun.jvm.hotspot.bugspot.tree.DoubleTreeNodeAdapter(val, f, true));
- }
- public void doPointer(sun.jvm.hotspot.debugger.cdbg.FieldIdentifier f, Address val) {
- children.add(new sun.jvm.hotspot.bugspot.tree.AddressTreeNodeAdapter(val, f, true));
- }
- public void doArray(sun.jvm.hotspot.debugger.cdbg.FieldIdentifier f, Address val) {
- children.add(new sun.jvm.hotspot.bugspot.tree.AddressTreeNodeAdapter(val, f, true));
- }
- public void doRef(sun.jvm.hotspot.debugger.cdbg.FieldIdentifier f, Address val) {
- children.add(new sun.jvm.hotspot.bugspot.tree.AddressTreeNodeAdapter(val, f, true));
- }
- public void doCompound(sun.jvm.hotspot.debugger.cdbg.FieldIdentifier f, Address val) {
- children.add(new sun.jvm.hotspot.bugspot.tree.ObjectTreeNodeAdapter(val, f, true));
- }
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/bugspot/tree/AddressTreeNodeAdapter.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.bugspot.tree;
-
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.cdbg.*;
-import sun.jvm.hotspot.ui.tree.SimpleTreeNode;
-
-/** Encapsulates a float value in a tree handled by SimpleTreeModel */
-
-public class AddressTreeNodeAdapter extends FieldTreeNodeAdapter {
- private Address val;
-
- public AddressTreeNodeAdapter(Address val, FieldIdentifier id) {
- this(val, id, false);
- }
-
- public AddressTreeNodeAdapter(Address val, FieldIdentifier id, boolean treeTableMode) {
- super(id, treeTableMode);
- this.val = val;
- }
-
- public int getChildCount() {
- return 0;
- }
-
- public SimpleTreeNode getChild(int index) {
- return null;
- }
-
- public boolean isLeaf() {
- return true;
- }
-
- public int getIndexOfChild(SimpleTreeNode child) {
- return 0;
- }
-
- public String getValue() {
- if (val != null) {
- return val.toString();
- }
- return "NULL";
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/bugspot/tree/DoubleTreeNodeAdapter.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.bugspot.tree;
-
-import sun.jvm.hotspot.debugger.cdbg.*;
-import sun.jvm.hotspot.ui.tree.SimpleTreeNode;
-
-/** Encapsulates a double value in a tree handled by SimpleTreeModel */
-
-public class DoubleTreeNodeAdapter extends FieldTreeNodeAdapter {
- private double val;
-
- public DoubleTreeNodeAdapter(double val, FieldIdentifier id) {
- this(val, id, false);
- }
-
- public DoubleTreeNodeAdapter(double val, FieldIdentifier id, boolean treeTableMode) {
- super(id, treeTableMode);
- this.val = val;
- }
-
- public int getChildCount() {
- return 0;
- }
-
- public SimpleTreeNode getChild(int index) {
- return null;
- }
-
- public boolean isLeaf() {
- return true;
- }
-
- public int getIndexOfChild(SimpleTreeNode child) {
- return 0;
- }
-
- public String getValue() {
- return Double.toString(val);
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/bugspot/tree/EnumTreeNodeAdapter.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.bugspot.tree;
-
-import sun.jvm.hotspot.debugger.cdbg.*;
-import sun.jvm.hotspot.ui.tree.SimpleTreeNode;
-
-/** Encapsulates an enumerated value in a tree handled by SimpleTreeModel */
-
-public class EnumTreeNodeAdapter extends FieldTreeNodeAdapter {
- private long val;
- private String enumName;
-
- public EnumTreeNodeAdapter(String enumName, long val, FieldIdentifier id) {
- this(enumName, val, id, false);
- }
-
- public EnumTreeNodeAdapter(String enumName, long val, FieldIdentifier id, boolean treeTableMode) {
- super(id, treeTableMode);
- this.enumName = enumName;
- this.val = val;
- }
-
- public int getChildCount() {
- return 0;
- }
-
- public SimpleTreeNode getChild(int index) {
- return null;
- }
-
- public boolean isLeaf() {
- return true;
- }
-
- public int getIndexOfChild(SimpleTreeNode child) {
- return 0;
- }
-
- public String getValue() {
- if (enumName != null) {
- return enumName;
- } else {
- return Long.toString(val);
- }
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/bugspot/tree/FieldTreeNodeAdapter.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.bugspot.tree;
-
-import sun.jvm.hotspot.debugger.cdbg.*;
-import sun.jvm.hotspot.ui.tree.SimpleTreeNode;
-
-/** Abstract base class for all adapters for fields of C/C++ objects */
-
-public abstract class FieldTreeNodeAdapter implements SimpleTreeNode {
- private FieldIdentifier id;
- private boolean treeTableMode;
-
- /** The identifier may be null, i.e., for the root of the tree */
- public FieldTreeNodeAdapter(FieldIdentifier id, boolean treeTableMode) {
- this.id = id;
- this.treeTableMode = treeTableMode;
- }
-
- public FieldIdentifier getID() {
- return id;
- }
-
- /** Defaults to false in subclasses */
- public boolean getTreeTableMode() {
- return treeTableMode;
- }
-
- public Type getType() {
- return getID().getType();
- }
-
- public String getName() {
- if (getID() != null) {
- return getID().toString();
- }
- return "";
- }
-
- public String toString() {
- if (treeTableMode) {
- return getName();
- } else {
- if (getID() != null) {
- return getName() + ": " + getValue();
- } else {
- return getValue();
- }
- }
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/bugspot/tree/FloatTreeNodeAdapter.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.bugspot.tree;
-
-import sun.jvm.hotspot.debugger.cdbg.*;
-import sun.jvm.hotspot.ui.tree.SimpleTreeNode;
-
-/** Encapsulates a float value in a tree handled by SimpleTreeModel */
-
-public class FloatTreeNodeAdapter extends FieldTreeNodeAdapter {
- private float val;
-
- public FloatTreeNodeAdapter(float val, FieldIdentifier id) {
- this(val, id, false);
- }
-
- public FloatTreeNodeAdapter(float val, FieldIdentifier id, boolean treeTableMode) {
- super(id, treeTableMode);
- this.val = val;
- }
-
- public int getChildCount() {
- return 0;
- }
-
- public SimpleTreeNode getChild(int index) {
- return null;
- }
-
- public boolean isLeaf() {
- return true;
- }
-
- public int getIndexOfChild(SimpleTreeNode child) {
- return 0;
- }
-
- public String getValue() {
- return Float.toString(val);
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/bugspot/tree/LongTreeNodeAdapter.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.bugspot.tree;
-
-import sun.jvm.hotspot.debugger.cdbg.*;
-import sun.jvm.hotspot.ui.tree.SimpleTreeNode;
-
-/** Encapsulates a long value in a tree handled by SimpleTreeModel */
-
-public class LongTreeNodeAdapter extends FieldTreeNodeAdapter {
- private long val;
-
- public LongTreeNodeAdapter(long val, FieldIdentifier id) {
- this(val, id, false);
- }
-
- public LongTreeNodeAdapter(long val, FieldIdentifier id, boolean treeTableMode) {
- super(id, treeTableMode);
- this.val = val;
- }
-
- public int getChildCount() {
- return 0;
- }
-
- public SimpleTreeNode getChild(int index) {
- return null;
- }
-
- public boolean isLeaf() {
- return true;
- }
-
- public int getIndexOfChild(SimpleTreeNode child) {
- return 0;
- }
-
- public String getValue() {
- return Long.toString(val);
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/bugspot/tree/ObjectTreeNodeAdapter.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,216 +0,0 @@
-/*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.bugspot.tree;
-
-import java.io.*;
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.cdbg.*;
-import sun.jvm.hotspot.ui.tree.SimpleTreeNode;
-
-/** An adapter class which allows C/C++ objects to be displayed in a
- tree via the SimpleTreeNode interface. */
-
-public class ObjectTreeNodeAdapter extends FieldTreeNodeAdapter {
- // Address of object
- private Address addr;
-
- /** The address may be null (for object fields of objcets which are
- null). The FieldIdentifier should not be null. treeTableMode
- defaults to false. */
- public ObjectTreeNodeAdapter(Address addr, FieldIdentifier id) {
- this(addr, id, false);
- }
-
- /** The address may be null (for object fields of objcets which are
- null). The FieldIdentifier should not be null. */
- public ObjectTreeNodeAdapter(Address addr, FieldIdentifier id, boolean treeTableMode) {
- super(id, treeTableMode);
- this.addr = addr;
- }
-
- public int getChildCount() {
- if (addr == null) {
- return 0;
- }
-
- Counter c = new Counter();
- getType().iterateObject(addr, c);
- return c.getNumFields();
- }
-
- public SimpleTreeNode getChild(int index) {
- if (addr == null) {
- return null;
- }
-
- Fetcher f = new Fetcher(index);
- getType().iterateObject(addr, f);
- return f.getChild();
- }
-
- public boolean isLeaf() {
- return (addr == null);
- }
-
- public int getIndexOfChild(SimpleTreeNode child) {
- FieldIdentifier id = ((FieldTreeNodeAdapter) child).getID();
- Finder f = new Finder(id);
- getType().iterateObject(addr, f);
- return f.getIndex();
- }
-
- public String getValue() {
- if (addr != null) {
- return addr.toString();
- }
- return "NULL";
- }
-
- /** Should be used only once, then have the number of fields
- fetched. */
- static class Counter extends DefaultObjectVisitor {
- private int numFields;
-
- public int getNumFields() {
- return numFields;
- }
-
- public void doBit(FieldIdentifier f, long val) { ++numFields; }
- public void doInt(FieldIdentifier f, long val) { ++numFields; }
- public void doEnum(FieldIdentifier f, long val, String enumName) { ++numFields; }
- public void doFloat(FieldIdentifier f, float val) { ++numFields; }
- public void doDouble(FieldIdentifier f, double val) { ++numFields; }
- public void doPointer(FieldIdentifier f, Address val) { ++numFields; }
- public void doArray(FieldIdentifier f, Address val) { ++numFields; }
- public void doRef(FieldIdentifier f, Address val) { ++numFields; }
- public void doCompound(FieldIdentifier f, Address addr) { ++numFields; }
- }
-
- /** Creates a new SimpleTreeNode for the given field. */
- class Fetcher extends DefaultObjectVisitor {
- private int index;
- private int curField;
- private SimpleTreeNode child;
-
- public Fetcher(int index) {
- this.index = index;
- }
-
- public SimpleTreeNode getChild() {
- return child;
- }
-
- public void doBit(FieldIdentifier f, long val) {
- if (curField == index) {
- child = new LongTreeNodeAdapter(val, f, getTreeTableMode());
- }
- ++curField;
- }
-
- public void doInt(FieldIdentifier f, long val) {
- if (curField == index) {
- child = new LongTreeNodeAdapter(val, f, getTreeTableMode());
- }
- ++curField;
- }
-
- public void doEnum(FieldIdentifier f, long val, String enumName) {
- if (curField == index) {
- child = new EnumTreeNodeAdapter(enumName, val, f, getTreeTableMode());
- }
- ++curField;
- }
-
- public void doFloat(FieldIdentifier f, float val) {
- if (curField == index) {
- child = new FloatTreeNodeAdapter(val, f, getTreeTableMode());
- }
- ++curField;
- }
-
- public void doDouble(FieldIdentifier f, double val) {
- if (curField == index) {
- child = new DoubleTreeNodeAdapter(val, f, getTreeTableMode());
- }
- ++curField;
- }
-
- public void doPointer(FieldIdentifier f, Address val) {
- if (curField == index) {
- child = new AddressTreeNodeAdapter(val, f, getTreeTableMode());
- }
- ++curField;
- }
-
- public void doArray(FieldIdentifier f, Address val) {
- if (curField == index) {
- child = new AddressTreeNodeAdapter(val, f, getTreeTableMode());
- }
- ++curField;
- }
-
- public void doRef(FieldIdentifier f, Address val) {
- if (curField == index) {
- child = new AddressTreeNodeAdapter(val, f, getTreeTableMode());
- }
- ++curField;
- }
-
- public void doCompound(FieldIdentifier f, Address val) {
- if (curField == index) {
- child = new ObjectTreeNodeAdapter(val, f, getTreeTableMode());
- }
- ++curField;
- }
- }
-
- /** Finds the index of the given FieldIdentifier. */
- static class Finder extends DefaultObjectVisitor {
- private FieldIdentifier id;
- private int curField;
- private int index = -1;
-
- public Finder(FieldIdentifier id) {
- this.id = id;
- }
-
- /** Returns -1 if not found */
- public int getIndex() {
- return index;
- }
-
- public void doBit(FieldIdentifier f, long val) { if (f.equals(id)) { index = curField; } ++curField; }
- public void doInt(FieldIdentifier f, long val) { if (f.equals(id)) { index = curField; } ++curField; }
- public void doEnum(FieldIdentifier f, long val,
- String enumName) { if (f.equals(id)) { index = curField; } ++curField; }
- public void doFloat(FieldIdentifier f, float val) { if (f.equals(id)) { index = curField; } ++curField; }
- public void doDouble(FieldIdentifier f, double val) { if (f.equals(id)) { index = curField; } ++curField; }
- public void doPointer(FieldIdentifier f, Address val) { if (f.equals(id)) { index = curField; } ++curField; }
- public void doArray(FieldIdentifier f, Address val) { if (f.equals(id)) { index = curField; } ++curField; }
- public void doRef(FieldIdentifier f, Address val) { if (f.equals(id)) { index = curField; } ++curField; }
- public void doCompound(FieldIdentifier f,
- Address val) { if (f.equals(id)) { index = curField; } ++curField; }
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/amd64/LinuxAMD64CFrame.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/amd64/LinuxAMD64CFrame.java Fri Mar 15 16:39:07 2013 -0700
@@ -60,8 +60,13 @@
return null;
}
+ // Check alignment of rbp
+ if ( dbg.getAddressValue(rbp) % ADDRESS_SIZE != 0) {
+ return null;
+ }
+
Address nextRBP = rbp.getAddressAt( 0 * ADDRESS_SIZE);
- if (nextRBP == null) {
+ if (nextRBP == null || nextRBP.lessThanOrEqual(rbp)) {
return null;
}
Address nextPC = rbp.getAddressAt( 1 * ADDRESS_SIZE);
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/x86/LinuxX86CFrame.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/x86/LinuxX86CFrame.java Fri Mar 15 16:39:07 2013 -0700
@@ -61,8 +61,13 @@
return null;
}
+ // Check alignment of ebp
+ if ( dbg.getAddressValue(ebp) % ADDRESS_SIZE != 0) {
+ return null;
+ }
+
Address nextEBP = ebp.getAddressAt( 0 * ADDRESS_SIZE);
- if (nextEBP == null) {
+ if (nextEBP == null || nextEBP.lessThanOrEqual(ebp)) {
return null;
}
Address nextPC = ebp.getAddressAt( 1 * ADDRESS_SIZE);
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/livejvm/BreakpointEvent.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.livejvm;
-
-import sun.jvm.hotspot.oops.*;
-import sun.jvm.hotspot.runtime.*;
-
-public class BreakpointEvent extends Event {
- private Oop thread;
- private Oop clazz;
- private JNIid method;
- private int location;
-
- public BreakpointEvent(Oop thread,
- Oop clazz,
- JNIid method,
- int location) {
- super(Event.Type.BREAKPOINT);
- this.thread = thread;
- this.clazz = clazz;
- this.method = method;
- this.location = location;
- }
-
- public Oop thread() { return thread; }
- public Oop clazz() { return clazz; }
- public JNIid methodID() { return method; }
- public int location() { return location; }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/livejvm/CIntegerAccessor.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.livejvm;
-
-import sun.jvm.hotspot.debugger.*;
-
-class CIntegerAccessor {
- private Address addr;
- private long numBytes;
- private boolean isUnsigned;
-
- CIntegerAccessor(Address addr, long numBytes, boolean isUnsigned) {
- this.addr = addr;
- this.numBytes = numBytes;
- this.isUnsigned = isUnsigned;
- }
-
- long getValue() {
- return addr.getCIntegerAt(0, numBytes, isUnsigned);
- }
-
- void setValue(long value) {
- addr.setCIntegerAt(0, numBytes, value);
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/livejvm/CStringAccessor.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.livejvm;
-
-import java.io.UnsupportedEncodingException;
-import sun.jvm.hotspot.debugger.*;
-
-class CStringAccessor {
- private Address addr;
- private int bufLen;
-
- CStringAccessor(Address addr, int bufLen) {
- this.addr = addr;
- this.bufLen = bufLen;
- }
-
- String getValue() throws DebuggerException {
- int len = 0;
- while ((addr.getCIntegerAt(len, 1, true) != 0) && (len < bufLen)) {
- ++len;
- }
- byte[] res = new byte[len];
- for (int i = 0; i < len; i++) {
- res[i] = (byte) addr.getCIntegerAt(i, 1, true);
- }
- try {
- return new String(res, "US-ASCII");
- } catch (UnsupportedEncodingException e) {
- throw new DebuggerException("Unable to use US-ASCII encoding");
- }
- }
-
- void setValue(String value) throws DebuggerException {
- try {
- byte[] data = value.getBytes("US-ASCII");
- if (data.length >= bufLen) {
- throw new DebuggerException("String too long");
- }
- for (int i = 0; i < data.length; i++) {
- addr.setCIntegerAt(i, 1, data[i]);
- }
- addr.setCIntegerAt(data.length, 1, 0);
- } catch (UnsupportedEncodingException e) {
- throw new DebuggerException("Unable to use US-ASCII encoding");
- }
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/livejvm/Event.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.livejvm;
-
-public class Event {
- public static class Type {
- private Type() {}
- public static final Type BREAKPOINT = new Type();
- public static final Type EXCEPTION = new Type();
- }
-
- private Type type;
-
- public Event(Type type) {
- this.type = type;
- }
-
- public Type getType() { return type; }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/livejvm/ExceptionEvent.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.livejvm;
-
-import sun.jvm.hotspot.oops.*;
-import sun.jvm.hotspot.runtime.*;
-
-public class ExceptionEvent extends Event {
- private Oop thread;
- private Oop clazz;
- private JNIid method;
- private int location;
- private Oop exception;
- private Oop catchClass;
- private JNIid catchMethod;
- private int catchLocation;
-
- public ExceptionEvent(Oop thread,
- Oop clazz,
- JNIid method,
- int location,
- Oop exception,
- Oop catchClass,
- JNIid catchMethod,
- int catchLocation) {
- super(Event.Type.EXCEPTION);
- this.thread = thread;
- this.clazz = clazz;
- this.method = method;
- this.location = location;
- this.exception = exception;
- this.catchClass = catchClass;
- this.catchMethod = catchMethod;
- this.catchLocation = catchLocation;
- }
-
- public Oop thread() { return thread; }
- public Oop clazz() { return clazz; }
- public JNIid methodID() { return method; }
- public int location() { return location; }
- public Oop exception() { return exception; }
- public Oop catchClass() { return catchClass; }
- public JNIid catchMethodID() { return catchMethod; }
- public int catchLocation() { return catchLocation; }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/livejvm/JNIHandleAccessor.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.livejvm;
-
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.oops.*;
-import sun.jvm.hotspot.utilities.*;
-
-class JNIHandleAccessor {
- private Address addr;
- private ObjectHeap heap;
-
- JNIHandleAccessor(Address addr, ObjectHeap heap) {
- this.addr = addr;
- this.heap = heap;
- }
-
- Oop getValue() {
- // Accessing the contents of the JNIHandle is a double dereference
- Address handle = addr.getAddressAt(0);
- if (handle == null) return null;
- return heap.newOop(handle.getOopHandleAt(0));
- }
-
- void setValue(Oop value) {
- Address handle = addr.getAddressAt(0);
- if (Assert.ASSERTS_ENABLED) {
- Assert.that(handle != null, "Must have valid global JNI handle for setting");
- }
- handle.setOopHandleAt(0, value.getHandle());
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/livejvm/ServiceabilityAgentJVMDIModule.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,415 +0,0 @@
-/*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.livejvm;
-
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.oops.*;
-import sun.jvm.hotspot.runtime.*;
-
-/** Provides Java programming language-level interaction with a live
- Java HotSpot VM via the use of the SA's JVMDI module. This is an
- experimental mechanism. The BugSpot debugger should be converted
- to use the JVMDI/JDWP-based JDI implementation for live process
- interaction once the JDI binding for the SA is complete. */
-
-public class ServiceabilityAgentJVMDIModule {
- private Debugger dbg;
- private String[] saLibNames;
- private String saLibName;
- private boolean attached;
-
- private boolean suspended;
-
- private static final int JVMDI_EVENT_BREAKPOINT = 2;
- private static final int JVMDI_EVENT_EXCEPTION = 4;
-
- private static long timeoutMillis = 3000;
-
- // Values in target process
- // Events sent from VM to SA
- private CIntegerAccessor saAttached;
- private CIntegerAccessor saEventPending;
- private CIntegerAccessor saEventKind;
- // Exception events
- private JNIHandleAccessor saExceptionThread;
- private JNIHandleAccessor saExceptionClass;
- private JNIid saExceptionMethod;
- private CIntegerAccessor saExceptionLocation;
- private JNIHandleAccessor saExceptionException;
- private JNIHandleAccessor saExceptionCatchClass;
- private JNIid saExceptionCatchMethod;
- private CIntegerAccessor saExceptionCatchLocation;
- // Breakpoint events
- private JNIHandleAccessor saBreakpointThread;
- private JNIHandleAccessor saBreakpointClass;
- private JNIid saBreakpointMethod;
- private CIntegerAccessor saBreakpointLocation;
- // Commands sent by the SA to the VM
- private int SA_CMD_SUSPEND_ALL;
- private int SA_CMD_RESUME_ALL;
- private int SA_CMD_TOGGLE_BREAKPOINT;
- private int SA_CMD_BUF_SIZE;
- private CIntegerAccessor saCmdPending;
- private CIntegerAccessor saCmdType;
- private CIntegerAccessor saCmdResult;
- private CStringAccessor saCmdResultErrMsg;
- // Toggle breakpoint command arguments
- private CStringAccessor saCmdBkptSrcFileName;
- private CStringAccessor saCmdBkptPkgName;
- private CIntegerAccessor saCmdBkptLineNumber;
- private CIntegerAccessor saCmdBkptResWasError;
- private CIntegerAccessor saCmdBkptResLineNumber;
- private CIntegerAccessor saCmdBkptResBCI;
- private CIntegerAccessor saCmdBkptResWasSet;
- private CStringAccessor saCmdBkptResMethodName;
- private CStringAccessor saCmdBkptResMethodSig;
-
- public ServiceabilityAgentJVMDIModule(Debugger dbg, String[] saLibNames) {
- this.dbg = dbg;
- this.saLibNames = saLibNames;
- }
-
- /** Indicates whether a call to attach() should complete without an
- exception. */
- public boolean canAttach() {
- return setupLookup("SA_CMD_SUSPEND_ALL");
- }
-
- /** Attempt to initiate a connection with the JVMDI module in the
- target VM. */
- public void attach() throws DebuggerException {
- if (!canAttach()) {
- throw new DebuggerException("Unable to initiate symbol lookup in SA's JVMDI module");
- }
-
- if (attached) {
- throw new DebuggerException("Already attached");
- }
-
- // Attempt to look up well-known symbols in the target VM.
- SA_CMD_SUSPEND_ALL = lookupConstInt("SA_CMD_SUSPEND_ALL");
- SA_CMD_RESUME_ALL = lookupConstInt("SA_CMD_RESUME_ALL");
- SA_CMD_TOGGLE_BREAKPOINT = lookupConstInt("SA_CMD_TOGGLE_BREAKPOINT");
- SA_CMD_BUF_SIZE = lookupConstInt("SA_CMD_BUF_SIZE");
-
- saAttached = lookupCInt("saAttached");
- saEventPending = lookupCInt("saEventPending");
- saEventKind = lookupCInt("saEventKind");
- saCmdPending = lookupCInt("saCmdPending");
- saCmdType = lookupCInt("saCmdType");
- saCmdResult = lookupCInt("saCmdResult");
- saCmdResultErrMsg = lookupCString("saCmdResultErrMsg", SA_CMD_BUF_SIZE);
- // Toggling of breakpoints
- saCmdBkptSrcFileName = lookupCString("saCmdBkptSrcFileName", SA_CMD_BUF_SIZE);
- saCmdBkptPkgName = lookupCString("saCmdBkptPkgName", SA_CMD_BUF_SIZE);
- saCmdBkptLineNumber = lookupCInt("saCmdBkptLineNumber");
- saCmdBkptResWasError = lookupCInt("saCmdBkptResWasError");
- saCmdBkptResLineNumber = lookupCInt("saCmdBkptResLineNumber");
- saCmdBkptResBCI = lookupCInt("saCmdBkptResBCI");
- saCmdBkptResWasSet = lookupCInt("saCmdBkptResWasSet");
- saCmdBkptResMethodName = lookupCString("saCmdBkptResMethodName", SA_CMD_BUF_SIZE);
- saCmdBkptResMethodSig = lookupCString("saCmdBkptResMethodSig", SA_CMD_BUF_SIZE);
-
- // Check for existence of symbols needed later
- // FIXME: should probably cache these since we can't support the
- // -Xrun module or the VM getting unloaded anyway
- lookup("saExceptionThread");
- lookup("saExceptionClass");
- lookup("saExceptionMethod");
- lookup("saExceptionLocation");
- lookup("saExceptionException");
- lookup("saExceptionCatchClass");
- lookup("saExceptionCatchMethod");
- lookup("saExceptionCatchLocation");
- lookup("saBreakpointThread");
- lookup("saBreakpointClass");
- lookup("saBreakpointMethod");
- lookup("saBreakpointLocation");
-
- saAttached.setValue(1);
- attached = true;
- }
-
- public void detach() {
- saAttached.setValue(0);
- attached = false;
- saLibName = null;
- }
-
- /** Set the timeout value (in milliseconds) for the VM to reply to
- commands. Once this timeout has elapsed, the VM is assumed to
- have disconnected. Defaults to 3000 milliseconds (3 seconds). */
- public void setCommandTimeout(long millis) {
- timeoutMillis = millis;
- }
-
- /** Get the timeout value (in milliseconds) for the VM to reply to
- commands. Once this timeout has elapsed, the VM is assumed to
- have disconnected. Defaults to 3000 milliseconds (3 seconds). */
- public long getCommandTimeout() {
- return timeoutMillis;
- }
-
- /** Indicates whether a Java debug event is pending */
- public boolean eventPending() {
- return (saEventPending.getValue() != 0);
- }
-
- /** Poll for event; returns null if none pending. */
- public Event eventPoll() {
- if (saEventPending.getValue() == 0) {
- return null;
- }
-
- int kind = (int) saEventKind.getValue();
- switch (kind) {
- case JVMDI_EVENT_EXCEPTION: {
- JNIHandleAccessor thread = lookupJNIHandle("saExceptionThread");
- JNIHandleAccessor clazz = lookupJNIHandle("saExceptionClass");
- JNIid method = lookupJNIid("saExceptionMethod");
- CIntegerAccessor location = lookupCInt("saExceptionLocation");
- JNIHandleAccessor exception = lookupJNIHandle("saExceptionException");
- JNIHandleAccessor catchClass = lookupJNIHandle("saExceptionCatchClass");
- JNIid catchMethod = lookupJNIid("saExceptionCatchMethod");
- CIntegerAccessor catchLocation = lookupCInt("saExceptionCatchLocation");
- return new ExceptionEvent(thread.getValue(), clazz.getValue(), method,
- (int) location.getValue(), exception.getValue(),
- catchClass.getValue(), catchMethod, (int) catchLocation.getValue());
- }
-
- case JVMDI_EVENT_BREAKPOINT: {
- JNIHandleAccessor thread = lookupJNIHandle("saBreakpointThread");
- JNIHandleAccessor clazz = lookupJNIHandle("saBreakpointClass");
- JNIid method = lookupJNIid("saBreakpointMethod");
- CIntegerAccessor location = lookupCInt("saBreakpointLocation");
- return new BreakpointEvent(thread.getValue(), clazz.getValue(),
- method, (int) location.getValue());
- }
-
- default:
- throw new DebuggerException("Unsupported event type " + kind);
- }
- }
-
- /** Continue past current event */
- public void eventContinue() {
- saEventPending.setValue(0);
- }
-
- /** Suspend all Java threads in the target VM. Throws
- DebuggerException if the VM disconnected. */
- public void suspend() {
- saCmdType.setValue(SA_CMD_SUSPEND_ALL);
- saCmdPending.setValue(1);
- waitForCommandCompletion();
- suspended = true;
- }
-
- /** Resume all Java threads in the target VM. Throws
- DebuggerException if the VM disconnected. */
- public void resume() {
- saCmdType.setValue(SA_CMD_RESUME_ALL);
- saCmdPending.setValue(1);
- waitForCommandCompletion();
- suspended = false;
- }
-
- /** Indicates whether all Java threads have been suspended via this
- interface. */
- public boolean isSuspended() {
- return suspended;
- }
-
- /** Information about toggling of breakpoints */
- public static class BreakpointToggleResult {
- private boolean success;
- private String errMsg;
- private int lineNumber;
- private int bci;
- private boolean wasSet;
- private String methodName;
- private String methodSig;
-
- /** Success constructor */
- public BreakpointToggleResult(int lineNumber, int bci, boolean wasSet,
- String methodName, String methodSig) {
- this.lineNumber = lineNumber;
- this.bci = bci;
- this.wasSet = wasSet;
- this.methodName = methodName;
- this.methodSig = methodSig;
- success = true;
- }
-
- /** Failure constructor */
- public BreakpointToggleResult(String errMsg) {
- this.errMsg = errMsg;
- success = false;
- }
-
- /** Indicates whether this represents a successful return or not */
- public boolean getSuccess() { return success; }
-
- /** Valid only if getSuccess() returns false */
- public String getErrMsg() { return errMsg; }
-
- /** Line number at which breakpoint toggle occurred; valid only if
- getSuccess() returns true. */
- public int getLineNumber() { return lineNumber; }
-
- /** BCI at which breakpoint toggle occurred; valid only if
- getSuccess() returns true. */
- public int getBCI() { return bci; }
-
- /** Indicates whether the breakpoint toggle was the set of a
- breakpoint or not; valid only if getSuccess() returns true. */
- public boolean getWasSet() { return wasSet; }
-
- /** Method name in which the breakpoint toggle occurred; valid
- only if getSuccess() returns true. */
- public String getMethodName() { return methodName; }
-
- /** Method signature in which the breakpoint toggle occurred;
- valid only if getSuccess() returns true. */
- public String getMethodSignature() { return methodSig; }
- }
-
- /** Toggle a breakpoint. Throws DebuggerException if a real error
- occurred; otherwise returns non-null BreakpointToggleResult. The
- work of scanning the loaded classes is done in the target VM
- because it turns out to be significantly faster than scanning
- through the system dictionary from the SA, and interactivity
- when setting breakpoints is important. */
- public BreakpointToggleResult toggleBreakpoint(String srcFileName,
- String pkgName,
- int lineNo) {
- saCmdBkptSrcFileName.setValue(srcFileName);
- saCmdBkptPkgName.setValue(pkgName);
- saCmdBkptLineNumber.setValue(lineNo);
- saCmdType.setValue(SA_CMD_TOGGLE_BREAKPOINT);
- saCmdPending.setValue(1);
- if (waitForCommandCompletion(true)) {
- return new BreakpointToggleResult((int) saCmdBkptResLineNumber.getValue(),
- (int) saCmdBkptResBCI.getValue(),
- (saCmdBkptResWasSet.getValue() != 0),
- saCmdBkptResMethodName.getValue(),
- saCmdBkptResMethodSig.getValue());
- } else {
- return new BreakpointToggleResult(saCmdResultErrMsg.getValue());
- }
- }
-
-
- //----------------------------------------------------------------------
- // Internals only below this point
- //
-
- private CIntegerAccessor lookupCInt(String symbolName) {
- return new CIntegerAccessor(lookup(symbolName), 4, false);
- }
-
- private CStringAccessor lookupCString(String symbolName, int bufLen) {
- return new CStringAccessor(lookup(symbolName), bufLen);
- }
-
- private JNIHandleAccessor lookupJNIHandle(String symbolName) {
- return new JNIHandleAccessor(lookup(symbolName), VM.getVM().getObjectHeap());
- }
-
- private JNIid lookupJNIid(String symbolName) {
- Address idAddr = lookup(symbolName).getAddressAt(0);
- if (idAddr == null) {
- return null;
- }
- return new JNIid(idAddr, VM.getVM().getObjectHeap());
- }
-
- private int lookupConstInt(String symbolName) {
- Address addr = lookup(symbolName);
- return (int) addr.getCIntegerAt(0, 4, false);
- }
-
- private boolean setupLookup(String symbolName) {
- if (saLibName == null) {
- for (int i = 0; i < saLibNames.length; i++) {
- Address addr = dbg.lookup(saLibNames[i], symbolName);
- if (addr != null) {
- saLibName = saLibNames[i];
- return true;
- }
- }
- return false;
- }
- return true;
- }
-
- private Address lookup(String symbolName) {
- if (saLibName == null) {
- for (int i = 0; i < saLibNames.length; i++) {
- Address addr = dbg.lookup(saLibNames[i], symbolName);
- if (addr != null) {
- saLibName = saLibNames[i];
- return addr;
- }
- }
- throw new DebuggerException("Unable to find symbol " + symbolName + " in any of the known names for the SA");
- }
-
- Address addr = dbg.lookup(saLibName, symbolName);
- if (addr == null) {
- throw new DebuggerException("Unable to find symbol " + symbolName + " in " + saLibName);
- }
- return addr;
- }
-
- private void waitForCommandCompletion() {
- waitForCommandCompletion(false);
- }
-
- /** Returns true if command succeeded, false if not */
- private boolean waitForCommandCompletion(boolean forBreakpoint) {
- long start = System.currentTimeMillis();
- long cur = start;
- while ((saCmdPending.getValue() != 0) &&
- (cur - start < timeoutMillis)) {
- try {
- java.lang.Thread.currentThread().sleep(10);
- } catch (InterruptedException e) {
- }
- cur = System.currentTimeMillis();
- }
- if (saCmdPending.getValue() != 0) {
- detach();
- throw new DebuggerException("VM appears to have died");
- }
- boolean succeeded = saCmdResult.getValue() == 0;
- if (!succeeded &&
- (!forBreakpoint || saCmdBkptResWasError.getValue() != 0)) {
- String err = saCmdResultErrMsg.getValue();
- throw new DebuggerException("Error executing JVMDI command: " + err);
- }
- return succeeded;
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/CMSCollector.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/CMSCollector.java Fri Mar 15 16:39:07 2013 -0700
@@ -61,15 +61,13 @@
CMSBitMap markBitMap = markBitMap();
long addressSize = VM.getVM().getAddressSize();
if ( markBitMap.isMarked(addr) && markBitMap.isMarked(addr.addOffsetTo(1*addressSize)) ) {
- System.err.println("Printezis bits are set...");
Address nextOneAddr = markBitMap.getNextMarkedWordAddress(addr.addOffsetTo(2*addressSize));
//return size in bytes
long size = (nextOneAddr.addOffsetTo(1*addressSize)).minus(addr);
return size;
} else {
- //missing Printezis marks
- System.err.println("Missing Printszis marks...");
- return -1;
+ //missing Printezis marks
+ return -1;
}
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/CompactibleFreeListSpace.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/CompactibleFreeListSpace.java Fri Mar 15 16:39:07 2013 -0700
@@ -191,7 +191,6 @@
//Find the object size using Printezis bits and skip over
long size = collector().blockSizeUsingPrintezisBits(cur);
if (size == -1) {
- System.err.println("Printezis bits not set...");
break;
}
cur = cur.addOffsetTo(adjustObjectSizeInBytes(size));
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -469,7 +469,6 @@
case JVM_CONSTANT_UnresolvedClassInError: return "JVM_CONSTANT_UnresolvedClassInError";
case JVM_CONSTANT_MethodHandleInError:return "JVM_CONSTANT_MethodHandleInError";
case JVM_CONSTANT_MethodTypeInError: return "JVM_CONSTANT_MethodTypeInError";
- case JVM_CONSTANT_Object: return "JVM_CONSTANT_Object";
}
throw new InternalError("Unknown tag: " + tag);
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/MethodData.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/MethodData.java Fri Mar 15 16:39:07 2013 -0700
@@ -184,7 +184,6 @@
if (trapReasonName[index] == null) {
throw new InternalError("missing reason for " + index);
}
- System.out.println(trapReasonName[index]);
}
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java Fri Mar 15 16:39:07 2013 -0700
@@ -335,7 +335,6 @@
}
if (obj == null) {
//Find the object size using Printezis bits and skip over
- System.err.println("Finding object size using Printezis bits and skipping over...");
long size = 0;
if ( (cmsSpaceOld != null) && cmsSpaceOld.contains(handle) ){
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -67,7 +67,6 @@
public static final int JVM_CONSTANT_UnresolvedClassInError = 103; // Error tag due to resolution error
public static final int JVM_CONSTANT_MethodHandleInError = 104; // Error tag due to resolution error
public static final int JVM_CONSTANT_MethodTypeInError = 105; // Error tag due to resolution error
- public static final int JVM_CONSTANT_Object = 106; // Required for BoundMethodHandle arguments.
// 1.5 major/minor version numbers from JVM spec. 3rd edition
public static final short MAJOR_VERSION = 49;
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java Fri Mar 15 16:39:07 2013 -0700
@@ -90,10 +90,6 @@
/** Flags indicating whether we are attached to a core, C1, or C2 build */
private boolean usingClientCompiler;
private boolean usingServerCompiler;
- /** Flag indicating whether UseTLAB is turned on */
- private boolean useTLAB;
- /** Flag indicating whether invokedynamic support is on */
- private boolean enableInvokeDynamic;
/** alignment constants */
private boolean isLP64;
private int bytesPerLong;
@@ -326,9 +322,6 @@
}
}
- useTLAB = (db.lookupIntConstant("UseTLAB").intValue() != 0);
- enableInvokeDynamic = (db.lookupIntConstant("EnableInvokeDynamic").intValue() != 0);
-
if (debugger != null) {
isLP64 = debugger.getMachineDescription().isLP64();
}
@@ -579,15 +572,6 @@
}
}
- /** Indicates whether Thread-Local Allocation Buffers are used */
- public boolean getUseTLAB() {
- return useTLAB;
- }
-
- public boolean getEnableInvokeDynamic() {
- return enableInvokeDynamic;
- }
-
public TypeDataBase getTypeDataBase() {
return db;
}
@@ -822,6 +806,12 @@
return objectAlignmentInBytes;
}
+ /** Indicates whether Thread-Local Allocation Buffers are used */
+ public boolean getUseTLAB() {
+ Flag flag = getCommandLineFlag("UseTLAB");
+ return (flag == null) ? false: flag.getBool();
+ }
+
// returns null, if not available.
public Flag[] getCommandLineFlags() {
if (commandLineFlags == null) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/ClassLoaderStats.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,277 @@
+/*
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.jvm.hotspot.tools;
+
+import java.io.*;
+import java.util.*;
+
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.memory.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.tools.*;
+import sun.jvm.hotspot.utilities.*;
+
+/**
+ A command line tool to print class loader statistics.
+*/
+
+public class ClassLoaderStats extends Tool {
+ boolean verbose = true;
+
+ public static void main(String[] args) {
+ ClassLoaderStats cls = new ClassLoaderStats();
+ cls.start(args);
+ cls.stop();
+ }
+
+ private static class ClassData {
+ Klass klass;
+ long size;
+
+ ClassData(Klass klass, long size) {
+ this.klass = klass; this.size = size;
+ }
+ }
+
+ private static class LoaderData {
+ long numClasses;
+ long classSize;
+ List classDetail = new ArrayList(); // List<ClassData>
+ }
+
+ public void run() {
+ printClassLoaderStatistics();
+ }
+
+ private void printClassLoaderStatistics() {
+ final PrintStream out = System.out;
+ final PrintStream err = System.err;
+ final Map loaderMap = new HashMap();
+ // loader data for bootstrap class loader
+ final LoaderData bootstrapLoaderData = new LoaderData();
+ if (verbose) {
+ err.print("finding class loader instances ..");
+ }
+
+ VM vm = VM.getVM();
+ ObjectHeap heap = vm.getObjectHeap();
+ Klass classLoaderKlass = vm.getSystemDictionary().getClassLoaderKlass();
+ try {
+ heap.iterateObjectsOfKlass(new DefaultHeapVisitor() {
+ public boolean doObj(Oop oop) {
+ loaderMap.put(oop, new LoaderData());
+ return false;
+ }
+ }, classLoaderKlass);
+ } catch (Exception se) {
+ se.printStackTrace();
+ }
+
+ if (verbose) {
+ err.println("done.");
+ err.print("computing per loader stat ..");
+ }
+
+ SystemDictionary dict = VM.getVM().getSystemDictionary();
+ dict.classesDo(new SystemDictionary.ClassAndLoaderVisitor() {
+ public void visit(Klass k, Oop loader) {
+ if (! (k instanceof InstanceKlass)) {
+ return;
+ }
+ LoaderData ld = (loader != null) ? (LoaderData)loaderMap.get(loader)
+ : bootstrapLoaderData;
+ if (ld != null) {
+ ld.numClasses++;
+ long size = computeSize((InstanceKlass)k);
+ ld.classDetail.add(new ClassData(k, size));
+ ld.classSize += size;
+ }
+ }
+ });
+
+ if (verbose) {
+ err.println("done.");
+ err.print("please wait.. computing liveness");
+ }
+
+ // compute reverse pointer analysis (takes long time for larger app)
+ ReversePtrsAnalysis analysis = new ReversePtrsAnalysis();
+
+ if (verbose) {
+ analysis.setHeapProgressThunk(new HeapProgressThunk() {
+ public void heapIterationFractionUpdate(double fractionOfHeapVisited) {
+ err.print('.');
+ }
+ // This will be called after the iteration is complete
+ public void heapIterationComplete() {
+ err.println("done.");
+ }
+ });
+ }
+
+ try {
+ analysis.run();
+ } catch (Exception e) {
+ // e.printStackTrace();
+ if (verbose)
+ err.println("liveness analysis may be inaccurate ...");
+ }
+ ReversePtrs liveness = VM.getVM().getRevPtrs();
+
+ out.println("class_loader\tclasses\tbytes\tparent_loader\talive?\ttype");
+ out.println();
+
+ long numClassLoaders = 1L;
+ long totalNumClasses = bootstrapLoaderData.numClasses;
+ long totalClassSize = bootstrapLoaderData.classSize;
+ long numAliveLoaders = 1L;
+ long numDeadLoaders = 0L;
+
+ // print bootstrap loader details
+ out.print("<bootstrap>");
+ out.print('\t');
+ out.print(bootstrapLoaderData.numClasses);
+ out.print('\t');
+ out.print(bootstrapLoaderData.classSize);
+ out.print('\t');
+ out.print(" null ");
+ out.print('\t');
+ // bootstrap loader is always alive
+ out.print("live");
+ out.print('\t');
+ out.println("<internal>");
+
+ for (Iterator keyItr = loaderMap.keySet().iterator(); keyItr.hasNext();) {
+ Oop loader = (Oop) keyItr.next();
+ LoaderData data = (LoaderData) loaderMap.get(loader);
+ numClassLoaders ++;
+ totalNumClasses += data.numClasses;
+ totalClassSize += data.classSize;
+
+ out.print(loader.getHandle());
+ out.print('\t');
+ out.print(data.numClasses);
+ out.print('\t');
+ out.print(data.classSize);
+ out.print('\t');
+
+ class ParentFinder extends DefaultOopVisitor {
+ public void doOop(OopField field, boolean isVMField) {
+ if (field.getID().getName().equals("parent")) {
+ parent = field.getValue(getObj());
+ }
+ }
+ private Oop parent = null;
+ public Oop getParent() { return parent; }
+ }
+
+ ParentFinder parentFinder = new ParentFinder();
+ loader.iterate(parentFinder, false);
+ Oop parent = parentFinder.getParent();
+ out.print((parent != null)? parent.getHandle().toString() : " null ");
+ out.print('\t');
+ boolean alive = (liveness != null) ? (liveness.get(loader) != null) : true;
+ out.print(alive? "live" : "dead");
+ if (alive) numAliveLoaders++; else numDeadLoaders++;
+ out.print('\t');
+ Klass loaderKlass = loader.getKlass();
+ if (loaderKlass != null) {
+ out.print(loaderKlass.getName().asString());
+ out.print('@');
+ out.print(loader.getKlass().getAddress());
+ } else {
+ out.print(" null! ");
+ }
+ out.println();
+ }
+
+ out.println();
+ // summary line
+ out.print("total = ");
+ out.print(numClassLoaders);
+ out.print('\t');
+ out.print(totalNumClasses);
+ out.print('\t');
+ out.print(totalClassSize);
+ out.print('\t');
+ out.print(" N/A ");
+ out.print('\t');
+ out.print("alive=");
+ out.print(numAliveLoaders);
+ out.print(", dead=");
+ out.print(numDeadLoaders);
+ out.print('\t');
+ out.print(" N/A ");
+ 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(GenericArray arr) {
+ return arr.getLength() != 0L ? arr.getSize() : 0L;
+ }
+
+ private long computeSize(InstanceKlass k) {
+ long size = 0L;
+ // the InstanceKlass object itself
+ size += k.getSize();
+
+ // Constant pool
+ ConstantPool cp = k.getConstants();
+ size += cp.getSize();
+ if (cp.getCache() != null) {
+ size += cp.getCache().getSize();
+ }
+ size += arraySize(cp.getTags());
+
+ // Interfaces
+ size += arraySize(k.getLocalInterfaces());
+ size += arraySize(k.getTransitiveInterfaces());
+
+ // Inner classes
+ size += arraySize(k.getInnerClasses());
+
+ // Fields
+ size += arraySize(k.getFields());
+
+ // Methods
+ MethodArray methods = k.getMethods();
+ int nmethods = (int) methods.getLength();
+ if (nmethods != 0L) {
+ size += methods.getSize();
+ for (int i = 0; i < nmethods; ++i) {
+ Method m = methods.at(i);
+ size += m.getSize();
+ size += m.getConstMethod().getSize();
+ }
+ }
+
+ return size;
+ }
+}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java Fri Mar 15 16:39:07 2013 -0700
@@ -57,17 +57,18 @@
printGCAlgorithm(flagMap);
System.out.println();
System.out.println("Heap Configuration:");
- printValue("MinHeapFreeRatio = ", getFlagValue("MinHeapFreeRatio", flagMap));
- printValue("MaxHeapFreeRatio = ", getFlagValue("MaxHeapFreeRatio", flagMap));
- printValMB("MaxHeapSize = ", getFlagValue("MaxHeapSize", flagMap));
- printValMB("NewSize = ", getFlagValue("NewSize", flagMap));
- printValMB("MaxNewSize = ", getFlagValue("MaxNewSize", flagMap));
- printValMB("OldSize = ", getFlagValue("OldSize", flagMap));
- printValue("NewRatio = ", getFlagValue("NewRatio", flagMap));
- printValue("SurvivorRatio = ", getFlagValue("SurvivorRatio", flagMap));
- printValMB("MetaspaceSize = ", getFlagValue("MetaspaceSize", flagMap));
- printValMB("MaxMetaspaceSize = ", getFlagValue("MaxMetaspaceSize", flagMap));
- printValMB("G1HeapRegionSize = ", HeapRegion.grainBytes());
+ printValue("MinHeapFreeRatio = ", getFlagValue("MinHeapFreeRatio", flagMap));
+ printValue("MaxHeapFreeRatio = ", getFlagValue("MaxHeapFreeRatio", flagMap));
+ printValMB("MaxHeapSize = ", getFlagValue("MaxHeapSize", flagMap));
+ printValMB("NewSize = ", getFlagValue("NewSize", flagMap));
+ printValMB("MaxNewSize = ", getFlagValue("MaxNewSize", flagMap));
+ printValMB("OldSize = ", getFlagValue("OldSize", flagMap));
+ printValue("NewRatio = ", getFlagValue("NewRatio", flagMap));
+ printValue("SurvivorRatio = ", getFlagValue("SurvivorRatio", flagMap));
+ printValMB("MetaspaceSize = ", getFlagValue("MetaspaceSize", flagMap));
+ printValMB("ClassMetaspaceSize = ", getFlagValue("ClassMetaspaceSize", flagMap));
+ printValMB("MaxMetaspaceSize = ", getFlagValue("MaxMetaspaceSize", flagMap));
+ printValMB("G1HeapRegionSize = ", HeapRegion.grainBytes());
System.out.println();
System.out.println("Heap Usage:");
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JMap.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JMap.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -45,7 +45,7 @@
}
protected String getCommandFlags() {
- return "-heap|-heap:format=b|-histo|-permstat|-finalizerinfo";
+ return "-heap|-heap:format=b|-histo|-clstats|-finalizerinfo";
}
protected void printFlagsUsage() {
@@ -53,14 +53,14 @@
System.out.println(" -heap\tto print java heap summary");
System.out.println(" -heap:format=b\tto dump java heap in hprof binary format");
System.out.println(" -histo\tto print histogram of java object heap");
- System.out.println(" -permstat\tto print permanent generation statistics");
+ System.out.println(" -clstats\tto print class loader statistics");
System.out.println(" -finalizerinfo\tto print information on objects awaiting finalization");
super.printFlagsUsage();
}
public static final int MODE_HEAP_SUMMARY = 0;
public static final int MODE_HISTOGRAM = 1;
- public static final int MODE_PERMSTAT = 2;
+ public static final int MODE_CLSTATS = 2;
public static final int MODE_PMAP = 3;
public static final int MODE_HEAP_GRAPH_HPROF_BIN = 4;
public static final int MODE_HEAP_GRAPH_GXL = 5;
@@ -78,8 +78,8 @@
tool = new ObjectHistogram();
break;
- case MODE_PERMSTAT:
- tool = new PermStat();
+ case MODE_CLSTATS:
+ tool = new ClassLoaderStats();
break;
case MODE_PMAP:
@@ -118,7 +118,9 @@
} else if (modeFlag.equals("-histo")) {
mode = MODE_HISTOGRAM;
} else if (modeFlag.equals("-permstat")) {
- mode = MODE_PERMSTAT;
+ mode = MODE_CLSTATS;
+ } else if (modeFlag.equals("-clstats")) {
+ mode = MODE_CLSTATS;
} else if (modeFlag.equals("-finalizerinfo")) {
mode = MODE_FINALIZERINFO;
} else {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PMap.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PMap.java Fri Mar 15 16:39:07 2013 -0700
@@ -58,10 +58,6 @@
}
}
- protected boolean requiresVM() {
- return false;
- }
-
public static void main(String[] args) throws Exception {
PMap t = new PMap();
t.start(args);
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java Fri Mar 15 16:39:07 2013 -0700
@@ -50,29 +50,23 @@
public void run(PrintStream out) {
Debugger dbg = getAgent().getDebugger();
- run(out, dbg, getAgent().isJavaMode());
+ run(out, dbg);
}
public void run(PrintStream out, Debugger dbg) {
- run(out, dbg, true);
- }
-
- private void run(PrintStream out, Debugger dbg, final boolean isJava) {
CDebugger cdbg = dbg.getCDebugger();
if (cdbg != null) {
ConcurrentLocksPrinter concLocksPrinter = null;
- if (isJava) {
- // compute and cache java Vframes.
- initJFrameCache();
- if (concurrentLocks) {
- concLocksPrinter = new ConcurrentLocksPrinter();
- }
- // print Java level deadlocks
- try {
- DeadlockDetector.print(out);
- } catch (Exception exp) {
- out.println("can't print deadlock information: " + exp.getMessage());
- }
+ // compute and cache java Vframes.
+ initJFrameCache();
+ if (concurrentLocks) {
+ concLocksPrinter = new ConcurrentLocksPrinter();
+ }
+ // print Java level deadlocks
+ try {
+ DeadlockDetector.print(out);
+ } catch (Exception exp) {
+ out.println("can't print deadlock information: " + exp.getMessage());
}
List l = cdbg.getThreadList();
@@ -100,63 +94,59 @@
}
out.println();
} else {
- if (isJava) {
- // look for one or more java frames
- String[] names = null;
- // check interpreter frame
- Interpreter interp = VM.getVM().getInterpreter();
- if (interp.contains(pc)) {
- names = getJavaNames(th, f.localVariableBase());
- // print codelet name if we can't determine method
- if (names == null || names.length == 0) {
- out.print("<interpreter> ");
- InterpreterCodelet ic = interp.getCodeletContaining(pc);
- if (ic != null) {
- String desc = ic.getDescription();
- if (desc != null) out.print(desc);
- }
- out.println();
- }
- } else {
- // look for known code blobs
- CodeCache c = VM.getVM().getCodeCache();
- if (c.contains(pc)) {
- CodeBlob cb = c.findBlobUnsafe(pc);
- if (cb.isNMethod()) {
- names = getJavaNames(th, f.localVariableBase());
- // just print compiled code, if can't determine method
- if (names == null || names.length == 0) {
- out.println("<Unknown compiled code>");
- }
- } else if (cb.isBufferBlob()) {
- out.println("<StubRoutines>");
- } else if (cb.isRuntimeStub()) {
- out.println("<RuntimeStub>");
- } else if (cb.isDeoptimizationStub()) {
- out.println("<DeoptimizationStub>");
- } else if (cb.isUncommonTrapStub()) {
- out.println("<UncommonTrap>");
- } else if (cb.isExceptionStub()) {
- out.println("<ExceptionStub>");
- } else if (cb.isSafepointStub()) {
- out.println("<SafepointStub>");
- } else {
- out.println("<Unknown code blob>");
- }
- } else {
- printUnknown(out);
- }
- }
- // print java frames, if any
- if (names != null && names.length != 0) {
- // print java frame(s)
- for (int i = 0; i < names.length; i++) {
- out.println(names[i]);
- }
- }
- } else {
- printUnknown(out);
- }
+ // look for one or more java frames
+ String[] names = null;
+ // check interpreter frame
+ Interpreter interp = VM.getVM().getInterpreter();
+ if (interp.contains(pc)) {
+ names = getJavaNames(th, f.localVariableBase());
+ // print codelet name if we can't determine method
+ if (names == null || names.length == 0) {
+ out.print("<interpreter> ");
+ InterpreterCodelet ic = interp.getCodeletContaining(pc);
+ if (ic != null) {
+ String desc = ic.getDescription();
+ if (desc != null) out.print(desc);
+ }
+ out.println();
+ }
+ } else {
+ // look for known code blobs
+ CodeCache c = VM.getVM().getCodeCache();
+ if (c.contains(pc)) {
+ CodeBlob cb = c.findBlobUnsafe(pc);
+ if (cb.isNMethod()) {
+ names = getJavaNames(th, f.localVariableBase());
+ // just print compiled code, if can't determine method
+ if (names == null || names.length == 0) {
+ out.println("<Unknown compiled code>");
+ }
+ } else if (cb.isBufferBlob()) {
+ out.println("<StubRoutines>");
+ } else if (cb.isRuntimeStub()) {
+ out.println("<RuntimeStub>");
+ } else if (cb.isDeoptimizationStub()) {
+ out.println("<DeoptimizationStub>");
+ } else if (cb.isUncommonTrapStub()) {
+ out.println("<UncommonTrap>");
+ } else if (cb.isExceptionStub()) {
+ out.println("<ExceptionStub>");
+ } else if (cb.isSafepointStub()) {
+ out.println("<SafepointStub>");
+ } else {
+ out.println("<Unknown code blob>");
+ }
+ } else {
+ printUnknown(out);
+ }
+ }
+ // print java frames, if any
+ if (names != null && names.length != 0) {
+ // print java frame(s)
+ for (int i = 0; i < names.length; i++) {
+ out.println(names[i]);
+ }
+ }
}
f = f.sender(th);
}
@@ -164,7 +154,7 @@
exp.printStackTrace();
// continue, may be we can do a better job for other threads
}
- if (isJava && concurrentLocks) {
+ if (concurrentLocks) {
JavaThread jthread = (JavaThread) proxyToThread.get(th);
if (jthread != null) {
concLocksPrinter.print(jthread, out);
@@ -180,10 +170,6 @@
}
}
- protected boolean requiresVM() {
- return false;
- }
-
public static void main(String[] args) throws Exception {
PStack t = new PStack();
t.start(args);
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PermStat.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,277 +0,0 @@
-/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.tools;
-
-import java.io.*;
-import java.util.*;
-
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.memory.*;
-import sun.jvm.hotspot.oops.*;
-import sun.jvm.hotspot.runtime.*;
-import sun.jvm.hotspot.tools.*;
-import sun.jvm.hotspot.utilities.*;
-
-/**
- A command line tool to print perm. generation statistics.
-*/
-
-public class PermStat extends Tool {
- boolean verbose = true;
-
- public static void main(String[] args) {
- PermStat ps = new PermStat();
- ps.start(args);
- ps.stop();
- }
-
- private static class ClassData {
- Klass klass;
- long size;
-
- ClassData(Klass klass, long size) {
- this.klass = klass; this.size = size;
- }
- }
-
- private static class LoaderData {
- long numClasses;
- long classSize;
- List classDetail = new ArrayList(); // List<ClassData>
- }
-
- public void run() {
- printClassLoaderStatistics();
- }
-
- private void printClassLoaderStatistics() {
- final PrintStream out = System.out;
- final PrintStream err = System.err;
- final Map loaderMap = new HashMap();
- // loader data for bootstrap class loader
- final LoaderData bootstrapLoaderData = new LoaderData();
- if (verbose) {
- err.print("finding class loader instances ..");
- }
-
- VM vm = VM.getVM();
- ObjectHeap heap = vm.getObjectHeap();
- Klass classLoaderKlass = vm.getSystemDictionary().getClassLoaderKlass();
- try {
- heap.iterateObjectsOfKlass(new DefaultHeapVisitor() {
- public boolean doObj(Oop oop) {
- loaderMap.put(oop, new LoaderData());
- return false;
- }
- }, classLoaderKlass);
- } catch (Exception se) {
- se.printStackTrace();
- }
-
- if (verbose) {
- err.println("done.");
- err.print("computing per loader stat ..");
- }
-
- SystemDictionary dict = VM.getVM().getSystemDictionary();
- dict.classesDo(new SystemDictionary.ClassAndLoaderVisitor() {
- public void visit(Klass k, Oop loader) {
- if (! (k instanceof InstanceKlass)) {
- return;
- }
- LoaderData ld = (loader != null) ? (LoaderData)loaderMap.get(loader)
- : bootstrapLoaderData;
- if (ld != null) {
- ld.numClasses++;
- long size = computeSize((InstanceKlass)k);
- ld.classDetail.add(new ClassData(k, size));
- ld.classSize += size;
- }
- }
- });
-
- if (verbose) {
- err.println("done.");
- err.print("please wait.. computing liveness");
- }
-
- // compute reverse pointer analysis (takes long time for larger app)
- ReversePtrsAnalysis analysis = new ReversePtrsAnalysis();
-
- if (verbose) {
- analysis.setHeapProgressThunk(new HeapProgressThunk() {
- public void heapIterationFractionUpdate(double fractionOfHeapVisited) {
- err.print('.');
- }
- // This will be called after the iteration is complete
- public void heapIterationComplete() {
- err.println("done.");
- }
- });
- }
-
- try {
- analysis.run();
- } catch (Exception e) {
- // e.printStackTrace();
- if (verbose)
- err.println("liveness analysis may be inaccurate ...");
- }
- ReversePtrs liveness = VM.getVM().getRevPtrs();
-
- out.println("class_loader\tclasses\tbytes\tparent_loader\talive?\ttype");
- out.println();
-
- long numClassLoaders = 1L;
- long totalNumClasses = bootstrapLoaderData.numClasses;
- long totalClassSize = bootstrapLoaderData.classSize;
- long numAliveLoaders = 1L;
- long numDeadLoaders = 0L;
-
- // print bootstrap loader details
- out.print("<bootstrap>");
- out.print('\t');
- out.print(bootstrapLoaderData.numClasses);
- out.print('\t');
- out.print(bootstrapLoaderData.classSize);
- out.print('\t');
- out.print(" null ");
- out.print('\t');
- // bootstrap loader is always alive
- out.print("live");
- out.print('\t');
- out.println("<internal>");
-
- for (Iterator keyItr = loaderMap.keySet().iterator(); keyItr.hasNext();) {
- Oop loader = (Oop) keyItr.next();
- LoaderData data = (LoaderData) loaderMap.get(loader);
- numClassLoaders ++;
- totalNumClasses += data.numClasses;
- totalClassSize += data.classSize;
-
- out.print(loader.getHandle());
- out.print('\t');
- out.print(data.numClasses);
- out.print('\t');
- out.print(data.classSize);
- out.print('\t');
-
- class ParentFinder extends DefaultOopVisitor {
- public void doOop(OopField field, boolean isVMField) {
- if (field.getID().getName().equals("parent")) {
- parent = field.getValue(getObj());
- }
- }
- private Oop parent = null;
- public Oop getParent() { return parent; }
- }
-
- ParentFinder parentFinder = new ParentFinder();
- loader.iterate(parentFinder, false);
- Oop parent = parentFinder.getParent();
- out.print((parent != null)? parent.getHandle().toString() : " null ");
- out.print('\t');
- boolean alive = (liveness != null) ? (liveness.get(loader) != null) : true;
- out.print(alive? "live" : "dead");
- if (alive) numAliveLoaders++; else numDeadLoaders++;
- out.print('\t');
- Klass loaderKlass = loader.getKlass();
- if (loaderKlass != null) {
- out.print(loaderKlass.getName().asString());
- out.print('@');
- out.print(loader.getKlass().getAddress());
- } else {
- out.print(" null! ");
- }
- out.println();
- }
-
- out.println();
- // summary line
- out.print("total = ");
- out.print(numClassLoaders);
- out.print('\t');
- out.print(totalNumClasses);
- out.print('\t');
- out.print(totalClassSize);
- out.print('\t');
- out.print(" N/A ");
- out.print('\t');
- out.print("alive=");
- out.print(numAliveLoaders);
- out.print(", dead=");
- out.print(numDeadLoaders);
- out.print('\t');
- out.print(" N/A ");
- 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(GenericArray arr) {
- return arr.getLength() != 0L ? arr.getSize() : 0L;
- }
-
- private long computeSize(InstanceKlass k) {
- long size = 0L;
- // the InstanceKlass object itself
- size += k.getSize();
-
- // Constant pool
- ConstantPool cp = k.getConstants();
- size += cp.getSize();
- if (cp.getCache() != null) {
- size += cp.getCache().getSize();
- }
- size += arraySize(cp.getTags());
-
- // Interfaces
- size += arraySize(k.getLocalInterfaces());
- size += arraySize(k.getTransitiveInterfaces());
-
- // Inner classes
- size += arraySize(k.getInnerClasses());
-
- // Fields
- size += arraySize(k.getFields());
-
- // Methods
- MethodArray methods = k.getMethods();
- int nmethods = (int) methods.getLength();
- if (nmethods != 0L) {
- size += methods.getSize();
- for (int i = 0; i < nmethods; ++i) {
- Method m = methods.at(i);
- size += m.getSize();
- size += m.getConstMethod().getSize();
- }
- }
-
- return size;
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java Fri Mar 15 16:39:07 2013 -0700
@@ -27,7 +27,6 @@
import java.io.PrintStream;
import java.util.Hashtable;
import sun.jvm.hotspot.*;
-import sun.jvm.hotspot.bugspot.*;
import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.debugger.*;
@@ -35,7 +34,7 @@
// override run & code main as shown below.
public abstract class Tool implements Runnable {
- private BugSpotAgent agent;
+ private HotSpotAgent agent;
private int debugeeType;
// debugeeType is one of constants below
@@ -51,12 +50,7 @@
return true;
}
- // whether this tool requires debuggee to be java process or core?
- protected boolean requiresVM() {
- return true;
- }
-
- protected void setAgent(BugSpotAgent a) {
+ protected void setAgent(HotSpotAgent a) {
agent = a;
}
@@ -64,7 +58,7 @@
debugeeType = dt;
}
- protected BugSpotAgent getAgent() {
+ protected HotSpotAgent getAgent() {
return agent;
}
@@ -155,7 +149,7 @@
usage();
}
- agent = new BugSpotAgent();
+ agent = new HotSpotAgent();
try {
switch (debugeeType) {
case DEBUGEE_PID:
@@ -198,33 +192,24 @@
err.println("Debugger attached successfully.");
- boolean isJava = agent.isJavaMode();
- if (isJava) {
- VM vm = VM.getVM();
- if (vm.isCore()) {
- err.println("Core build detected.");
- } else if (vm.isClientCompiler()) {
- err.println("Client compiler detected.");
- } else if (vm.isServerCompiler()) {
- err.println("Server compiler detected.");
- } else {
- throw new RuntimeException("Fatal error: " +
- "should have been able to detect core/C1/C2 build");
- }
+ VM vm = VM.getVM();
+ if (vm.isCore()) {
+ err.println("Core build detected.");
+ } else if (vm.isClientCompiler()) {
+ err.println("Client compiler detected.");
+ } else if (vm.isServerCompiler()) {
+ err.println("Server compiler detected.");
+ } else {
+ throw new RuntimeException("Fatal error: "
+ + "should have been able to detect core/C1/C2 build");
+ }
- String version = vm.getVMRelease();
- if (version != null) {
- err.print("JVM version is ");
- err.println(version);
- }
+ String version = vm.getVMRelease();
+ if (version != null) {
+ err.print("JVM version is ");
+ err.println(version);
+ }
- run();
- } else { // not a java process or core
- if (requiresVM()) {
- err.println(getName() + " requires a java VM process/core!");
- } else {
- run();
- }
- }
+ run();
}
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/SAPanel.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/SAPanel.java Fri Mar 15 16:39:07 2013 -0700
@@ -50,7 +50,7 @@
/**
* This base class encapsulates many of the events that are fired from
* the various panels in this directory so they can easily be plugged
- * in to different containing frameworks (HSDB, BugSpot).
+ * in to different containing frameworks (HSDB).
*/
public class SAPanel extends JPanel {
protected List listeners = new ArrayList();
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/ConstantTag.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/ConstantTag.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -51,7 +51,6 @@
private static final int JVM_CONSTANT_UnresolvedClassInError = 103; // Resolution failed
private static final int JVM_CONSTANT_MethodHandleInError = 104; // Error tag due to resolution error
private static final int JVM_CONSTANT_MethodTypeInError = 105; // Error tag due to resolution error
- private static final int JVM_CONSTANT_Object = 106; // Required for BoundMethodHandle arguments.
// JVM_CONSTANT_MethodHandle subtypes //FIXME: connect these to data structure
private static int JVM_REF_getField = 1;
@@ -96,8 +95,6 @@
public boolean isKlassIndex() { return tag == JVM_CONSTANT_ClassIndex; }
public boolean isStringIndex() { return tag == JVM_CONSTANT_StringIndex; }
- public boolean isObject() { return tag == JVM_CONSTANT_Object; }
-
public boolean isKlassReference() { return isKlassIndex() || isUnresolvedKlass(); }
public boolean isFieldOrMethod() { return isField() || isMethod() || isInterfaceMethod(); }
public boolean isSymbol() { return isUtf8(); }
@@ -123,7 +120,6 @@
case JVM_CONSTANT_StringIndex :
case JVM_CONSTANT_MethodHandle :
case JVM_CONSTANT_MethodType :
- case JVM_CONSTANT_Object :
return BasicType.T_OBJECT;
default:
throw new InternalError("unexpected tag: " + tag);
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js Fri Mar 15 16:39:07 2013 -0700
@@ -31,7 +31,6 @@
sapkg.hotspot = Packages.sun.jvm.hotspot;
sapkg.asm = sapkg.hotspot.asm;
-sapkg.bugspot = sapkg.hotspot.bugspot;
sapkg.c1 = sapkg.hotspot.c1;
sapkg.code = sapkg.hotspot.code;
sapkg.compiler = sapkg.hotspot.compiler;
@@ -40,7 +39,6 @@
// sapkg.debugger = sapkg.hotspot.debugger;
sapkg.interpreter = sapkg.hotspot.interpreter;
-sapkg.livejvm = sapkg.hotspot.livejvm;
sapkg.jdi = sapkg.hotspot.jdi;
sapkg.memory = sapkg.hotspot.memory;
sapkg.oops = sapkg.hotspot.oops;
--- a/hotspot/agent/src/share/native/jvmdi/sa.cpp Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,601 +0,0 @@
-/*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <vector>
-#include "sa.hpp"
-#include "jni.h"
-#include "jvmdi.h"
-
-#ifndef WIN32
- #include <inttypes.h>
-#else
- typedef int int32_t;
-#endif
-
-#ifdef WIN32
- #include <windows.h>
- #define YIELD() Sleep(0)
- #define SLEEP() Sleep(10)
- #define vsnprintf _vsnprintf
-#else
- Error: please port YIELD() and SLEEP() macros to your platform
-#endif
-
-using namespace std;
-
-//////////////////////////////////////////////////////////////////////
-// //
-// Exported "interface" for Java language-level interaction between //
-// the SA and the VM. Note that the SA knows about the layout of //
-// certain VM data structures and that knowledge is taken advantage //
-// of in this code, although this interfaces with the VM via JVMDI. //
-// //
-//////////////////////////////////////////////////////////////////////
-
-extern "C" {
- /////////////////////////////////////
- // //
- // Events sent by the VM to the SA //
- // //
- /////////////////////////////////////
-
- // Set by the SA when it attaches. Indicates that events should be
- // posted via these exported variables, and that the VM should wait
- // for those events to be acknowledged by the SA (via its setting
- // saEventPending to 0).
- JNIEXPORT volatile int32_t saAttached = 0;
-
- // Set to nonzero value by the VM when an event has been posted; set
- // back to 0 by the SA when it has processed that event.
- JNIEXPORT volatile int32_t saEventPending = 0;
-
- // Kind of the event (from jvmdi.h)
- JNIEXPORT volatile int32_t saEventKind = 0;
-
- //
- // Exception events
- //
- JNIEXPORT jthread saExceptionThread;
- JNIEXPORT jclass saExceptionClass;
- JNIEXPORT jmethodID saExceptionMethod;
- JNIEXPORT int32_t saExceptionLocation;
- JNIEXPORT jobject saExceptionException;
- JNIEXPORT jclass saExceptionCatchClass;
- JNIEXPORT jmethodID saExceptionCatchMethod;
- JNIEXPORT int32_t saExceptionCatchLocation;
-
- //
- // Breakpoint events
- //
- JNIEXPORT jthread saBreakpointThread;
- JNIEXPORT jclass saBreakpointClass;
- JNIEXPORT jmethodID saBreakpointMethod;
- JNIEXPORT jlocation saBreakpointLocation;
-
- ///////////////////////////////////////
- // //
- // Commands sent by the SA to the VM //
- // //
- ///////////////////////////////////////
-
- extern JNIEXPORT const int32_t SA_CMD_SUSPEND_ALL = 0;
- extern JNIEXPORT const int32_t SA_CMD_RESUME_ALL = 1;
- extern JNIEXPORT const int32_t SA_CMD_TOGGLE_BREAKPOINT = 2;
- extern JNIEXPORT const int32_t SA_CMD_BUF_SIZE = 1024;
-
- // SA sets this to a nonzero value when it is requesting a command
- // to be processed; VM sets it back to 0 when the command has been
- // executed
- JNIEXPORT volatile int32_t saCmdPending = 0;
-
- // SA sets this to one of the manifest constants above to indicate
- // the kind of command to be executed
- JNIEXPORT volatile int32_t saCmdType = 0;
-
- // VM sets this to 0 if the last command succeeded or a nonzero
- // value if it failed
- JNIEXPORT volatile int32_t saCmdResult = 0;
-
- // If last command failed, this buffer will contain a descriptive
- // error message
- JNIEXPORT char saCmdResultErrMsg[SA_CMD_BUF_SIZE];
-
- //
- // Toggling of breakpoint command arguments.
- //
- // Originally there were separate set/clear breakpoint commands
- // taking a class name, method name and signature, and the iteration
- // through the debug information was done in the SA. It turns out
- // that doing this work in the target VM is significantly faster,
- // and since interactivity when setting and clearing breakpoints is
- // important, the solution which resulted in more C/C++ code was used.
- //
-
- // Source file name
- JNIEXPORT char saCmdBkptSrcFileName[SA_CMD_BUF_SIZE];
-
- // Package name ('/' as separator instead of '.')
- JNIEXPORT char saCmdBkptPkgName[SA_CMD_BUF_SIZE];
-
- // Line number
- JNIEXPORT int32_t saCmdBkptLineNumber;
-
- // Output back to SA: indicator whether the last failure of a
- // breakpoint toggle command was really an error or just a lack of
- // debug information covering the requested line. 0 if not error.
- // Valid only if saCmdResult != 0.
- JNIEXPORT int32_t saCmdBkptResWasError;
-
- // Output back to SA: resulting line number at which the breakpoint
- // was set or cleared (valid only if saCmdResult == 0)
- JNIEXPORT int32_t saCmdBkptResLineNumber;
-
- // Output back to SA: resulting byte code index at which the
- // breakpoint was set or cleared (valid only if saCmdResult == 0)
- JNIEXPORT int32_t saCmdBkptResBCI;
-
- // Output back to SA: indicator whether the breakpoint operation
- // resulted in a set or cleared breakpoint; nonzero if set, zero if
- // cleared (valid only if saCmdResult == 0)
- JNIEXPORT int32_t saCmdBkptResWasSet;
-
- // Output back to SA: method name the breakpoint was set in (valid
- // only if saCmdResult == 0)
- JNIEXPORT char saCmdBkptResMethodName[SA_CMD_BUF_SIZE];
-
- // Output back to SA: method signature (JNI style) the breakpoint
- // was set in (valid only if saCmdResult == 0)
- JNIEXPORT char saCmdBkptResMethodSig[SA_CMD_BUF_SIZE];
-}
-
-// Internal state
-static JavaVM* jvm = NULL;
-static JVMDI_Interface_1* jvmdi = NULL;
-static jthread debugThreadObj = NULL;
-static bool suspended = false;
-static vector<jthread> suspendedThreads;
-static JVMDI_RawMonitor eventLock = NULL;
-
-class MonitorLocker {
-private:
- JVMDI_RawMonitor lock;
-public:
- MonitorLocker(JVMDI_RawMonitor lock) {
- this->lock = lock;
- if (lock != NULL) {
- jvmdi->RawMonitorEnter(lock);
- }
- }
- ~MonitorLocker() {
- if (lock != NULL) {
- jvmdi->RawMonitorExit(lock);
- }
- }
-};
-
-class JvmdiDeallocator {
-private:
- void* ptr;
-public:
- JvmdiDeallocator(void* ptr) {
- this->ptr = ptr;
- }
- ~JvmdiDeallocator() {
- jvmdi->Deallocate((jbyte*) ptr);
- }
-};
-
-class JvmdiRefListDeallocator {
-private:
- JNIEnv* env;
- jobject* refList;
- jint refCount;
-public:
- JvmdiRefListDeallocator(JNIEnv* env, jobject* refList, jint refCount) {
- this->env = env;
- this->refList = refList;
- this->refCount = refCount;
- }
- ~JvmdiRefListDeallocator() {
- for (int i = 0; i < refCount; i++) {
- env->DeleteGlobalRef(refList[i]);
- }
- jvmdi->Deallocate((jbyte*) refList);
- }
-};
-
-static void
-stop(char* msg) {
- fprintf(stderr, "%s", msg);
- fprintf(stderr, "\n");
- exit(1);
-}
-
-// This fills in the command result error message, sets the command
-// result to -1, and clears the pending command flag
-static void
-reportErrorToSA(const char* str, ...) {
- va_list varargs;
- va_start(varargs, str);
- vsnprintf(saCmdResultErrMsg, sizeof(saCmdResultErrMsg), str, varargs);
- va_end(varargs);
- saCmdResult = -1;
- saCmdPending = 0;
-}
-
-static bool
-packageNameMatches(char* clazzName, char* pkg) {
- int pkgLen = strlen(pkg);
- int clazzNameLen = strlen(clazzName);
-
- if (pkgLen >= clazzNameLen + 1) {
- return false;
- }
-
- if (strncmp(clazzName, pkg, pkgLen)) {
- return false;
- }
-
- // Ensure that '/' is the next character if non-empty package name
- int l = pkgLen;
- if (l > 0) {
- if (clazzName[l] != '/') {
- return false;
- }
- l++;
- }
- // Ensure that there are no more trailing slashes
- while (l < clazzNameLen) {
- if (clazzName[l++] == '/') {
- return false;
- }
- }
- return true;
-}
-
-static void
-executeOneCommand(JNIEnv* env) {
- switch (saCmdType) {
- case SA_CMD_SUSPEND_ALL: {
- if (suspended) {
- reportErrorToSA("Target process already suspended");
- return;
- }
-
- // We implement this by getting all of the threads and calling
- // SuspendThread on each one, except for the thread object
- // corresponding to this thread. Each thread for which the call
- // succeeded (i.e., did not return JVMDI_ERROR_INVALID_THREAD)
- // is added to a list which is remembered for later resumption.
- // Note that this currently has race conditions since a thread
- // might be started after we call GetAllThreads and since a
- // thread for which we got an error earlier might be resumed by
- // the VM while we are busy suspending other threads. We could
- // solve this by looping until there are no more threads we can
- // suspend, but a more robust and scalable solution is to add
- // this functionality to the JVMDI interface (i.e.,
- // "suspendAll"). Probably need to provide an exclude list for
- // such a routine.
- jint threadCount;
- jthread* threads;
- if (jvmdi->GetAllThreads(&threadCount, &threads) != JVMDI_ERROR_NONE) {
- reportErrorToSA("Error while getting thread list");
- return;
- }
-
-
- for (int i = 0; i < threadCount; i++) {
- jthread thr = threads[i];
- if (!env->IsSameObject(thr, debugThreadObj)) {
- jvmdiError err = jvmdi->SuspendThread(thr);
- if (err == JVMDI_ERROR_NONE) {
- // Remember this thread and do not free it
- suspendedThreads.push_back(thr);
- continue;
- } else {
- fprintf(stderr, " SA: Error %d while suspending thread\n", err);
- // FIXME: stop, resume all threads, report error
- }
- }
- env->DeleteGlobalRef(thr);
- }
-
- // Free up threads
- jvmdi->Deallocate((jbyte*) threads);
-
- // Suspension is complete
- suspended = true;
- break;
- }
-
- case SA_CMD_RESUME_ALL: {
- if (!suspended) {
- reportErrorToSA("Target process already suspended");
- return;
- }
-
- saCmdResult = 0;
- bool errorOccurred = false;
- jvmdiError firstError;
- for (int i = 0; i < suspendedThreads.size(); i++) {
- jthread thr = suspendedThreads[i];
- jvmdiError err = jvmdi->ResumeThread(thr);
- env->DeleteGlobalRef(thr);
- if (err != JVMDI_ERROR_NONE) {
- if (!errorOccurred) {
- errorOccurred = true;
- firstError = err;
- }
- }
- }
- suspendedThreads.clear();
- suspended = false;
- if (errorOccurred) {
- reportErrorToSA("Error %d while resuming threads", firstError);
- return;
- }
- break;
- }
-
- case SA_CMD_TOGGLE_BREAKPOINT: {
- saCmdBkptResWasError = 1;
-
- // Search line number info for all loaded classes
- jint classCount;
- jclass* classes;
-
- jvmdiError glcRes = jvmdi->GetLoadedClasses(&classCount, &classes);
- if (glcRes != JVMDI_ERROR_NONE) {
- reportErrorToSA("Error %d while getting loaded classes", glcRes);
- return;
- }
- JvmdiRefListDeallocator rld(env, (jobject*) classes, classCount);
-
- bool done = false;
- bool gotOne = false;
- jclass targetClass;
- jmethodID targetMethod;
- jlocation targetLocation;
- jint targetLineNumber;
-
- for (int i = 0; i < classCount && !done; i++) {
- fflush(stderr);
- jclass clazz = classes[i];
- char* srcName;
- jvmdiError sfnRes = jvmdi->GetSourceFileName(clazz, &srcName);
- if (sfnRes == JVMDI_ERROR_NONE) {
- JvmdiDeallocator de1(srcName);
- if (!strcmp(srcName, saCmdBkptSrcFileName)) {
- // Got a match. Now see whether the package name of the class also matches
- char* clazzName;
- jvmdiError sigRes = jvmdi->GetClassSignature(clazz, &clazzName);
- if (sigRes != JVMDI_ERROR_NONE) {
- reportErrorToSA("Error %d while getting a class's signature", sigRes);
- return;
- }
- JvmdiDeallocator de2(clazzName);
- if (packageNameMatches(clazzName + 1, saCmdBkptPkgName)) {
- // Iterate through all methods
- jint methodCount;
- jmethodID* methods;
- if (jvmdi->GetClassMethods(clazz, &methodCount, &methods) != JVMDI_ERROR_NONE) {
- reportErrorToSA("Error while getting methods of class %s", clazzName);
- return;
- }
- JvmdiDeallocator de3(methods);
- for (int j = 0; j < methodCount && !done; j++) {
- jmethodID m = methods[j];
- jint entryCount;
- JVMDI_line_number_entry* table;
- jvmdiError lnRes = jvmdi->GetLineNumberTable(clazz, m, &entryCount, &table);
- if (lnRes == JVMDI_ERROR_NONE) {
- JvmdiDeallocator de4(table);
- // Look for line number greater than or equal to requested line
- for (int k = 0; k < entryCount && !done; k++) {
- JVMDI_line_number_entry& entry = table[k];
- if (entry.line_number >= saCmdBkptLineNumber &&
- (!gotOne || entry.line_number < targetLineNumber)) {
- gotOne = true;
- targetClass = clazz;
- targetMethod = m;
- targetLocation = entry.start_location;
- targetLineNumber = entry.line_number;
- done = (targetLineNumber == saCmdBkptLineNumber);
- }
- }
- } else if (lnRes != JVMDI_ERROR_ABSENT_INFORMATION) {
- reportErrorToSA("Unexpected error %d while fetching line number table", lnRes);
- return;
- }
- }
- }
- }
- } else if (sfnRes != JVMDI_ERROR_ABSENT_INFORMATION) {
- reportErrorToSA("Unexpected error %d while fetching source file name", sfnRes);
- return;
- }
- }
-
- bool wasSet = true;
- if (gotOne) {
- // Really toggle this breakpoint
- jvmdiError bpRes;
- bpRes = jvmdi->SetBreakpoint(targetClass, targetMethod, targetLocation);
- if (bpRes == JVMDI_ERROR_DUPLICATE) {
- bpRes = jvmdi->ClearBreakpoint(targetClass, targetMethod, targetLocation);
- wasSet = false;
- }
- if (bpRes != JVMDI_ERROR_NONE) {
- reportErrorToSA("Unexpected error %d while setting or clearing breakpoint at bci %d, line %d",
- bpRes, targetLocation, targetLineNumber);
- return;
- }
- } else {
- saCmdBkptResWasError = 0;
- reportErrorToSA("No debug information found covering this line");
- return;
- }
-
- // Provide result
- saCmdBkptResLineNumber = targetLineNumber;
- saCmdBkptResBCI = targetLocation;
- saCmdBkptResWasSet = (wasSet ? 1 : 0);
- {
- char* methodName;
- char* methodSig;
- if (jvmdi->GetMethodName(targetClass, targetMethod, &methodName, &methodSig)
- == JVMDI_ERROR_NONE) {
- JvmdiDeallocator mnd(methodName);
- JvmdiDeallocator msd(methodSig);
- strncpy(saCmdBkptResMethodName, methodName, SA_CMD_BUF_SIZE);
- strncpy(saCmdBkptResMethodSig, methodSig, SA_CMD_BUF_SIZE);
- } else {
- strncpy(saCmdBkptResMethodName, "<error>", SA_CMD_BUF_SIZE);
- strncpy(saCmdBkptResMethodSig, "<error>", SA_CMD_BUF_SIZE);
- }
- }
- break;
- }
-
- default:
- reportErrorToSA("Command %d not yet supported", saCmdType);
- return;
- }
-
- // Successful command execution
- saCmdResult = 0;
- saCmdPending = 0;
-}
-
-static void
-saCommandThread(void *arg) {
- JNIEnv* env = NULL;
- if (jvm->GetEnv((void **) &env, JNI_VERSION_1_2) != JNI_OK) {
- stop("Error while starting Serviceability Agent "
- "command thread: could not get JNI environment");
- }
-
- while (1) {
- // Wait for command
- while (!saCmdPending) {
- SLEEP();
- }
-
- executeOneCommand(env);
- }
-}
-
-static void
-saEventHook(JNIEnv *env, JVMDI_Event *event)
-{
- MonitorLocker ml(eventLock);
-
- saEventKind = event->kind;
-
- if (event->kind == JVMDI_EVENT_VM_INIT) {
- // Create event lock
- if (jvmdi->CreateRawMonitor("Serviceability Agent Event Lock", &eventLock)
- != JVMDI_ERROR_NONE) {
- stop("Unable to create Serviceability Agent's event lock");
- }
- // Start thread which receives commands from the SA.
- jclass threadClass = env->FindClass("java/lang/Thread");
- if (threadClass == NULL) stop("Unable to find class java/lang/Thread");
- jstring threadName = env->NewStringUTF("Serviceability Agent Command Thread");
- if (threadName == NULL) stop("Unable to allocate debug thread name");
- jmethodID ctor = env->GetMethodID(threadClass, "<init>", "(Ljava/lang/String;)V");
- if (ctor == NULL) stop("Unable to find appropriate constructor for java/lang/Thread");
- // Allocate thread object
- jthread thr = (jthread) env->NewObject(threadClass, ctor, threadName);
- if (thr == NULL) stop("Unable to allocate debug thread's java/lang/Thread instance");
- // Remember which thread this is
- debugThreadObj = env->NewGlobalRef(thr);
- if (debugThreadObj == NULL) stop("Unable to allocate global ref for debug thread object");
- // Start thread
- jvmdiError err;
- if ((err = jvmdi->RunDebugThread(thr, &saCommandThread, NULL, JVMDI_THREAD_NORM_PRIORITY))
- != JVMDI_ERROR_NONE) {
- char buf[256];
- sprintf(buf, "Error %d while starting debug thread", err);
- stop(buf);
- }
- // OK, initialization is done
- return;
- }
-
- if (!saAttached) {
- return;
- }
-
- switch (event->kind) {
- case JVMDI_EVENT_EXCEPTION: {
- fprintf(stderr, "SA: Exception thrown -- ignoring\n");
- saExceptionThread = event->u.exception.thread;
- saExceptionClass = event->u.exception.clazz;
- saExceptionMethod = event->u.exception.method;
- saExceptionLocation = event->u.exception.location;
- saExceptionException = event->u.exception.exception;
- saExceptionCatchClass = event->u.exception.catch_clazz;
- saExceptionCatchClass = event->u.exception.catch_clazz;
- saExceptionCatchMethod = event->u.exception.catch_method;
- saExceptionCatchLocation = event->u.exception.catch_location;
- // saEventPending = 1;
- break;
- }
-
- case JVMDI_EVENT_BREAKPOINT: {
- saBreakpointThread = event->u.breakpoint.thread;
- saBreakpointClass = event->u.breakpoint.clazz;
- saBreakpointMethod = event->u.breakpoint.method;
- saBreakpointLocation = event->u.breakpoint.location;
- saEventPending = 1;
- break;
- }
-
- default:
- break;
- }
-
- while (saAttached && saEventPending) {
- SLEEP();
- }
-}
-
-extern "C" {
-JNIEXPORT jint JNICALL
-JVM_OnLoad(JavaVM *vm, char *options, void *reserved)
-{
- jvm = vm;
- if (jvm->GetEnv((void**) &jvmdi, JVMDI_VERSION_1) != JNI_OK) {
- return -1;
- }
- if (jvmdi->SetEventHook(&saEventHook) != JVMDI_ERROR_NONE) {
- return -1;
- }
- return 0;
-}
-};
--- a/hotspot/agent/src/share/native/jvmdi/sa.dsp Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,105 +0,0 @@
-# Microsoft Developer Studio Project File - Name="sa" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
-
-CFG=sa - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "sa.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "sa.mak" CFG="sa - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "sa - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "sa - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-MTL=midl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "sa - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SA_EXPORTS" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /I "D:\jdk1.4\include" /I "D:\jdk1.4\include\win32" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SA_EXPORTS" /YX /FD /c
-# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
-
-!ELSEIF "$(CFG)" == "sa - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SA_EXPORTS" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "D:\jdk1.4\include" /I "D:\jdk1.4\include\win32" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SA_EXPORTS" /YX /FD /GZ /c
-# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
-
-!ENDIF
-
-# Begin Target
-
-# Name "sa - Win32 Release"
-# Name "sa - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\sa.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
--- a/hotspot/agent/src/share/native/jvmdi/sa.dsw Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-Microsoft Developer Studio Workspace File, Format Version 6.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "sa"=.\sa.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
--- a/hotspot/agent/src/share/native/jvmdi/sa.hpp Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "jni.h"
-
-extern "C" {
-JNIEXPORT jint JNICALL
-JVM_OnLoad(JavaVM *vm, char *options, void *reserved);
-}
--- a/hotspot/make/Makefile Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/make/Makefile Fri Mar 15 16:39:07 2013 -0700
@@ -464,9 +464,6 @@
$(EXPORT_LIB_DIR)/%.jar: $(GEN_DIR)/%.jar
$(install-file)
-$(EXPORT_JRE_LIB_DIR)/%.jar: $(GEN_DIR)/%.jar
- $(install-file)
-
# Include files (jvmti.h, jvmticmlr.h, jni.h, $(JDK_INCLUDE_SUBDIR)/jni_md.h, jmm.h, jfr.h)
$(EXPORT_INCLUDE_DIR)/%: $(GEN_DIR)/jvmtifiles/%
$(install-file)
--- a/hotspot/make/bsd/makefiles/defs.make Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/make/bsd/makefiles/defs.make Fri Mar 15 16:39:07 2013 -0700
@@ -157,8 +157,6 @@
EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client
EXPORT_MINIMAL_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/minimal
-EXPORT_LIST += $(EXPORT_JRE_LIB_DIR)/wb.jar
-
ifeq ($(findstring true, $(JVM_VARIANT_SERVER) $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.$(LIBRARY_SUFFIX)
--- a/hotspot/make/bsd/makefiles/gcc.make Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/make/bsd/makefiles/gcc.make Fri Mar 15 16:39:07 2013 -0700
@@ -229,6 +229,20 @@
CFLAGS += -DDONT_USE_PRECOMPILED_HEADER
endif
+ifeq ($(OS_VENDOR), Darwin)
+ # Setting these parameters makes it an error to link to macosx APIs that are
+ # newer than the given OS version and makes the linked binaries compatible even
+ # if built on a newer version of the OS.
+ # The expected format is X.Y.Z
+ ifeq ($(MACOSX_VERSION_MIN),)
+ MACOSX_VERSION_MIN=10.7.0
+ endif
+ # The macro takes the version with no dots, ex: 1070
+ CFLAGS += -DMAC_OS_X_VERSION_MAX_ALLOWED=$(subst .,,$(MACOSX_VERSION_MIN)) \
+ -mmacosx-version-min=$(MACOSX_VERSION_MIN)
+ LDFLAGS += -mmacosx-version-min=$(MACOSX_VERSION_MIN)
+endif
+
#------------------------------------------------------------------------
# Linker flags
--- a/hotspot/make/bsd/makefiles/vm.make Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/make/bsd/makefiles/vm.make Fri Mar 15 16:39:07 2013 -0700
@@ -94,7 +94,12 @@
# This is VERY important! The version define must only be supplied to vm_version.o
# If not, ccache will not re-use the cache at all, since the version string might contain
# a time and date.
-vm_version.o: CXXFLAGS += ${JRE_VERSION}
+CXXFLAGS/vm_version.o += ${JRE_VERSION}
+
+CXXFLAGS/BYFILE = $(CXXFLAGS/$@)
+
+# File specific flags
+CXXFLAGS += $(CXXFLAGS/BYFILE)
ifdef DEFAULT_LIBPATH
CXXFLAGS += -DDEFAULT_LIBPATH="\"$(DEFAULT_LIBPATH)\""
@@ -332,9 +337,6 @@
# Serviceability agent
include $(MAKEFILES_DIR)/saproc.make
-# Whitebox testing API
-include $(MAKEFILES_DIR)/wb.make
-
#----------------------------------------------------------------------
ifeq ($(OS_VENDOR), Darwin)
@@ -342,10 +344,10 @@
dsymutil $(LIBJVM)
# no libjvm_db for macosx
-build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(BUILDLIBSAPROC) dtraceCheck $(LIBJVM).dSYM $(WB_JAR)
+build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(BUILDLIBSAPROC) dtraceCheck $(LIBJVM).dSYM
echo "Doing vm.make build:"
else
-build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(BUILDLIBSAPROC) $(WB_JAR)
+build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(BUILDLIBSAPROC)
endif
install: install_jvm install_jsig install_saproc
--- a/hotspot/make/bsd/makefiles/wb.make Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-#
-# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-#
-
-# Rules to build whitebox testing library, used by vm.make
-WB = wb
-
-WBSRCDIR = $(GAMMADIR)/src/share/tools/whitebox
-
-WB_JAR = $(GENERATED)/$(WB).jar
-
-WB_JAVA_SRCS = $(shell find $(WBSRCDIR) -name '*.java')
-WB_JAVA_CLASSDIR = $(GENERATED)/wb/classes
-
-WB_JAVA_CLASSES = $(patsubst $(WBSRCDIR)/%,$(WB_JAVA_CLASSDIR)/%, \
- $(patsubst %.java,%.class,$(WB_JAVA_SRCS)))
-
-$(WB_JAVA_CLASSDIR)/%.class: $(WBSRCDIR)/%.java $(WB_JAVA_CLASSDIR)
- $(REMOTE) $(COMPILE.JAVAC) -sourcepath $(WBSRCDIR) -nowarn -d $(WB_JAVA_CLASSDIR) $<
-
-$(WB_JAR): $(WB_JAVA_CLASSES)
- $(QUIETLY) $(REMOTE) $(RUN.JAR) cf $@ -C $(WB_JAVA_CLASSDIR)/ .
-
-$(WB_JAVA_CLASSDIR):
- $(QUIETLY) mkdir -p $@
-
--- a/hotspot/make/excludeSrc.make Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/make/excludeSrc.make Fri Mar 15 16:39:07 2013 -0700
@@ -78,7 +78,7 @@
Src_Files_EXCLUDE += \
cmsAdaptiveSizePolicy.cpp cmsCollectorPolicy.cpp \
- cmsGCAdaptivePolicyCounters.cpp cmsLockVerifier.cpp cmsPermGen.cpp compactibleFreeListSpace.cpp \
+ cmsGCAdaptivePolicyCounters.cpp cmsLockVerifier.cpp compactibleFreeListSpace.cpp \
concurrentMarkSweepGeneration.cpp concurrentMarkSweepThread.cpp \
freeChunk.cpp adaptiveFreeList.cpp promotionInfo.cpp vmCMSOperations.cpp collectionSetChooser.cpp \
concurrentG1Refine.cpp concurrentG1RefineThread.cpp concurrentMark.cpp concurrentMarkThread.cpp \
@@ -91,11 +91,11 @@
gcTaskManager.cpp gcTaskThread.cpp objectStartArray.cpp parallelScavengeHeap.cpp parMarkBitMap.cpp \
pcTasks.cpp psAdaptiveSizePolicy.cpp psCompactionManager.cpp psGCAdaptivePolicyCounters.cpp \
psGenerationCounters.cpp psMarkSweep.cpp psMarkSweepDecorator.cpp psOldGen.cpp psParallelCompact.cpp \
- psPermGen.cpp psPromotionLAB.cpp psPromotionManager.cpp psScavenge.cpp psTasks.cpp psVirtualspace.cpp \
+ psPromotionLAB.cpp psPromotionManager.cpp psScavenge.cpp psTasks.cpp psVirtualspace.cpp \
psYoungGen.cpp vmPSOperations.cpp asParNewGeneration.cpp parCardTableModRefBS.cpp \
parGCAllocBuffer.cpp parNewGeneration.cpp mutableSpace.cpp gSpaceCounters.cpp allocationStats.cpp \
spaceCounters.cpp gcAdaptivePolicyCounters.cpp mutableNUMASpace.cpp immutableSpace.cpp \
- immutableSpace.cpp g1MemoryPool.cpp psMemoryPool.cpp yieldWorkingGroup.cpp g1Log.cpp
+ immutableSpace.cpp g1MemoryPool.cpp psMemoryPool.cpp yieldingWorkGroup.cpp g1Log.cpp
endif
ifeq ($(INCLUDE_NMT), false)
--- a/hotspot/make/hotspot_version Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/make/hotspot_version Fri Mar 15 16:39:07 2013 -0700
@@ -35,7 +35,7 @@
HS_MAJOR_VER=25
HS_MINOR_VER=0
-HS_BUILD_NUMBER=19
+HS_BUILD_NUMBER=22
JDK_MAJOR_VER=1
JDK_MINOR_VER=8
--- a/hotspot/make/linux/makefiles/defs.make Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/make/linux/makefiles/defs.make Fri Mar 15 16:39:07 2013 -0700
@@ -258,8 +258,6 @@
EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client
EXPORT_MINIMAL_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/minimal
-EXPORT_LIST += $(EXPORT_JRE_LIB_DIR)/wb.jar
-
ifeq ($(findstring true, $(JVM_VARIANT_SERVER) $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.$(LIBRARY_SUFFIX)
--- a/hotspot/make/linux/makefiles/vm.make Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/make/linux/makefiles/vm.make Fri Mar 15 16:39:07 2013 -0700
@@ -100,7 +100,13 @@
# This is VERY important! The version define must only be supplied to vm_version.o
# If not, ccache will not re-use the cache at all, since the version string might contain
# a time and date.
-vm_version.o: CXXFLAGS += ${JRE_VERSION}
+CXXFLAGS/vm_version.o += ${JRE_VERSION}
+
+CXXFLAGS/BYFILE = $(CXXFLAGS/$@)
+
+# File specific flags
+CXXFLAGS += $(CXXFLAGS/BYFILE)
+
ifndef JAVASE_EMBEDDED
ifneq (${ARCH},arm)
@@ -375,12 +381,9 @@
# Serviceability agent
include $(MAKEFILES_DIR)/saproc.make
-# Whitebox testing API
-include $(MAKEFILES_DIR)/wb.make
-
#----------------------------------------------------------------------
-build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(BUILDLIBSAPROC) dtraceCheck $(WB_JAR)
+build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(BUILDLIBSAPROC) dtraceCheck
install: install_jvm install_jsig install_saproc
--- a/hotspot/make/linux/makefiles/wb.make Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-#
-# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-#
-
-# Rules to build whitebox testing library, used by vm.make
-WB = wb
-
-WBSRCDIR = $(GAMMADIR)/src/share/tools/whitebox
-
-WB_JAR = $(GENERATED)/$(WB).jar
-
-WB_JAVA_SRCS = $(shell find $(WBSRCDIR) -name '*.java')
-WB_JAVA_CLASSDIR = $(GENERATED)/wb/classes
-
-WB_JAVA_CLASSES = $(patsubst $(WBSRCDIR)/%,$(WB_JAVA_CLASSDIR)/%, \
- $(patsubst %.java,%.class,$(WB_JAVA_SRCS)))
-
-$(WB_JAVA_CLASSDIR)/%.class: $(WBSRCDIR)/%.java $(WB_JAVA_CLASSDIR)
- $(REMOTE) $(COMPILE.JAVAC) -sourcepath $(WBSRCDIR) -nowarn -d $(WB_JAVA_CLASSDIR) $<
-
-$(WB_JAR): $(WB_JAVA_CLASSES)
- $(QUIETLY) $(REMOTE) $(RUN.JAR) cf $@ -C $(WB_JAVA_CLASSDIR)/ .
-
-$(WB_JAVA_CLASSDIR):
- $(QUIETLY) mkdir -p $@
-
--- a/hotspot/make/sa.files Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/make/sa.files Fri Mar 15 16:39:07 2013 -0700
@@ -24,10 +24,7 @@
# This filelist macro is included in platform specific sa.make
# included all packages/*.java. package list can be generated by
-# $(GAMMADIR)/agent/make/build-pkglist. Then manually removed all
-# classes in sun.jvm.hotspot.ui (and subpackages), all ui classes
-# in sun.jvm.hotspot.bugspot/hotspot and SPARC and x86 disassembler
-# classes and sun.jvm.hotspot.utilities.soql.
+# $(GAMMADIR)/agent/make/build-pkglist.
# define AGENT_DIR before including this file in sa.make
@@ -40,8 +37,6 @@
$(AGENT_SRC_DIR)/sun/jvm/hotspot/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/sparc/*.java \
-$(AGENT_SRC_DIR)/sun/jvm/hotspot/bugspot/*.java \
-$(AGENT_SRC_DIR)/sun/jvm/hotspot/bugspot/tree/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/c1/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/ci/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/code/*.java \
@@ -82,7 +77,6 @@
$(AGENT_SRC_DIR)/sun/jvm/hotspot/gc_interface/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/interpreter/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/jdi/*.java \
-$(AGENT_SRC_DIR)/sun/jvm/hotspot/livejvm/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/memory/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/oops/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/opto/*.java \
--- a/hotspot/make/solaris/makefiles/defs.make Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/make/solaris/makefiles/defs.make Fri Mar 15 16:39:07 2013 -0700
@@ -187,8 +187,6 @@
endif
endif
-EXPORT_LIST += $(EXPORT_JRE_LIB_DIR)/wb.jar
-
EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server
EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client
--- a/hotspot/make/solaris/makefiles/vm.make Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/make/solaris/makefiles/vm.make Fri Mar 15 16:39:07 2013 -0700
@@ -88,7 +88,13 @@
# This is VERY important! The version define must only be supplied to vm_version.o
# If not, ccache will not re-use the cache at all, since the version string might contain
# a time and date.
-vm_version.o: CXXFLAGS += ${JRE_VERSION}
+CXXFLAGS/vm_version.o += ${JRE_VERSION}
+
+CXXFLAGS/BYFILE = $(CXXFLAGS/$@)
+
+# File specific flags
+CXXFLAGS += $(CXXFLAGS/BYFILE)
+
# CFLAGS_WARN holds compiler options to suppress/enable warnings.
CFLAGS += $(CFLAGS_WARN)
@@ -341,12 +347,9 @@
# Serviceability agent
include $(MAKEFILES_DIR)/saproc.make
-# Whitebox testing API
-include $(MAKEFILES_DIR)/wb.make
-
#----------------------------------------------------------------------
-build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(LIBJVM_DTRACE) $(BUILDLIBSAPROC) dtraceCheck $(WB_JAR)
+build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(LIBJVM_DTRACE) $(BUILDLIBSAPROC) dtraceCheck
install: install_jvm install_jsig install_saproc
--- a/hotspot/make/solaris/makefiles/wb.make Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-#
-# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-# Rules to build whitebox testing library, used by vm.make
-
-WB = wb
-
-WBSRCDIR = $(GAMMADIR)/src/share/tools/whitebox
-
-WB_JAR = $(GENERATED)/$(WB).jar
-
-WB_JAVA_SRCS = $(shell find $(WBSRCDIR) -name '*.java')
-WB_JAVA_CLASSDIR = $(GENERATED)/wb/classes
-
-WB_JAVA_CLASSES = $(patsubst $(WBSRCDIR)/%,$(WB_JAVA_CLASSDIR)/%, \
- $(patsubst %.java,%.class,$(WB_JAVA_SRCS)))
-
-$(WB_JAVA_CLASSDIR)/%.class: $(WBSRCDIR)/%.java $(WB_JAVA_CLASSDIR)
- $(REMOTE) $(COMPILE.JAVAC) -sourcepath $(WBSRCDIR) -nowarn -d $(WB_JAVA_CLASSDIR) $<
-
-$(WB_JAR): $(WB_JAVA_CLASSES)
- $(QUIETLY) $(REMOTE) $(RUN.JAR) cf $@ -C $(WB_JAVA_CLASSDIR)/ .
-
-$(WB_JAVA_CLASSDIR):
- $(QUIETLY) mkdir -p $@
-
--- a/hotspot/make/windows/makefiles/debug.make Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/make/windows/makefiles/debug.make Fri Mar 15 16:39:07 2013 -0700
@@ -33,7 +33,7 @@
BUILD_PCH_FILE=_build_pch_file.obj
!endif
-default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA wb
+default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA
!include ../local.make
!include compile.make
@@ -72,4 +72,3 @@
!include $(WorkSpace)/make/windows/makefiles/shared.make
!include $(WorkSpace)/make/windows/makefiles/sa.make
!include $(WorkSpace)/make/windows/makefiles/launcher.make
-!include $(WorkSpace)/make/windows/makefiles/wb.make
--- a/hotspot/make/windows/makefiles/defs.make Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/make/windows/makefiles/defs.make Fri Mar 15 16:39:07 2013 -0700
@@ -277,8 +277,6 @@
endif
endif
-EXPORT_LIST += $(EXPORT_JRE_LIB_DIR)/wb.jar
-
ifeq ($(BUILD_WIN_SA), 1)
EXPORT_LIST += $(EXPORT_JRE_BIN_DIR)/sawindbg.$(LIBRARY_SUFFIX)
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
--- a/hotspot/make/windows/makefiles/fastdebug.make Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/make/windows/makefiles/fastdebug.make Fri Mar 15 16:39:07 2013 -0700
@@ -33,7 +33,7 @@
BUILD_PCH_FILE=_build_pch_file.obj
!endif
-default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA wb
+default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA
!include ../local.make
!include compile.make
@@ -71,4 +71,3 @@
!include $(WorkSpace)/make/windows/makefiles/shared.make
!include $(WorkSpace)/make/windows/makefiles/sa.make
!include $(WorkSpace)/make/windows/makefiles/launcher.make
-!include $(WorkSpace)/make/windows/makefiles/wb.make
--- a/hotspot/make/windows/makefiles/product.make Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/make/windows/makefiles/product.make Fri Mar 15 16:39:07 2013 -0700
@@ -32,7 +32,7 @@
BUILD_PCH_FILE=_build_pch_file.obj
!endif
-default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA wb
+default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA
!include ../local.make
!include compile.make
@@ -82,4 +82,3 @@
!include $(WorkSpace)/make/windows/makefiles/shared.make
!include $(WorkSpace)/make/windows/makefiles/sa.make
!include $(WorkSpace)/make/windows/makefiles/launcher.make
-!include $(WorkSpace)/make/windows/makefiles/wb.make
--- a/hotspot/make/windows/makefiles/wb.make Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-#
-# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-#
-
-# This makefile is used to build the whitebox testing lib
-# and compile the tests which use it
-
-!include $(WorkSpace)/make/windows/makefiles/rules.make
-
-WBSRCDIR = $(WorkSpace)/src/share/tools/whitebox
-
-# turn GENERATED into a windows path to get sane dependencies
-WB_CLASSES=$(GENERATED:/=\)\wb\classes
-WB_JAR=$(GENERATED:/=\)\wb.jar
-
-# call recursive make to do wildcard expansion
-.SUFFIXES : .java .class
-wb_java_srcs: $(WorkSpace)\src\share\tools\whitebox\sun\hotspot\*.java $(WB_CLASSES)
- $(MAKE) -f $(WorkSpace)\make\windows\makefiles\$(BUILD_FLAVOR).make $(**:.java=.class)
-
-
-{$(WorkSpace)\src\share\tools\whitebox\sun\hotspot}.java.class::
- $(COMPILE_JAVAC) -sourcepath $(WBSRCDIR) -d $(WB_CLASSES) $<
-
-$(WB_JAR): wb_java_srcs
- $(RUN_JAR) cf $@ -C $(WB_CLASSES) .
-
-# turn $@ to a unix path because mkdir in PATH is cygwin/mks mkdir
-$(WB_CLASSES):
- mkdir -p $(@:\=/)
-
-# main target to build wb
-wb: $(WB_JAR)
-
--- a/hotspot/src/cpu/sparc/vm/frame_sparc.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/cpu/sparc/vm/frame_sparc.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -216,6 +216,11 @@
}
}
+ // Could just be some random pointer within the codeBlob
+ if (!_cb->code_contains(_pc)) {
+ return false;
+ }
+
// Entry frame checks
if (is_entry_frame()) {
// an entry frame must have a valid fp.
--- a/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -340,8 +340,6 @@
__ bind(notInt);
// __ cmp(O2, JVM_CONSTANT_String);
- __ brx(Assembler::equal, true, Assembler::pt, isString);
- __ delayed()->cmp(O2, JVM_CONSTANT_Object);
__ brx(Assembler::notEqual, true, Assembler::pt, notString);
__ delayed()->ldf(FloatRegisterImpl::S, O0, O1, Ftos_f);
__ bind(isString);
--- a/hotspot/src/cpu/x86/vm/frame_x86.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/cpu/x86/vm/frame_x86.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -91,6 +91,12 @@
return false;
}
}
+
+ // Could just be some random pointer within the codeBlob
+ if (!_cb->code_contains(_pc)) {
+ return false;
+ }
+
// Entry frame checks
if (is_entry_frame()) {
// an entry frame must have a valid fp.
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -2695,7 +2695,7 @@
assert(thread->is_VM_thread(), "Must be VMThread");
// read current suspend action
int action = osthread->sr.suspend_action();
- if (action == SR_SUSPEND) {
+ if (action == os::Bsd::SuspendResume::SR_SUSPEND) {
suspend_save_context(osthread, siginfo, context);
// Notify the suspend action is about to be completed. do_suspend()
@@ -2717,12 +2717,12 @@
do {
sigsuspend(&suspend_set);
// ignore all returns until we get a resume signal
- } while (osthread->sr.suspend_action() != SR_CONTINUE);
+ } while (osthread->sr.suspend_action() != os::Bsd::SuspendResume::SR_CONTINUE);
resume_clear_context(osthread);
} else {
- assert(action == SR_CONTINUE, "unexpected sr action");
+ assert(action == os::Bsd::SuspendResume::SR_CONTINUE, "unexpected sr action");
// nothing special to do - just leave the handler
}
@@ -2776,7 +2776,7 @@
// but this seems the normal response to library errors
static bool do_suspend(OSThread* osthread) {
// mark as suspended and send signal
- osthread->sr.set_suspend_action(SR_SUSPEND);
+ osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_SUSPEND);
int status = pthread_kill(osthread->pthread_id(), SR_signum);
assert_status(status == 0, status, "pthread_kill");
@@ -2785,18 +2785,18 @@
for (int i = 0; !osthread->sr.is_suspended(); i++) {
os::yield_all(i);
}
- osthread->sr.set_suspend_action(SR_NONE);
+ osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_NONE);
return true;
}
else {
- osthread->sr.set_suspend_action(SR_NONE);
+ osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_NONE);
return false;
}
}
static void do_resume(OSThread* osthread) {
assert(osthread->sr.is_suspended(), "thread should be suspended");
- osthread->sr.set_suspend_action(SR_CONTINUE);
+ osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_CONTINUE);
int status = pthread_kill(osthread->pthread_id(), SR_signum);
assert_status(status == 0, status, "pthread_kill");
@@ -2806,7 +2806,7 @@
os::yield_all(i);
}
}
- osthread->sr.set_suspend_action(SR_NONE);
+ osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_NONE);
}
////////////////////////////////////////////////////////////////////////////////
@@ -2887,7 +2887,9 @@
void signalHandler(int sig, siginfo_t* info, void* uc) {
assert(info != NULL && uc != NULL, "it must be old kernel");
+ int orig_errno = errno; // Preserve errno value over signal handler.
JVM_handle_bsd_signal(sig, info, uc, true);
+ errno = orig_errno;
}
@@ -3901,15 +3903,27 @@
jlong os::current_thread_cpu_time() {
#ifdef __APPLE__
return os::thread_cpu_time(Thread::current(), true /* user + sys */);
+#else
+ Unimplemented();
+ return 0;
#endif
}
jlong os::thread_cpu_time(Thread* thread) {
+#ifdef __APPLE__
+ return os::thread_cpu_time(thread, true /* user + sys */);
+#else
+ Unimplemented();
+ return 0;
+#endif
}
jlong os::current_thread_cpu_time(bool user_sys_cpu_time) {
#ifdef __APPLE__
return os::thread_cpu_time(Thread::current(), user_sys_cpu_time);
+#else
+ Unimplemented();
+ return 0;
#endif
}
@@ -3933,6 +3947,9 @@
} else {
return ((jlong)tinfo.user_time.seconds * 1000000000) + ((jlong)tinfo.user_time.microseconds * (jlong)1000);
}
+#else
+ Unimplemented();
+ return 0;
#endif
}
--- a/hotspot/src/os/bsd/vm/os_bsd.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/os/bsd/vm/os_bsd.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -151,36 +151,25 @@
// for BsdThreads are no longer needed.
class SuspendResume {
private:
- volatile int _suspend_action;
+ volatile int _suspend_action;
+ volatile jint _state;
+ public:
// values for suspend_action:
- #define SR_NONE (0x00)
- #define SR_SUSPEND (0x01) // suspend request
- #define SR_CONTINUE (0x02) // resume request
+ enum {
+ SR_NONE = 0x00,
+ SR_SUSPEND = 0x01, // suspend request
+ SR_CONTINUE = 0x02, // resume request
+ SR_SUSPENDED = 0x20 // values for _state: + SR_NONE
+ };
- volatile jint _state;
- // values for _state: + SR_NONE
- #define SR_SUSPENDED (0x20)
- public:
SuspendResume() { _suspend_action = SR_NONE; _state = SR_NONE; }
int suspend_action() const { return _suspend_action; }
void set_suspend_action(int x) { _suspend_action = x; }
// atomic updates for _state
- void set_suspended() {
- jint temp, temp2;
- do {
- temp = _state;
- temp2 = Atomic::cmpxchg(temp | SR_SUSPENDED, &_state, temp);
- } while (temp2 != temp);
- }
- void clear_suspended() {
- jint temp, temp2;
- do {
- temp = _state;
- temp2 = Atomic::cmpxchg(temp & ~SR_SUSPENDED, &_state, temp);
- } while (temp2 != temp);
- }
+ inline void set_suspended();
+ inline void clear_suspended();
bool is_suspended() { return _state & SR_SUSPENDED; }
#undef SR_SUSPENDED
--- a/hotspot/src/os/bsd/vm/os_bsd.inline.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/os/bsd/vm/os_bsd.inline.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -25,7 +25,6 @@
#ifndef OS_BSD_VM_OS_BSD_INLINE_HPP
#define OS_BSD_VM_OS_BSD_INLINE_HPP
-#include "runtime/atomic.hpp"
#include "runtime/atomic.inline.hpp"
#include "runtime/os.hpp"
@@ -286,4 +285,21 @@
const char* optval, socklen_t optlen) {
return ::setsockopt(fd, level, optname, optval, optlen);
}
+
+inline void os::Bsd::SuspendResume::set_suspended() {
+ jint temp, temp2;
+ do {
+ temp = _state;
+ temp2 = Atomic::cmpxchg(temp | SR_SUSPENDED, &_state, temp);
+ } while (temp2 != temp);
+}
+
+inline void os::Bsd::SuspendResume::clear_suspended() {
+ jint temp, temp2;
+ do {
+ temp = _state;
+ temp2 = Atomic::cmpxchg(temp & ~SR_SUSPENDED, &_state, temp);
+ } while (temp2 != temp);
+}
+
#endif // OS_BSD_VM_OS_BSD_INLINE_HPP
--- a/hotspot/src/os/linux/vm/os_linux.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/os/linux/vm/os_linux.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -3461,7 +3461,7 @@
assert(thread->is_VM_thread(), "Must be VMThread");
// read current suspend action
int action = osthread->sr.suspend_action();
- if (action == SR_SUSPEND) {
+ if (action == os::Linux::SuspendResume::SR_SUSPEND) {
suspend_save_context(osthread, siginfo, context);
// Notify the suspend action is about to be completed. do_suspend()
@@ -3483,12 +3483,12 @@
do {
sigsuspend(&suspend_set);
// ignore all returns until we get a resume signal
- } while (osthread->sr.suspend_action() != SR_CONTINUE);
+ } while (osthread->sr.suspend_action() != os::Linux::SuspendResume::SR_CONTINUE);
resume_clear_context(osthread);
} else {
- assert(action == SR_CONTINUE, "unexpected sr action");
+ assert(action == os::Linux::SuspendResume::SR_CONTINUE, "unexpected sr action");
// nothing special to do - just leave the handler
}
@@ -3542,7 +3542,7 @@
// but this seems the normal response to library errors
static bool do_suspend(OSThread* osthread) {
// mark as suspended and send signal
- osthread->sr.set_suspend_action(SR_SUSPEND);
+ osthread->sr.set_suspend_action(os::Linux::SuspendResume::SR_SUSPEND);
int status = pthread_kill(osthread->pthread_id(), SR_signum);
assert_status(status == 0, status, "pthread_kill");
@@ -3551,18 +3551,18 @@
for (int i = 0; !osthread->sr.is_suspended(); i++) {
os::yield_all(i);
}
- osthread->sr.set_suspend_action(SR_NONE);
+ osthread->sr.set_suspend_action(os::Linux::SuspendResume::SR_NONE);
return true;
}
else {
- osthread->sr.set_suspend_action(SR_NONE);
+ osthread->sr.set_suspend_action(os::Linux::SuspendResume::SR_NONE);
return false;
}
}
static void do_resume(OSThread* osthread) {
assert(osthread->sr.is_suspended(), "thread should be suspended");
- osthread->sr.set_suspend_action(SR_CONTINUE);
+ osthread->sr.set_suspend_action(os::Linux::SuspendResume::SR_CONTINUE);
int status = pthread_kill(osthread->pthread_id(), SR_signum);
assert_status(status == 0, status, "pthread_kill");
@@ -3572,7 +3572,7 @@
os::yield_all(i);
}
}
- osthread->sr.set_suspend_action(SR_NONE);
+ osthread->sr.set_suspend_action(os::Linux::SuspendResume::SR_NONE);
}
////////////////////////////////////////////////////////////////////////////////
@@ -3653,7 +3653,9 @@
void signalHandler(int sig, siginfo_t* info, void* uc) {
assert(info != NULL && uc != NULL, "it must be old kernel");
+ int orig_errno = errno; // Preserve errno value over signal handler.
JVM_handle_linux_signal(sig, info, uc, true);
+ errno = orig_errno;
}
@@ -4741,49 +4743,26 @@
//
static jlong slow_thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {
- static bool proc_pid_cpu_avail = true;
static bool proc_task_unchecked = true;
static const char *proc_stat_path = "/proc/%d/stat";
pid_t tid = thread->osthread()->thread_id();
- int i;
char *s;
char stat[2048];
int statlen;
char proc_name[64];
int count;
long sys_time, user_time;
- char string[64];
char cdummy;
int idummy;
long ldummy;
FILE *fp;
- // We first try accessing /proc/<pid>/cpu since this is faster to
- // process. If this file is not present (linux kernels 2.5 and above)
- // then we open /proc/<pid>/stat.
- if ( proc_pid_cpu_avail ) {
- sprintf(proc_name, "/proc/%d/cpu", tid);
- fp = fopen(proc_name, "r");
- if ( fp != NULL ) {
- count = fscanf( fp, "%s %lu %lu\n", string, &user_time, &sys_time);
- fclose(fp);
- if ( count != 3 ) return -1;
-
- if (user_sys_cpu_time) {
- return ((jlong)sys_time + (jlong)user_time) * (1000000000 / clock_tics_per_sec);
- } else {
- return (jlong)user_time * (1000000000 / clock_tics_per_sec);
- }
- }
- else proc_pid_cpu_avail = false;
- }
-
// The /proc/<tid>/stat aggregates per-process usage on
// new Linux kernels 2.6+ where NPTL is supported.
// The /proc/self/task/<tid>/stat still has the per-thread usage.
// See bug 6328462.
- // There can be no directory /proc/self/task on kernels 2.4 with NPTL
- // and possibly in some other cases, so we check its availability.
+ // There possibly can be cases where there is no directory
+ // /proc/self/task, so we check its availability.
if (proc_task_unchecked && os::Linux::is_NPTL()) {
// This is executed only once
proc_task_unchecked = false;
@@ -4808,7 +4787,6 @@
// We don't really need to know the command string, just find the last
// occurrence of ")" and then start parsing from there. See bug 4726580.
s = strrchr(stat, ')');
- i = 0;
if (s == NULL ) return -1;
// Skip blank chars
--- a/hotspot/src/os/linux/vm/os_linux.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/os/linux/vm/os_linux.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -209,39 +209,27 @@
// for LinuxThreads are no longer needed.
class SuspendResume {
private:
- volatile int _suspend_action;
+ volatile int _suspend_action;
+ volatile jint _state;
+ public:
// values for suspend_action:
- #define SR_NONE (0x00)
- #define SR_SUSPEND (0x01) // suspend request
- #define SR_CONTINUE (0x02) // resume request
+ enum {
+ SR_NONE = 0x00,
+ SR_SUSPEND = 0x01, // suspend request
+ SR_CONTINUE = 0x02, // resume request
+ SR_SUSPENDED = 0x20 // values for _state: + SR_NONE
+ };
- volatile jint _state;
- // values for _state: + SR_NONE
- #define SR_SUSPENDED (0x20)
- public:
SuspendResume() { _suspend_action = SR_NONE; _state = SR_NONE; }
int suspend_action() const { return _suspend_action; }
void set_suspend_action(int x) { _suspend_action = x; }
// atomic updates for _state
- void set_suspended() {
- jint temp, temp2;
- do {
- temp = _state;
- temp2 = Atomic::cmpxchg(temp | SR_SUSPENDED, &_state, temp);
- } while (temp2 != temp);
- }
- void clear_suspended() {
- jint temp, temp2;
- do {
- temp = _state;
- temp2 = Atomic::cmpxchg(temp & ~SR_SUSPENDED, &_state, temp);
- } while (temp2 != temp);
- }
+ inline void set_suspended();
+ inline void clear_suspended();
bool is_suspended() { return _state & SR_SUSPENDED; }
- #undef SR_SUSPENDED
};
private:
--- a/hotspot/src/os/linux/vm/os_linux.inline.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/os/linux/vm/os_linux.inline.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -25,7 +25,6 @@
#ifndef OS_LINUX_VM_OS_LINUX_INLINE_HPP
#define OS_LINUX_VM_OS_LINUX_INLINE_HPP
-#include "runtime/atomic.hpp"
#include "runtime/atomic.inline.hpp"
#include "runtime/os.hpp"
@@ -288,4 +287,21 @@
const char* optval, socklen_t optlen) {
return ::setsockopt(fd, level, optname, optval, optlen);
}
+
+inline void os::Linux::SuspendResume::set_suspended() {
+ jint temp, temp2;
+ do {
+ temp = _state;
+ temp2 = Atomic::cmpxchg(temp | SR_SUSPENDED, &_state, temp);
+ } while (temp2 != temp);
+}
+
+inline void os::Linux::SuspendResume::clear_suspended() {
+ jint temp, temp2;
+ do {
+ temp = _state;
+ temp2 = Atomic::cmpxchg(temp & ~SR_SUSPENDED, &_state, temp);
+ } while (temp2 != temp);
+}
+
#endif // OS_LINUX_VM_OS_LINUX_INLINE_HPP
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -1865,7 +1865,7 @@
// Die immediately, no exit hook, no abort hook, no cleanup.
void os::die() {
- _exit(-1);
+ ::abort(); // dump core (for debugging)
}
// unused
@@ -4317,7 +4317,9 @@
void signalHandler(int sig, siginfo_t* info, void* ucVoid) {
+ int orig_errno = errno; // Preserve errno value over signal handler.
JVM_handle_solaris_signal(sig, info, ucVoid, true);
+ errno = orig_errno;
}
/* Do not delete - if guarantee is ever removed, a signal handler (even empty)
--- a/hotspot/src/os/solaris/vm/os_solaris.inline.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/os/solaris/vm/os_solaris.inline.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -25,7 +25,6 @@
#ifndef OS_SOLARIS_VM_OS_SOLARIS_INLINE_HPP
#define OS_SOLARIS_VM_OS_SOLARIS_INLINE_HPP
-#include "runtime/atomic.hpp"
#include "runtime/atomic.inline.hpp"
#include "runtime/os.hpp"
--- a/hotspot/src/os/windows/vm/decoder_windows.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/os/windows/vm/decoder_windows.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "prims/jvm.h"
+#include "runtime/arguments.hpp"
#include "decoder_windows.hpp"
WindowsDecoder::WindowsDecoder() {
--- a/hotspot/src/os/windows/vm/os_windows.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/os/windows/vm/os_windows.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -1940,7 +1940,7 @@
// a counter for each possible signal value, including signal_thread exit signal
static volatile jint pending_signals[NSIG+1] = { 0 };
-static HANDLE sig_sem;
+static HANDLE sig_sem = NULL;
void os::signal_init_pd() {
// Initialize signal structures
@@ -1970,10 +1970,11 @@
void os::signal_notify(int signal_number) {
BOOL ret;
-
- Atomic::inc(&pending_signals[signal_number]);
- ret = ::ReleaseSemaphore(sig_sem, 1, NULL);
- assert(ret != 0, "ReleaseSemaphore() failed");
+ if (sig_sem != NULL) {
+ Atomic::inc(&pending_signals[signal_number]);
+ ret = ::ReleaseSemaphore(sig_sem, 1, NULL);
+ assert(ret != 0, "ReleaseSemaphore() failed");
+ }
}
static int check_pending_signals(bool wait_for_signal) {
--- a/hotspot/src/os/windows/vm/os_windows.inline.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/os/windows/vm/os_windows.inline.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -25,7 +25,6 @@
#ifndef OS_WINDOWS_VM_OS_WINDOWS_INLINE_HPP
#define OS_WINDOWS_VM_OS_WINDOWS_INLINE_HPP
-#include "runtime/atomic.hpp"
#include "runtime/atomic.inline.hpp"
#include "runtime/os.hpp"
--- a/hotspot/src/os_cpu/bsd_x86/vm/atomic_bsd_x86.inline.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/os_cpu/bsd_x86/vm/atomic_bsd_x86.inline.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,6 @@
#ifndef OS_CPU_BSD_X86_VM_ATOMIC_BSD_X86_INLINE_HPP
#define OS_CPU_BSD_X86_VM_ATOMIC_BSD_X86_INLINE_HPP
-#include "orderAccess_bsd_x86.inline.hpp"
#include "runtime/atomic.hpp"
#include "runtime/os.hpp"
#include "vm_version_x86.hpp"
--- a/hotspot/src/os_cpu/bsd_x86/vm/orderAccess_bsd_x86.inline.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/os_cpu/bsd_x86/vm/orderAccess_bsd_x86.inline.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,8 +25,9 @@
#ifndef OS_CPU_BSD_X86_VM_ORDERACCESS_BSD_X86_INLINE_HPP
#define OS_CPU_BSD_X86_VM_ORDERACCESS_BSD_X86_INLINE_HPP
-#include "runtime/atomic.hpp"
+#include "runtime/atomic.inline.hpp"
#include "runtime/orderAccess.hpp"
+#include "runtime/os.hpp"
#include "vm_version_x86.hpp"
// Implementation of class OrderAccess.
--- a/hotspot/src/os_cpu/bsd_zero/vm/atomic_bsd_zero.inline.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/os_cpu/bsd_zero/vm/atomic_bsd_zero.inline.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright 2007, 2008, 2011 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -26,7 +26,6 @@
#ifndef OS_CPU_BSD_ZERO_VM_ATOMIC_BSD_ZERO_INLINE_HPP
#define OS_CPU_BSD_ZERO_VM_ATOMIC_BSD_ZERO_INLINE_HPP
-#include "orderAccess_bsd_zero.inline.hpp"
#include "runtime/atomic.hpp"
#include "runtime/os.hpp"
#include "vm_version_zero.hpp"
--- a/hotspot/src/os_cpu/linux_sparc/vm/atomic_linux_sparc.inline.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/os_cpu/linux_sparc/vm/atomic_linux_sparc.inline.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,6 @@
#ifndef OS_CPU_LINUX_SPARC_VM_ATOMIC_LINUX_SPARC_INLINE_HPP
#define OS_CPU_LINUX_SPARC_VM_ATOMIC_LINUX_SPARC_INLINE_HPP
-#include "orderAccess_linux_sparc.inline.hpp"
#include "runtime/atomic.hpp"
#include "runtime/os.hpp"
#include "vm_version_sparc.hpp"
--- a/hotspot/src/os_cpu/linux_x86/vm/atomic_linux_x86.inline.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/os_cpu/linux_x86/vm/atomic_linux_x86.inline.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,6 @@
#ifndef OS_CPU_LINUX_X86_VM_ATOMIC_LINUX_X86_INLINE_HPP
#define OS_CPU_LINUX_X86_VM_ATOMIC_LINUX_X86_INLINE_HPP
-#include "orderAccess_linux_x86.inline.hpp"
#include "runtime/atomic.hpp"
#include "runtime/os.hpp"
#include "vm_version_x86.hpp"
--- a/hotspot/src/os_cpu/linux_x86/vm/orderAccess_linux_x86.inline.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/os_cpu/linux_x86/vm/orderAccess_linux_x86.inline.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,8 +25,9 @@
#ifndef OS_CPU_LINUX_X86_VM_ORDERACCESS_LINUX_X86_INLINE_HPP
#define OS_CPU_LINUX_X86_VM_ORDERACCESS_LINUX_X86_INLINE_HPP
-#include "runtime/atomic.hpp"
+#include "runtime/atomic.inline.hpp"
#include "runtime/orderAccess.hpp"
+#include "runtime/os.hpp"
#include "vm_version_x86.hpp"
// Implementation of class OrderAccess.
--- a/hotspot/src/os_cpu/linux_zero/vm/atomic_linux_zero.inline.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/os_cpu/linux_zero/vm/atomic_linux_zero.inline.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright 2007, 2008, 2011 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -26,7 +26,6 @@
#ifndef OS_CPU_LINUX_ZERO_VM_ATOMIC_LINUX_ZERO_INLINE_HPP
#define OS_CPU_LINUX_ZERO_VM_ATOMIC_LINUX_ZERO_INLINE_HPP
-#include "orderAccess_linux_zero.inline.hpp"
#include "runtime/atomic.hpp"
#include "runtime/os.hpp"
#include "vm_version_zero.hpp"
--- a/hotspot/src/os_cpu/solaris_sparc/vm/atomic_solaris_sparc.inline.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/atomic_solaris_sparc.inline.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,6 @@
#ifndef OS_CPU_SOLARIS_SPARC_VM_ATOMIC_SOLARIS_SPARC_INLINE_HPP
#define OS_CPU_SOLARIS_SPARC_VM_ATOMIC_SOLARIS_SPARC_INLINE_HPP
-#include "orderAccess_solaris_sparc.inline.hpp"
#include "runtime/atomic.hpp"
#include "runtime/os.hpp"
#include "vm_version_sparc.hpp"
--- a/hotspot/src/os_cpu/solaris_sparc/vm/orderAccess_solaris_sparc.inline.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/orderAccess_solaris_sparc.inline.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
#ifndef OS_CPU_SOLARIS_SPARC_VM_ORDERACCESS_SOLARIS_SPARC_INLINE_HPP
#define OS_CPU_SOLARIS_SPARC_VM_ORDERACCESS_SOLARIS_SPARC_INLINE_HPP
+#include "runtime/atomic.inline.hpp"
#include "runtime/orderAccess.hpp"
#include "vm_version_sparc.hpp"
--- a/hotspot/src/os_cpu/solaris_x86/vm/atomic_solaris_x86.inline.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/os_cpu/solaris_x86/vm/atomic_solaris_x86.inline.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,6 @@
#ifndef OS_CPU_SOLARIS_X86_VM_ATOMIC_SOLARIS_X86_INLINE_HPP
#define OS_CPU_SOLARIS_X86_VM_ATOMIC_SOLARIS_X86_INLINE_HPP
-#include "orderAccess_solaris_x86.inline.hpp"
#include "runtime/atomic.hpp"
#include "runtime/os.hpp"
#include "vm_version_x86.hpp"
--- a/hotspot/src/os_cpu/solaris_x86/vm/orderAccess_solaris_x86.inline.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/os_cpu/solaris_x86/vm/orderAccess_solaris_x86.inline.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
#ifndef OS_CPU_SOLARIS_X86_VM_ORDERACCESS_SOLARIS_X86_INLINE_HPP
#define OS_CPU_SOLARIS_X86_VM_ORDERACCESS_SOLARIS_X86_INLINE_HPP
-#include "runtime/atomic.hpp"
+#include "runtime/atomic.inline.hpp"
#include "runtime/orderAccess.hpp"
#include "runtime/os.hpp"
#include "vm_version_x86.hpp"
--- a/hotspot/src/os_cpu/windows_x86/vm/atomic_windows_x86.inline.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/os_cpu/windows_x86/vm/atomic_windows_x86.inline.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,6 @@
#ifndef OS_CPU_WINDOWS_X86_VM_ATOMIC_WINDOWS_X86_INLINE_HPP
#define OS_CPU_WINDOWS_X86_VM_ATOMIC_WINDOWS_X86_INLINE_HPP
-#include "orderAccess_windows_x86.inline.hpp"
#include "runtime/atomic.hpp"
#include "runtime/os.hpp"
#include "vm_version_x86.hpp"
--- a/hotspot/src/os_cpu/windows_x86/vm/orderAccess_windows_x86.inline.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/os_cpu/windows_x86/vm/orderAccess_windows_x86.inline.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,12 +25,11 @@
#ifndef OS_CPU_WINDOWS_X86_VM_ORDERACCESS_WINDOWS_X86_INLINE_HPP
#define OS_CPU_WINDOWS_X86_VM_ORDERACCESS_WINDOWS_X86_INLINE_HPP
-#include "runtime/atomic.hpp"
+#include "runtime/atomic.inline.hpp"
#include "runtime/orderAccess.hpp"
+#include "runtime/os.hpp"
#include "vm_version_x86.hpp"
-#pragma warning(disable: 4035) // Disables warnings reporting missing return statement
-
// Implementation of class OrderAccess.
inline void OrderAccess::loadload() { acquire(); }
@@ -214,6 +213,4 @@
#endif // AMD64
}
-#pragma warning(default: 4035) // Enables warnings reporting missing return statement
-
#endif // OS_CPU_WINDOWS_X86_VM_ORDERACCESS_WINDOWS_X86_INLINE_HPP
--- a/hotspot/src/share/tools/whitebox/sun/hotspot/WhiteBox.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.hotspot;
-
-import java.lang.reflect.Method;
-import java.security.BasicPermission;
-import sun.hotspot.parser.DiagnosticCommand;
-
-public class WhiteBox {
-
- @SuppressWarnings("serial")
- public static class WhiteBoxPermission extends BasicPermission {
- public WhiteBoxPermission(String s) {
- super(s);
- }
- }
-
- private WhiteBox() {}
- private static final WhiteBox instance = new WhiteBox();
- private static native void registerNatives();
-
- /**
- * Returns the singleton WhiteBox instance.
- *
- * The returned WhiteBox object should be carefully guarded
- * by the caller, since it can be used to read and write data
- * at arbitrary memory addresses. It must never be passed to
- * untrusted code.
- */
- public synchronized static WhiteBox getWhiteBox() {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- sm.checkPermission(new WhiteBoxPermission("getInstance"));
- }
- return instance;
- }
-
- static {
- registerNatives();
- }
-
- // Memory
- public native long getObjectAddress(Object o);
- public native int getHeapOopSize();
-
- // Runtime
- // Make sure class name is in the correct format
- public boolean isClassAlive(String name) {
- return isClassAlive0(name.replace('.', '/'));
- }
- private native boolean isClassAlive0(String name);
-
- // G1
- public native boolean g1InConcurrentMark();
- public native boolean g1IsHumongous(Object o);
- public native long g1NumFreeRegions();
- public native int g1RegionSize();
- public native Object[] parseCommandLine(String commandline, DiagnosticCommand[] args);
-
- // NMT
- public native boolean NMTAllocTest();
- public native boolean NMTFreeTestMemory();
- public native boolean NMTWaitForDataMerge();
-
- // Compiler
- public native void deoptimizeAll();
- public native boolean isMethodCompiled(Method method);
- public native boolean isMethodCompilable(Method method);
- public native boolean isMethodQueuedForCompilation(Method method);
- public native int deoptimizeMethod(Method method);
- public native void makeMethodNotCompilable(Method method);
- public native int getMethodCompilationLevel(Method method);
- public native boolean setDontInlineMethod(Method method, boolean value);
- public native int getCompileQueuesSize();
-}
--- a/hotspot/src/share/tools/whitebox/sun/hotspot/parser/DiagnosticCommand.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-package sun.hotspot.parser;
-
-public class DiagnosticCommand {
-
- public enum DiagnosticArgumentType {
- JLONG, BOOLEAN, STRING, NANOTIME, STRINGARRAY, MEMORYSIZE
- }
-
- private String name;
- private String desc;
- private DiagnosticArgumentType type;
- private boolean mandatory;
- private String defaultValue;
-
- public DiagnosticCommand(String name, String desc, DiagnosticArgumentType type,
- boolean mandatory, String defaultValue) {
- this.name = name;
- this.desc = desc;
- this.type = type;
- this.mandatory = mandatory;
- this.defaultValue = defaultValue;
- }
-
- public String getName() {
- return name;
- }
-
- public String getDesc() {
- return desc;
- }
-
- public DiagnosticArgumentType getType() {
- return type;
- }
-
- public boolean isMandatory() {
- return mandatory;
- }
-
- public String getDefaultValue() {
- return defaultValue;
- }
-}
--- a/hotspot/src/share/vm/adlc/formssel.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/adlc/formssel.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -753,10 +753,11 @@
!strcmp(_matrule->_rChild->_opType,"DecodeNKlass") ||
!strcmp(_matrule->_rChild->_opType,"EncodePKlass") ||
!strcmp(_matrule->_rChild->_opType,"LoadN") ||
- !strcmp(_matrule->_rChild->_opType,"GetAndSetN") ||
!strcmp(_matrule->_rChild->_opType,"LoadNKlass") ||
!strcmp(_matrule->_rChild->_opType,"CreateEx") || // type of exception
- !strcmp(_matrule->_rChild->_opType,"CheckCastPP")) ) return true;
+ !strcmp(_matrule->_rChild->_opType,"CheckCastPP") ||
+ !strcmp(_matrule->_rChild->_opType,"GetAndSetP") ||
+ !strcmp(_matrule->_rChild->_opType,"GetAndSetN")) ) return true;
else if ( is_ideal_load() == Form::idealP ) return true;
else if ( is_ideal_store() != Form::none ) return true;
--- a/hotspot/src/share/vm/c1/c1_FrameMap.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/c1/c1_FrameMap.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -308,27 +308,6 @@
return sp_offset_for_monitor_base(index) + in_ByteSize(BasicObjectLock::obj_offset_in_bytes());
}
-void FrameMap::print_frame_layout() const {
- int svar;
- tty->print_cr("#####################################");
- tty->print_cr("Frame size in words %d", framesize());
-
- if( _num_monitors > 0) {
- tty->print_cr("monitor [0]:%d | [%2d]:%d",
- in_bytes(sp_offset_for_monitor_base(0)),
- in_bytes(sp_offset_for_monitor_base(_num_monitors)));
- }
- if( _num_spills > 0) {
- svar = _num_spills - 1;
- if(svar == 0)
- tty->print_cr("spill [0]:%d", in_bytes(sp_offset_for_spill(0)));
- else
- tty->print_cr("spill [0]:%d | [%2d]:%d", in_bytes(sp_offset_for_spill(0)),
- svar,
- in_bytes(sp_offset_for_spill(svar)));
- }
-}
-
// For OopMaps, map a local variable or spill index to an VMReg.
// This is the offset from sp() in the frame of the slot for the index,
--- a/hotspot/src/share/vm/c1/c1_FrameMap.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/c1/c1_FrameMap.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -226,8 +226,6 @@
return make_new_address(sp_offset_for_monitor_object(monitor_index));
}
- void print_frame_layout() const;
-
// Creates Location describing desired slot and returns it via pointer
// to Location object. Returns true if the stack frame offset was legal
// (as defined by Location::legal_offset_in_bytes()), false otherwise.
--- a/hotspot/src/share/vm/c1/c1_LIR.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/c1/c1_LIR.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -814,7 +814,7 @@
// only visit register parameters
int n = opJavaCall->_arguments->length();
- for (int i = 0; i < n; i++) {
+ for (int i = opJavaCall->_receiver->is_valid() ? 1 : 0; i < n; i++) {
if (!opJavaCall->_arguments->at(i)->is_pointer()) {
do_input(*opJavaCall->_arguments->adr_at(i));
}
--- a/hotspot/src/share/vm/ci/ciEnv.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/ci/ciEnv.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -597,10 +597,6 @@
assert (klass->is_instance_klass() || klass->is_array_klass(),
"must be an instance or array klass ");
return ciConstant(T_OBJECT, klass->java_mirror());
- } else if (tag.is_object()) {
- oop obj = cpool->object_at(index);
- ciObject* ciobj = get_object(obj);
- return ciConstant(T_OBJECT, ciobj);
} else if (tag.is_method_type()) {
// must execute Java code to link this CP entry into cache[i].f1
ciSymbol* signature = get_symbol(cpool->method_type_signature_at(index));
--- a/hotspot/src/share/vm/classfile/classLoaderData.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/classfile/classLoaderData.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -234,6 +234,7 @@
void add_to_deallocate_list(Metadata* m);
static ClassLoaderData* class_loader_data(oop loader);
+ static ClassLoaderData* class_loader_data_or_null(oop loader);
static ClassLoaderData* anonymous_class_loader_data(oop loader, TRAPS);
static void print_loader(ClassLoaderData *loader_data, outputStream *out);
--- a/hotspot/src/share/vm/classfile/classLoaderData.inline.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/classfile/classLoaderData.inline.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -25,9 +25,15 @@
#include "classfile/classLoaderData.hpp"
#include "classfile/javaClasses.hpp"
+inline ClassLoaderData* ClassLoaderData::class_loader_data_or_null(oop loader) {
+ if (loader == NULL) {
+ return ClassLoaderData::the_null_class_loader_data();
+ }
+ return java_lang_ClassLoader::loader_data(loader);
+}
+
inline ClassLoaderData* ClassLoaderData::class_loader_data(oop loader) {
- if (loader == NULL) return ClassLoaderData::the_null_class_loader_data();
- ClassLoaderData* loader_data = java_lang_ClassLoader::loader_data(loader);
+ ClassLoaderData* loader_data = class_loader_data_or_null(loader);
assert(loader_data != NULL, "Must be");
return loader_data;
}
--- a/hotspot/src/share/vm/classfile/dictionary.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/classfile/dictionary.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -347,6 +347,7 @@
assert_locked_or_safepoint(SystemDictionary_lock);
assert(obj() != NULL, "adding NULL obj");
assert(obj()->name() == class_name, "sanity check on name");
+ assert(loader_data != NULL, "Must be non-NULL");
unsigned int hash = compute_hash(class_name, loader_data);
int index = hash_to_index(hash);
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -866,16 +866,22 @@
// the new entry.
Klass* SystemDictionary::find(Symbol* class_name,
- Handle class_loader,
- Handle protection_domain,
- TRAPS) {
+ Handle class_loader,
+ Handle protection_domain,
+ TRAPS) {
// UseNewReflection
// The result of this call should be consistent with the result
// of the call to resolve_instance_class_or_null().
// See evaluation 6790209 and 4474172 for more details.
class_loader = Handle(THREAD, java_lang_ClassLoader::non_reflection_class_loader(class_loader()));
- ClassLoaderData* loader_data = register_loader(class_loader, CHECK_NULL);
+ ClassLoaderData* loader_data = ClassLoaderData::class_loader_data_or_null(class_loader());
+
+ if (loader_data == NULL) {
+ // If the ClassLoaderData has not been setup,
+ // then the class loader has no entries in the dictionary.
+ return NULL;
+ }
unsigned int d_hash = dictionary()->compute_hash(class_name, loader_data);
int d_index = dictionary()->hash_to_index(d_hash);
--- a/hotspot/src/share/vm/classfile/verifier.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/classfile/verifier.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -61,7 +61,8 @@
# include "bytes_ppc.hpp"
#endif
-#define NOFAILOVER_MAJOR_VERSION 51
+#define NOFAILOVER_MAJOR_VERSION 51
+#define STATIC_METHOD_IN_INTERFACE_MAJOR_VERSION 52
// Access to external entry for VerifyClassCodes - old byte code verifier
@@ -2317,6 +2318,11 @@
types = (1 << JVM_CONSTANT_InterfaceMethodref) |
(1 << JVM_CONSTANT_Methodref);
break;
+ case Bytecodes::_invokestatic:
+ types = (_klass->major_version() < STATIC_METHOD_IN_INTERFACE_MAJOR_VERSION) ?
+ (1 << JVM_CONSTANT_Methodref) :
+ ((1 << JVM_CONSTANT_InterfaceMethodref) | (1 << JVM_CONSTANT_Methodref));
+ break;
default:
types = 1 << JVM_CONSTANT_Methodref;
}
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -300,8 +300,7 @@
}
}
-// Wait until the next synchronous GC, a concurrent full gc request,
-// or a timeout, whichever is earlier.
+// Wait until any cms_lock event
void ConcurrentMarkSweepThread::wait_on_cms_lock(long t_millis) {
MutexLockerEx x(CGC_lock,
Mutex::_no_safepoint_check_flag);
@@ -315,15 +314,100 @@
"Should not be set");
}
+// Wait until the next synchronous GC, a concurrent full gc request,
+// or a timeout, whichever is earlier.
+void ConcurrentMarkSweepThread::wait_on_cms_lock_for_scavenge(long t_millis) {
+ // Wait time in millis or 0 value representing infinite wait for a scavenge
+ assert(t_millis >= 0, "Wait time for scavenge should be 0 or positive");
+
+ GenCollectedHeap* gch = GenCollectedHeap::heap();
+ double start_time_secs = os::elapsedTime();
+ double end_time_secs = start_time_secs + (t_millis / ((double) MILLIUNITS));
+
+ // Total collections count before waiting loop
+ unsigned int before_count;
+ {
+ MutexLockerEx hl(Heap_lock, Mutex::_no_safepoint_check_flag);
+ before_count = gch->total_collections();
+ }
+
+ unsigned int loop_count = 0;
+
+ while(!_should_terminate) {
+ double now_time = os::elapsedTime();
+ long wait_time_millis;
+
+ if(t_millis != 0) {
+ // New wait limit
+ wait_time_millis = (long) ((end_time_secs - now_time) * MILLIUNITS);
+ if(wait_time_millis <= 0) {
+ // Wait time is over
+ break;
+ }
+ } else {
+ // No wait limit, wait if necessary forever
+ wait_time_millis = 0;
+ }
+
+ // Wait until the next event or the remaining timeout
+ {
+ MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
+
+ if (_should_terminate || _collector->_full_gc_requested) {
+ return;
+ }
+ set_CMS_flag(CMS_cms_wants_token); // to provoke notifies
+ assert(t_millis == 0 || wait_time_millis > 0, "Sanity");
+ CGC_lock->wait(Mutex::_no_safepoint_check_flag, wait_time_millis);
+ clear_CMS_flag(CMS_cms_wants_token);
+ assert(!CMS_flag_is_set(CMS_cms_has_token | CMS_cms_wants_token),
+ "Should not be set");
+ }
+
+ // Extra wait time check before entering the heap lock to get the collection count
+ if(t_millis != 0 && os::elapsedTime() >= end_time_secs) {
+ // Wait time is over
+ break;
+ }
+
+ // Total collections count after the event
+ unsigned int after_count;
+ {
+ MutexLockerEx hl(Heap_lock, Mutex::_no_safepoint_check_flag);
+ after_count = gch->total_collections();
+ }
+
+ if(before_count != after_count) {
+ // There was a collection - success
+ break;
+ }
+
+ // Too many loops warning
+ if(++loop_count == 0) {
+ warning("wait_on_cms_lock_for_scavenge() has looped %u times", loop_count - 1);
+ }
+ }
+}
+
void ConcurrentMarkSweepThread::sleepBeforeNextCycle() {
while (!_should_terminate) {
if (CMSIncrementalMode) {
icms_wait();
+ if(CMSWaitDuration >= 0) {
+ // Wait until the next synchronous GC, a concurrent full gc
+ // request or a timeout, whichever is earlier.
+ wait_on_cms_lock_for_scavenge(CMSWaitDuration);
+ }
return;
} else {
- // Wait until the next synchronous GC, a concurrent full gc
- // request or a timeout, whichever is earlier.
- wait_on_cms_lock(CMSWaitDuration);
+ if(CMSWaitDuration >= 0) {
+ // Wait until the next synchronous GC, a concurrent full gc
+ // request or a timeout, whichever is earlier.
+ wait_on_cms_lock_for_scavenge(CMSWaitDuration);
+ } else {
+ // Wait until any cms_lock event or check interval not to call shouldConcurrentCollect permanently
+ wait_on_cms_lock(CMSCheckInterval);
+ }
}
// Check if we should start a CMS collection cycle
if (_collector->shouldConcurrentCollect()) {
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -130,6 +130,12 @@
// A concurrent full gc request terminates the wait.
void wait_on_cms_lock(long t_millis);
+ // Wait on CMS lock until the next synchronous GC
+ // or given timeout, whichever is earlier. A timeout value
+ // of 0 indicates that there is no upper bound on the wait time.
+ // A concurrent full gc request terminates the wait.
+ void wait_on_cms_lock_for_scavenge(long t_millis);
+
// The CMS thread will yield during the work portion of its cycle
// only when requested to. Both synchronous and asychronous requests
// are provided:
--- a/hotspot/src/share/vm/gc_implementation/g1/collectionSetChooser.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/gc_implementation/g1/collectionSetChooser.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -146,43 +146,6 @@
verify();
}
-uint CollectionSetChooser::calc_min_old_cset_length() {
- // The min old CSet region bound is based on the maximum desired
- // number of mixed GCs after a cycle. I.e., even if some old regions
- // look expensive, we should add them to the CSet anyway to make
- // sure we go through the available old regions in no more than the
- // maximum desired number of mixed GCs.
- //
- // The calculation is based on the number of marked regions we added
- // to the CSet chooser in the first place, not how many remain, so
- // that the result is the same during all mixed GCs that follow a cycle.
-
- const size_t region_num = (size_t) _length;
- const size_t gc_num = (size_t) G1MixedGCCountTarget;
- size_t result = region_num / gc_num;
- // emulate ceiling
- if (result * gc_num < region_num) {
- result += 1;
- }
- return (uint) result;
-}
-
-uint CollectionSetChooser::calc_max_old_cset_length() {
- // The max old CSet region bound is based on the threshold expressed
- // as a percentage of the heap size. I.e., it should bound the
- // number of old regions added to the CSet irrespective of how many
- // of them are available.
-
- G1CollectedHeap* g1h = G1CollectedHeap::heap();
- const size_t region_num = g1h->n_regions();
- const size_t perc = (size_t) G1OldCSetRegionThresholdPercent;
- size_t result = region_num * perc / 100;
- // emulate ceiling
- if (100 * result < region_num * perc) {
- result += 1;
- }
- return (uint) result;
-}
void CollectionSetChooser::add_region(HeapRegion* hr) {
assert(!hr->isHumongous(),
--- a/hotspot/src/share/vm/gc_implementation/g1/collectionSetChooser.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/gc_implementation/g1/collectionSetChooser.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -51,6 +51,8 @@
uint _curr_index;
// The number of candidate old regions added to the CSet chooser.
+ // Note: this is not updated when removing a region using
+ // remove_and_move_to_next() below.
uint _length;
// Keeps track of the start of the next array chunk to be claimed by
@@ -111,13 +113,8 @@
hr->live_bytes() < _region_live_threshold_bytes;
}
- // Calculate the minimum number of old regions we'll add to the CSet
- // during a mixed GC.
- uint calc_min_old_cset_length();
-
- // Calculate the maximum number of old regions we'll add to the CSet
- // during a mixed GC.
- uint calc_max_old_cset_length();
+ // Returns the number candidate old regions added
+ uint length() { return _length; }
// Serial version.
void add_region(HeapRegion *hr);
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -117,7 +117,7 @@
if (G1Log::fine()) {
gclog_or_tty->date_stamp(PrintGCDateStamps);
gclog_or_tty->stamp(PrintGCTimeStamps);
- gclog_or_tty->print_cr("[GC concurrent-root-region-scan-end, %1.7lf]",
+ gclog_or_tty->print_cr("[GC concurrent-root-region-scan-end, %1.7lf secs]",
scan_end - scan_start);
}
}
@@ -150,7 +150,7 @@
if (G1Log::fine()) {
gclog_or_tty->date_stamp(PrintGCDateStamps);
gclog_or_tty->stamp(PrintGCTimeStamps);
- gclog_or_tty->print_cr("[GC concurrent-mark-end, %1.7lf sec]",
+ gclog_or_tty->print_cr("[GC concurrent-mark-end, %1.7lf secs]",
mark_end_sec - mark_start_sec);
}
@@ -234,7 +234,7 @@
if (G1Log::fine()) {
gclog_or_tty->date_stamp(PrintGCDateStamps);
gclog_or_tty->stamp(PrintGCTimeStamps);
- gclog_or_tty->print_cr("[GC concurrent-cleanup-end, %1.7lf]",
+ gclog_or_tty->print_cr("[GC concurrent-cleanup-end, %1.7lf secs]",
cleanup_end_sec - cleanup_start_sec);
}
}
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -267,7 +267,15 @@
double max_gc_time = (double) MaxGCPauseMillis / 1000.0;
double time_slice = (double) GCPauseIntervalMillis / 1000.0;
_mmu_tracker = new G1MMUTrackerQueue(time_slice, max_gc_time);
- _sigma = (double) G1ConfidencePercent / 100.0;
+
+ uintx confidence_perc = G1ConfidencePercent;
+ // Put an artificial ceiling on this so that it's not set to a silly value.
+ if (confidence_perc > 100) {
+ confidence_perc = 100;
+ warning("G1ConfidencePercent is set to a value that is too large, "
+ "it's been updated to %u", confidence_perc);
+ }
+ _sigma = (double) confidence_perc / 100.0;
// start conservatively (around 50ms is about right)
_concurrent_mark_remark_times_ms->add(0.05);
@@ -1798,6 +1806,14 @@
}
#endif // !PRODUCT
+double G1CollectorPolicy::reclaimable_bytes_perc(size_t reclaimable_bytes) {
+ // Returns the given amount of reclaimable bytes (that represents
+ // the amount of reclaimable space still to be collected) as a
+ // percentage of the current heap capacity.
+ size_t capacity_bytes = _g1->capacity();
+ return (double) reclaimable_bytes * 100.0 / (double) capacity_bytes;
+}
+
bool G1CollectorPolicy::next_gc_should_be_mixed(const char* true_action_str,
const char* false_action_str) {
CollectionSetChooser* cset_chooser = _collectionSetChooser;
@@ -1807,19 +1823,21 @@
ergo_format_reason("candidate old regions not available"));
return false;
}
+
+ // Is the amount of uncollected reclaimable space above G1HeapWastePercent?
size_t reclaimable_bytes = cset_chooser->remaining_reclaimable_bytes();
- size_t capacity_bytes = _g1->capacity();
- double perc = (double) reclaimable_bytes * 100.0 / (double) capacity_bytes;
+ double reclaimable_perc = reclaimable_bytes_perc(reclaimable_bytes);
double threshold = (double) G1HeapWastePercent;
- if (perc < threshold) {
+ if (reclaimable_perc <= threshold) {
ergo_verbose4(ErgoMixedGCs,
false_action_str,
- ergo_format_reason("reclaimable percentage lower than threshold")
+ ergo_format_reason("reclaimable percentage not over threshold")
ergo_format_region("candidate old regions")
ergo_format_byte_perc("reclaimable")
ergo_format_perc("threshold"),
cset_chooser->remaining_regions(),
- reclaimable_bytes, perc, threshold);
+ reclaimable_bytes,
+ reclaimable_perc, threshold);
return false;
}
@@ -1830,10 +1848,50 @@
ergo_format_byte_perc("reclaimable")
ergo_format_perc("threshold"),
cset_chooser->remaining_regions(),
- reclaimable_bytes, perc, threshold);
+ reclaimable_bytes,
+ reclaimable_perc, threshold);
return true;
}
+uint G1CollectorPolicy::calc_min_old_cset_length() {
+ // The min old CSet region bound is based on the maximum desired
+ // number of mixed GCs after a cycle. I.e., even if some old regions
+ // look expensive, we should add them to the CSet anyway to make
+ // sure we go through the available old regions in no more than the
+ // maximum desired number of mixed GCs.
+ //
+ // The calculation is based on the number of marked regions we added
+ // to the CSet chooser in the first place, not how many remain, so
+ // that the result is the same during all mixed GCs that follow a cycle.
+
+ const size_t region_num = (size_t) _collectionSetChooser->length();
+ const size_t gc_num = (size_t) MAX2(G1MixedGCCountTarget, (uintx) 1);
+ size_t result = region_num / gc_num;
+ // emulate ceiling
+ if (result * gc_num < region_num) {
+ result += 1;
+ }
+ return (uint) result;
+}
+
+uint G1CollectorPolicy::calc_max_old_cset_length() {
+ // The max old CSet region bound is based on the threshold expressed
+ // as a percentage of the heap size. I.e., it should bound the
+ // number of old regions added to the CSet irrespective of how many
+ // of them are available.
+
+ G1CollectedHeap* g1h = G1CollectedHeap::heap();
+ const size_t region_num = g1h->n_regions();
+ const size_t perc = (size_t) G1OldCSetRegionThresholdPercent;
+ size_t result = region_num * perc / 100;
+ // emulate ceiling
+ if (100 * result < region_num * perc) {
+ result += 1;
+ }
+ return (uint) result;
+}
+
+
void G1CollectorPolicy::finalize_cset(double target_pause_time_ms) {
double young_start_time_sec = os::elapsedTime();
@@ -1847,7 +1905,7 @@
double base_time_ms = predict_base_elapsed_time_ms(_pending_cards);
double predicted_pause_time_ms = base_time_ms;
- double time_remaining_ms = target_pause_time_ms - base_time_ms;
+ double time_remaining_ms = MAX2(target_pause_time_ms - base_time_ms, 0.0);
ergo_verbose4(ErgoCSetConstruction | ErgoHigh,
"start choosing CSet",
@@ -1885,7 +1943,7 @@
_collection_set = _inc_cset_head;
_collection_set_bytes_used_before = _inc_cset_bytes_used_before;
- time_remaining_ms -= _inc_cset_predicted_elapsed_time_ms;
+ time_remaining_ms = MAX2(time_remaining_ms - _inc_cset_predicted_elapsed_time_ms, 0.0);
predicted_pause_time_ms += _inc_cset_predicted_elapsed_time_ms;
ergo_verbose3(ErgoCSetConstruction | ErgoHigh,
@@ -1909,8 +1967,8 @@
if (!gcs_are_young()) {
CollectionSetChooser* cset_chooser = _collectionSetChooser;
cset_chooser->verify();
- const uint min_old_cset_length = cset_chooser->calc_min_old_cset_length();
- const uint max_old_cset_length = cset_chooser->calc_max_old_cset_length();
+ const uint min_old_cset_length = calc_min_old_cset_length();
+ const uint max_old_cset_length = calc_max_old_cset_length();
uint expensive_region_num = 0;
bool check_time_remaining = adaptive_young_list_length();
@@ -1928,6 +1986,30 @@
break;
}
+
+ // Stop adding regions if the remaining reclaimable space is
+ // not above G1HeapWastePercent.
+ size_t reclaimable_bytes = cset_chooser->remaining_reclaimable_bytes();
+ double reclaimable_perc = reclaimable_bytes_perc(reclaimable_bytes);
+ double threshold = (double) G1HeapWastePercent;
+ if (reclaimable_perc <= threshold) {
+ // We've added enough old regions that the amount of uncollected
+ // reclaimable space is at or below the waste threshold. Stop
+ // adding old regions to the CSet.
+ ergo_verbose5(ErgoCSetConstruction,
+ "finish adding old regions to CSet",
+ ergo_format_reason("reclaimable percentage not over threshold")
+ ergo_format_region("old")
+ ergo_format_region("max")
+ ergo_format_byte_perc("reclaimable")
+ ergo_format_perc("threshold"),
+ old_cset_region_length(),
+ max_old_cset_length,
+ reclaimable_bytes,
+ reclaimable_perc, threshold);
+ break;
+ }
+
double predicted_time_ms = predict_region_elapsed_time_ms(hr, gcs_are_young());
if (check_time_remaining) {
if (predicted_time_ms > time_remaining_ms) {
@@ -1967,7 +2049,7 @@
}
// We will add this region to the CSet.
- time_remaining_ms -= predicted_time_ms;
+ time_remaining_ms = MAX2(time_remaining_ms - predicted_time_ms, 0.0);
predicted_pause_time_ms += predicted_time_ms;
cset_chooser->remove_and_move_to_next(hr);
_g1->old_set_remove(hr);
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -619,6 +619,18 @@
bool predict_will_fit(uint young_length, double base_time_ms,
uint base_free_regions, double target_pause_time_ms);
+ // Calculate the minimum number of old regions we'll add to the CSet
+ // during a mixed GC.
+ uint calc_min_old_cset_length();
+
+ // Calculate the maximum number of old regions we'll add to the CSet
+ // during a mixed GC.
+ uint calc_max_old_cset_length();
+
+ // Returns the given amount of uncollected reclaimable space
+ // as a percentage of the current heap capacity.
+ double reclaimable_bytes_perc(size_t reclaimable_bytes);
+
public:
G1CollectorPolicy();
--- a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -32,7 +32,7 @@
#define G1_FLAGS(develop, develop_pd, product, product_pd, diagnostic, experimental, notproduct, manageable, product_rw) \
\
- product(intx, G1ConfidencePercent, 50, \
+ product(uintx, G1ConfidencePercent, 50, \
"Confidence level for MMU/pause predictions") \
\
develop(intx, G1MarkingOverheadPercent, 0, \
--- a/hotspot/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -373,6 +373,8 @@
" does not exceed used.end() = " PTR_FORMAT ","
" yet last_chunk_index_to_check " INTPTR_FORMAT
" exceeds last_chunk_index " INTPTR_FORMAT,
+ last_block, last_block + last_block_size,
+ used.end(),
last_chunk_index_to_check, last_chunk_index));
assert(sp->used_region().end() > used.end(),
err_msg("Expansion did not happen: "
--- a/hotspot/src/share/vm/interpreter/bytecodeTracer.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/interpreter/bytecodeTracer.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -335,9 +335,6 @@
st->print_cr(" %s", constants->resolved_klass_at(i)->external_name());
} else if (tag.is_unresolved_klass()) {
st->print_cr(" <unresolved klass at %d>", i);
- } else if (tag.is_object()) {
- st->print(" <Object>");
- print_oop(constants->object_at(i), st);
} else if (tag.is_method_type()) {
int i2 = constants->method_type_index_at(i);
st->print(" <MethodType> %d", i2);
--- a/hotspot/src/share/vm/interpreter/linkResolver.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -1241,7 +1241,6 @@
void LinkResolver::resolve_invokedynamic(CallInfo& result, constantPoolHandle pool, int index, TRAPS) {
assert(EnableInvokeDynamic, "");
- pool->set_has_invokedynamic(); // mark header to flag active call sites
//resolve_pool(<resolved_klass>, method_name, method_signature, current_klass, pool, index, CHECK);
Symbol* method_name = pool->name_ref_at(index);
--- a/hotspot/src/share/vm/interpreter/rewriter.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/interpreter/rewriter.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -48,7 +48,6 @@
add_cp_cache_entry(i);
break;
case JVM_CONSTANT_String:
- case JVM_CONSTANT_Object:
case JVM_CONSTANT_MethodHandle : // fall through
case JVM_CONSTANT_MethodType : // fall through
add_resolved_references_entry(i);
@@ -238,7 +237,7 @@
address p = bcp + offset;
int cp_index = is_wide ? Bytes::get_Java_u2(p) : (u1)(*p);
constantTag tag = _pool->tag_at(cp_index).value();
- if (tag.is_method_handle() || tag.is_method_type() || tag.is_string() || tag.is_object()) {
+ if (tag.is_method_handle() || tag.is_method_type() || tag.is_string()) {
int ref_index = cp_entry_to_resolved_references(cp_index);
if (is_wide) {
(*bcp) = Bytecodes::_fast_aldc_w;
--- a/hotspot/src/share/vm/memory/allocation.inline.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/memory/allocation.inline.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
#ifndef SHARE_VM_MEMORY_ALLOCATION_INLINE_HPP
#define SHARE_VM_MEMORY_ALLOCATION_INLINE_HPP
+#include "runtime/atomic.inline.hpp"
#include "runtime/os.hpp"
// Explicit C-heap memory management
--- a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -694,7 +694,7 @@
if (failed) {
if (!failures) {
tty->cr();
- tty->print_cr("== CT verification failed: ["PTR_FORMAT","PTR_FORMAT"]");
+ tty->print_cr("== CT verification failed: ["PTR_FORMAT","PTR_FORMAT"]", start, end);
tty->print_cr("== %sexpecting value: %d",
(val_equals) ? "" : "not ", val);
failures = true;
--- a/hotspot/src/share/vm/memory/cardTableRS.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/memory/cardTableRS.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -353,7 +353,7 @@
assert(jp >= _begin && jp < _end,
err_msg("Error: jp " PTR_FORMAT " should be within "
"[_begin, _end) = [" PTR_FORMAT "," PTR_FORMAT ")",
- _begin, _end));
+ jp, _begin, _end));
oop obj = oopDesc::load_decode_heap_oop(p);
guarantee(obj == NULL || (HeapWord*)obj >= _boundary,
err_msg("pointer " PTR_FORMAT " at " PTR_FORMAT " on "
--- a/hotspot/src/share/vm/memory/collectorPolicy.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/memory/collectorPolicy.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -168,11 +168,11 @@
void GenCollectorPolicy::initialize_size_policy(size_t init_eden_size,
size_t init_promo_size,
size_t init_survivor_size) {
- const double max_gc_minor_pause_sec = ((double) MaxGCMinorPauseMillis)/1000.0;
+ const double max_gc_pause_sec = ((double) MaxGCPauseMillis)/1000.0;
_size_policy = new AdaptiveSizePolicy(init_eden_size,
init_promo_size,
init_survivor_size,
- max_gc_minor_pause_sec,
+ max_gc_pause_sec,
GCTimeRatio);
}
--- a/hotspot/src/share/vm/memory/metaspaceCounters.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/memory/metaspaceCounters.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -25,12 +25,14 @@
#include "precompiled.hpp"
#include "memory/metaspaceCounters.hpp"
#include "memory/resourceArea.hpp"
-
-#define METASPACE_NAME "perm"
+#include "utilities/exceptions.hpp"
MetaspaceCounters* MetaspaceCounters::_metaspace_counters = NULL;
-MetaspaceCounters::MetaspaceCounters() {
+MetaspaceCounters::MetaspaceCounters() :
+ _capacity(NULL),
+ _used(NULL),
+ _max_capacity(NULL) {
if (UsePerfData) {
size_t min_capacity = MetaspaceAux::min_chunk_size();
size_t max_capacity = MetaspaceAux::reserved_in_bytes();
@@ -41,6 +43,25 @@
}
}
+static PerfVariable* create_ms_variable(const char *ns,
+ const char *name,
+ size_t value,
+ TRAPS) {
+ const char *path = PerfDataManager::counter_name(ns, name);
+ PerfVariable *result =
+ PerfDataManager::create_variable(SUN_GC, path, PerfData::U_Bytes, value,
+ CHECK_NULL);
+ return result;
+}
+
+static void create_ms_constant(const char *ns,
+ const char *name,
+ size_t value,
+ TRAPS) {
+ const char *path = PerfDataManager::counter_name(ns, name);
+ PerfDataManager::create_constant(SUN_GC, path, PerfData::U_Bytes, value, CHECK);
+}
+
void MetaspaceCounters::initialize(size_t min_capacity,
size_t max_capacity,
size_t curr_capacity,
@@ -50,93 +71,32 @@
EXCEPTION_MARK;
ResourceMark rm;
- // Create a name that will be recognized by jstat tools as
- // the perm gen. Change this to a Metaspace name when the
- // tools are fixed.
- // name to recognize "sun.gc.generation.2.*"
-
- const char* name = METASPACE_NAME;
- const int ordinal = 2;
- const int spaces = 1;
-
- const char* cns = PerfDataManager::name_space("generation", ordinal);
-
- _name_space = NEW_C_HEAP_ARRAY(char, strlen(cns)+1, mtClass);
- strcpy(_name_space, cns);
-
- const char* cname = PerfDataManager::counter_name(_name_space, "name");
- PerfDataManager::create_string_constant(SUN_GC, cname, name, CHECK);
-
- // End of perm gen like name creation
-
- cname = PerfDataManager::counter_name(_name_space, "spaces");
- PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_None,
- spaces, CHECK);
-
- cname = PerfDataManager::counter_name(_name_space, "minCapacity");
- PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_Bytes,
- min_capacity, CHECK);
-
- cname = PerfDataManager::counter_name(_name_space, "maxCapacity");
- PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_Bytes,
- max_capacity, CHECK);
+ const char *ms = "metaspace";
- cname = PerfDataManager::counter_name(_name_space, "capacity");
- _current_size =
- PerfDataManager::create_variable(SUN_GC, cname, PerfData::U_Bytes,
- curr_capacity, CHECK);
-
- // SpaceCounter like counters
- // name to recognize "sun.gc.generation.2.space.0.*"
- {
- const int space_ordinal = 0;
- const char* cns = PerfDataManager::name_space(_name_space, "space",
- space_ordinal);
-
- char* space_name_space = NEW_C_HEAP_ARRAY(char, strlen(cns)+1, mtClass);
- strcpy(space_name_space, cns);
-
- const char* cname = PerfDataManager::counter_name(space_name_space, "name");
- PerfDataManager::create_string_constant(SUN_GC, cname, name, CHECK);
-
- cname = PerfDataManager::counter_name(space_name_space, "maxCapacity");
- _max_capacity = PerfDataManager::create_variable(SUN_GC, cname,
- PerfData::U_Bytes,
- (jlong)max_capacity, CHECK);
-
- cname = PerfDataManager::counter_name(space_name_space, "capacity");
- _capacity = PerfDataManager::create_variable(SUN_GC, cname,
- PerfData::U_Bytes,
- curr_capacity, CHECK);
-
- cname = PerfDataManager::counter_name(space_name_space, "used");
- _used = PerfDataManager::create_variable(SUN_GC,
- cname,
- PerfData::U_Bytes,
- used,
- CHECK);
-
- cname = PerfDataManager::counter_name(space_name_space, "initCapacity");
- PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_Bytes,
- min_capacity, CHECK);
- }
+ create_ms_constant(ms, "minCapacity", min_capacity, CHECK);
+ _max_capacity = create_ms_variable(ms, "maxCapacity", max_capacity, CHECK);
+ _capacity = create_ms_variable(ms, "capacity", curr_capacity, CHECK);
+ _used = create_ms_variable(ms, "used", used, CHECK);
}
}
void MetaspaceCounters::update_capacity() {
assert(UsePerfData, "Should not be called unless being used");
+ assert(_capacity != NULL, "Should be initialized");
size_t capacity_in_bytes = MetaspaceAux::capacity_in_bytes();
_capacity->set_value(capacity_in_bytes);
}
void MetaspaceCounters::update_used() {
assert(UsePerfData, "Should not be called unless being used");
+ assert(_used != NULL, "Should be initialized");
size_t used_in_bytes = MetaspaceAux::used_in_bytes();
_used->set_value(used_in_bytes);
}
void MetaspaceCounters::update_max_capacity() {
assert(UsePerfData, "Should not be called unless being used");
+ assert(_max_capacity != NULL, "Should be initialized");
size_t reserved_in_bytes = MetaspaceAux::reserved_in_bytes();
_max_capacity->set_value(reserved_in_bytes);
}
@@ -146,18 +106,19 @@
update_used();
update_capacity();
update_max_capacity();
- _current_size->set_value(MetaspaceAux::reserved_in_bytes());
}
}
void MetaspaceCounters::initialize_performance_counters() {
if (UsePerfData) {
+ assert(_metaspace_counters == NULL, "Should only be initialized once");
_metaspace_counters = new MetaspaceCounters();
}
}
void MetaspaceCounters::update_performance_counters() {
if (UsePerfData) {
+ assert(_metaspace_counters != NULL, "Should be initialized");
_metaspace_counters->update_all();
}
}
--- a/hotspot/src/share/vm/memory/metaspaceCounters.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/memory/metaspaceCounters.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -29,11 +29,9 @@
class MetaspaceCounters: public CHeapObj<mtClass> {
friend class VMStructs;
- PerfVariable* _current_size;
PerfVariable* _capacity;
PerfVariable* _used;
PerfVariable* _max_capacity;
- char* _name_space;
static MetaspaceCounters* _metaspace_counters;
void initialize(size_t min_capacity,
size_t max_capacity,
--- a/hotspot/src/share/vm/oops/constantPool.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/oops/constantPool.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -695,10 +695,6 @@
result_oop = string_at_impl(this_oop, index, cache_index, CHECK_NULL);
break;
- case JVM_CONSTANT_Object:
- result_oop = this_oop->object_at(index);
- break;
-
case JVM_CONSTANT_MethodHandleInError:
case JVM_CONSTANT_MethodTypeInError:
{
@@ -1824,8 +1820,6 @@
st->print_cr(internal_name());
if (flags() != 0) {
st->print(" - flags: 0x%x", flags());
- if (has_pseudo_string()) st->print(" has_pseudo_string");
- if (has_invokedynamic()) st->print(" has_invokedynamic");
if (has_preresolution()) st->print(" has_preresolution");
if (on_stack()) st->print(" on_stack");
st->cr();
@@ -1869,13 +1863,14 @@
st->print(" name_and_type_index=%d", uncached_name_and_type_ref_index_at(index));
break;
case JVM_CONSTANT_String :
- unresolved_string_at(index)->print_value_on(st);
+ if (is_pseudo_string_at(index)) {
+ oop anObj = pseudo_string_at(index);
+ anObj->print_value_on(st);
+ st->print(" {0x%lx}", (address)anObj);
+ } else {
+ unresolved_string_at(index)->print_value_on(st);
+ }
break;
- case JVM_CONSTANT_Object : {
- oop anObj = object_at(index);
- anObj->print_value_on(st);
- st->print(" {0x%lx}", (address)anObj);
- } break;
case JVM_CONSTANT_Integer :
st->print("%d", int_at(index));
break;
@@ -1939,8 +1934,6 @@
void ConstantPool::print_value_on(outputStream* st) const {
assert(is_constantPool(), "must be constantPool");
st->print("constant pool [%d]", length());
- if (has_pseudo_string()) st->print("/pseudo_string");
- if (has_invokedynamic()) st->print("/invokedynamic");
if (has_preresolution()) st->print("/preresolution");
if (operands() != NULL) st->print("/operands[%d]", operands()->length());
print_address_on(st);
--- a/hotspot/src/share/vm/oops/constantPool.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/oops/constantPool.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -97,10 +97,8 @@
Array<u2>* _reference_map;
enum {
- _has_invokedynamic = 1, // Flags
- _has_pseudo_string = 2,
- _has_preresolution = 4,
- _on_stack = 8
+ _has_preresolution = 1, // Flags
+ _on_stack = 2
};
int _flags; // old fashioned bit twiddling
@@ -175,12 +173,6 @@
Array<u1>* tags() const { return _tags; }
Array<u2>* operands() const { return _operands; }
- bool has_invokedynamic() const { return (_flags & _has_invokedynamic) != 0; }
- void set_has_invokedynamic() { _flags |= _has_invokedynamic; }
-
- bool has_pseudo_string() const { return (_flags & _has_pseudo_string) != 0; }
- void set_has_pseudo_string() { _flags |= _has_pseudo_string; }
-
bool has_preresolution() const { return (_flags & _has_preresolution) != 0; }
void set_has_preresolution() { _flags |= _has_preresolution; }
@@ -324,14 +316,6 @@
resolved_references()->obj_at_put(obj_index, str);
}
- void set_object_tag_at(int which) {
- release_tag_at_put(which, JVM_CONSTANT_Object);
- }
-
- void object_at_put(int which, oop obj) {
- resolved_references()->obj_at_put(cp_to_object_index(which), obj);
- }
-
// For temporary use while constructing constant pool
void string_index_at_put(int which, int string_index) {
tag_at_put(which, JVM_CONSTANT_StringIndex);
@@ -429,12 +413,6 @@
// Version that can be used before string oop array is created.
oop uncached_string_at(int which, TRAPS);
- oop object_at(int which) {
- assert(tag_at(which).is_object(), "Corrupted constant pool");
- int obj_index = cp_to_object_index(which);
- return resolved_references()->obj_at(obj_index);
- }
-
// A "pseudo-string" is an non-string oop that has found is way into
// a String entry.
// Under EnableInvokeDynamic this can happen if the user patches a live
@@ -454,10 +432,18 @@
return s;
}
+ oop pseudo_string_at(int which) {
+ assert(tag_at(which).is_string(), "Corrupted constant pool");
+ assert(unresolved_string_at(which) == NULL, "shouldn't have symbol");
+ int obj_index = cp_to_object_index(which);
+ oop s = resolved_references()->obj_at(obj_index);
+ return s;
+ }
+
void pseudo_string_at_put(int which, int obj_index, oop x) {
assert(EnableInvokeDynamic, "");
- set_has_pseudo_string(); // mark header
assert(tag_at(which).is_string(), "Corrupted constant pool");
+ unresolved_string_at_put(which, NULL); // indicates patched string
string_at_put(which, obj_index, x); // this works just fine
}
--- a/hotspot/src/share/vm/oops/generateOopMap.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/oops/generateOopMap.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1853,7 +1853,6 @@
if (tag.is_klass() ||
tag.is_unresolved_klass() ||
tag.is_string() ||
- tag.is_object() ||
tag.is_method_handle() ||
tag.is_method_type()) {
assert(bt == T_OBJECT, "Guard is incorrect");
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -2170,7 +2170,11 @@
if (impl != NULL) {
if (!impl->is_loader_alive(is_alive)) {
// remove this guy
- *adr_implementor() = NULL;
+ Klass** klass = adr_implementor();
+ assert(klass != NULL, "null klass");
+ if (klass != NULL) {
+ *klass = NULL;
+ }
}
}
}
@@ -3151,9 +3155,10 @@
if (protection_domain() != NULL) {
guarantee(protection_domain()->is_oop(), "should be oop");
}
- if (host_klass() != NULL) {
- guarantee(host_klass()->is_metadata(), "should be in metaspace");
- guarantee(host_klass()->is_klass(), "should be klass");
+ const Klass* host = host_klass();
+ if (host != NULL) {
+ guarantee(host->is_metadata(), "should be in metaspace");
+ guarantee(host->is_klass(), "should be klass");
}
if (signers() != NULL) {
guarantee(signers()->is_objArray(), "should be obj array");
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -536,7 +536,9 @@
assert(is_anonymous(), "not anonymous");
Klass** addr = (Klass**)adr_host_klass();
assert(addr != NULL, "no reversed space");
- *addr = host;
+ if (addr != NULL) {
+ *addr = host;
+ }
}
bool is_anonymous() const {
return (_misc_flags & _misc_is_anonymous) != 0;
@@ -758,7 +760,10 @@
void set_implementor(Klass* k) {
assert(is_interface(), "not interface");
Klass** addr = adr_implementor();
- *addr = k;
+ assert(addr != NULL, "null addr");
+ if (addr != NULL) {
+ *addr = k;
+ }
}
int nof_implementors() const {
--- a/hotspot/src/share/vm/oops/method.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/oops/method.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -456,6 +456,8 @@
void print_codes_on(int from, int to, outputStream* st) const PRODUCT_RETURN;
// method parameters
+ bool has_method_parameters() const
+ { return constMethod()->has_method_parameters(); }
int method_parameters_length() const
{ return constMethod()->method_parameters_length(); }
MethodParametersElement* method_parameters_start() const
--- a/hotspot/src/share/vm/oops/symbol.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/oops/symbol.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
#include "classfile/altHashing.hpp"
#include "classfile/classLoaderData.hpp"
#include "oops/symbol.hpp"
+#include "runtime/atomic.inline.hpp"
#include "runtime/os.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
@@ -210,6 +211,28 @@
return AltHashing::murmur3_32(seed, (const jbyte*)as_C_string(), utf8_length());
}
+void Symbol::increment_refcount() {
+ // Only increment the refcount if positive. If negative either
+ // overflow has occurred or it is a permanent symbol in a read only
+ // shared archive.
+ if (_refcount >= 0) {
+ Atomic::inc(&_refcount);
+ NOT_PRODUCT(Atomic::inc(&_total_count);)
+ }
+}
+
+void Symbol::decrement_refcount() {
+ if (_refcount >= 0) {
+ Atomic::dec(&_refcount);
+#ifdef ASSERT
+ if (_refcount < 0) {
+ print();
+ assert(false, "reference count underflow for symbol");
+ }
+#endif
+ }
+}
+
void Symbol::print_on(outputStream* st) const {
if (this == NULL) {
st->print_cr("NULL");
--- a/hotspot/src/share/vm/oops/symbol.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/oops/symbol.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,6 @@
#include "utilities/utf8.hpp"
#include "memory/allocation.hpp"
-#include "runtime/atomic.hpp"
// A Symbol is a canonicalized string.
// All Symbols reside in global SymbolTable and are reference counted.
@@ -150,8 +149,8 @@
// Reference counting. See comments above this class for when to use.
int refcount() const { return _refcount; }
- inline void increment_refcount();
- inline void decrement_refcount();
+ void increment_refcount();
+ void decrement_refcount();
int byte_at(int index) const {
assert(index >=0 && index < _length, "symbol index overflow");
@@ -232,26 +231,4 @@
return (((uintptr_t)this < (uintptr_t)other) ? -1
: ((uintptr_t)this == (uintptr_t) other) ? 0 : 1);
}
-
-inline void Symbol::increment_refcount() {
- // Only increment the refcount if positive. If negative either
- // overflow has occurred or it is a permanent symbol in a read only
- // shared archive.
- if (_refcount >= 0) {
- Atomic::inc(&_refcount);
- NOT_PRODUCT(Atomic::inc(&_total_count);)
- }
-}
-
-inline void Symbol::decrement_refcount() {
- if (_refcount >= 0) {
- Atomic::dec(&_refcount);
-#ifdef ASSERT
- if (_refcount < 0) {
- print();
- assert(false, "reference count underflow for symbol");
- }
-#endif
- }
-}
#endif // SHARE_VM_OOPS_SYMBOL_HPP
--- a/hotspot/src/share/vm/opto/bytecodeInfo.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/opto/bytecodeInfo.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -47,7 +47,8 @@
_site_invoke_ratio(site_invoke_ratio),
_max_inline_level(max_inline_level),
_count_inline_bcs(method()->code_size_for_inlining()),
- _subtrees(c->comp_arena(), 2, 0, NULL)
+ _subtrees(c->comp_arena(), 2, 0, NULL),
+ _msg(NULL)
{
NOT_PRODUCT(_count_inlines = 0;)
if (_caller_jvms != NULL) {
@@ -77,7 +78,8 @@
_method(callee_method),
_site_invoke_ratio(site_invoke_ratio),
_max_inline_level(max_inline_level),
- _count_inline_bcs(method()->code_size())
+ _count_inline_bcs(method()->code_size()),
+ _msg(NULL)
{
NOT_PRODUCT(_count_inlines = 0;)
assert(!UseOldInlining, "do not use for old stuff");
@@ -95,8 +97,10 @@
);
}
-// positive filter: should callee be inlined? returns NULL, if yes, or rejection msg
-const char* InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const {
+// positive filter: should callee be inlined?
+bool InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_method,
+ int caller_bci, ciCallProfile& profile,
+ WarmCallInfo* wci_result) {
// Allows targeted inlining
if(callee_method->should_inline()) {
*wci_result = *(WarmCallInfo::always_hot());
@@ -104,11 +108,10 @@
CompileTask::print_inline_indent(inline_level());
tty->print_cr("Inlined method is hot: ");
}
- return NULL;
+ set_msg("force inline by CompilerOracle");
+ return true;
}
- // positive filter: should send be inlined? returns NULL (--> yes)
- // or rejection msg
int size = callee_method->code_size_for_inlining();
// Check for too many throws (and not too huge)
@@ -119,11 +122,13 @@
CompileTask::print_inline_indent(inline_level());
tty->print_cr("Inlined method with many throws (throws=%d):", callee_method->interpreter_throwout_count());
}
- return NULL;
+ set_msg("many throws");
+ return true;
}
if (!UseOldInlining) {
- return NULL; // size and frequency are represented in a new way
+ set_msg("!UseOldInlining");
+ return true; // size and frequency are represented in a new way
}
int default_max_inline_size = C->max_inline_size();
@@ -153,31 +158,44 @@
// Not hot. Check for medium-sized pre-existing nmethod at cold sites.
if (callee_method->has_compiled_code() &&
callee_method->instructions_size() > inline_small_code_size)
- return "already compiled into a medium method";
+ set_msg("already compiled into a medium method");
+ return false;
}
if (size > max_inline_size) {
- if (max_inline_size > default_max_inline_size)
- return "hot method too big";
- return "too big";
+ if (max_inline_size > default_max_inline_size) {
+ set_msg("hot method too big");
+ } else {
+ set_msg("too big");
+ }
+ return false;
}
- return NULL;
+ return true;
}
-// negative filter: should callee NOT be inlined? returns NULL, ok to inline, or rejection msg
-const char* InlineTree::should_not_inline(ciMethod *callee_method, ciMethod* caller_method, WarmCallInfo* wci_result) const {
- // negative filter: should send NOT be inlined? returns NULL (--> inline) or rejection msg
+// negative filter: should callee NOT be inlined?
+bool InlineTree::should_not_inline(ciMethod *callee_method,
+ ciMethod* caller_method,
+ WarmCallInfo* wci_result) {
+
+ const char* fail_msg = NULL;
+
+ // First check all inlining restrictions which are required for correctness
+ if ( callee_method->is_abstract()) {
+ fail_msg = "abstract method"; // // note: we allow ik->is_abstract()
+ } else if (!callee_method->holder()->is_initialized()) {
+ fail_msg = "method holder not initialized";
+ } else if ( callee_method->is_native()) {
+ fail_msg = "native method";
+ } else if ( callee_method->dont_inline()) {
+ fail_msg = "don't inline by annotation";
+ }
+
if (!UseOldInlining) {
- const char* fail = NULL;
- if ( callee_method->is_abstract()) fail = "abstract method";
- // note: we allow ik->is_abstract()
- if (!callee_method->holder()->is_initialized()) fail = "method holder not initialized";
- if ( callee_method->is_native()) fail = "native method";
- if ( callee_method->dont_inline()) fail = "don't inline by annotation";
-
- if (fail) {
+ if (fail_msg != NULL) {
*wci_result = *(WarmCallInfo::always_cold());
- return fail;
+ set_msg(fail_msg);
+ return true;
}
if (callee_method->has_unloaded_classes_in_signature()) {
@@ -199,20 +217,23 @@
// %%% adjust wci_result->size()?
}
- return NULL;
+ return false;
+ }
+
+ // one more inlining restriction
+ if (fail_msg == NULL && callee_method->has_unloaded_classes_in_signature()) {
+ fail_msg = "unloaded signature classes";
}
- // First check all inlining restrictions which are required for correctness
- if ( callee_method->is_abstract()) return "abstract method";
- // note: we allow ik->is_abstract()
- if (!callee_method->holder()->is_initialized()) return "method holder not initialized";
- if ( callee_method->is_native()) return "native method";
- if ( callee_method->dont_inline()) return "don't inline by annotation";
- if ( callee_method->has_unloaded_classes_in_signature()) return "unloaded signature classes";
+ if (fail_msg != NULL) {
+ set_msg(fail_msg);
+ return true;
+ }
+ // ignore heuristic controls on inlining
if (callee_method->should_inline()) {
- // ignore heuristic controls on inlining
- return NULL;
+ set_msg("force inline by CompilerOracle");
+ return false;
}
// Now perform checks which are heuristic
@@ -220,7 +241,8 @@
if (!callee_method->force_inline()) {
if (callee_method->has_compiled_code() &&
callee_method->instructions_size() > InlineSmallCode) {
- return "already compiled into a big method";
+ set_msg("already compiled into a big method");
+ return true;
}
}
@@ -231,17 +253,21 @@
const InlineTree *top = this;
while (top->caller_tree() != NULL) top = top->caller_tree();
ciInstanceKlass* k = top->method()->holder();
- if (!k->is_subclass_of(C->env()->Throwable_klass()))
- return "exception method";
+ if (!k->is_subclass_of(C->env()->Throwable_klass())) {
+ set_msg("exception method");
+ return true;
+ }
}
if (callee_method->should_not_inline()) {
- return "disallowed by CompilerOracle";
+ set_msg("disallowed by CompilerOracle");
+ return true;
}
#ifndef PRODUCT
if (ciReplay::should_not_inline(callee_method)) {
- return "disallowed by ciReplay";
+ set_msg("disallowed by ciReplay");
+ return true;
}
#endif
@@ -249,19 +275,23 @@
// Do not inline StringCache::profile() method used only at the beginning.
if (callee_method->name() == ciSymbol::profile_name() &&
callee_method->holder()->name() == ciSymbol::java_lang_StringCache()) {
- return "profiling method";
+ set_msg("profiling method");
+ return true;
}
}
// use frequency-based objections only for non-trivial methods
- if (callee_method->code_size() <= MaxTrivialSize) return NULL;
+ if (callee_method->code_size() <= MaxTrivialSize) {
+ return false;
+ }
// don't use counts with -Xcomp or CTW
if (UseInterpreter && !CompileTheWorld) {
if (!callee_method->has_compiled_code() &&
!callee_method->was_executed_more_than(0)) {
- return "never executed";
+ set_msg("never executed");
+ return true;
}
if (is_init_with_ea(callee_method, caller_method, C)) {
@@ -270,39 +300,44 @@
} else if (!callee_method->was_executed_more_than(MIN2(MinInliningThreshold,
CompileThreshold >> 1))) {
- return "executed < MinInliningThreshold times";
+ set_msg("executed < MinInliningThreshold times");
+ return true;
}
}
- return NULL;
+ return false;
}
//-----------------------------try_to_inline-----------------------------------
-// return NULL if ok, reason for not inlining otherwise
+// return true if ok
// Relocated from "InliningClosure::try_to_inline"
-const char* InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result, bool& should_delay) {
- // Old algorithm had funny accumulating BC-size counters
+bool InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_method,
+ int caller_bci, ciCallProfile& profile,
+ WarmCallInfo* wci_result, bool& should_delay) {
+
+ // Old algorithm had funny accumulating BC-size counters
if (UseOldInlining && ClipInlining
&& (int)count_inline_bcs() >= DesiredMethodLimit) {
if (!callee_method->force_inline() || !IncrementalInline) {
- return "size > DesiredMethodLimit";
+ set_msg("size > DesiredMethodLimit");
+ return false;
} else if (!C->inlining_incrementally()) {
should_delay = true;
}
}
- const char *msg = NULL;
- msg = should_inline(callee_method, caller_method, caller_bci, profile, wci_result);
- if (msg != NULL)
- return msg;
-
- msg = should_not_inline(callee_method, caller_method, wci_result);
- if (msg != NULL)
- return msg;
+ if (!should_inline(callee_method, caller_method, caller_bci, profile,
+ wci_result)) {
+ return false;
+ }
+ if (should_not_inline(callee_method, caller_method, wci_result)) {
+ return false;
+ }
if (InlineAccessors && callee_method->is_accessor()) {
// accessor methods are not subject to any of the following limits.
- return NULL;
+ set_msg("accessor");
+ return true;
}
// suppress a few checks for accessors and trivial methods
@@ -312,7 +347,8 @@
if (C->over_inlining_cutoff()) {
if ((!callee_method->force_inline() && !caller_method->is_compiled_lambda_form())
|| !IncrementalInline) {
- return "NodeCountInliningCutoff";
+ set_msg("NodeCountInliningCutoff");
+ return false;
} else {
should_delay = true;
}
@@ -326,16 +362,19 @@
} else if (profile.count() == 0) {
// don't inline unreached call sites
- return "call site not reached";
+ set_msg("call site not reached");
+ return false;
}
}
if (!C->do_inlining() && InlineAccessors) {
- return "not an accessor";
+ set_msg("not an accessor");
+ return false;
}
if (inline_level() > _max_inline_level) {
if (!callee_method->force_inline() || !IncrementalInline) {
- return "inlining too deep";
+ set_msg("inlining too deep");
+ return false;
} else if (!C->inlining_incrementally()) {
should_delay = true;
}
@@ -345,15 +384,19 @@
if (!callee_method->is_compiled_lambda_form()) {
// count the current method and the callee
int inline_level = (method() == callee_method) ? 1 : 0;
- if (inline_level > MaxRecursiveInlineLevel)
- return "recursively inlining too deep";
+ if (inline_level > MaxRecursiveInlineLevel) {
+ set_msg("recursively inlining too deep");
+ return false;
+ }
// count callers of current method and callee
JVMState* jvms = caller_jvms();
while (jvms != NULL && jvms->has_method()) {
if (jvms->method() == callee_method) {
inline_level++;
- if (inline_level > MaxRecursiveInlineLevel)
- return "recursively inlining too deep";
+ if (inline_level > MaxRecursiveInlineLevel) {
+ set_msg("recursively inlining too deep");
+ return false;
+ }
}
jvms = jvms->caller();
}
@@ -364,14 +407,15 @@
if (UseOldInlining && ClipInlining
&& (int)count_inline_bcs() + size >= DesiredMethodLimit) {
if (!callee_method->force_inline() || !IncrementalInline) {
- return "size > DesiredMethodLimit";
+ set_msg("size > DesiredMethodLimit");
+ return false;
} else if (!C->inlining_incrementally()) {
should_delay = true;
}
}
// ok, inline this method
- return NULL;
+ return true;
}
//------------------------------pass_initial_checks----------------------------
@@ -421,17 +465,18 @@
//------------------------------print_inlining---------------------------------
void InlineTree::print_inlining(ciMethod* callee_method, int caller_bci,
- const char* msg, bool success) const {
- assert(msg != NULL, "just checking");
+ bool success) const {
+ const char* inline_msg = msg();
+ assert(inline_msg != NULL, "just checking");
if (C->log() != NULL) {
if (success) {
- C->log()->inline_success(msg);
+ C->log()->inline_success(inline_msg);
} else {
- C->log()->inline_fail(msg);
+ C->log()->inline_fail(inline_msg);
}
}
if (PrintInlining) {
- C->print_inlining(callee_method, inline_level(), caller_bci, msg);
+ C->print_inlining(callee_method, inline_level(), caller_bci, inline_msg);
if (callee_method == NULL) tty->print(" callee not monotonic or profiled");
if (Verbose && callee_method) {
const InlineTree *top = this;
@@ -455,49 +500,51 @@
}
assert(_method == jvms->method(), "redundant instance state");
#endif
- const char *failure_msg = NULL;
int caller_bci = jvms->bci();
- ciMethod *caller_method = jvms->method();
+ ciMethod* caller_method = jvms->method();
// Do some initial checks.
if (!pass_initial_checks(caller_method, caller_bci, callee_method)) {
- print_inlining(callee_method, caller_bci, "failed initial checks",
- false /* !success */);
+ set_msg("failed initial checks");
+ print_inlining(callee_method, caller_bci, false /* !success */);
return NULL;
}
// Do some parse checks.
- failure_msg = check_can_parse(callee_method);
- if (failure_msg != NULL) {
- print_inlining(callee_method, caller_bci, failure_msg,
- false /* !success */);
+ set_msg(check_can_parse(callee_method));
+ if (msg() != NULL) {
+ print_inlining(callee_method, caller_bci, false /* !success */);
return NULL;
}
// Check if inlining policy says no.
WarmCallInfo wci = *(initial_wci);
- failure_msg = try_to_inline(callee_method, caller_method, caller_bci, profile,
- &wci, should_delay);
+ bool success = try_to_inline(callee_method, caller_method, caller_bci,
+ profile, &wci, should_delay);
#ifndef PRODUCT
if (UseOldInlining && InlineWarmCalls
&& (PrintOpto || PrintOptoInlining || PrintInlining)) {
bool cold = wci.is_cold();
bool hot = !cold && wci.is_hot();
- bool old_cold = (failure_msg != NULL);
+ bool old_cold = !success;
if (old_cold != cold || (Verbose || WizardMode)) {
+ if (msg() == NULL) {
+ set_msg("OK");
+ }
tty->print(" OldInlining= %4s : %s\n WCI=",
- old_cold ? "cold" : "hot", failure_msg ? failure_msg : "OK");
+ old_cold ? "cold" : "hot", msg());
wci.print();
}
}
#endif
if (UseOldInlining) {
- if (failure_msg == NULL)
+ if (success) {
wci = *(WarmCallInfo::always_hot());
- else
+ } else {
wci = *(WarmCallInfo::always_cold());
}
+ }
if (!InlineWarmCalls) {
if (!wci.is_cold() && !wci.is_hot()) {
// Do not inline the warm calls.
@@ -507,9 +554,10 @@
if (!wci.is_cold()) {
// Inline!
- print_inlining(callee_method, caller_bci,
- failure_msg ? failure_msg : "inline (hot)",
- true /* success */);
+ if (msg() == NULL) {
+ set_msg("inline (hot)");
+ }
+ print_inlining(callee_method, caller_bci, true /* success */);
if (UseOldInlining)
build_inline_tree_for_callee(callee_method, jvms, caller_bci);
if (InlineWarmCalls && !wci.is_hot())
@@ -518,9 +566,10 @@
}
// Do not inline
- print_inlining(callee_method, caller_bci,
- failure_msg ? failure_msg : "too cold to inline",
- false /* !success */ );
+ if (msg() == NULL) {
+ set_msg("too cold to inline");
+ }
+ print_inlining(callee_method, caller_bci, false /* !success */ );
return NULL;
}
--- a/hotspot/src/share/vm/opto/c2_globals.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/opto/c2_globals.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -54,6 +54,12 @@
#define C2_FLAGS(develop, develop_pd, product, product_pd, diagnostic, experimental, notproduct) \
\
+ develop(bool, StressLCM, false, \
+ "Randomize instruction scheduling in LCM") \
+ \
+ develop(bool, StressGCM, false, \
+ "Randomize instruction scheduling in GCM") \
+ \
notproduct(intx, CompileZapFirst, 0, \
"If +ZapDeadCompiledLocals, " \
"skip this many before compiling in zap calls") \
--- a/hotspot/src/share/vm/opto/compile.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/opto/compile.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -2899,6 +2899,13 @@
}
}
break;
+ case Op_MemBarStoreStore:
+ // Break the link with AllocateNode: it is no longer useful and
+ // confuses register allocation.
+ if (n->req() > MemBarNode::Precedent) {
+ n->set_req(MemBarNode::Precedent, top());
+ }
+ break;
default:
assert( !n->is_Call(), "" );
assert( !n->is_Mem(), "" );
@@ -3669,3 +3676,38 @@
n->set_req(0, NULL);
}
}
+
+// Auxiliary method to support randomized stressing/fuzzing.
+//
+// This method can be called the arbitrary number of times, with current count
+// as the argument. The logic allows selecting a single candidate from the
+// running list of candidates as follows:
+// int count = 0;
+// Cand* selected = null;
+// while(cand = cand->next()) {
+// if (randomized_select(++count)) {
+// selected = cand;
+// }
+// }
+//
+// Including count equalizes the chances any candidate is "selected".
+// This is useful when we don't have the complete list of candidates to choose
+// from uniformly. In this case, we need to adjust the randomicity of the
+// selection, or else we will end up biasing the selection towards the latter
+// candidates.
+//
+// Quick back-envelope calculation shows that for the list of n candidates
+// the equal probability for the candidate to persist as "best" can be
+// achieved by replacing it with "next" k-th candidate with the probability
+// of 1/k. It can be easily shown that by the end of the run, the
+// probability for any candidate is converged to 1/n, thus giving the
+// uniform distribution among all the candidates.
+//
+// We don't care about the domain size as long as (RANDOMIZED_DOMAIN / count) is large.
+#define RANDOMIZED_DOMAIN_POW 29
+#define RANDOMIZED_DOMAIN (1 << RANDOMIZED_DOMAIN_POW)
+#define RANDOMIZED_DOMAIN_MASK ((1 << (RANDOMIZED_DOMAIN_POW + 1)) - 1)
+bool Compile::randomized_select(int count) {
+ assert(count > 0, "only positive");
+ return (os::random() & RANDOMIZED_DOMAIN_MASK) < (RANDOMIZED_DOMAIN / count);
+}
--- a/hotspot/src/share/vm/opto/compile.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/opto/compile.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -678,6 +678,7 @@
void record_dead_node(uint idx) { if (_dead_node_list.test_set(idx)) return;
_dead_node_count++;
}
+ bool is_dead_node(uint idx) { return _dead_node_list.test(idx) != 0; }
uint dead_node_count() { return _dead_node_count; }
void reset_dead_node_list() { _dead_node_list.Reset();
_dead_node_count = 0;
@@ -1086,6 +1087,9 @@
// Definitions of pd methods
static void pd_compiler2_init();
+
+ // Auxiliary method for randomized fuzzing/stressing
+ static bool randomized_select(int count);
};
#endif // SHARE_VM_OPTO_COMPILE_HPP
--- a/hotspot/src/share/vm/opto/gcm.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/opto/gcm.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -1046,6 +1046,8 @@
}
#endif
+ int cand_cnt = 0; // number of candidates tried
+
// Walk up the dominator tree from LCA (Lowest common ancestor) to
// the earliest legal location. Capture the least execution frequency.
while (LCA != early) {
@@ -1071,8 +1073,11 @@
LCA->_pre_order, LCA->_nodes[0]->_idx, start_lat, end_idx, end_lat, LCA_freq);
}
#endif
+ cand_cnt++;
if (LCA_freq < least_freq || // Better Frequency
- ( !in_latency && // No block containing latency
+ (StressGCM && Compile::randomized_select(cand_cnt)) || // Should be randomly accepted in stress mode
+ (!StressGCM && // Otherwise, choose with latency
+ !in_latency && // No block containing latency
LCA_freq < least_freq * delta && // No worse frequency
target >= end_lat && // within latency range
!self->is_iteratively_computed() ) // But don't hoist IV increments
@@ -1210,7 +1215,8 @@
}
// If there is no opportunity to hoist, then we're done.
- bool try_to_hoist = (LCA != early);
+ // In stress mode, try to hoist even the single operations.
+ bool try_to_hoist = StressGCM || (LCA != early);
// Must clone guys stay next to use; no hoisting allowed.
// Also cannot hoist guys that alter memory or are otherwise not
--- a/hotspot/src/share/vm/opto/lcm.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/opto/lcm.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -421,6 +421,7 @@
uint latency = 0; // Bigger is scheduled first
uint score = 0; // Bigger is better
int idx = -1; // Index in worklist
+ int cand_cnt = 0; // Candidate count
for( uint i=0; i<cnt; i++ ) { // Inspect entire worklist
// Order in worklist is used to break ties.
@@ -503,11 +504,14 @@
uint n_score = n->req(); // Many inputs get high score to break ties
// Keep best latency found
- if( choice < n_choice ||
- ( choice == n_choice &&
- ( latency < n_latency ||
- ( latency == n_latency &&
- ( score < n_score ))))) {
+ cand_cnt++;
+ if (choice < n_choice ||
+ (choice == n_choice &&
+ ((StressLCM && Compile::randomized_select(cand_cnt)) ||
+ (!StressLCM &&
+ (latency < n_latency ||
+ (latency == n_latency &&
+ (score < n_score))))))) {
choice = n_choice;
latency = n_latency;
score = n_score;
--- a/hotspot/src/share/vm/opto/library_call.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/opto/library_call.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -1481,10 +1481,10 @@
Node* arg = round_double_node(argument(0));
Node* n;
switch (id) {
- case vmIntrinsics::_dabs: n = new (C) AbsDNode( arg); break;
- case vmIntrinsics::_dsqrt: n = new (C) SqrtDNode(0, arg); break;
- case vmIntrinsics::_dlog: n = new (C) LogDNode( arg); break;
- case vmIntrinsics::_dlog10: n = new (C) Log10DNode( arg); break;
+ case vmIntrinsics::_dabs: n = new (C) AbsDNode( arg); break;
+ case vmIntrinsics::_dsqrt: n = new (C) SqrtDNode(C, control(), arg); break;
+ case vmIntrinsics::_dlog: n = new (C) LogDNode(C, control(), arg); break;
+ case vmIntrinsics::_dlog10: n = new (C) Log10DNode(C, control(), arg); break;
default: fatal_unexpected_iid(id); break;
}
set_result(_gvn.transform(n));
@@ -1499,9 +1499,9 @@
Node* n = NULL;
switch (id) {
- case vmIntrinsics::_dsin: n = new (C) SinDNode(arg); break;
- case vmIntrinsics::_dcos: n = new (C) CosDNode(arg); break;
- case vmIntrinsics::_dtan: n = new (C) TanDNode(arg); break;
+ case vmIntrinsics::_dsin: n = new (C) SinDNode(C, control(), arg); break;
+ case vmIntrinsics::_dcos: n = new (C) CosDNode(C, control(), arg); break;
+ case vmIntrinsics::_dtan: n = new (C) TanDNode(C, control(), arg); break;
default: fatal_unexpected_iid(id); break;
}
n = _gvn.transform(n);
--- a/hotspot/src/share/vm/opto/macro.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/opto/macro.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -1101,12 +1101,6 @@
Node* klass_node = alloc->in(AllocateNode::KlassNode);
Node* initial_slow_test = alloc->in(AllocateNode::InitialTest);
- Node* storestore = alloc->storestore();
- if (storestore != NULL) {
- // Break this link that is no longer useful and confuses register allocation
- storestore->set_req(MemBarNode::Precedent, top());
- }
-
assert(ctrl != NULL, "must have control");
// We need a Region and corresponding Phi's to merge the slow-path and fast-path results.
// they will not be used if "always_slow" is set
@@ -1324,7 +1318,7 @@
// No InitializeNode or no stores captured by zeroing
// elimination. Simply add the MemBarStoreStore after object
// initialization.
- MemBarNode* mb = MemBarNode::make(C, Op_MemBarStoreStore, Compile::AliasIdxBot, fast_oop_rawmem);
+ MemBarNode* mb = MemBarNode::make(C, Op_MemBarStoreStore, Compile::AliasIdxBot);
transform_later(mb);
mb->init_req(TypeFunc::Memory, fast_oop_rawmem);
--- a/hotspot/src/share/vm/opto/memnode.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/opto/memnode.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -238,7 +238,7 @@
return this;
ctl = in(MemNode::Control);
// Don't bother trying to transform a dead node
- if( ctl && ctl->is_top() ) return NodeSentinel;
+ if (ctl && ctl->is_top()) return NodeSentinel;
PhaseIterGVN *igvn = phase->is_IterGVN();
// Wait if control on the worklist.
@@ -262,8 +262,8 @@
}
// Ignore if memory is dead, or self-loop
Node *mem = in(MemNode::Memory);
- if( phase->type( mem ) == Type::TOP ) return NodeSentinel; // caller will return NULL
- assert( mem != this, "dead loop in MemNode::Ideal" );
+ if (phase->type( mem ) == Type::TOP) return NodeSentinel; // caller will return NULL
+ assert(mem != this, "dead loop in MemNode::Ideal");
if (can_reshape && igvn != NULL && igvn->_worklist.member(mem)) {
// This memory slice may be dead.
@@ -273,12 +273,12 @@
}
Node *address = in(MemNode::Address);
- const Type *t_adr = phase->type( address );
- if( t_adr == Type::TOP ) return NodeSentinel; // caller will return NULL
-
- if( can_reshape && igvn != NULL &&
+ const Type *t_adr = phase->type(address);
+ if (t_adr == Type::TOP) return NodeSentinel; // caller will return NULL
+
+ if (can_reshape && igvn != NULL &&
(igvn->_worklist.member(address) ||
- igvn->_worklist.size() > 0 && (phase->type(address) != adr_type())) ) {
+ igvn->_worklist.size() > 0 && (t_adr != adr_type())) ) {
// The address's base and type may change when the address is processed.
// Delay this mem node transformation until the address is processed.
phase->is_IterGVN()->_worklist.push(this);
@@ -288,7 +288,7 @@
// Do NOT remove or optimize the next lines: ensure a new alias index
// is allocated for an oop pointer type before Escape Analysis.
// Note: C++ will not remove it since the call has side effect.
- if ( t_adr->isa_oopptr() ) {
+ if (t_adr->isa_oopptr()) {
int alias_idx = phase->C->get_alias_index(t_adr->is_ptr());
}
@@ -296,6 +296,26 @@
Node* base = NULL;
if (address->is_AddP())
base = address->in(AddPNode::Base);
+ if (base != NULL && phase->type(base)->higher_equal(TypePtr::NULL_PTR) &&
+ !t_adr->isa_rawptr()) {
+ // Note: raw address has TOP base and top->higher_equal(TypePtr::NULL_PTR) is true.
+ Compile* C = phase->C;
+ tty->cr();
+ tty->print_cr("===== NULL+offs not RAW address =====");
+ if (C->is_dead_node(this->_idx)) tty->print_cr("'this' is dead");
+ if ((ctl != NULL) && C->is_dead_node(ctl->_idx)) tty->print_cr("'ctl' is dead");
+ if (C->is_dead_node(mem->_idx)) tty->print_cr("'mem' is dead");
+ if (C->is_dead_node(address->_idx)) tty->print_cr("'address' is dead");
+ if (C->is_dead_node(base->_idx)) tty->print_cr("'base' is dead");
+ tty->cr();
+ base->dump(1);
+ tty->cr();
+ this->dump(2);
+ tty->print("this->adr_type(): "); adr_type()->dump(); tty->cr();
+ tty->print("phase->type(address): "); t_adr->dump(); tty->cr();
+ tty->print("phase->type(base): "); phase->type(address)->dump(); tty->cr();
+ tty->cr();
+ }
assert(base == NULL || t_adr->isa_rawptr() ||
!phase->type(base)->higher_equal(TypePtr::NULL_PTR), "NULL+offs not RAW address?");
#endif
@@ -320,6 +340,9 @@
if (mem != old_mem) {
set_req(MemNode::Memory, mem);
+ if (can_reshape && old_mem->outcnt() == 0) {
+ igvn->_worklist.push(old_mem);
+ }
if (phase->type( mem ) == Type::TOP) return NodeSentinel;
return this;
}
@@ -2319,9 +2342,9 @@
if (ReduceFieldZeroing && /*can_reshape &&*/
mem->is_Proj() && mem->in(0)->is_Initialize()) {
InitializeNode* init = mem->in(0)->as_Initialize();
- intptr_t offset = init->can_capture_store(this, phase);
+ intptr_t offset = init->can_capture_store(this, phase, can_reshape);
if (offset > 0) {
- Node* moved = init->capture_store(this, offset, phase);
+ Node* moved = init->capture_store(this, offset, phase, can_reshape);
// If the InitializeNode captured me, it made a raw copy of me,
// and I need to disappear.
if (moved != NULL) {
@@ -3134,7 +3157,7 @@
// an initialization. Returns zero if a check fails.
// On success, returns the (constant) offset to which the store applies,
// within the initialized memory.
-intptr_t InitializeNode::can_capture_store(StoreNode* st, PhaseTransform* phase) {
+intptr_t InitializeNode::can_capture_store(StoreNode* st, PhaseTransform* phase, bool can_reshape) {
const int FAIL = 0;
if (st->req() != MemNode::ValueIn + 1)
return FAIL; // an inscrutable StoreNode (card mark?)
@@ -3156,6 +3179,91 @@
if (!detect_init_independence(val, true, complexity_count))
return FAIL; // stored value must be 'simple enough'
+ // The Store can be captured only if nothing after the allocation
+ // and before the Store is using the memory location that the store
+ // overwrites.
+ bool failed = false;
+ // If is_complete_with_arraycopy() is true the shape of the graph is
+ // well defined and is safe so no need for extra checks.
+ if (!is_complete_with_arraycopy()) {
+ // We are going to look at each use of the memory state following
+ // the allocation to make sure nothing reads the memory that the
+ // Store writes.
+ const TypePtr* t_adr = phase->type(adr)->isa_ptr();
+ int alias_idx = phase->C->get_alias_index(t_adr);
+ ResourceMark rm;
+ Unique_Node_List mems;
+ mems.push(mem);
+ Node* unique_merge = NULL;
+ for (uint next = 0; next < mems.size(); ++next) {
+ Node *m = mems.at(next);
+ for (DUIterator_Fast jmax, j = m->fast_outs(jmax); j < jmax; j++) {
+ Node *n = m->fast_out(j);
+ if (n->outcnt() == 0) {
+ continue;
+ }
+ if (n == st) {
+ continue;
+ } else if (n->in(0) != NULL && n->in(0) != ctl) {
+ // If the control of this use is different from the control
+ // of the Store which is right after the InitializeNode then
+ // this node cannot be between the InitializeNode and the
+ // Store.
+ continue;
+ } else if (n->is_MergeMem()) {
+ if (n->as_MergeMem()->memory_at(alias_idx) == m) {
+ // We can hit a MergeMemNode (that will likely go away
+ // later) that is a direct use of the memory state
+ // following the InitializeNode on the same slice as the
+ // store node that we'd like to capture. We need to check
+ // the uses of the MergeMemNode.
+ mems.push(n);
+ }
+ } else if (n->is_Mem()) {
+ Node* other_adr = n->in(MemNode::Address);
+ if (other_adr == adr) {
+ failed = true;
+ break;
+ } else {
+ const TypePtr* other_t_adr = phase->type(other_adr)->isa_ptr();
+ if (other_t_adr != NULL) {
+ int other_alias_idx = phase->C->get_alias_index(other_t_adr);
+ if (other_alias_idx == alias_idx) {
+ // A load from the same memory slice as the store right
+ // after the InitializeNode. We check the control of the
+ // object/array that is loaded from. If it's the same as
+ // the store control then we cannot capture the store.
+ assert(!n->is_Store(), "2 stores to same slice on same control?");
+ Node* base = other_adr;
+ assert(base->is_AddP(), err_msg_res("should be addp but is %s", base->Name()));
+ base = base->in(AddPNode::Base);
+ if (base != NULL) {
+ base = base->uncast();
+ if (base->is_Proj() && base->in(0) == alloc) {
+ failed = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+ } else {
+ failed = true;
+ break;
+ }
+ }
+ }
+ }
+ if (failed) {
+ if (!can_reshape) {
+ // We decided we couldn't capture the store during parsing. We
+ // should try again during the next IGVN once the graph is
+ // cleaner.
+ phase->C->record_for_igvn(st);
+ }
+ return FAIL;
+ }
+
return offset; // success
}
@@ -3266,11 +3374,11 @@
// rawstore1 rawstore2)
//
Node* InitializeNode::capture_store(StoreNode* st, intptr_t start,
- PhaseTransform* phase) {
+ PhaseTransform* phase, bool can_reshape) {
assert(stores_are_sane(phase), "");
if (start < 0) return NULL;
- assert(can_capture_store(st, phase) == start, "sanity");
+ assert(can_capture_store(st, phase, can_reshape) == start, "sanity");
Compile* C = phase->C;
int size_in_bytes = st->memory_size();
--- a/hotspot/src/share/vm/opto/memnode.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/opto/memnode.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -1072,11 +1072,11 @@
// See if this store can be captured; return offset where it initializes.
// Return 0 if the store cannot be moved (any sort of problem).
- intptr_t can_capture_store(StoreNode* st, PhaseTransform* phase);
+ intptr_t can_capture_store(StoreNode* st, PhaseTransform* phase, bool can_reshape);
// Capture another store; reformat it to write my internal raw memory.
// Return the captured copy, else NULL if there is some sort of problem.
- Node* capture_store(StoreNode* st, intptr_t start, PhaseTransform* phase);
+ Node* capture_store(StoreNode* st, intptr_t start, PhaseTransform* phase, bool can_reshape);
// Find captured store which corresponds to the range [start..start+size).
// Return my own memory projection (meaning the initial zero bits)
--- a/hotspot/src/share/vm/opto/node.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/opto/node.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -1261,6 +1261,7 @@
if (dead->is_expensive()) {
igvn->C->remove_expensive_node(dead);
}
+ igvn->C->record_dead_node(dead->_idx);
// Kill all inputs to the dead guy
for (uint i=0; i < dead->req(); i++) {
Node *n = dead->in(i); // Get input to dead guy
--- a/hotspot/src/share/vm/opto/parse.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/opto/parse.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -58,7 +58,7 @@
GrowableArray<InlineTree*> _subtrees;
void print_impl(outputStream* stj, int indent) const PRODUCT_RETURN;
-
+ const char* _msg;
protected:
InlineTree(Compile* C,
const InlineTree* caller_tree,
@@ -70,17 +70,29 @@
InlineTree *build_inline_tree_for_callee(ciMethod* callee_method,
JVMState* caller_jvms,
int caller_bci);
- const char* try_to_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result, bool& should_delay);
- const char* should_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const;
- const char* should_not_inline(ciMethod* callee_method, ciMethod* caller_method, WarmCallInfo* wci_result) const;
+ bool try_to_inline(ciMethod* callee_method,
+ ciMethod* caller_method,
+ int caller_bci,
+ ciCallProfile& profile,
+ WarmCallInfo* wci_result,
+ bool& should_delay);
+ bool should_inline(ciMethod* callee_method,
+ ciMethod* caller_method,
+ int caller_bci,
+ ciCallProfile& profile,
+ WarmCallInfo* wci_result);
+ bool should_not_inline(ciMethod* callee_method,
+ ciMethod* caller_method,
+ WarmCallInfo* wci_result);
void print_inlining(ciMethod* callee_method, int caller_bci,
- const char* msg, bool success) const;
+ bool success) const;
- InlineTree *caller_tree() const { return _caller_tree; }
+ InlineTree* caller_tree() const { return _caller_tree; }
InlineTree* callee_at(int bci, ciMethod* m) const;
int inline_level() const { return stack_depth(); }
int stack_depth() const { return _caller_jvms ? _caller_jvms->depth() : 0; }
-
+ const char* msg() const { return _msg; }
+ void set_msg(const char* msg) { _msg = msg; }
public:
static const char* check_can_parse(ciMethod* callee);
--- a/hotspot/src/share/vm/opto/phaseX.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/opto/phaseX.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -1197,6 +1197,18 @@
assert(!(i < imax), "sanity");
}
}
+ if (ReduceFieldZeroing && dead->is_Load() && i == MemNode::Memory &&
+ in->is_Proj() && in->in(0) != NULL && in->in(0)->is_Initialize()) {
+ // A Load that directly follows an InitializeNode is
+ // going away. The Stores that follow are candidates
+ // again to be captured by the InitializeNode.
+ for (DUIterator_Fast jmax, j = in->fast_outs(jmax); j < jmax; j++) {
+ Node *n = in->fast_out(j);
+ if (n->is_Store()) {
+ _worklist.push(n);
+ }
+ }
+ }
}
}
C->record_dead_node(dead->_idx);
--- a/hotspot/src/share/vm/opto/subnode.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/opto/subnode.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -399,7 +399,10 @@
// Cosinus of a double
class CosDNode : public Node {
public:
- CosDNode( Node *in1 ) : Node(0, in1) {}
+ CosDNode(Compile* C, Node *c, Node *in1) : Node(c, in1) {
+ init_flags(Flag_is_expensive);
+ C->add_expensive_node(this);
+ }
virtual int Opcode() const;
const Type *bottom_type() const { return Type::DOUBLE; }
virtual uint ideal_reg() const { return Op_RegD; }
@@ -410,7 +413,10 @@
// Sinus of a double
class SinDNode : public Node {
public:
- SinDNode( Node *in1 ) : Node(0, in1) {}
+ SinDNode(Compile* C, Node *c, Node *in1) : Node(c, in1) {
+ init_flags(Flag_is_expensive);
+ C->add_expensive_node(this);
+ }
virtual int Opcode() const;
const Type *bottom_type() const { return Type::DOUBLE; }
virtual uint ideal_reg() const { return Op_RegD; }
@@ -422,7 +428,10 @@
// tangens of a double
class TanDNode : public Node {
public:
- TanDNode(Node *in1 ) : Node(0, in1) {}
+ TanDNode(Compile* C, Node *c,Node *in1) : Node(c, in1) {
+ init_flags(Flag_is_expensive);
+ C->add_expensive_node(this);
+ }
virtual int Opcode() const;
const Type *bottom_type() const { return Type::DOUBLE; }
virtual uint ideal_reg() const { return Op_RegD; }
@@ -445,7 +454,10 @@
// square root a double
class SqrtDNode : public Node {
public:
- SqrtDNode(Node *c, Node *in1 ) : Node(c, in1) {}
+ SqrtDNode(Compile* C, Node *c, Node *in1) : Node(c, in1) {
+ init_flags(Flag_is_expensive);
+ C->add_expensive_node(this);
+ }
virtual int Opcode() const;
const Type *bottom_type() const { return Type::DOUBLE; }
virtual uint ideal_reg() const { return Op_RegD; }
@@ -470,7 +482,10 @@
// Log_e of a double
class LogDNode : public Node {
public:
- LogDNode( Node *in1 ) : Node(0, in1) {}
+ LogDNode(Compile* C, Node *c, Node *in1) : Node(c, in1) {
+ init_flags(Flag_is_expensive);
+ C->add_expensive_node(this);
+ }
virtual int Opcode() const;
const Type *bottom_type() const { return Type::DOUBLE; }
virtual uint ideal_reg() const { return Op_RegD; }
@@ -481,7 +496,10 @@
// Log_10 of a double
class Log10DNode : public Node {
public:
- Log10DNode( Node *in1 ) : Node(0, in1) {}
+ Log10DNode(Compile* C, Node *c, Node *in1) : Node(c, in1) {
+ init_flags(Flag_is_expensive);
+ C->add_expensive_node(this);
+ }
virtual int Opcode() const;
const Type *bottom_type() const { return Type::DOUBLE; }
virtual uint ideal_reg() const { return Op_RegD; }
--- a/hotspot/src/share/vm/opto/superword.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/opto/superword.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -143,7 +143,8 @@
// Ready the block
- construct_bb();
+ if (!construct_bb())
+ return; // Exit if no interesting nodes or complex graph.
dependence_graph();
@@ -615,6 +616,7 @@
if (n == stop) break;
preds.push(n);
prev = n;
+ assert(n->is_Mem(), err_msg_res("unexpected node %s", n->Name()));
n = n->in(MemNode::Memory);
}
}
@@ -1578,7 +1580,7 @@
//------------------------------construct_bb---------------------------
// Construct reverse postorder list of block members
-void SuperWord::construct_bb() {
+bool SuperWord::construct_bb() {
Node* entry = bb();
assert(_stk.length() == 0, "stk is empty");
@@ -1596,6 +1598,12 @@
Node *n = lpt()->_body.at(i);
set_bb_idx(n, i); // Create a temporary map
if (in_bb(n)) {
+ if (n->is_LoadStore() || n->is_MergeMem() ||
+ (n->is_Proj() && !n->as_Proj()->is_CFG())) {
+ // Bailout if the loop has LoadStore, MergeMem or data Proj
+ // nodes. Superword optimization does not work with them.
+ return false;
+ }
bb_ct++;
if (!n->is_CFG()) {
bool found = false;
@@ -1620,6 +1628,10 @@
if (in_bb(n) && (n->is_Phi() && n->bottom_type() == Type::MEMORY)) {
Node* n_tail = n->in(LoopNode::LoopBackControl);
if (n_tail != n->in(LoopNode::EntryControl)) {
+ if (!n_tail->is_Mem()) {
+ assert(n_tail->is_Mem(), err_msg_res("unexpected node for memory slice: %s", n_tail->Name()));
+ return false; // Bailout
+ }
_mem_slice_head.push(n);
_mem_slice_tail.push(n_tail);
}
@@ -1695,6 +1707,7 @@
}
#endif
assert(rpo_idx == -1 && bb_ct == _block.length(), "all block members found");
+ return (_mem_slice_head.length() > 0) || (_data_entry.length() > 0);
}
//------------------------------initialize_bb---------------------------
--- a/hotspot/src/share/vm/opto/superword.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/opto/superword.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -380,7 +380,7 @@
// Is use->in(u_idx) a vector use?
bool is_vector_use(Node* use, int u_idx);
// Construct reverse postorder list of block members
- void construct_bb();
+ bool construct_bb();
// Initialize per node info
void initialize_bb();
// Insert n into block after pos
--- a/hotspot/src/share/vm/prims/jvmtiEnter.xsl Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/prims/jvmtiEnter.xsl Fri Mar 15 16:39:07 2013 -0700
@@ -773,7 +773,7 @@
</xsl:text>
<xsl:apply-templates select=".." mode="traceError">
<xsl:with-param name="err">JVMTI_ERROR_INVALID_THREAD</xsl:with-param>
- <xsl:with-param name="comment"> - jthread resolved to NULL - jthread = %0x%x</xsl:with-param>
+ <xsl:with-param name="comment"> - jthread resolved to NULL - jthread = 0x%x</xsl:with-param>
<xsl:with-param name="extraValue">, <xsl:value-of select="$name"/></xsl:with-param>
</xsl:apply-templates>
<xsl:text>
@@ -782,7 +782,7 @@
</xsl:text>
<xsl:apply-templates select=".." mode="traceError">
<xsl:with-param name="err">JVMTI_ERROR_INVALID_THREAD</xsl:with-param>
- <xsl:with-param name="comment"> - oop is not a thread - jthread = %0x%x</xsl:with-param>
+ <xsl:with-param name="comment"> - oop is not a thread - jthread = 0x%x</xsl:with-param>
<xsl:with-param name="extraValue">, <xsl:value-of select="$name"/></xsl:with-param>
</xsl:apply-templates>
<xsl:text>
@@ -794,7 +794,7 @@
<xsl:with-param name="err">
<xsl:text>JVMTI_ERROR_THREAD_NOT_ALIVE</xsl:text>
</xsl:with-param>
- <xsl:with-param name="comment"> - not a Java thread - jthread = %0x%x</xsl:with-param>
+ <xsl:with-param name="comment"> - not a Java thread - jthread = 0x%x</xsl:with-param>
<xsl:with-param name="extraValue">, <xsl:value-of select="$name"/></xsl:with-param>
</xsl:apply-templates>
<xsl:text>
@@ -838,7 +838,7 @@
</xsl:text>
<xsl:apply-templates select=".." mode="traceError">
<xsl:with-param name="err">JVMTI_ERROR_ILLEGAL_ARGUMENT</xsl:with-param>
- <xsl:with-param name="comment"> - negative depth - jthread = %0x%x</xsl:with-param>
+ <xsl:with-param name="comment"> - negative depth - jthread = 0x%x</xsl:with-param>
<xsl:with-param name="extraValue">, <xsl:value-of select="$name"/></xsl:with-param>
</xsl:apply-templates>
<xsl:text>
--- a/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -997,13 +997,19 @@
// move our object at this point. However, our owner value is safe
// since it is either the Lock word on a stack or a JavaThread *.
owning_thread = Threads::owning_thread_from_monitor_owner(owner, !at_safepoint);
- assert(owning_thread != NULL, "sanity check");
- if (owning_thread != NULL) { // robustness
+ // Cannot assume (owning_thread != NULL) here because this function
+ // may not have been called at a safepoint and the owning_thread
+ // might not be suspended.
+ if (owning_thread != NULL) {
// The monitor's owner either has to be the current thread, at safepoint
// or it has to be suspended. Any of these conditions will prevent both
// contending and waiting threads from modifying the state of
// the monitor.
if (!at_safepoint && !JvmtiEnv::is_thread_fully_suspended(owning_thread, true, &debug_bits)) {
+ // Don't worry! This return of JVMTI_ERROR_THREAD_NOT_SUSPENDED
+ // will not make it back to the JVM/TI agent. The error code will
+ // get intercepted in JvmtiEnv::GetObjectMonitorUsage() which
+ // will retry the call via a VM_GetObjectMonitorUsage VM op.
return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
}
HandleMark hm;
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -1558,6 +1558,18 @@
} break;
}
} // end for each bytecode
+
+ // We also need to rewrite the parameter name indexes, if there is
+ // method parameter data present
+ if(method->has_method_parameters()) {
+ const int len = method->method_parameters_length();
+ MethodParametersElement* elem = method->method_parameters_start();
+
+ for (int i = 0; i < len; i++) {
+ const u2 cp_index = elem[i].name_cp_index;
+ elem[i].name_cp_index = find_new_index(cp_index);
+ }
+ }
} // end rewrite_cp_refs_in_method()
--- a/hotspot/src/share/vm/runtime/arguments.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -1738,16 +1738,6 @@
return false;
}
-static void force_serial_gc() {
- FLAG_SET_DEFAULT(UseSerialGC, true);
- FLAG_SET_DEFAULT(UseParNewGC, false);
- FLAG_SET_DEFAULT(UseConcMarkSweepGC, false);
- FLAG_SET_DEFAULT(CMSIncrementalMode, false); // special CMS suboption
- FLAG_SET_DEFAULT(UseParallelGC, false);
- FLAG_SET_DEFAULT(UseParallelOldGC, false);
- FLAG_SET_DEFAULT(UseG1GC, false);
-}
-
static bool verify_serial_gc_flags() {
return (UseSerialGC &&
!(UseParNewGC || (UseConcMarkSweepGC || CMSIncrementalMode) || UseG1GC ||
@@ -2191,19 +2181,6 @@
FREE_C_HEAP_ARRAY(char, altclasses_path, mtInternal);
}
- if (WhiteBoxAPI) {
- // Append wb.jar to bootclasspath if enabled
- const char* wb_jar = "wb.jar";
- size_t wb_path_len = strlen(get_meta_index_dir()) + 1 +
- strlen(wb_jar);
- char* wb_path = NEW_C_HEAP_ARRAY(char, wb_path_len, mtInternal);
- strcpy(wb_path, get_meta_index_dir());
- strcat(wb_path, wb_jar);
- scp.add_suffix(wb_path);
- scp_assembly_required = true;
- FREE_C_HEAP_ARRAY(char, wb_path, mtInternal);
- }
-
// Parse _JAVA_OPTIONS environment variable (if present) (mimics classic VM)
result = parse_java_options_environment_variable(&scp, &scp_assembly_required);
if (result != JNI_OK) {
@@ -2498,7 +2475,12 @@
}
// Out of the box management support
if (match_option(option, "-Dcom.sun.management", &tail)) {
+#if INCLUDE_MANAGEMENT
FLAG_SET_CMDLINE(bool, ManagementServer, true);
+#else
+ vm_exit_during_initialization(
+ "-Dcom.sun.management is not supported in this VM.", NULL);
+#endif
}
// -Xint
} else if (match_option(option, "-Xint", &tail)) {
@@ -2844,6 +2826,11 @@
// away and will cause VM initialization failures!
warning("-XX:+UseVMInterruptibleIO is obsolete and will be removed in a future release.");
FLAG_SET_CMDLINE(bool, UseVMInterruptibleIO, true);
+#if !INCLUDE_MANAGEMENT
+ } else if (match_option(option, "-XX:+ManagementServer", &tail)) {
+ vm_exit_during_initialization(
+ "ManagementServer is not supported in this VM.", NULL);
+#endif // INCLUDE_MANAGEMENT
} else if (match_option(option, "-XX:", &tail)) { // -XX:xxxx
// Skip -XX:Flags= since that case has already been handled
if (strncmp(tail, "Flags=", strlen("Flags=")) != 0) {
@@ -3072,6 +3059,27 @@
} \
} while(0)
+
+#define UNSUPPORTED_GC_OPTION(gc) \
+do { \
+ if (gc) { \
+ if (FLAG_IS_CMDLINE(gc)) { \
+ warning(#gc " is not supported in this VM. Using Serial GC."); \
+ } \
+ FLAG_SET_DEFAULT(gc, false); \
+ } \
+} while(0)
+
+static void force_serial_gc() {
+ FLAG_SET_DEFAULT(UseSerialGC, true);
+ FLAG_SET_DEFAULT(CMSIncrementalMode, false); // special CMS suboption
+ UNSUPPORTED_GC_OPTION(UseG1GC);
+ UNSUPPORTED_GC_OPTION(UseParallelGC);
+ UNSUPPORTED_GC_OPTION(UseParallelOldGC);
+ UNSUPPORTED_GC_OPTION(UseConcMarkSweepGC);
+ UNSUPPORTED_GC_OPTION(UseParNewGC);
+}
+
// Parse entry point called from JNI_CreateJavaVM
jint Arguments::parse(const JavaVMInitArgs* args) {
@@ -3187,28 +3195,15 @@
hotspotrc, hotspotrc);
}
-#if (defined JAVASE_EMBEDDED || defined ARM)
- UNSUPPORTED_OPTION(UseG1GC, "G1 GC");
-#endif
-
#ifdef _ALLBSD_SOURCE // UseLargePages is not yet supported on BSD.
UNSUPPORTED_OPTION(UseLargePages, "-XX:+UseLargePages");
#endif
-#if !INCLUDE_ALL_GCS
- if (UseParallelGC) {
- warning("Parallel GC is not supported in this VM. Using Serial GC.");
- }
- if (UseParallelOldGC) {
- warning("Parallel Old GC is not supported in this VM. Using Serial GC.");
- }
- if (UseConcMarkSweepGC) {
- warning("Concurrent Mark Sweep GC is not supported in this VM. Using Serial GC.");
- }
- if (UseParNewGC) {
- warning("Par New GC is not supported in this VM. Using Serial GC.");
- }
-#endif // INCLUDE_ALL_GCS
+#if INCLUDE_ALL_GCS
+ #if (defined JAVASE_EMBEDDED || defined ARM)
+ UNSUPPORTED_OPTION(UseG1GC, "G1 GC");
+ #endif
+#endif
#ifndef PRODUCT
if (TraceBytecodesAt != 0) {
--- a/hotspot/src/share/vm/runtime/atomic.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/runtime/atomic.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -29,10 +29,17 @@
class Atomic : AllStatic {
public:
+ // Atomic operations on jlong types are not available on all 32-bit
+ // platforms. If atomic ops on jlongs are defined here they must only
+ // be used from code that verifies they are available at runtime and
+ // can provide an alternative action if not - see supports_cx8() for
+ // a means to test availability.
+
// Atomically store to a location
inline static void store (jbyte store_value, jbyte* dest);
inline static void store (jshort store_value, jshort* dest);
inline static void store (jint store_value, jint* dest);
+ // See comment above about using jlong atomics on 32-bit platforms
inline static void store (jlong store_value, jlong* dest);
inline static void store_ptr(intptr_t store_value, intptr_t* dest);
inline static void store_ptr(void* store_value, void* dest);
@@ -40,17 +47,19 @@
inline static void store (jbyte store_value, volatile jbyte* dest);
inline static void store (jshort store_value, volatile jshort* dest);
inline static void store (jint store_value, volatile jint* dest);
+ // See comment above about using jlong atomics on 32-bit platforms
inline static void store (jlong store_value, volatile jlong* dest);
inline static void store_ptr(intptr_t store_value, volatile intptr_t* dest);
inline static void store_ptr(void* store_value, volatile void* dest);
+ // See comment above about using jlong atomics on 32-bit platforms
inline static jlong load(volatile jlong* src);
// Atomically add to a location, return updated value
inline static jint add (jint add_value, volatile jint* dest);
inline static intptr_t add_ptr(intptr_t add_value, volatile intptr_t* dest);
inline static void* add_ptr(intptr_t add_value, volatile void* dest);
-
+ // See comment above about using jlong atomics on 32-bit platforms
static jlong add (jlong add_value, volatile jlong* dest);
// Atomically increment location
@@ -75,6 +84,7 @@
// barrier across the cmpxchg. I.e., it's really a 'fence_cmpxchg_acquire'.
static jbyte cmpxchg (jbyte exchange_value, volatile jbyte* dest, jbyte compare_value);
inline static jint cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value);
+ // See comment above about using jlong atomics on 32-bit platforms
inline static jlong cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value);
static unsigned int cmpxchg(unsigned int exchange_value,
--- a/hotspot/src/share/vm/runtime/frame.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/runtime/frame.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -1070,7 +1070,12 @@
// First consult the ADLC on where it puts parameter 0 for this signature.
VMReg reg = SharedRuntime::name_for_receiver();
- oop r = *caller.oopmapreg_to_location(reg, reg_map);
+ oop* oop_adr = caller.oopmapreg_to_location(reg, reg_map);
+ if (oop_adr == NULL) {
+ guarantee(oop_adr != NULL, "bad register save location");
+ return NULL;
+ }
+ oop r = *oop_adr;
assert(Universe::heap()->is_in_or_null(r), err_msg("bad receiver: " INTPTR_FORMAT " (" INTX_FORMAT ")", (intptr_t) r, (intptr_t) r));
return r;
}
--- a/hotspot/src/share/vm/runtime/globals.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/runtime/globals.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -1751,6 +1751,10 @@
manageable(intx, CMSWaitDuration, 2000, \
"Time in milliseconds that CMS thread waits for young GC") \
\
+ develop(uintx, CMSCheckInterval, 1000, \
+ "Interval in milliseconds that CMS thread checks if it " \
+ "should start a collection cycle") \
+ \
product(bool, CMSYield, true, \
"Yield between steps of concurrent mark & sweep") \
\
--- a/hotspot/src/share/vm/runtime/synchronizer.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/runtime/synchronizer.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -813,6 +813,7 @@
}
if (owner != NULL) {
+ // owning_thread_from_monitor_owner() may also return NULL here
return Threads::owning_thread_from_monitor_owner(owner, doLock);
}
--- a/hotspot/src/share/vm/runtime/thread.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/runtime/thread.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -4285,7 +4285,9 @@
if (owner == (address)p) return p;
}
}
- assert(UseHeavyMonitors == false, "Did not find owning Java thread with UseHeavyMonitors enabled");
+ // Cannot assert on lack of success here since this function may be
+ // used by code that is trying to report useful problem information
+ // like deadlock detection.
if (UseHeavyMonitors) return NULL;
//
@@ -4303,7 +4305,7 @@
}
}
}
- assert(the_owner != NULL, "Did not find owning Java thread for lock word address");
+ // cannot assert on lack of success here; see above comment
return the_owner;
}
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -2109,8 +2109,6 @@
/* Useful globals */ \
/******************/ \
\
- declare_constant(UseTLAB) \
- declare_constant(EnableInvokeDynamic) \
\
/**************/ \
/* Stack bias */ \
--- a/hotspot/src/share/vm/services/memReporter.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/services/memReporter.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -419,7 +419,7 @@
_output->print_cr("[" PTR_FORMAT "] %s+0x%x", pc, buf, offset);
_output->print("%28s", " ");
} else {
- _output->print("[" PTR_FORMAT "]%18s", " ");
+ _output->print("[" PTR_FORMAT "]%18s", pc, " ");
}
_output->print_cr("(mmap: reserved=%d%s, committed=%d%s)",
@@ -596,7 +596,7 @@
_output->print_cr("[" PTR_FORMAT "] %s+0x%x", pc, buf, offset);
_output->print("%28s", " ");
} else {
- _output->print("[" PTR_FORMAT "]%18s", " ");
+ _output->print("[" PTR_FORMAT "]%18s", pc, " ");
}
}
--- a/hotspot/src/share/vm/services/memSnapshot.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/services/memSnapshot.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -528,7 +528,8 @@
// an arena record can be followed by a size record, we need to remove both
if (matched_rec->is_arena_record()) {
MemPointerRecord* next = (MemPointerRecord*)malloc_snapshot_itr.peek_next();
- if (next->is_arena_memory_record() && next->is_memory_record_of_arena(matched_rec)) {
+ if (next != NULL && next->is_arena_memory_record() &&
+ next->is_memory_record_of_arena(matched_rec)) {
malloc_snapshot_itr.remove();
}
}
--- a/hotspot/src/share/vm/services/threadService.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/services/threadService.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -327,8 +327,28 @@
while (waitingToLockMonitor != NULL || waitingToLockBlocker != NULL) {
cycle->add_thread(currentThread);
if (waitingToLockMonitor != NULL) {
- currentThread = Threads::owning_thread_from_monitor_owner((address)waitingToLockMonitor->owner(),
- false /* no locking needed */);
+ currentThread = Threads::owning_thread_from_monitor_owner(
+ (address)waitingToLockMonitor->owner(),
+ false /* no locking needed */);
+ if (currentThread == NULL) {
+ // This function is called at a safepoint so the JavaThread
+ // that owns waitingToLockMonitor should be findable, but
+ // if it is not findable, then the previous currentThread is
+ // blocked permanently. We record this as a deadlock.
+ num_deadlocks++;
+
+ cycle->set_deadlock(true);
+
+ // add this cycle to the deadlocks list
+ if (deadlocks == NULL) {
+ deadlocks = cycle;
+ } else {
+ last->set_next(cycle);
+ }
+ last = cycle;
+ cycle = new DeadlockCycle();
+ break;
+ }
} else {
if (concurrent_locks) {
if (waitingToLockBlocker->is_a(SystemDictionary::abstract_ownable_synchronizer_klass())) {
@@ -841,7 +861,17 @@
owner_desc = " (JVMTI raw monitor),\n which is held by";
}
currentThread = Threads::owning_thread_from_monitor_owner(
- (address)waitingToLockMonitor->owner(), false /* no locking needed */);
+ (address)waitingToLockMonitor->owner(),
+ false /* no locking needed */);
+ if (currentThread == NULL) {
+ // The deadlock was detected at a safepoint so the JavaThread
+ // that owns waitingToLockMonitor should be findable, but
+ // if it is not findable, then the previous currentThread is
+ // blocked permanently.
+ st->print("%s UNKNOWN_owner_addr=" PTR_FORMAT, owner_desc,
+ (address)waitingToLockMonitor->owner());
+ continue;
+ }
} else {
st->print(" waiting for ownable synchronizer " INTPTR_FORMAT ", (a %s)",
(address)waitingToLockBlocker,
--- a/hotspot/src/share/vm/utilities/constantTag.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/utilities/constantTag.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -52,7 +52,6 @@
case JVM_CONSTANT_StringIndex :
case JVM_CONSTANT_MethodHandle :
case JVM_CONSTANT_MethodType :
- case JVM_CONSTANT_Object :
return T_OBJECT;
default:
ShouldNotReachHere();
@@ -96,8 +95,6 @@
return "MethodType Error";
case JVM_CONSTANT_InvokeDynamic :
return "InvokeDynamic";
- case JVM_CONSTANT_Object :
- return "Object";
case JVM_CONSTANT_Utf8 :
return "Utf8";
case JVM_CONSTANT_UnresolvedClass :
--- a/hotspot/src/share/vm/utilities/constantTag.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/utilities/constantTag.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -43,8 +43,7 @@
JVM_CONSTANT_UnresolvedClassInError = 103, // Error tag due to resolution error
JVM_CONSTANT_MethodHandleInError = 104, // Error tag due to resolution error
JVM_CONSTANT_MethodTypeInError = 105, // Error tag due to resolution error
- JVM_CONSTANT_Object = 106, // Required for BoundMethodHandle arguments.
- JVM_CONSTANT_InternalMax = 106 // Last implementation tag
+ JVM_CONSTANT_InternalMax = 105 // Last implementation tag
};
@@ -84,8 +83,6 @@
bool is_klass_index() const { return _tag == JVM_CONSTANT_ClassIndex; }
bool is_string_index() const { return _tag == JVM_CONSTANT_StringIndex; }
- bool is_object() const { return _tag == JVM_CONSTANT_Object; }
-
bool is_klass_reference() const { return is_klass_index() || is_unresolved_klass(); }
bool is_klass_or_reference() const{ return is_klass() || is_klass_reference(); }
bool is_field_or_method() const { return is_field() || is_method() || is_interface_method(); }
@@ -98,7 +95,7 @@
bool is_loadable_constant() const {
return ((_tag >= JVM_CONSTANT_Integer && _tag <= JVM_CONSTANT_String) ||
is_method_type() || is_method_handle() ||
- is_unresolved_klass() || is_object());
+ is_unresolved_klass());
}
constantTag() {
--- a/hotspot/src/share/vm/utilities/debug.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/utilities/debug.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -228,28 +228,16 @@
report_vm_error(file, line, "fatal error", message);
}
-// Used by report_vm_out_of_memory to detect recursion.
-static jint _exiting_out_of_mem = 0;
-
void report_vm_out_of_memory(const char* file, int line, size_t size,
const char* message) {
if (Debugging) return;
- // We try to gather additional information for the first out of memory
- // error only; gathering additional data might cause an allocation and a
- // recursive out_of_memory condition.
-
- const jint exiting = 1;
- // If we succeed in changing the value, we're the first one in.
- bool first_time_here = Atomic::xchg(exiting, &_exiting_out_of_mem) != exiting;
+ Thread* thread = ThreadLocalStorage::get_thread_slow();
+ VMError(thread, file, line, size, message).report_and_die();
- if (first_time_here) {
- Thread* thread = ThreadLocalStorage::get_thread_slow();
- VMError(thread, file, line, size, message).report_and_die();
- }
-
- // Dump core and abort
- vm_abort(true);
+ // The UseOSErrorReporting option in report_and_die() may allow a return
+ // to here. If so then we'll have to figure out how to handle it.
+ guarantee(false, "report_and_die() should not return here");
}
void report_should_not_call(const char* file, int line) {
--- a/hotspot/src/share/vm/utilities/numberSeq.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/utilities/numberSeq.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -245,7 +245,7 @@
void NumberSeq::dump_on(outputStream* s) {
AbsSeq::dump_on(s);
- s->print_cr("\t\t _last = %7.3f, _maximum = %7.3f");
+ s->print_cr("\t\t _last = %7.3f, _maximum = %7.3f", _last, _maximum);
}
void TruncatedSeq::dump_on(outputStream* s) {
--- a/hotspot/src/share/vm/utilities/ostream.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/utilities/ostream.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -431,7 +431,7 @@
rotatingFileStream::rotatingFileStream(const char* file_name) {
_cur_file_num = 0;
- _bytes_writen = 0L;
+ _bytes_written = 0L;
_file_name = NEW_C_HEAP_ARRAY(char, strlen(file_name)+10, mtInternal);
jio_snprintf(_file_name, strlen(file_name)+10, "%s.%d", file_name, _cur_file_num);
_file = fopen(_file_name, "w");
@@ -440,7 +440,7 @@
rotatingFileStream::rotatingFileStream(const char* file_name, const char* opentype) {
_cur_file_num = 0;
- _bytes_writen = 0L;
+ _bytes_written = 0L;
_file_name = NEW_C_HEAP_ARRAY(char, strlen(file_name)+10, mtInternal);
jio_snprintf(_file_name, strlen(file_name)+10, "%s.%d", file_name, _cur_file_num);
_file = fopen(_file_name, opentype);
@@ -448,10 +448,9 @@
}
void rotatingFileStream::write(const char* s, size_t len) {
- if (_file != NULL) {
- // Make an unused local variable to avoid warning from gcc 4.x compiler.
+ if (_file != NULL) {
size_t count = fwrite(s, 1, len, _file);
- Atomic::add((jlong)count, &_bytes_writen);
+ _bytes_written += count;
}
update_position(s, len);
}
@@ -465,7 +464,10 @@
// concurrent GC threads to run parallel with VMThread at safepoint, write and rotate_log
// must be synchronized.
void rotatingFileStream::rotate_log() {
- if (_bytes_writen < (jlong)GCLogFileSize) return;
+ if (_bytes_written < (jlong)GCLogFileSize) {
+ return;
+ }
+
#ifdef ASSERT
Thread *thread = Thread::current();
assert(thread == NULL ||
@@ -475,7 +477,7 @@
if (NumberOfGCLogFiles == 1) {
// rotate in same file
rewind();
- _bytes_writen = 0L;
+ _bytes_written = 0L;
return;
}
@@ -491,7 +493,7 @@
}
_file = fopen(_file_name, "w");
if (_file != NULL) {
- _bytes_writen = 0L;
+ _bytes_written = 0L;
_need_close = true;
} else {
tty->print_cr("failed to open rotation log file %s due to %s\n",
--- a/hotspot/src/share/vm/utilities/ostream.hpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/utilities/ostream.hpp Fri Mar 15 16:39:07 2013 -0700
@@ -231,7 +231,7 @@
class rotatingFileStream : public fileStream {
protected:
char* _file_name;
- jlong _bytes_writen;
+ jlong _bytes_written;
uintx _cur_file_num; // current logfile rotation number, from 0 to MaxGCLogFileNumbers-1
public:
rotatingFileStream(const char* file_name);
--- a/hotspot/src/share/vm/utilities/yieldingWorkgroup.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/src/share/vm/utilities/yieldingWorkgroup.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -24,9 +24,7 @@
#include "precompiled.hpp"
#include "utilities/macros.hpp"
-#if INCLUDE_ALL_GCS
#include "utilities/yieldingWorkgroup.hpp"
-#endif // INCLUDE_ALL_GCS
// Forward declaration of classes declared here.
--- a/hotspot/test/TEST.ROOT Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/test/TEST.ROOT Fri Mar 15 16:39:07 2013 -0700
@@ -28,4 +28,4 @@
# DO NOT EDIT without first contacting hotspot-regtest@sun.com
# The list of keywords supported in this test suite
-keys=cte_test jcmd nmt regression
+keys=cte_test jcmd nmt regression gc
--- a/hotspot/test/compiler/5091921/Test6850611.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/test/compiler/5091921/Test6850611.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,7 @@
* @bug 6850611
* @summary int / long arithmetic seems to be broken in 1.6.0_14 HotSpot Server VM (Win XP)
*
- * @run main Test6850611
+ * @run main/timeout=480 Test6850611
*/
public class Test6850611 {
--- a/hotspot/test/compiler/5091921/Test6890943.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/test/compiler/5091921/Test6890943.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,7 @@
* @bug 6890943
* @summary JVM mysteriously gives wrong result on 64-bit 1.6 VMs in hotspot mode.
*
- * @run shell Test6890943.sh
+ * @run shell/timeout=240 Test6890943.sh
*/
import java.util.*;
import java.io.*;
--- a/hotspot/test/compiler/5091921/Test6890943.sh Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/test/compiler/5091921/Test6890943.sh Fri Mar 15 16:39:07 2013 -0700
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -52,7 +52,10 @@
${TESTJAVA}/bin/javac -d . Test6890943.java
-${TESTJAVA}/bin/java -XX:-PrintVMOptions ${TESTVMOPTS} Test6890943 < input6890943.txt > test.out 2>&1
+${TESTJAVA}/bin/java -XX:-PrintVMOptions -XX:+IgnoreUnrecognizedVMOptions ${TESTVMOPTS} Test6890943 < input6890943.txt > pretest.out 2>&1
+
+# This test sometimes tickles an unrelated performance warning that interferes with diff.
+grep -v 'warning: Performance bug: SystemDictionary' pretest.out > test.out
diff output6890943.txt test.out
--- a/hotspot/test/compiler/5091921/Test6905845.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/test/compiler/5091921/Test6905845.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,7 @@
* @bug 6905845
* @summary Server VM improperly optimizing away loop.
*
- * @run main Test6905845
+ * @run main/timeout=480 Test6905845
*/
public class Test6905845 {
--- a/hotspot/test/compiler/5091921/Test6992759.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/test/compiler/5091921/Test6992759.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,7 @@
* @bug 6992759
* @summary Bad code generated for integer <= comparison, fails for Integer.MAX_VALUE
*
- * @run main Test6992759
+ * @run main/timeout=240 Test6992759
*/
public class Test6992759 {
--- a/hotspot/test/compiler/6431242/Test.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/test/compiler/6431242/Test.java Fri Mar 15 16:39:07 2013 -0700
@@ -25,7 +25,7 @@
/*
* @test
* @bug 6431242
- * @run main/othervm -server -XX:+PrintCompilation Test
+ * @run main Test
*/
public class Test{
--- a/hotspot/test/compiler/6589834/Test_ia32.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/test/compiler/6589834/Test_ia32.java Fri Mar 15 16:39:07 2013 -0700
@@ -26,7 +26,7 @@
* @bug 6589834
* @summary deoptimization problem with -XX:+DeoptimizeALot
*
- * @run main/othervm -server Test_ia32
+ * @run main Test_ia32
*/
/***************************************************************************************
--- a/hotspot/test/compiler/6636138/Test1.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/test/compiler/6636138/Test1.java Fri Mar 15 16:39:07 2013 -0700
@@ -26,7 +26,7 @@
* @bug 6636138
* @summary SuperWord::co_locate_pack(Node_List* p) generates memory graph that leads to memory order violation.
*
- * @run main/othervm -server -Xbatch -XX:CompileOnly=Test1.init Test1
+ * @run main/othervm -Xbatch -XX:CompileOnly=Test1.init Test1
*/
public class Test1 {
--- a/hotspot/test/compiler/6636138/Test2.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/test/compiler/6636138/Test2.java Fri Mar 15 16:39:07 2013 -0700
@@ -26,7 +26,7 @@
* @bug 6636138
* @summary SuperWord::co_locate_pack(Node_List* p) generates memory graph that leads to memory order violation.
*
- * @run main/othervm -server -Xbatch -XX:CompileOnly=Test2.shift Test2
+ * @run main/othervm -Xbatch -XX:CompileOnly=Test2.shift Test2
*/
public class Test2 {
--- a/hotspot/test/compiler/6795161/Test.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/test/compiler/6795161/Test.java Fri Mar 15 16:39:07 2013 -0700
@@ -26,7 +26,7 @@
* @test
* @bug 6795161
* @summary Escape analysis leads to data corruption
- * @run main/othervm -server -XX:+IgnoreUnrecognizedVMOptions -Xcomp -XX:CompileOnly=Test -XX:+DoEscapeAnalysis Test
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -Xcomp -XX:CompileOnly=Test -XX:+DoEscapeAnalysis Test
*/
class Test_Class_1 {
--- a/hotspot/test/compiler/6852078/Test6852078.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/test/compiler/6852078/Test6852078.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,7 @@
* @bug 6852078
* @summary Disable SuperWord optimization for unsafe read/write
*
- * @run main/othervm Test6852078
+ * @run main Test6852078
*/
import java.util.*;
@@ -50,7 +50,11 @@
}
public static void main(String [] args) {
+ long start = System.currentTimeMillis();
for (int i=0; i<2000; i++) {
+ // To protect slow systems from test-too-long timeouts
+ if ((i > 100) && ((System.currentTimeMillis() - start) > 100000))
+ break;
Test6852078 t = new Test6852078(args);
}
}
--- a/hotspot/test/compiler/6946040/TestCharShortByteSwap.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/test/compiler/6946040/TestCharShortByteSwap.java Fri Mar 15 16:39:07 2013 -0700
@@ -26,7 +26,7 @@
* @test
* @bug 6946040
* @summary Tests Character/Short.reverseBytes and their intrinsics implementation in the server compiler
- * @run main/othervm -Xbatch -server -XX:CompileOnly=.testChar,.testShort TestCharShortByteSwap
+ * @run main/othervm -Xbatch -XX:CompileOnly=.testChar,.testShort TestCharShortByteSwap
*/
// This test must run without any command line arguments.
--- a/hotspot/test/compiler/7068051/Test7068051.sh Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/test/compiler/7068051/Test7068051.sh Fri Mar 15 16:39:07 2013 -0700
@@ -45,5 +45,5 @@
${TESTJAVA}/bin/javac -d . Test7068051.java
-${TESTJAVA}/bin/java -showversion -Xbatch ${TESTVMOPTS} Test7068051 foo.jar
+${TESTJAVA}/bin/java ${TESTVMOPTS} -showversion -Xbatch Test7068051 foo.jar
--- a/hotspot/test/compiler/8000805/Test8000805.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/test/compiler/8000805/Test8000805.java Fri Mar 15 16:39:07 2013 -0700
@@ -26,7 +26,7 @@
* @bug 8000805
* @summary JMM issue: short loads are non-atomic
*
- * @run main/othervm -server -XX:-TieredCompilation -Xcomp -XX:+PrintCompilation -XX:CompileOnly=Test8000805.loadS2LmaskFF,Test8000805.loadS2Lmask16,Test8000805.loadS2Lmask13,Test8000805.loadUS_signExt,Test8000805.loadB2L_mask8 Test8000805
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -Xcomp -XX:+PrintCompilation -XX:CompileOnly=Test8000805.loadS2LmaskFF,Test8000805.loadS2Lmask16,Test8000805.loadS2Lmask13,Test8000805.loadUS_signExt,Test8000805.loadB2L_mask8 Test8000805
*/
public class Test8000805 {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/8004867/TestIntAtomicCAS.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,969 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8004867
+ * @summary VM crashing with assert "share/vm/opto/node.hpp:357 - assert(i < _max) failed: oob"
+ *
+ * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestIntAtomicCAS
+ * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:+OptimizeFill TestIntAtomicCAS
+ */
+
+import java.util.concurrent.atomic.AtomicIntegerArray;
+
+public class TestIntAtomicCAS {
+ private static final int ARRLEN = 97;
+ private static final int ITERS = 11000;
+ private static final int OFFSET = 3;
+ private static final int SCALE = 2;
+ private static final int ALIGN_OFF = 8;
+ private static final int UNALIGN_OFF = 5;
+
+ public static void main(String args[]) {
+ System.out.println("Testing Integer array atomic CAS operations");
+ int errn = test(false);
+ if (errn > 0) {
+ System.err.println("FAILED: " + errn + " errors");
+ System.exit(97);
+ }
+ System.out.println("PASSED");
+ }
+
+ static int test(boolean test_only) {
+ AtomicIntegerArray a1 = new AtomicIntegerArray(ARRLEN);
+ AtomicIntegerArray a2 = new AtomicIntegerArray(ARRLEN);
+ // Initialize
+ for (int i=0; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ a2.set(i, -1);
+ }
+ System.out.println("Warmup");
+ for (int i=0; i<ITERS; i++) {
+ test_ci(a1);
+ test_vi(a2, 123, -1);
+ test_cp(a1, a2);
+ test_2ci(a1, a2);
+ test_2vi(a1, a2, 123, 103);
+ test_ci_neg(a1, 123);
+ test_vi_neg(a2, 123, 103);
+ test_cp_neg(a1, a2);
+ test_2ci_neg(a1, a2);
+ test_2vi_neg(a1, a2, 123, 103);
+ test_ci_oppos(a1, 123);
+ test_vi_oppos(a2, 123, 103);
+ test_cp_oppos(a1, a2);
+ test_2ci_oppos(a1, a2);
+ test_2vi_oppos(a1, a2, 123, 103);
+ test_ci_off(a1, 123);
+ test_vi_off(a2, 123, 103);
+ test_cp_off(a1, a2);
+ test_2ci_off(a1, a2);
+ test_2vi_off(a1, a2, 123, 103);
+ test_ci_inv(a1, OFFSET, 123);
+ test_vi_inv(a2, 123, OFFSET, 103);
+ test_cp_inv(a1, a2, OFFSET);
+ test_2ci_inv(a1, a2, OFFSET);
+ test_2vi_inv(a1, a2, 123, 103, OFFSET);
+ test_ci_scl(a1, 123);
+ test_vi_scl(a2, 123, 103);
+ test_cp_scl(a1, a2);
+ test_2ci_scl(a1, a2);
+ test_2vi_scl(a1, a2, 123, 103);
+ test_cp_alndst(a1, a2);
+ test_cp_alnsrc(a1, a2);
+ test_2ci_aln(a1, a2);
+ test_2vi_aln(a1, a2, 123, 103);
+ test_cp_unalndst(a1, a2);
+ test_cp_unalnsrc(a1, a2);
+ test_2ci_unaln(a1, a2);
+ test_2vi_unaln(a1, a2, 123, 103);
+ }
+ // Initialize
+ for (int i=0; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ a2.set(i, -1);
+ }
+ // Test and verify results
+ System.out.println("Verification");
+ int errn = 0;
+ {
+ test_ci(a1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_ci: a1", i, a1.get(i), -123);
+ }
+ test_vi(a2, 123, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_vi: a2", i, a2.get(i), 123);
+ }
+ test_cp(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_cp: a1", i, a1.get(i), 123);
+ }
+ test_2ci(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_2ci: a1", i, a1.get(i), -123);
+ errn += verify("test_2ci: a2", i, a2.get(i), -103);
+ }
+ test_2vi(a1, a2, 123, 103);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_2vi: a1", i, a1.get(i), 123);
+ errn += verify("test_2vi: a2", i, a2.get(i), 103);
+ }
+ // Reset for negative stride
+ for (int i=0; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ a2.set(i, -1);
+ }
+ test_ci_neg(a1, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_ci_neg: a1", i, a1.get(i), -123);
+ }
+ test_vi_neg(a2, 123, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_vi_neg: a2", i, a2.get(i), 123);
+ }
+ test_cp_neg(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_cp_neg: a1", i, a1.get(i), 123);
+ }
+ test_2ci_neg(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_2ci_neg: a1", i, a1.get(i), -123);
+ errn += verify("test_2ci_neg: a2", i, a2.get(i), -103);
+ }
+ test_2vi_neg(a1, a2, 123, 103);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_2vi_neg: a1", i, a1.get(i), 123);
+ errn += verify("test_2vi_neg: a2", i, a2.get(i), 103);
+ }
+ // Reset for opposite stride
+ for (int i=0; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ a2.set(i, -1);
+ }
+ test_ci_oppos(a1, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_ci_oppos: a1", i, a1.get(i), -123);
+ }
+ test_vi_oppos(a2, 123, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_vi_oppos: a2", i, a2.get(i), 123);
+ }
+ test_cp_oppos(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_cp_oppos: a1", i, a1.get(i), 123);
+ }
+ test_2ci_oppos(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_2ci_oppos: a1", i, a1.get(i), -123);
+ errn += verify("test_2ci_oppos: a2", i, a2.get(i), -103);
+ }
+ test_2vi_oppos(a1, a2, 123, 103);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_2vi_oppos: a1", i, a1.get(i), 123);
+ errn += verify("test_2vi_oppos: a2", i, a2.get(i), 103);
+ }
+ // Reset for indexing with offset
+ for (int i=0; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ a2.set(i, -1);
+ }
+ test_ci_off(a1, -1);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_ci_off: a1", i, a1.get(i), -123);
+ }
+ test_vi_off(a2, 123, -1);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_vi_off: a2", i, a2.get(i), 123);
+ }
+ test_cp_off(a1, a2);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_cp_off: a1", i, a1.get(i), 123);
+ }
+ test_2ci_off(a1, a2);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_2ci_off: a1", i, a1.get(i), -123);
+ errn += verify("test_2ci_off: a2", i, a2.get(i), -103);
+ }
+ test_2vi_off(a1, a2, 123, 103);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_2vi_off: a1", i, a1.get(i), 123);
+ errn += verify("test_2vi_off: a2", i, a2.get(i), 103);
+ }
+ for (int i=0; i<OFFSET; i++) {
+ errn += verify("test_2vi_off: a1", i, a1.get(i), -1);
+ errn += verify("test_2vi_off: a2", i, a2.get(i), -1);
+ }
+ // Reset for indexing with invariant offset
+ for (int i=0; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ a2.set(i, -1);
+ }
+ test_ci_inv(a1, OFFSET, -1);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_ci_inv: a1", i, a1.get(i), -123);
+ }
+ test_vi_inv(a2, 123, OFFSET, -1);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_vi_inv: a2", i, a2.get(i), 123);
+ }
+ test_cp_inv(a1, a2, OFFSET);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_cp_inv: a1", i, a1.get(i), 123);
+ }
+ test_2ci_inv(a1, a2, OFFSET);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_2ci_inv: a1", i, a1.get(i), -123);
+ errn += verify("test_2ci_inv: a2", i, a2.get(i), -103);
+ }
+ test_2vi_inv(a1, a2, 123, 103, OFFSET);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_2vi_inv: a1", i, a1.get(i), 123);
+ errn += verify("test_2vi_inv: a2", i, a2.get(i), 103);
+ }
+ for (int i=0; i<OFFSET; i++) {
+ errn += verify("test_2vi_inv: a1", i, a1.get(i), -1);
+ errn += verify("test_2vi_inv: a2", i, a2.get(i), -1);
+ }
+ // Reset for indexing with scale
+ for (int i=0; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ a2.set(i, -1);
+ }
+ test_ci_scl(a1, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ int val = (i%SCALE != 0) ? -1 : -123;
+ errn += verify("test_ci_scl: a1", i, a1.get(i), val);
+ }
+ test_vi_scl(a2, 123, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ int val = (i%SCALE != 0) ? -1 : 123;
+ errn += verify("test_vi_scl: a2", i, a2.get(i), val);
+ }
+ test_cp_scl(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ int val = (i%SCALE != 0) ? -1 : 123;
+ errn += verify("test_cp_scl: a1", i, a1.get(i), val);
+ }
+ test_2ci_scl(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ if (i%SCALE != 0) {
+ errn += verify("test_2ci_scl: a1", i, a1.get(i), -1);
+ } else if (i*SCALE < ARRLEN) {
+ errn += verify("test_2ci_scl: a1", i*SCALE, a1.get(i*SCALE), -123);
+ }
+ if (i%SCALE != 0) {
+ errn += verify("test_2ci_scl: a2", i, a2.get(i), -1);
+ } else if (i*SCALE < ARRLEN) {
+ errn += verify("test_2ci_scl: a2", i*SCALE, a2.get(i*SCALE), -103);
+ }
+ }
+ test_2vi_scl(a1, a2, 123, 103);
+ for (int i=0; i<ARRLEN; i++) {
+ if (i%SCALE != 0) {
+ errn += verify("test_2vi_scl: a1", i, a1.get(i), -1);
+ } else if (i*SCALE < ARRLEN) {
+ errn += verify("test_2vi_scl: a1", i*SCALE, a1.get(i*SCALE), 123);
+ }
+ if (i%SCALE != 0) {
+ errn += verify("test_2vi_scl: a2", i, a2.get(i), -1);
+ } else if (i*SCALE < ARRLEN) {
+ errn += verify("test_2vi_scl: a2", i*SCALE, a2.get(i*SCALE), 103);
+ }
+ }
+ // Reset for 2 arrays with relative aligned offset
+ for (int i=0; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ a2.set(i, -1);
+ }
+ test_vi(a2, 123, -1);
+ test_cp_alndst(a1, a2);
+ for (int i=0; i<ALIGN_OFF; i++) {
+ errn += verify("test_cp_alndst: a1", i, a1.get(i), -1);
+ }
+ for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_cp_alndst: a1", i, a1.get(i), 123);
+ }
+ for (int i=0; i<ALIGN_OFF; i++) {
+ a1.set(i, 123);
+ }
+ test_vi(a2, -123, 123);
+ test_cp_alnsrc(a1, a2);
+ for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+ errn += verify("test_cp_alnsrc: a1", i, a1.get(i), -123);
+ }
+ for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_cp_alnsrc: a1", i, a1.get(i), 123);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ a2.set(i, -1);
+ }
+ test_2ci_aln(a1, a2);
+ for (int i=0; i<ALIGN_OFF; i++) {
+ errn += verify("test_2ci_aln: a1", i, a1.get(i), -1);
+ }
+ for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2ci_aln: a1", i, a1.get(i), -123);
+ }
+ for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+ errn += verify("test_2ci_aln: a2", i, a2.get(i), -103);
+ }
+ for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2ci_aln: a2", i, a2.get(i), -1);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ a2.set(i, -1);
+ }
+ test_2vi_aln(a1, a2, 123, 103);
+ for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+ errn += verify("test_2vi_aln: a1", i, a1.get(i), 123);
+ }
+ for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2vi_aln: a1", i, a1.get(i), -1);
+ }
+ for (int i=0; i<ALIGN_OFF; i++) {
+ errn += verify("test_2vi_aln: a2", i, a2.get(i), -1);
+ }
+ for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2vi_aln: a2", i, a2.get(i), 103);
+ }
+
+ // Reset for 2 arrays with relative unaligned offset
+ for (int i=0; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ a2.set(i, -1);
+ }
+ test_vi(a2, 123, -1);
+ test_cp_unalndst(a1, a2);
+ for (int i=0; i<UNALIGN_OFF; i++) {
+ errn += verify("test_cp_unalndst: a1", i, a1.get(i), -1);
+ }
+ for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_cp_unalndst: a1", i, a1.get(i), 123);
+ }
+ test_vi(a2, -123, 123);
+ test_cp_unalnsrc(a1, a2);
+ for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+ errn += verify("test_cp_unalnsrc: a1", i, a1.get(i), -123);
+ }
+ for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_cp_unalnsrc: a1", i, a1.get(i), 123);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ a2.set(i, -1);
+ }
+ test_2ci_unaln(a1, a2);
+ for (int i=0; i<UNALIGN_OFF; i++) {
+ errn += verify("test_2ci_unaln: a1", i, a1.get(i), -1);
+ }
+ for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2ci_unaln: a1", i, a1.get(i), -123);
+ }
+ for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+ errn += verify("test_2ci_unaln: a2", i, a2.get(i), -103);
+ }
+ for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2ci_unaln: a2", i, a2.get(i), -1);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ a2.set(i, -1);
+ }
+ test_2vi_unaln(a1, a2, 123, 103);
+ for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+ errn += verify("test_2vi_unaln: a1", i, a1.get(i), 123);
+ }
+ for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2vi_unaln: a1", i, a1.get(i), -1);
+ }
+ for (int i=0; i<UNALIGN_OFF; i++) {
+ errn += verify("test_2vi_unaln: a2", i, a2.get(i), -1);
+ }
+ for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2vi_unaln: a2", i, a2.get(i), 103);
+ }
+
+ // Reset for aligned overlap initialization
+ for (int i=0; i<ALIGN_OFF; i++) {
+ a1.set(i, i);
+ }
+ for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ }
+ test_cp_alndst(a1, a1);
+ for (int i=0; i<ARRLEN; i++) {
+ int v = i%ALIGN_OFF;
+ errn += verify("test_cp_alndst_overlap: a1", i, a1.get(i), v);
+ }
+ for (int i=0; i<ALIGN_OFF; i++) {
+ a1.set((i+ALIGN_OFF), -1);
+ }
+ test_cp_alnsrc(a1, a1);
+ for (int i=0; i<ALIGN_OFF; i++) {
+ errn += verify("test_cp_alnsrc_overlap: a1", i, a1.get(i), -1);
+ }
+ for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+ int v = i%ALIGN_OFF;
+ errn += verify("test_cp_alnsrc_overlap: a1", i, a1.get(i), v);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ }
+ test_2ci_aln(a1, a1);
+ for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+ errn += verify("test_2ci_aln_overlap: a1", i, a1.get(i), -103);
+ }
+ for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2ci_aln_overlap: a1", i, a1.get(i), -123);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ }
+ test_2vi_aln(a1, a1, 123, 103);
+ for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+ errn += verify("test_2vi_aln_overlap: a1", i, a1.get(i), 123);
+ }
+ for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2vi_aln_overlap: a1", i, a1.get(i), 103);
+ }
+
+ // Reset for unaligned overlap initialization
+ for (int i=0; i<UNALIGN_OFF; i++) {
+ a1.set(i, i);
+ }
+ for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ }
+ test_cp_unalndst(a1, a1);
+ for (int i=0; i<ARRLEN; i++) {
+ int v = i%UNALIGN_OFF;
+ errn += verify("test_cp_unalndst_overlap: a1", i, a1.get(i), v);
+ }
+ for (int i=0; i<UNALIGN_OFF; i++) {
+ a1.set((i+UNALIGN_OFF), -1);
+ }
+ test_cp_unalnsrc(a1, a1);
+ for (int i=0; i<UNALIGN_OFF; i++) {
+ errn += verify("test_cp_unalnsrc_overlap: a1", i, a1.get(i), -1);
+ }
+ for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+ int v = i%UNALIGN_OFF;
+ errn += verify("test_cp_unalnsrc_overlap: a1", i, a1.get(i), v);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ }
+ test_2ci_unaln(a1, a1);
+ for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+ errn += verify("test_2ci_unaln_overlap: a1", i, a1.get(i), -103);
+ }
+ for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2ci_unaln_overlap: a1", i, a1.get(i), -123);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ }
+ test_2vi_unaln(a1, a1, 123, 103);
+ for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+ errn += verify("test_2vi_unaln_overlap: a1", i, a1.get(i), 123);
+ }
+ for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2vi_unaln_overlap: a1", i, a1.get(i), 103);
+ }
+
+ }
+
+ if (errn > 0 || test_only)
+ return errn;
+
+ // Initialize
+ for (int i=0; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ a2.set(i, -1);
+ }
+ System.out.println("Time");
+ long start, end;
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_ci(a1);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_ci: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_vi(a2, 123, -1);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_vi: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_ci_neg(a1, 123);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_ci_neg: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_vi_neg(a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_vi_neg: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_neg(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_neg: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_neg(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_neg: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_neg(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_neg: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_ci_oppos(a1, 123);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_ci_oppos: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_vi_oppos(a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_vi_oppos: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_oppos(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_oppos: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_oppos(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_oppos: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_oppos(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_oppos: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_ci_off(a1, 123);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_ci_off: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_vi_off(a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_vi_off: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_off(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_off: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_off(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_off: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_off(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_off: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_ci_inv(a1, OFFSET, 123);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_ci_inv: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_vi_inv(a2, 123, OFFSET, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_vi_inv: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_inv(a1, a2, OFFSET);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_inv: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_inv(a1, a2, OFFSET);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_inv: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_inv(a1, a2, 123, 103, OFFSET);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_inv: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_ci_scl(a1, 123);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_ci_scl: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_vi_scl(a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_vi_scl: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_scl(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_scl: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_scl(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_scl: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_scl(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_scl: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_alndst(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_alndst: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_alnsrc(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_alnsrc: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_aln(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_aln: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_aln(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_aln: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_unalndst(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_unalndst: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_unalnsrc(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_unalnsrc: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_unaln(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_unaln: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_unaln(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_unaln: " + (end - start));
+
+ return errn;
+ }
+
+ static void test_ci(AtomicIntegerArray a) {
+ for (int i = 0; i < ARRLEN; i+=1) {
+ a.compareAndSet(i, -1, -123);
+ }
+ }
+ static void test_vi(AtomicIntegerArray a, int b, int old) {
+ for (int i = 0; i < ARRLEN; i+=1) {
+ a.compareAndSet(i, old, b);
+ }
+ }
+ static void test_cp(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = 0; i < ARRLEN; i+=1) {
+ a.compareAndSet(i, -123, b.get(i));
+ }
+ }
+ static void test_2ci(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = 0; i < ARRLEN; i+=1) {
+ a.compareAndSet(i, 123, -123);
+ b.compareAndSet(i, 123, -103);
+ }
+ }
+ static void test_2vi(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) {
+ for (int i = 0; i < ARRLEN; i+=1) {
+ a.compareAndSet(i, -123, c);
+ b.compareAndSet(i, -103, d);
+ }
+ }
+ static void test_ci_neg(AtomicIntegerArray a, int old) {
+ for (int i = ARRLEN-1; i >= 0; i-=1) {
+ a.compareAndSet(i, old, -123);
+ }
+ }
+ static void test_vi_neg(AtomicIntegerArray a, int b, int old) {
+ for (int i = ARRLEN-1; i >= 0; i-=1) {
+ a.compareAndSet(i, old, b);
+ }
+ }
+ static void test_cp_neg(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = ARRLEN-1; i >= 0; i-=1) {
+ a.compareAndSet(i, -123, b.get(i));
+ }
+ }
+ static void test_2ci_neg(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = ARRLEN-1; i >= 0; i-=1) {
+ a.compareAndSet(i, 123, -123);
+ b.compareAndSet(i, 123, -103);
+ }
+ }
+ static void test_2vi_neg(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) {
+ for (int i = ARRLEN-1; i >= 0; i-=1) {
+ a.compareAndSet(i, -123, c);
+ b.compareAndSet(i, -103, d);
+ }
+ }
+ static void test_ci_oppos(AtomicIntegerArray a, int old) {
+ int limit = ARRLEN-1;
+ for (int i = 0; i < ARRLEN; i+=1) {
+ a.compareAndSet((limit-i), old, -123);
+ }
+ }
+ static void test_vi_oppos(AtomicIntegerArray a, int b, int old) {
+ int limit = ARRLEN-1;
+ for (int i = limit; i >= 0; i-=1) {
+ a.compareAndSet((limit-i), old, b);
+ }
+ }
+ static void test_cp_oppos(AtomicIntegerArray a, AtomicIntegerArray b) {
+ int limit = ARRLEN-1;
+ for (int i = 0; i < ARRLEN; i+=1) {
+ a.compareAndSet(i, -123, b.get(limit-i));
+ }
+ }
+ static void test_2ci_oppos(AtomicIntegerArray a, AtomicIntegerArray b) {
+ int limit = ARRLEN-1;
+ for (int i = 0; i < ARRLEN; i+=1) {
+ a.compareAndSet((limit-i), 123, -123);
+ b.compareAndSet(i, 123, -103);
+ }
+ }
+ static void test_2vi_oppos(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) {
+ int limit = ARRLEN-1;
+ for (int i = limit; i >= 0; i-=1) {
+ a.compareAndSet(i, -123, c);
+ b.compareAndSet((limit-i), -103, d);
+ }
+ }
+ static void test_ci_off(AtomicIntegerArray a, int old) {
+ for (int i = 0; i < ARRLEN-OFFSET; i+=1) {
+ a.compareAndSet((i+OFFSET), old, -123);
+ }
+ }
+ static void test_vi_off(AtomicIntegerArray a, int b, int old) {
+ for (int i = 0; i < ARRLEN-OFFSET; i+=1) {
+ a.compareAndSet((i+OFFSET), old, b);
+ }
+ }
+ static void test_cp_off(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = 0; i < ARRLEN-OFFSET; i+=1) {
+ a.compareAndSet((i+OFFSET), -123, b.get(i+OFFSET));
+ }
+ }
+ static void test_2ci_off(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = 0; i < ARRLEN-OFFSET; i+=1) {
+ a.compareAndSet((i+OFFSET), 123, -123);
+ b.compareAndSet((i+OFFSET), 123, -103);
+ }
+ }
+ static void test_2vi_off(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) {
+ for (int i = 0; i < ARRLEN-OFFSET; i+=1) {
+ a.compareAndSet((i+OFFSET), -123, c);
+ b.compareAndSet((i+OFFSET), -103, d);
+ }
+ }
+ static void test_ci_inv(AtomicIntegerArray a, int k, int old) {
+ for (int i = 0; i < ARRLEN-k; i+=1) {
+ a.compareAndSet((i+k), old, -123);
+ }
+ }
+ static void test_vi_inv(AtomicIntegerArray a, int b, int k, int old) {
+ for (int i = 0; i < ARRLEN-k; i+=1) {
+ a.compareAndSet((i+k), old, b);
+ }
+ }
+ static void test_cp_inv(AtomicIntegerArray a, AtomicIntegerArray b, int k) {
+ for (int i = 0; i < ARRLEN-k; i+=1) {
+ a.compareAndSet((i+k), -123, b.get(i+k));
+ }
+ }
+ static void test_2ci_inv(AtomicIntegerArray a, AtomicIntegerArray b, int k) {
+ for (int i = 0; i < ARRLEN-k; i+=1) {
+ a.compareAndSet((i+k), 123, -123);
+ b.compareAndSet((i+k), 123, -103);
+ }
+ }
+ static void test_2vi_inv(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d, int k) {
+ for (int i = 0; i < ARRLEN-k; i+=1) {
+ a.compareAndSet((i+k), -123, c);
+ b.compareAndSet((i+k), -103, d);
+ }
+ }
+ static void test_ci_scl(AtomicIntegerArray a, int old) {
+ for (int i = 0; i*SCALE < ARRLEN; i+=1) {
+ a.compareAndSet((i*SCALE), old, -123);
+ }
+ }
+ static void test_vi_scl(AtomicIntegerArray a, int b, int old) {
+ for (int i = 0; i*SCALE < ARRLEN; i+=1) {
+ a.compareAndSet((i*SCALE), old, b);
+ }
+ }
+ static void test_cp_scl(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = 0; i*SCALE < ARRLEN; i+=1) {
+ a.compareAndSet((i*SCALE), -123, b.get(i*SCALE));
+ }
+ }
+ static void test_2ci_scl(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = 0; i*SCALE < ARRLEN; i+=1) {
+ a.compareAndSet((i*SCALE), 123, -123);
+ b.compareAndSet((i*SCALE), 123, -103);
+ }
+ }
+ static void test_2vi_scl(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) {
+ for (int i = 0; i*SCALE < ARRLEN; i+=1) {
+ a.compareAndSet((i*SCALE), -123, c);
+ b.compareAndSet((i*SCALE), -103, d);
+ }
+ }
+ static void test_cp_alndst(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) {
+ a.compareAndSet((i+ALIGN_OFF), -1, b.get(i));
+ }
+ }
+ static void test_cp_alnsrc(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) {
+ a.getAndSet(i, b.get(i+ALIGN_OFF));
+ }
+ }
+ static void test_2ci_aln(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) {
+ a.compareAndSet((i+ALIGN_OFF), -1, -123);
+ b.getAndSet(i, -103);
+ }
+ }
+ static void test_2vi_aln(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) {
+ for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) {
+ a.getAndSet(i, c);
+ b.getAndSet((i+ALIGN_OFF), d);
+ }
+ }
+ static void test_cp_unalndst(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) {
+ a.compareAndSet((i+UNALIGN_OFF), -1, b.get(i));
+ }
+ }
+ static void test_cp_unalnsrc(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) {
+ a.getAndSet(i, b.get(i+UNALIGN_OFF));
+ }
+ }
+ static void test_2ci_unaln(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) {
+ a.compareAndSet((i+UNALIGN_OFF), -1, -123);
+ b.getAndSet(i, -103);
+ }
+ }
+ static void test_2vi_unaln(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) {
+ for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) {
+ a.getAndSet(i, c);
+ b.getAndSet((i+UNALIGN_OFF), d);
+ }
+ }
+
+ static int verify(String text, int i, int elem, int val) {
+ if (elem != val) {
+ System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+ return 1;
+ }
+ return 0;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/8004867/TestIntAtomicOrdered.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,969 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8004867
+ * @summary VM crashing with assert "share/vm/opto/node.hpp:357 - assert(i < _max) failed: oob"
+ *
+ * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestIntAtomicOrdered
+ * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:+OptimizeFill TestIntAtomicOrdered
+ */
+
+import java.util.concurrent.atomic.AtomicIntegerArray;
+
+public class TestIntAtomicOrdered {
+ private static final int ARRLEN = 97;
+ private static final int ITERS = 11000;
+ private static final int OFFSET = 3;
+ private static final int SCALE = 2;
+ private static final int ALIGN_OFF = 8;
+ private static final int UNALIGN_OFF = 5;
+
+ public static void main(String args[]) {
+ System.out.println("Testing Integer array atomic ordered operations");
+ int errn = test(false);
+ if (errn > 0) {
+ System.err.println("FAILED: " + errn + " errors");
+ System.exit(97);
+ }
+ System.out.println("PASSED");
+ }
+
+ static int test(boolean test_only) {
+ AtomicIntegerArray a1 = new AtomicIntegerArray(ARRLEN);
+ AtomicIntegerArray a2 = new AtomicIntegerArray(ARRLEN);
+ // Initialize
+ for (int i=0; i<ARRLEN; i++) {
+ a1.lazySet(i, -1);
+ a2.lazySet(i, -1);
+ }
+ System.out.println("Warmup");
+ for (int i=0; i<ITERS; i++) {
+ test_ci(a1);
+ test_vi(a2, 123, -1);
+ test_cp(a1, a2);
+ test_2ci(a1, a2);
+ test_2vi(a1, a2, 123, 103);
+ test_ci_neg(a1, 123);
+ test_vi_neg(a2, 123, 103);
+ test_cp_neg(a1, a2);
+ test_2ci_neg(a1, a2);
+ test_2vi_neg(a1, a2, 123, 103);
+ test_ci_oppos(a1, 123);
+ test_vi_oppos(a2, 123, 103);
+ test_cp_oppos(a1, a2);
+ test_2ci_oppos(a1, a2);
+ test_2vi_oppos(a1, a2, 123, 103);
+ test_ci_off(a1, 123);
+ test_vi_off(a2, 123, 103);
+ test_cp_off(a1, a2);
+ test_2ci_off(a1, a2);
+ test_2vi_off(a1, a2, 123, 103);
+ test_ci_inv(a1, OFFSET, 123);
+ test_vi_inv(a2, 123, OFFSET, 103);
+ test_cp_inv(a1, a2, OFFSET);
+ test_2ci_inv(a1, a2, OFFSET);
+ test_2vi_inv(a1, a2, 123, 103, OFFSET);
+ test_ci_scl(a1, 123);
+ test_vi_scl(a2, 123, 103);
+ test_cp_scl(a1, a2);
+ test_2ci_scl(a1, a2);
+ test_2vi_scl(a1, a2, 123, 103);
+ test_cp_alndst(a1, a2);
+ test_cp_alnsrc(a1, a2);
+ test_2ci_aln(a1, a2);
+ test_2vi_aln(a1, a2, 123, 103);
+ test_cp_unalndst(a1, a2);
+ test_cp_unalnsrc(a1, a2);
+ test_2ci_unaln(a1, a2);
+ test_2vi_unaln(a1, a2, 123, 103);
+ }
+ // Initialize
+ for (int i=0; i<ARRLEN; i++) {
+ a1.lazySet(i, -1);
+ a2.lazySet(i, -1);
+ }
+ // Test and verify results
+ System.out.println("Verification");
+ int errn = 0;
+ {
+ test_ci(a1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_ci: a1", i, a1.get(i), -123);
+ }
+ test_vi(a2, 123, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_vi: a2", i, a2.get(i), 123);
+ }
+ test_cp(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_cp: a1", i, a1.get(i), 123);
+ }
+ test_2ci(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_2ci: a1", i, a1.get(i), -123);
+ errn += verify("test_2ci: a2", i, a2.get(i), -103);
+ }
+ test_2vi(a1, a2, 123, 103);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_2vi: a1", i, a1.get(i), 123);
+ errn += verify("test_2vi: a2", i, a2.get(i), 103);
+ }
+ // Reset for negative stride
+ for (int i=0; i<ARRLEN; i++) {
+ a1.lazySet(i, -1);
+ a2.lazySet(i, -1);
+ }
+ test_ci_neg(a1, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_ci_neg: a1", i, a1.get(i), -123);
+ }
+ test_vi_neg(a2, 123, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_vi_neg: a2", i, a2.get(i), 123);
+ }
+ test_cp_neg(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_cp_neg: a1", i, a1.get(i), 123);
+ }
+ test_2ci_neg(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_2ci_neg: a1", i, a1.get(i), -123);
+ errn += verify("test_2ci_neg: a2", i, a2.get(i), -103);
+ }
+ test_2vi_neg(a1, a2, 123, 103);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_2vi_neg: a1", i, a1.get(i), 123);
+ errn += verify("test_2vi_neg: a2", i, a2.get(i), 103);
+ }
+ // Reset for opposite stride
+ for (int i=0; i<ARRLEN; i++) {
+ a1.lazySet(i, -1);
+ a2.lazySet(i, -1);
+ }
+ test_ci_oppos(a1, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_ci_oppos: a1", i, a1.get(i), -123);
+ }
+ test_vi_oppos(a2, 123, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_vi_oppos: a2", i, a2.get(i), 123);
+ }
+ test_cp_oppos(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_cp_oppos: a1", i, a1.get(i), 123);
+ }
+ test_2ci_oppos(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_2ci_oppos: a1", i, a1.get(i), -123);
+ errn += verify("test_2ci_oppos: a2", i, a2.get(i), -103);
+ }
+ test_2vi_oppos(a1, a2, 123, 103);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_2vi_oppos: a1", i, a1.get(i), 123);
+ errn += verify("test_2vi_oppos: a2", i, a2.get(i), 103);
+ }
+ // Reset for indexing with offset
+ for (int i=0; i<ARRLEN; i++) {
+ a1.lazySet(i, -1);
+ a2.lazySet(i, -1);
+ }
+ test_ci_off(a1, -1);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_ci_off: a1", i, a1.get(i), -123);
+ }
+ test_vi_off(a2, 123, -1);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_vi_off: a2", i, a2.get(i), 123);
+ }
+ test_cp_off(a1, a2);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_cp_off: a1", i, a1.get(i), 123);
+ }
+ test_2ci_off(a1, a2);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_2ci_off: a1", i, a1.get(i), -123);
+ errn += verify("test_2ci_off: a2", i, a2.get(i), -103);
+ }
+ test_2vi_off(a1, a2, 123, 103);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_2vi_off: a1", i, a1.get(i), 123);
+ errn += verify("test_2vi_off: a2", i, a2.get(i), 103);
+ }
+ for (int i=0; i<OFFSET; i++) {
+ errn += verify("test_2vi_off: a1", i, a1.get(i), -1);
+ errn += verify("test_2vi_off: a2", i, a2.get(i), -1);
+ }
+ // Reset for indexing with invariant offset
+ for (int i=0; i<ARRLEN; i++) {
+ a1.lazySet(i, -1);
+ a2.lazySet(i, -1);
+ }
+ test_ci_inv(a1, OFFSET, -1);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_ci_inv: a1", i, a1.get(i), -123);
+ }
+ test_vi_inv(a2, 123, OFFSET, -1);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_vi_inv: a2", i, a2.get(i), 123);
+ }
+ test_cp_inv(a1, a2, OFFSET);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_cp_inv: a1", i, a1.get(i), 123);
+ }
+ test_2ci_inv(a1, a2, OFFSET);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_2ci_inv: a1", i, a1.get(i), -123);
+ errn += verify("test_2ci_inv: a2", i, a2.get(i), -103);
+ }
+ test_2vi_inv(a1, a2, 123, 103, OFFSET);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_2vi_inv: a1", i, a1.get(i), 123);
+ errn += verify("test_2vi_inv: a2", i, a2.get(i), 103);
+ }
+ for (int i=0; i<OFFSET; i++) {
+ errn += verify("test_2vi_inv: a1", i, a1.get(i), -1);
+ errn += verify("test_2vi_inv: a2", i, a2.get(i), -1);
+ }
+ // Reset for indexing with scale
+ for (int i=0; i<ARRLEN; i++) {
+ a1.lazySet(i, -1);
+ a2.lazySet(i, -1);
+ }
+ test_ci_scl(a1, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ int val = (i%SCALE != 0) ? -1 : -123;
+ errn += verify("test_ci_scl: a1", i, a1.get(i), val);
+ }
+ test_vi_scl(a2, 123, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ int val = (i%SCALE != 0) ? -1 : 123;
+ errn += verify("test_vi_scl: a2", i, a2.get(i), val);
+ }
+ test_cp_scl(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ int val = (i%SCALE != 0) ? -1 : 123;
+ errn += verify("test_cp_scl: a1", i, a1.get(i), val);
+ }
+ test_2ci_scl(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ if (i%SCALE != 0) {
+ errn += verify("test_2ci_scl: a1", i, a1.get(i), -1);
+ } else if (i*SCALE < ARRLEN) {
+ errn += verify("test_2ci_scl: a1", i*SCALE, a1.get(i*SCALE), -123);
+ }
+ if (i%SCALE != 0) {
+ errn += verify("test_2ci_scl: a2", i, a2.get(i), -1);
+ } else if (i*SCALE < ARRLEN) {
+ errn += verify("test_2ci_scl: a2", i*SCALE, a2.get(i*SCALE), -103);
+ }
+ }
+ test_2vi_scl(a1, a2, 123, 103);
+ for (int i=0; i<ARRLEN; i++) {
+ if (i%SCALE != 0) {
+ errn += verify("test_2vi_scl: a1", i, a1.get(i), -1);
+ } else if (i*SCALE < ARRLEN) {
+ errn += verify("test_2vi_scl: a1", i*SCALE, a1.get(i*SCALE), 123);
+ }
+ if (i%SCALE != 0) {
+ errn += verify("test_2vi_scl: a2", i, a2.get(i), -1);
+ } else if (i*SCALE < ARRLEN) {
+ errn += verify("test_2vi_scl: a2", i*SCALE, a2.get(i*SCALE), 103);
+ }
+ }
+ // Reset for 2 arrays with relative aligned offset
+ for (int i=0; i<ARRLEN; i++) {
+ a1.lazySet(i, -1);
+ a2.lazySet(i, -1);
+ }
+ test_vi(a2, 123, -1);
+ test_cp_alndst(a1, a2);
+ for (int i=0; i<ALIGN_OFF; i++) {
+ errn += verify("test_cp_alndst: a1", i, a1.get(i), -1);
+ }
+ for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_cp_alndst: a1", i, a1.get(i), 123);
+ }
+ for (int i=0; i<ALIGN_OFF; i++) {
+ a1.lazySet(i, 123);
+ }
+ test_vi(a2, -123, 123);
+ test_cp_alnsrc(a1, a2);
+ for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+ errn += verify("test_cp_alnsrc: a1", i, a1.get(i), -123);
+ }
+ for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_cp_alnsrc: a1", i, a1.get(i), 123);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1.lazySet(i, -1);
+ a2.lazySet(i, -1);
+ }
+ test_2ci_aln(a1, a2);
+ for (int i=0; i<ALIGN_OFF; i++) {
+ errn += verify("test_2ci_aln: a1", i, a1.get(i), -1);
+ }
+ for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2ci_aln: a1", i, a1.get(i), -123);
+ }
+ for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+ errn += verify("test_2ci_aln: a2", i, a2.get(i), -103);
+ }
+ for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2ci_aln: a2", i, a2.get(i), -1);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1.lazySet(i, -1);
+ a2.lazySet(i, -1);
+ }
+ test_2vi_aln(a1, a2, 123, 103);
+ for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+ errn += verify("test_2vi_aln: a1", i, a1.get(i), 123);
+ }
+ for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2vi_aln: a1", i, a1.get(i), -1);
+ }
+ for (int i=0; i<ALIGN_OFF; i++) {
+ errn += verify("test_2vi_aln: a2", i, a2.get(i), -1);
+ }
+ for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2vi_aln: a2", i, a2.get(i), 103);
+ }
+
+ // Reset for 2 arrays with relative unaligned offset
+ for (int i=0; i<ARRLEN; i++) {
+ a1.lazySet(i, -1);
+ a2.lazySet(i, -1);
+ }
+ test_vi(a2, 123, -1);
+ test_cp_unalndst(a1, a2);
+ for (int i=0; i<UNALIGN_OFF; i++) {
+ errn += verify("test_cp_unalndst: a1", i, a1.get(i), -1);
+ }
+ for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_cp_unalndst: a1", i, a1.get(i), 123);
+ }
+ test_vi(a2, -123, 123);
+ test_cp_unalnsrc(a1, a2);
+ for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+ errn += verify("test_cp_unalnsrc: a1", i, a1.get(i), -123);
+ }
+ for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_cp_unalnsrc: a1", i, a1.get(i), 123);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1.lazySet(i, -1);
+ a2.lazySet(i, -1);
+ }
+ test_2ci_unaln(a1, a2);
+ for (int i=0; i<UNALIGN_OFF; i++) {
+ errn += verify("test_2ci_unaln: a1", i, a1.get(i), -1);
+ }
+ for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2ci_unaln: a1", i, a1.get(i), -123);
+ }
+ for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+ errn += verify("test_2ci_unaln: a2", i, a2.get(i), -103);
+ }
+ for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2ci_unaln: a2", i, a2.get(i), -1);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1.lazySet(i, -1);
+ a2.lazySet(i, -1);
+ }
+ test_2vi_unaln(a1, a2, 123, 103);
+ for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+ errn += verify("test_2vi_unaln: a1", i, a1.get(i), 123);
+ }
+ for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2vi_unaln: a1", i, a1.get(i), -1);
+ }
+ for (int i=0; i<UNALIGN_OFF; i++) {
+ errn += verify("test_2vi_unaln: a2", i, a2.get(i), -1);
+ }
+ for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2vi_unaln: a2", i, a2.get(i), 103);
+ }
+
+ // Reset for aligned overlap initialization
+ for (int i=0; i<ALIGN_OFF; i++) {
+ a1.lazySet(i, i);
+ }
+ for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+ a1.lazySet(i, -1);
+ }
+ test_cp_alndst(a1, a1);
+ for (int i=0; i<ARRLEN; i++) {
+ int v = i%ALIGN_OFF;
+ errn += verify("test_cp_alndst_overlap: a1", i, a1.get(i), v);
+ }
+ for (int i=0; i<ALIGN_OFF; i++) {
+ a1.lazySet((i+ALIGN_OFF), -1);
+ }
+ test_cp_alnsrc(a1, a1);
+ for (int i=0; i<ALIGN_OFF; i++) {
+ errn += verify("test_cp_alnsrc_overlap: a1", i, a1.get(i), -1);
+ }
+ for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+ int v = i%ALIGN_OFF;
+ errn += verify("test_cp_alnsrc_overlap: a1", i, a1.get(i), v);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1.lazySet(i, -1);
+ }
+ test_2ci_aln(a1, a1);
+ for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+ errn += verify("test_2ci_aln_overlap: a1", i, a1.get(i), -103);
+ }
+ for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2ci_aln_overlap: a1", i, a1.get(i), -123);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1.lazySet(i, -1);
+ }
+ test_2vi_aln(a1, a1, 123, 103);
+ for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+ errn += verify("test_2vi_aln_overlap: a1", i, a1.get(i), 123);
+ }
+ for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2vi_aln_overlap: a1", i, a1.get(i), 103);
+ }
+
+ // Reset for unaligned overlap initialization
+ for (int i=0; i<UNALIGN_OFF; i++) {
+ a1.lazySet(i, i);
+ }
+ for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+ a1.lazySet(i, -1);
+ }
+ test_cp_unalndst(a1, a1);
+ for (int i=0; i<ARRLEN; i++) {
+ int v = i%UNALIGN_OFF;
+ errn += verify("test_cp_unalndst_overlap: a1", i, a1.get(i), v);
+ }
+ for (int i=0; i<UNALIGN_OFF; i++) {
+ a1.lazySet((i+UNALIGN_OFF), -1);
+ }
+ test_cp_unalnsrc(a1, a1);
+ for (int i=0; i<UNALIGN_OFF; i++) {
+ errn += verify("test_cp_unalnsrc_overlap: a1", i, a1.get(i), -1);
+ }
+ for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+ int v = i%UNALIGN_OFF;
+ errn += verify("test_cp_unalnsrc_overlap: a1", i, a1.get(i), v);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1.lazySet(i, -1);
+ }
+ test_2ci_unaln(a1, a1);
+ for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+ errn += verify("test_2ci_unaln_overlap: a1", i, a1.get(i), -103);
+ }
+ for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2ci_unaln_overlap: a1", i, a1.get(i), -123);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1.lazySet(i, -1);
+ }
+ test_2vi_unaln(a1, a1, 123, 103);
+ for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+ errn += verify("test_2vi_unaln_overlap: a1", i, a1.get(i), 123);
+ }
+ for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2vi_unaln_overlap: a1", i, a1.get(i), 103);
+ }
+
+ }
+
+ if (errn > 0 || test_only)
+ return errn;
+
+ // Initialize
+ for (int i=0; i<ARRLEN; i++) {
+ a1.lazySet(i, -1);
+ a2.lazySet(i, -1);
+ }
+ System.out.println("Time");
+ long start, end;
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_ci(a1);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_ci: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_vi(a2, 123, -1);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_vi: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_ci_neg(a1, 123);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_ci_neg: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_vi_neg(a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_vi_neg: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_neg(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_neg: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_neg(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_neg: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_neg(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_neg: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_ci_oppos(a1, 123);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_ci_oppos: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_vi_oppos(a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_vi_oppos: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_oppos(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_oppos: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_oppos(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_oppos: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_oppos(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_oppos: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_ci_off(a1, 123);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_ci_off: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_vi_off(a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_vi_off: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_off(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_off: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_off(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_off: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_off(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_off: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_ci_inv(a1, OFFSET, 123);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_ci_inv: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_vi_inv(a2, 123, OFFSET, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_vi_inv: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_inv(a1, a2, OFFSET);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_inv: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_inv(a1, a2, OFFSET);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_inv: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_inv(a1, a2, 123, 103, OFFSET);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_inv: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_ci_scl(a1, 123);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_ci_scl: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_vi_scl(a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_vi_scl: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_scl(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_scl: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_scl(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_scl: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_scl(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_scl: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_alndst(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_alndst: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_alnsrc(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_alnsrc: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_aln(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_aln: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_aln(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_aln: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_unalndst(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_unalndst: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_unalnsrc(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_unalnsrc: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_unaln(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_unaln: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_unaln(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_unaln: " + (end - start));
+
+ return errn;
+ }
+
+ static void test_ci(AtomicIntegerArray a) {
+ for (int i = 0; i < ARRLEN; i+=1) {
+ a.lazySet(i, -123);
+ }
+ }
+ static void test_vi(AtomicIntegerArray a, int b, int old) {
+ for (int i = 0; i < ARRLEN; i+=1) {
+ a.lazySet(i, b);
+ }
+ }
+ static void test_cp(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = 0; i < ARRLEN; i+=1) {
+ a.lazySet(i, b.get(i));
+ }
+ }
+ static void test_2ci(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = 0; i < ARRLEN; i+=1) {
+ a.lazySet(i, -123);
+ b.lazySet(i, -103);
+ }
+ }
+ static void test_2vi(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) {
+ for (int i = 0; i < ARRLEN; i+=1) {
+ a.lazySet(i, c);
+ b.lazySet(i, d);
+ }
+ }
+ static void test_ci_neg(AtomicIntegerArray a, int old) {
+ for (int i = ARRLEN-1; i >= 0; i-=1) {
+ a.lazySet(i,-123);
+ }
+ }
+ static void test_vi_neg(AtomicIntegerArray a, int b, int old) {
+ for (int i = ARRLEN-1; i >= 0; i-=1) {
+ a.lazySet(i, b);
+ }
+ }
+ static void test_cp_neg(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = ARRLEN-1; i >= 0; i-=1) {
+ a.lazySet(i, b.get(i));
+ }
+ }
+ static void test_2ci_neg(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = ARRLEN-1; i >= 0; i-=1) {
+ a.lazySet(i, -123);
+ b.lazySet(i, -103);
+ }
+ }
+ static void test_2vi_neg(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) {
+ for (int i = ARRLEN-1; i >= 0; i-=1) {
+ a.lazySet(i, c);
+ b.lazySet(i, d);
+ }
+ }
+ static void test_ci_oppos(AtomicIntegerArray a, int old) {
+ int limit = ARRLEN-1;
+ for (int i = 0; i < ARRLEN; i+=1) {
+ a.lazySet((limit-i), -123);
+ }
+ }
+ static void test_vi_oppos(AtomicIntegerArray a, int b, int old) {
+ int limit = ARRLEN-1;
+ for (int i = limit; i >= 0; i-=1) {
+ a.lazySet((limit-i), b);
+ }
+ }
+ static void test_cp_oppos(AtomicIntegerArray a, AtomicIntegerArray b) {
+ int limit = ARRLEN-1;
+ for (int i = 0; i < ARRLEN; i+=1) {
+ a.lazySet(i, b.get(limit-i));
+ }
+ }
+ static void test_2ci_oppos(AtomicIntegerArray a, AtomicIntegerArray b) {
+ int limit = ARRLEN-1;
+ for (int i = 0; i < ARRLEN; i+=1) {
+ a.lazySet((limit-i), -123);
+ b.lazySet(i, -103);
+ }
+ }
+ static void test_2vi_oppos(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) {
+ int limit = ARRLEN-1;
+ for (int i = limit; i >= 0; i-=1) {
+ a.lazySet(i, c);
+ b.lazySet((limit-i), d);
+ }
+ }
+ static void test_ci_off(AtomicIntegerArray a, int old) {
+ for (int i = 0; i < ARRLEN-OFFSET; i+=1) {
+ a.lazySet((i+OFFSET), -123);
+ }
+ }
+ static void test_vi_off(AtomicIntegerArray a, int b, int old) {
+ for (int i = 0; i < ARRLEN-OFFSET; i+=1) {
+ a.lazySet((i+OFFSET), b);
+ }
+ }
+ static void test_cp_off(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = 0; i < ARRLEN-OFFSET; i+=1) {
+ a.lazySet((i+OFFSET), b.get(i+OFFSET));
+ }
+ }
+ static void test_2ci_off(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = 0; i < ARRLEN-OFFSET; i+=1) {
+ a.lazySet((i+OFFSET), -123);
+ b.lazySet((i+OFFSET), -103);
+ }
+ }
+ static void test_2vi_off(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) {
+ for (int i = 0; i < ARRLEN-OFFSET; i+=1) {
+ a.lazySet((i+OFFSET), c);
+ b.lazySet((i+OFFSET), d);
+ }
+ }
+ static void test_ci_inv(AtomicIntegerArray a, int k, int old) {
+ for (int i = 0; i < ARRLEN-k; i+=1) {
+ a.lazySet((i+k),-123);
+ }
+ }
+ static void test_vi_inv(AtomicIntegerArray a, int b, int k, int old) {
+ for (int i = 0; i < ARRLEN-k; i+=1) {
+ a.lazySet((i+k), b);
+ }
+ }
+ static void test_cp_inv(AtomicIntegerArray a, AtomicIntegerArray b, int k) {
+ for (int i = 0; i < ARRLEN-k; i+=1) {
+ a.lazySet((i+k), b.get(i+k));
+ }
+ }
+ static void test_2ci_inv(AtomicIntegerArray a, AtomicIntegerArray b, int k) {
+ for (int i = 0; i < ARRLEN-k; i+=1) {
+ a.lazySet((i+k), -123);
+ b.lazySet((i+k), -103);
+ }
+ }
+ static void test_2vi_inv(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d, int k) {
+ for (int i = 0; i < ARRLEN-k; i+=1) {
+ a.lazySet((i+k), c);
+ b.lazySet((i+k), d);
+ }
+ }
+ static void test_ci_scl(AtomicIntegerArray a, int old) {
+ for (int i = 0; i*SCALE < ARRLEN; i+=1) {
+ a.lazySet((i*SCALE), -123);
+ }
+ }
+ static void test_vi_scl(AtomicIntegerArray a, int b, int old) {
+ for (int i = 0; i*SCALE < ARRLEN; i+=1) {
+ a.lazySet((i*SCALE), b);
+ }
+ }
+ static void test_cp_scl(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = 0; i*SCALE < ARRLEN; i+=1) {
+ a.lazySet((i*SCALE), b.get(i*SCALE));
+ }
+ }
+ static void test_2ci_scl(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = 0; i*SCALE < ARRLEN; i+=1) {
+ a.lazySet((i*SCALE), -123);
+ b.lazySet((i*SCALE), -103);
+ }
+ }
+ static void test_2vi_scl(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) {
+ for (int i = 0; i*SCALE < ARRLEN; i+=1) {
+ a.lazySet((i*SCALE), c);
+ b.lazySet((i*SCALE), d);
+ }
+ }
+ static void test_cp_alndst(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) {
+ a.lazySet((i+ALIGN_OFF), b.get(i));
+ }
+ }
+ static void test_cp_alnsrc(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) {
+ a.lazySet(i, b.get(i+ALIGN_OFF));
+ }
+ }
+ static void test_2ci_aln(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) {
+ a.lazySet((i+ALIGN_OFF), -123);
+ b.lazySet(i, -103);
+ }
+ }
+ static void test_2vi_aln(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) {
+ for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) {
+ a.lazySet(i, c);
+ b.lazySet((i+ALIGN_OFF), d);
+ }
+ }
+ static void test_cp_unalndst(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) {
+ a.lazySet((i+UNALIGN_OFF), b.get(i));
+ }
+ }
+ static void test_cp_unalnsrc(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) {
+ a.lazySet(i, b.get(i+UNALIGN_OFF));
+ }
+ }
+ static void test_2ci_unaln(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) {
+ a.lazySet((i+UNALIGN_OFF), -123);
+ b.lazySet(i, -103);
+ }
+ }
+ static void test_2vi_unaln(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) {
+ for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) {
+ a.lazySet(i, c);
+ b.lazySet((i+UNALIGN_OFF), d);
+ }
+ }
+
+ static int verify(String text, int i, int elem, int val) {
+ if (elem != val) {
+ System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+ return 1;
+ }
+ return 0;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/8004867/TestIntAtomicVolatile.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,969 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8004867
+ * @summary VM crashing with assert "share/vm/opto/node.hpp:357 - assert(i < _max) failed: oob"
+ *
+ * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestIntAtomicVolatile
+ * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:+OptimizeFill TestIntAtomicVolatile
+ */
+
+import java.util.concurrent.atomic.AtomicIntegerArray;
+
+public class TestIntAtomicVolatile {
+ private static final int ARRLEN = 97;
+ private static final int ITERS = 11000;
+ private static final int OFFSET = 3;
+ private static final int SCALE = 2;
+ private static final int ALIGN_OFF = 8;
+ private static final int UNALIGN_OFF = 5;
+
+ public static void main(String args[]) {
+ System.out.println("Testing Integer array atomic volatile operations");
+ int errn = test(false);
+ if (errn > 0) {
+ System.err.println("FAILED: " + errn + " errors");
+ System.exit(97);
+ }
+ System.out.println("PASSED");
+ }
+
+ static int test(boolean test_only) {
+ AtomicIntegerArray a1 = new AtomicIntegerArray(ARRLEN);
+ AtomicIntegerArray a2 = new AtomicIntegerArray(ARRLEN);
+ // Initialize
+ for (int i=0; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ a2.set(i, -1);
+ }
+ System.out.println("Warmup");
+ for (int i=0; i<ITERS; i++) {
+ test_ci(a1);
+ test_vi(a2, 123, -1);
+ test_cp(a1, a2);
+ test_2ci(a1, a2);
+ test_2vi(a1, a2, 123, 103);
+ test_ci_neg(a1, 123);
+ test_vi_neg(a2, 123, 103);
+ test_cp_neg(a1, a2);
+ test_2ci_neg(a1, a2);
+ test_2vi_neg(a1, a2, 123, 103);
+ test_ci_oppos(a1, 123);
+ test_vi_oppos(a2, 123, 103);
+ test_cp_oppos(a1, a2);
+ test_2ci_oppos(a1, a2);
+ test_2vi_oppos(a1, a2, 123, 103);
+ test_ci_off(a1, 123);
+ test_vi_off(a2, 123, 103);
+ test_cp_off(a1, a2);
+ test_2ci_off(a1, a2);
+ test_2vi_off(a1, a2, 123, 103);
+ test_ci_inv(a1, OFFSET, 123);
+ test_vi_inv(a2, 123, OFFSET, 103);
+ test_cp_inv(a1, a2, OFFSET);
+ test_2ci_inv(a1, a2, OFFSET);
+ test_2vi_inv(a1, a2, 123, 103, OFFSET);
+ test_ci_scl(a1, 123);
+ test_vi_scl(a2, 123, 103);
+ test_cp_scl(a1, a2);
+ test_2ci_scl(a1, a2);
+ test_2vi_scl(a1, a2, 123, 103);
+ test_cp_alndst(a1, a2);
+ test_cp_alnsrc(a1, a2);
+ test_2ci_aln(a1, a2);
+ test_2vi_aln(a1, a2, 123, 103);
+ test_cp_unalndst(a1, a2);
+ test_cp_unalnsrc(a1, a2);
+ test_2ci_unaln(a1, a2);
+ test_2vi_unaln(a1, a2, 123, 103);
+ }
+ // Initialize
+ for (int i=0; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ a2.set(i, -1);
+ }
+ // Test and verify results
+ System.out.println("Verification");
+ int errn = 0;
+ {
+ test_ci(a1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_ci: a1", i, a1.get(i), -123);
+ }
+ test_vi(a2, 123, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_vi: a2", i, a2.get(i), 123);
+ }
+ test_cp(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_cp: a1", i, a1.get(i), 123);
+ }
+ test_2ci(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_2ci: a1", i, a1.get(i), -123);
+ errn += verify("test_2ci: a2", i, a2.get(i), -103);
+ }
+ test_2vi(a1, a2, 123, 103);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_2vi: a1", i, a1.get(i), 123);
+ errn += verify("test_2vi: a2", i, a2.get(i), 103);
+ }
+ // Reset for negative stride
+ for (int i=0; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ a2.set(i, -1);
+ }
+ test_ci_neg(a1, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_ci_neg: a1", i, a1.get(i), -123);
+ }
+ test_vi_neg(a2, 123, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_vi_neg: a2", i, a2.get(i), 123);
+ }
+ test_cp_neg(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_cp_neg: a1", i, a1.get(i), 123);
+ }
+ test_2ci_neg(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_2ci_neg: a1", i, a1.get(i), -123);
+ errn += verify("test_2ci_neg: a2", i, a2.get(i), -103);
+ }
+ test_2vi_neg(a1, a2, 123, 103);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_2vi_neg: a1", i, a1.get(i), 123);
+ errn += verify("test_2vi_neg: a2", i, a2.get(i), 103);
+ }
+ // Reset for opposite stride
+ for (int i=0; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ a2.set(i, -1);
+ }
+ test_ci_oppos(a1, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_ci_oppos: a1", i, a1.get(i), -123);
+ }
+ test_vi_oppos(a2, 123, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_vi_oppos: a2", i, a2.get(i), 123);
+ }
+ test_cp_oppos(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_cp_oppos: a1", i, a1.get(i), 123);
+ }
+ test_2ci_oppos(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_2ci_oppos: a1", i, a1.get(i), -123);
+ errn += verify("test_2ci_oppos: a2", i, a2.get(i), -103);
+ }
+ test_2vi_oppos(a1, a2, 123, 103);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_2vi_oppos: a1", i, a1.get(i), 123);
+ errn += verify("test_2vi_oppos: a2", i, a2.get(i), 103);
+ }
+ // Reset for indexing with offset
+ for (int i=0; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ a2.set(i, -1);
+ }
+ test_ci_off(a1, -1);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_ci_off: a1", i, a1.get(i), -123);
+ }
+ test_vi_off(a2, 123, -1);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_vi_off: a2", i, a2.get(i), 123);
+ }
+ test_cp_off(a1, a2);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_cp_off: a1", i, a1.get(i), 123);
+ }
+ test_2ci_off(a1, a2);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_2ci_off: a1", i, a1.get(i), -123);
+ errn += verify("test_2ci_off: a2", i, a2.get(i), -103);
+ }
+ test_2vi_off(a1, a2, 123, 103);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_2vi_off: a1", i, a1.get(i), 123);
+ errn += verify("test_2vi_off: a2", i, a2.get(i), 103);
+ }
+ for (int i=0; i<OFFSET; i++) {
+ errn += verify("test_2vi_off: a1", i, a1.get(i), -1);
+ errn += verify("test_2vi_off: a2", i, a2.get(i), -1);
+ }
+ // Reset for indexing with invariant offset
+ for (int i=0; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ a2.set(i, -1);
+ }
+ test_ci_inv(a1, OFFSET, -1);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_ci_inv: a1", i, a1.get(i), -123);
+ }
+ test_vi_inv(a2, 123, OFFSET, -1);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_vi_inv: a2", i, a2.get(i), 123);
+ }
+ test_cp_inv(a1, a2, OFFSET);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_cp_inv: a1", i, a1.get(i), 123);
+ }
+ test_2ci_inv(a1, a2, OFFSET);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_2ci_inv: a1", i, a1.get(i), -123);
+ errn += verify("test_2ci_inv: a2", i, a2.get(i), -103);
+ }
+ test_2vi_inv(a1, a2, 123, 103, OFFSET);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_2vi_inv: a1", i, a1.get(i), 123);
+ errn += verify("test_2vi_inv: a2", i, a2.get(i), 103);
+ }
+ for (int i=0; i<OFFSET; i++) {
+ errn += verify("test_2vi_inv: a1", i, a1.get(i), -1);
+ errn += verify("test_2vi_inv: a2", i, a2.get(i), -1);
+ }
+ // Reset for indexing with scale
+ for (int i=0; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ a2.set(i, -1);
+ }
+ test_ci_scl(a1, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ int val = (i%SCALE != 0) ? -1 : -123;
+ errn += verify("test_ci_scl: a1", i, a1.get(i), val);
+ }
+ test_vi_scl(a2, 123, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ int val = (i%SCALE != 0) ? -1 : 123;
+ errn += verify("test_vi_scl: a2", i, a2.get(i), val);
+ }
+ test_cp_scl(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ int val = (i%SCALE != 0) ? -1 : 123;
+ errn += verify("test_cp_scl: a1", i, a1.get(i), val);
+ }
+ test_2ci_scl(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ if (i%SCALE != 0) {
+ errn += verify("test_2ci_scl: a1", i, a1.get(i), -1);
+ } else if (i*SCALE < ARRLEN) {
+ errn += verify("test_2ci_scl: a1", i*SCALE, a1.get(i*SCALE), -123);
+ }
+ if (i%SCALE != 0) {
+ errn += verify("test_2ci_scl: a2", i, a2.get(i), -1);
+ } else if (i*SCALE < ARRLEN) {
+ errn += verify("test_2ci_scl: a2", i*SCALE, a2.get(i*SCALE), -103);
+ }
+ }
+ test_2vi_scl(a1, a2, 123, 103);
+ for (int i=0; i<ARRLEN; i++) {
+ if (i%SCALE != 0) {
+ errn += verify("test_2vi_scl: a1", i, a1.get(i), -1);
+ } else if (i*SCALE < ARRLEN) {
+ errn += verify("test_2vi_scl: a1", i*SCALE, a1.get(i*SCALE), 123);
+ }
+ if (i%SCALE != 0) {
+ errn += verify("test_2vi_scl: a2", i, a2.get(i), -1);
+ } else if (i*SCALE < ARRLEN) {
+ errn += verify("test_2vi_scl: a2", i*SCALE, a2.get(i*SCALE), 103);
+ }
+ }
+ // Reset for 2 arrays with relative aligned offset
+ for (int i=0; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ a2.set(i, -1);
+ }
+ test_vi(a2, 123, -1);
+ test_cp_alndst(a1, a2);
+ for (int i=0; i<ALIGN_OFF; i++) {
+ errn += verify("test_cp_alndst: a1", i, a1.get(i), -1);
+ }
+ for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_cp_alndst: a1", i, a1.get(i), 123);
+ }
+ for (int i=0; i<ALIGN_OFF; i++) {
+ a1.set(i, 123);
+ }
+ test_vi(a2, -123, 123);
+ test_cp_alnsrc(a1, a2);
+ for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+ errn += verify("test_cp_alnsrc: a1", i, a1.get(i), -123);
+ }
+ for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_cp_alnsrc: a1", i, a1.get(i), 123);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ a2.set(i, -1);
+ }
+ test_2ci_aln(a1, a2);
+ for (int i=0; i<ALIGN_OFF; i++) {
+ errn += verify("test_2ci_aln: a1", i, a1.get(i), -1);
+ }
+ for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2ci_aln: a1", i, a1.get(i), -123);
+ }
+ for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+ errn += verify("test_2ci_aln: a2", i, a2.get(i), -103);
+ }
+ for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2ci_aln: a2", i, a2.get(i), -1);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ a2.set(i, -1);
+ }
+ test_2vi_aln(a1, a2, 123, 103);
+ for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+ errn += verify("test_2vi_aln: a1", i, a1.get(i), 123);
+ }
+ for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2vi_aln: a1", i, a1.get(i), -1);
+ }
+ for (int i=0; i<ALIGN_OFF; i++) {
+ errn += verify("test_2vi_aln: a2", i, a2.get(i), -1);
+ }
+ for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2vi_aln: a2", i, a2.get(i), 103);
+ }
+
+ // Reset for 2 arrays with relative unaligned offset
+ for (int i=0; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ a2.set(i, -1);
+ }
+ test_vi(a2, 123, -1);
+ test_cp_unalndst(a1, a2);
+ for (int i=0; i<UNALIGN_OFF; i++) {
+ errn += verify("test_cp_unalndst: a1", i, a1.get(i), -1);
+ }
+ for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_cp_unalndst: a1", i, a1.get(i), 123);
+ }
+ test_vi(a2, -123, 123);
+ test_cp_unalnsrc(a1, a2);
+ for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+ errn += verify("test_cp_unalnsrc: a1", i, a1.get(i), -123);
+ }
+ for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_cp_unalnsrc: a1", i, a1.get(i), 123);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ a2.set(i, -1);
+ }
+ test_2ci_unaln(a1, a2);
+ for (int i=0; i<UNALIGN_OFF; i++) {
+ errn += verify("test_2ci_unaln: a1", i, a1.get(i), -1);
+ }
+ for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2ci_unaln: a1", i, a1.get(i), -123);
+ }
+ for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+ errn += verify("test_2ci_unaln: a2", i, a2.get(i), -103);
+ }
+ for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2ci_unaln: a2", i, a2.get(i), -1);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ a2.set(i, -1);
+ }
+ test_2vi_unaln(a1, a2, 123, 103);
+ for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+ errn += verify("test_2vi_unaln: a1", i, a1.get(i), 123);
+ }
+ for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2vi_unaln: a1", i, a1.get(i), -1);
+ }
+ for (int i=0; i<UNALIGN_OFF; i++) {
+ errn += verify("test_2vi_unaln: a2", i, a2.get(i), -1);
+ }
+ for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2vi_unaln: a2", i, a2.get(i), 103);
+ }
+
+ // Reset for aligned overlap initialization
+ for (int i=0; i<ALIGN_OFF; i++) {
+ a1.set(i, i);
+ }
+ for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ }
+ test_cp_alndst(a1, a1);
+ for (int i=0; i<ARRLEN; i++) {
+ int v = i%ALIGN_OFF;
+ errn += verify("test_cp_alndst_overlap: a1", i, a1.get(i), v);
+ }
+ for (int i=0; i<ALIGN_OFF; i++) {
+ a1.set((i+ALIGN_OFF), -1);
+ }
+ test_cp_alnsrc(a1, a1);
+ for (int i=0; i<ALIGN_OFF; i++) {
+ errn += verify("test_cp_alnsrc_overlap: a1", i, a1.get(i), -1);
+ }
+ for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+ int v = i%ALIGN_OFF;
+ errn += verify("test_cp_alnsrc_overlap: a1", i, a1.get(i), v);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ }
+ test_2ci_aln(a1, a1);
+ for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+ errn += verify("test_2ci_aln_overlap: a1", i, a1.get(i), -103);
+ }
+ for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2ci_aln_overlap: a1", i, a1.get(i), -123);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ }
+ test_2vi_aln(a1, a1, 123, 103);
+ for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+ errn += verify("test_2vi_aln_overlap: a1", i, a1.get(i), 123);
+ }
+ for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2vi_aln_overlap: a1", i, a1.get(i), 103);
+ }
+
+ // Reset for unaligned overlap initialization
+ for (int i=0; i<UNALIGN_OFF; i++) {
+ a1.set(i, i);
+ }
+ for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ }
+ test_cp_unalndst(a1, a1);
+ for (int i=0; i<ARRLEN; i++) {
+ int v = i%UNALIGN_OFF;
+ errn += verify("test_cp_unalndst_overlap: a1", i, a1.get(i), v);
+ }
+ for (int i=0; i<UNALIGN_OFF; i++) {
+ a1.set((i+UNALIGN_OFF), -1);
+ }
+ test_cp_unalnsrc(a1, a1);
+ for (int i=0; i<UNALIGN_OFF; i++) {
+ errn += verify("test_cp_unalnsrc_overlap: a1", i, a1.get(i), -1);
+ }
+ for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+ int v = i%UNALIGN_OFF;
+ errn += verify("test_cp_unalnsrc_overlap: a1", i, a1.get(i), v);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ }
+ test_2ci_unaln(a1, a1);
+ for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+ errn += verify("test_2ci_unaln_overlap: a1", i, a1.get(i), -103);
+ }
+ for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2ci_unaln_overlap: a1", i, a1.get(i), -123);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ }
+ test_2vi_unaln(a1, a1, 123, 103);
+ for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+ errn += verify("test_2vi_unaln_overlap: a1", i, a1.get(i), 123);
+ }
+ for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2vi_unaln_overlap: a1", i, a1.get(i), 103);
+ }
+
+ }
+
+ if (errn > 0 || test_only)
+ return errn;
+
+ // Initialize
+ for (int i=0; i<ARRLEN; i++) {
+ a1.set(i, -1);
+ a2.set(i, -1);
+ }
+ System.out.println("Time");
+ long start, end;
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_ci(a1);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_ci: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_vi(a2, 123, -1);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_vi: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_ci_neg(a1, 123);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_ci_neg: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_vi_neg(a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_vi_neg: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_neg(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_neg: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_neg(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_neg: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_neg(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_neg: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_ci_oppos(a1, 123);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_ci_oppos: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_vi_oppos(a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_vi_oppos: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_oppos(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_oppos: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_oppos(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_oppos: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_oppos(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_oppos: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_ci_off(a1, 123);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_ci_off: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_vi_off(a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_vi_off: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_off(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_off: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_off(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_off: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_off(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_off: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_ci_inv(a1, OFFSET, 123);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_ci_inv: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_vi_inv(a2, 123, OFFSET, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_vi_inv: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_inv(a1, a2, OFFSET);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_inv: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_inv(a1, a2, OFFSET);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_inv: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_inv(a1, a2, 123, 103, OFFSET);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_inv: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_ci_scl(a1, 123);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_ci_scl: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_vi_scl(a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_vi_scl: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_scl(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_scl: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_scl(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_scl: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_scl(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_scl: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_alndst(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_alndst: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_alnsrc(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_alnsrc: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_aln(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_aln: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_aln(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_aln: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_unalndst(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_unalndst: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_unalnsrc(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_unalnsrc: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_unaln(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_unaln: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_unaln(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_unaln: " + (end - start));
+
+ return errn;
+ }
+
+ static void test_ci(AtomicIntegerArray a) {
+ for (int i = 0; i < ARRLEN; i+=1) {
+ a.set(i, -123);
+ }
+ }
+ static void test_vi(AtomicIntegerArray a, int b, int old) {
+ for (int i = 0; i < ARRLEN; i+=1) {
+ a.set(i, b);
+ }
+ }
+ static void test_cp(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = 0; i < ARRLEN; i+=1) {
+ a.set(i, b.get(i));
+ }
+ }
+ static void test_2ci(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = 0; i < ARRLEN; i+=1) {
+ a.set(i, -123);
+ b.set(i, -103);
+ }
+ }
+ static void test_2vi(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) {
+ for (int i = 0; i < ARRLEN; i+=1) {
+ a.set(i, c);
+ b.set(i, d);
+ }
+ }
+ static void test_ci_neg(AtomicIntegerArray a, int old) {
+ for (int i = ARRLEN-1; i >= 0; i-=1) {
+ a.set(i,-123);
+ }
+ }
+ static void test_vi_neg(AtomicIntegerArray a, int b, int old) {
+ for (int i = ARRLEN-1; i >= 0; i-=1) {
+ a.set(i, b);
+ }
+ }
+ static void test_cp_neg(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = ARRLEN-1; i >= 0; i-=1) {
+ a.set(i, b.get(i));
+ }
+ }
+ static void test_2ci_neg(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = ARRLEN-1; i >= 0; i-=1) {
+ a.set(i, -123);
+ b.set(i, -103);
+ }
+ }
+ static void test_2vi_neg(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) {
+ for (int i = ARRLEN-1; i >= 0; i-=1) {
+ a.set(i, c);
+ b.set(i, d);
+ }
+ }
+ static void test_ci_oppos(AtomicIntegerArray a, int old) {
+ int limit = ARRLEN-1;
+ for (int i = 0; i < ARRLEN; i+=1) {
+ a.set((limit-i), -123);
+ }
+ }
+ static void test_vi_oppos(AtomicIntegerArray a, int b, int old) {
+ int limit = ARRLEN-1;
+ for (int i = limit; i >= 0; i-=1) {
+ a.set((limit-i), b);
+ }
+ }
+ static void test_cp_oppos(AtomicIntegerArray a, AtomicIntegerArray b) {
+ int limit = ARRLEN-1;
+ for (int i = 0; i < ARRLEN; i+=1) {
+ a.set(i, b.get(limit-i));
+ }
+ }
+ static void test_2ci_oppos(AtomicIntegerArray a, AtomicIntegerArray b) {
+ int limit = ARRLEN-1;
+ for (int i = 0; i < ARRLEN; i+=1) {
+ a.set((limit-i), -123);
+ b.set(i, -103);
+ }
+ }
+ static void test_2vi_oppos(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) {
+ int limit = ARRLEN-1;
+ for (int i = limit; i >= 0; i-=1) {
+ a.set(i, c);
+ b.set((limit-i), d);
+ }
+ }
+ static void test_ci_off(AtomicIntegerArray a, int old) {
+ for (int i = 0; i < ARRLEN-OFFSET; i+=1) {
+ a.set((i+OFFSET), -123);
+ }
+ }
+ static void test_vi_off(AtomicIntegerArray a, int b, int old) {
+ for (int i = 0; i < ARRLEN-OFFSET; i+=1) {
+ a.set((i+OFFSET), b);
+ }
+ }
+ static void test_cp_off(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = 0; i < ARRLEN-OFFSET; i+=1) {
+ a.set((i+OFFSET), b.get(i+OFFSET));
+ }
+ }
+ static void test_2ci_off(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = 0; i < ARRLEN-OFFSET; i+=1) {
+ a.set((i+OFFSET), -123);
+ b.set((i+OFFSET), -103);
+ }
+ }
+ static void test_2vi_off(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) {
+ for (int i = 0; i < ARRLEN-OFFSET; i+=1) {
+ a.set((i+OFFSET), c);
+ b.set((i+OFFSET), d);
+ }
+ }
+ static void test_ci_inv(AtomicIntegerArray a, int k, int old) {
+ for (int i = 0; i < ARRLEN-k; i+=1) {
+ a.set((i+k),-123);
+ }
+ }
+ static void test_vi_inv(AtomicIntegerArray a, int b, int k, int old) {
+ for (int i = 0; i < ARRLEN-k; i+=1) {
+ a.set((i+k), b);
+ }
+ }
+ static void test_cp_inv(AtomicIntegerArray a, AtomicIntegerArray b, int k) {
+ for (int i = 0; i < ARRLEN-k; i+=1) {
+ a.set((i+k), b.get(i+k));
+ }
+ }
+ static void test_2ci_inv(AtomicIntegerArray a, AtomicIntegerArray b, int k) {
+ for (int i = 0; i < ARRLEN-k; i+=1) {
+ a.set((i+k), -123);
+ b.set((i+k), -103);
+ }
+ }
+ static void test_2vi_inv(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d, int k) {
+ for (int i = 0; i < ARRLEN-k; i+=1) {
+ a.set((i+k), c);
+ b.set((i+k), d);
+ }
+ }
+ static void test_ci_scl(AtomicIntegerArray a, int old) {
+ for (int i = 0; i*SCALE < ARRLEN; i+=1) {
+ a.set((i*SCALE), -123);
+ }
+ }
+ static void test_vi_scl(AtomicIntegerArray a, int b, int old) {
+ for (int i = 0; i*SCALE < ARRLEN; i+=1) {
+ a.set((i*SCALE), b);
+ }
+ }
+ static void test_cp_scl(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = 0; i*SCALE < ARRLEN; i+=1) {
+ a.set((i*SCALE), b.get(i*SCALE));
+ }
+ }
+ static void test_2ci_scl(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = 0; i*SCALE < ARRLEN; i+=1) {
+ a.set((i*SCALE), -123);
+ b.set((i*SCALE), -103);
+ }
+ }
+ static void test_2vi_scl(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) {
+ for (int i = 0; i*SCALE < ARRLEN; i+=1) {
+ a.set((i*SCALE), c);
+ b.set((i*SCALE), d);
+ }
+ }
+ static void test_cp_alndst(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) {
+ a.set((i+ALIGN_OFF), b.get(i));
+ }
+ }
+ static void test_cp_alnsrc(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) {
+ a.set(i, b.get(i+ALIGN_OFF));
+ }
+ }
+ static void test_2ci_aln(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) {
+ a.set((i+ALIGN_OFF), -123);
+ b.set(i, -103);
+ }
+ }
+ static void test_2vi_aln(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) {
+ for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) {
+ a.set(i, c);
+ b.set((i+ALIGN_OFF), d);
+ }
+ }
+ static void test_cp_unalndst(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) {
+ a.set((i+UNALIGN_OFF), b.get(i));
+ }
+ }
+ static void test_cp_unalnsrc(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) {
+ a.set(i, b.get(i+UNALIGN_OFF));
+ }
+ }
+ static void test_2ci_unaln(AtomicIntegerArray a, AtomicIntegerArray b) {
+ for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) {
+ a.set((i+UNALIGN_OFF), -123);
+ b.set(i, -103);
+ }
+ }
+ static void test_2vi_unaln(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) {
+ for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) {
+ a.set(i, c);
+ b.set((i+UNALIGN_OFF), d);
+ }
+ }
+
+ static int verify(String text, int i, int elem, int val) {
+ if (elem != val) {
+ System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+ return 1;
+ }
+ return 0;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/8004867/TestIntUnsafeCAS.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,998 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8004867
+ * @summary VM crashing with assert "share/vm/opto/node.hpp:357 - assert(i < _max) failed: oob"
+ *
+ * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestIntUnsafeCAS
+ * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:+OptimizeFill TestIntUnsafeCAS
+ */
+
+import sun.misc.Unsafe;
+import java.lang.reflect.*;
+
+public class TestIntUnsafeCAS {
+ private static final int ARRLEN = 97;
+ private static final int ITERS = 11000;
+ private static final int OFFSET = 3;
+ private static final int SCALE = 2;
+ private static final int ALIGN_OFF = 8;
+ private static final int UNALIGN_OFF = 5;
+
+ private static final Unsafe unsafe;
+ private static final int BASE;
+ static {
+ try {
+ Class c = TestIntUnsafeCAS.class.getClassLoader().loadClass("sun.misc.Unsafe");
+ Field f = c.getDeclaredField("theUnsafe");
+ f.setAccessible(true);
+ unsafe = (Unsafe)f.get(c);
+ BASE = unsafe.arrayBaseOffset(int[].class);
+ } catch (Exception e) {
+ InternalError err = new InternalError();
+ err.initCause(e);
+ throw err;
+ }
+ }
+
+ public static void main(String args[]) {
+ System.out.println("Testing Integer array unsafe CAS operations");
+ int errn = test(false);
+ if (errn > 0) {
+ System.err.println("FAILED: " + errn + " errors");
+ System.exit(97);
+ }
+ System.out.println("PASSED");
+ }
+
+ static int test(boolean test_only) {
+ int[] a1 = new int[ARRLEN];
+ int[] a2 = new int[ARRLEN];
+ // Initialize
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ System.out.println("Warmup");
+ for (int i=0; i<ITERS; i++) {
+ test_ci(a1);
+ test_vi(a2, 123, -1);
+ test_cp(a1, a2);
+ test_2ci(a1, a2);
+ test_2vi(a1, a2, 123, 103);
+ test_ci_neg(a1, 123);
+ test_vi_neg(a2, 123, 103);
+ test_cp_neg(a1, a2);
+ test_2ci_neg(a1, a2);
+ test_2vi_neg(a1, a2, 123, 103);
+ test_ci_oppos(a1, 123);
+ test_vi_oppos(a2, 123, 103);
+ test_cp_oppos(a1, a2);
+ test_2ci_oppos(a1, a2);
+ test_2vi_oppos(a1, a2, 123, 103);
+ test_ci_off(a1, 123);
+ test_vi_off(a2, 123, 103);
+ test_cp_off(a1, a2);
+ test_2ci_off(a1, a2);
+ test_2vi_off(a1, a2, 123, 103);
+ test_ci_inv(a1, OFFSET, 123);
+ test_vi_inv(a2, 123, OFFSET, 103);
+ test_cp_inv(a1, a2, OFFSET);
+ test_2ci_inv(a1, a2, OFFSET);
+ test_2vi_inv(a1, a2, 123, 103, OFFSET);
+ test_ci_scl(a1, 123);
+ test_vi_scl(a2, 123, 103);
+ test_cp_scl(a1, a2);
+ test_2ci_scl(a1, a2);
+ test_2vi_scl(a1, a2, 123, 103);
+ test_cp_alndst(a1, a2);
+ test_cp_alnsrc(a1, a2);
+ test_2ci_aln(a1, a2);
+ test_2vi_aln(a1, a2, 123, 103);
+ test_cp_unalndst(a1, a2);
+ test_cp_unalnsrc(a1, a2);
+ test_2ci_unaln(a1, a2);
+ test_2vi_unaln(a1, a2, 123, 103);
+ }
+ // Initialize
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ // Test and verify results
+ System.out.println("Verification");
+ int errn = 0;
+ {
+ test_ci(a1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_ci: a1", i, a1[i], -123);
+ }
+ test_vi(a2, 123, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_vi: a2", i, a2[i], 123);
+ }
+ test_cp(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_cp: a1", i, a1[i], 123);
+ }
+ test_2ci(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_2ci: a1", i, a1[i], -123);
+ errn += verify("test_2ci: a2", i, a2[i], -103);
+ }
+ test_2vi(a1, a2, 123, 103);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_2vi: a1", i, a1[i], 123);
+ errn += verify("test_2vi: a2", i, a2[i], 103);
+ }
+ // Reset for negative stride
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ test_ci_neg(a1, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_ci_neg: a1", i, a1[i], -123);
+ }
+ test_vi_neg(a2, 123, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_vi_neg: a2", i, a2[i], 123);
+ }
+ test_cp_neg(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_cp_neg: a1", i, a1[i], 123);
+ }
+ test_2ci_neg(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_2ci_neg: a1", i, a1[i], -123);
+ errn += verify("test_2ci_neg: a2", i, a2[i], -103);
+ }
+ test_2vi_neg(a1, a2, 123, 103);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_2vi_neg: a1", i, a1[i], 123);
+ errn += verify("test_2vi_neg: a2", i, a2[i], 103);
+ }
+ // Reset for opposite stride
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ test_ci_oppos(a1, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_ci_oppos: a1", i, a1[i], -123);
+ }
+ test_vi_oppos(a2, 123, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_vi_oppos: a2", i, a2[i], 123);
+ }
+ test_cp_oppos(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_cp_oppos: a1", i, a1[i], 123);
+ }
+ test_2ci_oppos(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_2ci_oppos: a1", i, a1[i], -123);
+ errn += verify("test_2ci_oppos: a2", i, a2[i], -103);
+ }
+ test_2vi_oppos(a1, a2, 123, 103);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_2vi_oppos: a1", i, a1[i], 123);
+ errn += verify("test_2vi_oppos: a2", i, a2[i], 103);
+ }
+ // Reset for indexing with offset
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ test_ci_off(a1, -1);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_ci_off: a1", i, a1[i], -123);
+ }
+ test_vi_off(a2, 123, -1);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_vi_off: a2", i, a2[i], 123);
+ }
+ test_cp_off(a1, a2);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_cp_off: a1", i, a1[i], 123);
+ }
+ test_2ci_off(a1, a2);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_2ci_off: a1", i, a1[i], -123);
+ errn += verify("test_2ci_off: a2", i, a2[i], -103);
+ }
+ test_2vi_off(a1, a2, 123, 103);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_2vi_off: a1", i, a1[i], 123);
+ errn += verify("test_2vi_off: a2", i, a2[i], 103);
+ }
+ for (int i=0; i<OFFSET; i++) {
+ errn += verify("test_2vi_off: a1", i, a1[i], -1);
+ errn += verify("test_2vi_off: a2", i, a2[i], -1);
+ }
+ // Reset for indexing with invariant offset
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ test_ci_inv(a1, OFFSET, -1);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_ci_inv: a1", i, a1[i], -123);
+ }
+ test_vi_inv(a2, 123, OFFSET, -1);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_vi_inv: a2", i, a2[i], 123);
+ }
+ test_cp_inv(a1, a2, OFFSET);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_cp_inv: a1", i, a1[i], 123);
+ }
+ test_2ci_inv(a1, a2, OFFSET);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_2ci_inv: a1", i, a1[i], -123);
+ errn += verify("test_2ci_inv: a2", i, a2[i], -103);
+ }
+ test_2vi_inv(a1, a2, 123, 103, OFFSET);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_2vi_inv: a1", i, a1[i], 123);
+ errn += verify("test_2vi_inv: a2", i, a2[i], 103);
+ }
+ for (int i=0; i<OFFSET; i++) {
+ errn += verify("test_2vi_inv: a1", i, a1[i], -1);
+ errn += verify("test_2vi_inv: a2", i, a2[i], -1);
+ }
+ // Reset for indexing with scale
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ test_ci_scl(a1, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ int val = (i%SCALE != 0) ? -1 : -123;
+ errn += verify("test_ci_scl: a1", i, a1[i], val);
+ }
+ test_vi_scl(a2, 123, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ int val = (i%SCALE != 0) ? -1 : 123;
+ errn += verify("test_vi_scl: a2", i, a2[i], val);
+ }
+ test_cp_scl(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ int val = (i%SCALE != 0) ? -1 : 123;
+ errn += verify("test_cp_scl: a1", i, a1[i], val);
+ }
+ test_2ci_scl(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ if (i%SCALE != 0) {
+ errn += verify("test_2ci_scl: a1", i, a1[i], -1);
+ } else if (i*SCALE < ARRLEN) {
+ errn += verify("test_2ci_scl: a1", i*SCALE, a1[i*SCALE], -123);
+ }
+ if (i%SCALE != 0) {
+ errn += verify("test_2ci_scl: a2", i, a2[i], -1);
+ } else if (i*SCALE < ARRLEN) {
+ errn += verify("test_2ci_scl: a2", i*SCALE, a2[i*SCALE], -103);
+ }
+ }
+ test_2vi_scl(a1, a2, 123, 103);
+ for (int i=0; i<ARRLEN; i++) {
+ if (i%SCALE != 0) {
+ errn += verify("test_2vi_scl: a1", i, a1[i], -1);
+ } else if (i*SCALE < ARRLEN) {
+ errn += verify("test_2vi_scl: a1", i*SCALE, a1[i*SCALE], 123);
+ }
+ if (i%SCALE != 0) {
+ errn += verify("test_2vi_scl: a2", i, a2[i], -1);
+ } else if (i*SCALE < ARRLEN) {
+ errn += verify("test_2vi_scl: a2", i*SCALE, a2[i*SCALE], 103);
+ }
+ }
+ // Reset for 2 arrays with relative aligned offset
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ test_vi(a2, 123, -1);
+ test_cp_alndst(a1, a2);
+ for (int i=0; i<ALIGN_OFF; i++) {
+ errn += verify("test_cp_alndst: a1", i, a1[i], -1);
+ }
+ for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_cp_alndst: a1", i, a1[i], 123);
+ }
+ for (int i=0; i<ALIGN_OFF; i++) {
+ a1[i] = 123;
+ }
+ test_vi(a2, -123, 123);
+ test_cp_alnsrc(a1, a2);
+ for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+ errn += verify("test_cp_alnsrc: a1", i, a1[i], -123);
+ }
+ for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_cp_alnsrc: a1", i, a1[i], 123);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ test_2ci_aln(a1, a2);
+ for (int i=0; i<ALIGN_OFF; i++) {
+ errn += verify("test_2ci_aln: a1", i, a1[i], -1);
+ }
+ for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2ci_aln: a1", i, a1[i], -123);
+ }
+ for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+ errn += verify("test_2ci_aln: a2", i, a2[i], -103);
+ }
+ for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2ci_aln: a2", i, a2[i], -1);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ test_2vi_aln(a1, a2, 123, 103);
+ for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+ errn += verify("test_2vi_aln: a1", i, a1[i], 123);
+ }
+ for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2vi_aln: a1", i, a1[i], -1);
+ }
+ for (int i=0; i<ALIGN_OFF; i++) {
+ errn += verify("test_2vi_aln: a2", i, a2[i], -1);
+ }
+ for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2vi_aln: a2", i, a2[i], 103);
+ }
+
+ // Reset for 2 arrays with relative unaligned offset
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ test_vi(a2, 123, -1);
+ test_cp_unalndst(a1, a2);
+ for (int i=0; i<UNALIGN_OFF; i++) {
+ errn += verify("test_cp_unalndst: a1", i, a1[i], -1);
+ }
+ for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_cp_unalndst: a1", i, a1[i], 123);
+ }
+ test_vi(a2, -123, 123);
+ test_cp_unalnsrc(a1, a2);
+ for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+ errn += verify("test_cp_unalnsrc: a1", i, a1[i], -123);
+ }
+ for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_cp_unalnsrc: a1", i, a1[i], 123);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ test_2ci_unaln(a1, a2);
+ for (int i=0; i<UNALIGN_OFF; i++) {
+ errn += verify("test_2ci_unaln: a1", i, a1[i], -1);
+ }
+ for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2ci_unaln: a1", i, a1[i], -123);
+ }
+ for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+ errn += verify("test_2ci_unaln: a2", i, a2[i], -103);
+ }
+ for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2ci_unaln: a2", i, a2[i], -1);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ test_2vi_unaln(a1, a2, 123, 103);
+ for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+ errn += verify("test_2vi_unaln: a1", i, a1[i], 123);
+ }
+ for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2vi_unaln: a1", i, a1[i], -1);
+ }
+ for (int i=0; i<UNALIGN_OFF; i++) {
+ errn += verify("test_2vi_unaln: a2", i, a2[i], -1);
+ }
+ for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2vi_unaln: a2", i, a2[i], 103);
+ }
+
+ // Reset for aligned overlap initialization
+ for (int i=0; i<ALIGN_OFF; i++) {
+ a1[i] = i;
+ }
+ for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+ a1[i] = -1;
+ }
+ test_cp_alndst(a1, a1);
+ for (int i=0; i<ARRLEN; i++) {
+ int v = i%ALIGN_OFF;
+ errn += verify("test_cp_alndst_overlap: a1", i, a1[i], v);
+ }
+ for (int i=0; i<ALIGN_OFF; i++) {
+ a1[i+ALIGN_OFF] = -1;
+ }
+ test_cp_alnsrc(a1, a1);
+ for (int i=0; i<ALIGN_OFF; i++) {
+ errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], -1);
+ }
+ for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+ int v = i%ALIGN_OFF;
+ errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], v);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ }
+ test_2ci_aln(a1, a1);
+ for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+ errn += verify("test_2ci_aln_overlap: a1", i, a1[i], -103);
+ }
+ for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2ci_aln_overlap: a1", i, a1[i], -123);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ }
+ test_2vi_aln(a1, a1, 123, 103);
+ for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+ errn += verify("test_2vi_aln_overlap: a1", i, a1[i], 123);
+ }
+ for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2vi_aln_overlap: a1", i, a1[i], 103);
+ }
+
+ // Reset for unaligned overlap initialization
+ for (int i=0; i<UNALIGN_OFF; i++) {
+ a1[i] = i;
+ }
+ for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+ a1[i] = -1;
+ }
+ test_cp_unalndst(a1, a1);
+ for (int i=0; i<ARRLEN; i++) {
+ int v = i%UNALIGN_OFF;
+ errn += verify("test_cp_unalndst_overlap: a1", i, a1[i], v);
+ }
+ for (int i=0; i<UNALIGN_OFF; i++) {
+ a1[i+UNALIGN_OFF] = -1;
+ }
+ test_cp_unalnsrc(a1, a1);
+ for (int i=0; i<UNALIGN_OFF; i++) {
+ errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], -1);
+ }
+ for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+ int v = i%UNALIGN_OFF;
+ errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], v);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ }
+ test_2ci_unaln(a1, a1);
+ for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+ errn += verify("test_2ci_unaln_overlap: a1", i, a1[i], -103);
+ }
+ for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2ci_unaln_overlap: a1", i, a1[i], -123);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ }
+ test_2vi_unaln(a1, a1, 123, 103);
+ for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+ errn += verify("test_2vi_unaln_overlap: a1", i, a1[i], 123);
+ }
+ for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2vi_unaln_overlap: a1", i, a1[i], 103);
+ }
+
+ }
+
+ if (errn > 0 || test_only)
+ return errn;
+
+ // Initialize
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ System.out.println("Time");
+ long start, end;
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_ci(a1);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_ci: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_vi(a2, 123, -1);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_vi: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_ci_neg(a1, 123);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_ci_neg: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_vi_neg(a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_vi_neg: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_neg(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_neg: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_neg(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_neg: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_neg(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_neg: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_ci_oppos(a1, 123);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_ci_oppos: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_vi_oppos(a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_vi_oppos: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_oppos(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_oppos: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_oppos(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_oppos: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_oppos(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_oppos: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_ci_off(a1, 123);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_ci_off: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_vi_off(a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_vi_off: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_off(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_off: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_off(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_off: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_off(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_off: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_ci_inv(a1, OFFSET, 123);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_ci_inv: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_vi_inv(a2, 123, OFFSET, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_vi_inv: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_inv(a1, a2, OFFSET);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_inv: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_inv(a1, a2, OFFSET);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_inv: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_inv(a1, a2, 123, 103, OFFSET);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_inv: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_ci_scl(a1, 123);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_ci_scl: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_vi_scl(a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_vi_scl: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_scl(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_scl: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_scl(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_scl: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_scl(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_scl: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_alndst(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_alndst: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_alnsrc(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_alnsrc: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_aln(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_aln: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_aln(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_aln: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_unalndst(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_unalndst: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_unalnsrc(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_unalnsrc: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_unaln(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_unaln: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_unaln(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_unaln: " + (end - start));
+
+ return errn;
+ }
+
+ private final static long byte_offset(int i) {
+ return ((long)i << 2) + BASE;
+ }
+
+ static void test_ci(int[] a) {
+ for (int i = 0; i < ARRLEN; i+=1) {
+ unsafe.compareAndSwapInt(a, byte_offset(i), -1, -123);
+ }
+ }
+ static void test_vi(int[] a, int b, int old) {
+ for (int i = 0; i < ARRLEN; i+=1) {
+ unsafe.compareAndSwapInt(a, byte_offset(i), old, b);
+ }
+ }
+ static void test_cp(int[] a, int[] b) {
+ for (int i = 0; i < ARRLEN; i+=1) {
+ unsafe.compareAndSwapInt(a, byte_offset(i), -123, b[i]);
+ }
+ }
+ static void test_2ci(int[] a, int[] b) {
+ for (int i = 0; i < ARRLEN; i+=1) {
+ unsafe.compareAndSwapInt(a, byte_offset(i), 123, -123);
+ unsafe.compareAndSwapInt(b, byte_offset(i), 123, -103);
+ }
+ }
+ static void test_2vi(int[] a, int[] b, int c, int d) {
+ for (int i = 0; i < ARRLEN; i+=1) {
+ unsafe.compareAndSwapInt(a, byte_offset(i), -123, c);
+ unsafe.compareAndSwapInt(b, byte_offset(i), -103, d);
+ }
+ }
+ static void test_ci_neg(int[] a, int old) {
+ for (int i = ARRLEN-1; i >= 0; i-=1) {
+ unsafe.compareAndSwapInt(a, byte_offset(i), old, -123);
+ }
+ }
+ static void test_vi_neg(int[] a, int b, int old) {
+ for (int i = ARRLEN-1; i >= 0; i-=1) {
+ unsafe.compareAndSwapInt(a, byte_offset(i), old, b);
+ }
+ }
+ static void test_cp_neg(int[] a, int[] b) {
+ for (int i = ARRLEN-1; i >= 0; i-=1) {
+ unsafe.compareAndSwapInt(a, byte_offset(i), -123, b[i]);
+ }
+ }
+ static void test_2ci_neg(int[] a, int[] b) {
+ for (int i = ARRLEN-1; i >= 0; i-=1) {
+ unsafe.compareAndSwapInt(a, byte_offset(i), 123, -123);
+ unsafe.compareAndSwapInt(b, byte_offset(i), 123, -103);
+ }
+ }
+ static void test_2vi_neg(int[] a, int[] b, int c, int d) {
+ for (int i = ARRLEN-1; i >= 0; i-=1) {
+ unsafe.compareAndSwapInt(a, byte_offset(i), -123, c);
+ unsafe.compareAndSwapInt(b, byte_offset(i), -103, d);
+ }
+ }
+ static void test_ci_oppos(int[] a, int old) {
+ int limit = ARRLEN-1;
+ for (int i = 0; i < ARRLEN; i+=1) {
+ unsafe.compareAndSwapInt(a, byte_offset(limit-i), old, -123);
+ }
+ }
+ static void test_vi_oppos(int[] a, int b, int old) {
+ int limit = ARRLEN-1;
+ for (int i = limit; i >= 0; i-=1) {
+ unsafe.compareAndSwapInt(a, byte_offset(limit-i), old, b);
+ }
+ }
+ static void test_cp_oppos(int[] a, int[] b) {
+ int limit = ARRLEN-1;
+ for (int i = 0; i < ARRLEN; i+=1) {
+ unsafe.compareAndSwapInt(a, byte_offset(i), -123, b[limit-i]);
+ }
+ }
+ static void test_2ci_oppos(int[] a, int[] b) {
+ int limit = ARRLEN-1;
+ for (int i = 0; i < ARRLEN; i+=1) {
+ unsafe.compareAndSwapInt(a, byte_offset(limit-i), 123, -123);
+ unsafe.compareAndSwapInt(b, byte_offset(i), 123, -103);
+ }
+ }
+ static void test_2vi_oppos(int[] a, int[] b, int c, int d) {
+ int limit = ARRLEN-1;
+ for (int i = limit; i >= 0; i-=1) {
+ unsafe.compareAndSwapInt(a, byte_offset(i), -123, c);
+ unsafe.compareAndSwapInt(b, byte_offset(limit-i), -103, d);
+ }
+ }
+ static void test_ci_off(int[] a, int old) {
+ for (int i = 0; i < ARRLEN-OFFSET; i+=1) {
+ unsafe.compareAndSwapInt(a, byte_offset(i+OFFSET), old, -123);
+ }
+ }
+ static void test_vi_off(int[] a, int b, int old) {
+ for (int i = 0; i < ARRLEN-OFFSET; i+=1) {
+ unsafe.compareAndSwapInt(a, byte_offset(i+OFFSET), old, b);
+ }
+ }
+ static void test_cp_off(int[] a, int[] b) {
+ for (int i = 0; i < ARRLEN-OFFSET; i+=1) {
+ unsafe.compareAndSwapInt(a, byte_offset(i+OFFSET), -123, b[i+OFFSET]);
+ }
+ }
+ static void test_2ci_off(int[] a, int[] b) {
+ for (int i = 0; i < ARRLEN-OFFSET; i+=1) {
+ unsafe.compareAndSwapInt(a, byte_offset(i+OFFSET), 123, -123);
+ unsafe.compareAndSwapInt(b, byte_offset(i+OFFSET), 123, -103);
+ }
+ }
+ static void test_2vi_off(int[] a, int[] b, int c, int d) {
+ for (int i = 0; i < ARRLEN-OFFSET; i+=1) {
+ unsafe.compareAndSwapInt(a, byte_offset(i+OFFSET), -123, c);
+ unsafe.compareAndSwapInt(b, byte_offset(i+OFFSET), -103, d);
+ }
+ }
+ static void test_ci_inv(int[] a, int k, int old) {
+ for (int i = 0; i < ARRLEN-k; i+=1) {
+ unsafe.compareAndSwapInt(a, byte_offset(i+k), old, -123);
+ }
+ }
+ static void test_vi_inv(int[] a, int b, int k, int old) {
+ for (int i = 0; i < ARRLEN-k; i+=1) {
+ unsafe.compareAndSwapInt(a, byte_offset(i+k), old, b);
+ }
+ }
+ static void test_cp_inv(int[] a, int[] b, int k) {
+ for (int i = 0; i < ARRLEN-k; i+=1) {
+ unsafe.compareAndSwapInt(a, byte_offset(i+k), -123, b[i+k]);
+ }
+ }
+ static void test_2ci_inv(int[] a, int[] b, int k) {
+ for (int i = 0; i < ARRLEN-k; i+=1) {
+ unsafe.compareAndSwapInt(a, byte_offset(i+k), 123, -123);
+ unsafe.compareAndSwapInt(b, byte_offset(i+k), 123, -103);
+ }
+ }
+ static void test_2vi_inv(int[] a, int[] b, int c, int d, int k) {
+ for (int i = 0; i < ARRLEN-k; i+=1) {
+ unsafe.compareAndSwapInt(a, byte_offset(i+k), -123, c);
+ unsafe.compareAndSwapInt(b, byte_offset(i+k), -103, d);
+ }
+ }
+ static void test_ci_scl(int[] a, int old) {
+ for (int i = 0; i*SCALE < ARRLEN; i+=1) {
+ unsafe.compareAndSwapInt(a, byte_offset(i*SCALE), old, -123);
+ }
+ }
+ static void test_vi_scl(int[] a, int b, int old) {
+ for (int i = 0; i*SCALE < ARRLEN; i+=1) {
+ unsafe.compareAndSwapInt(a, byte_offset(i*SCALE), old, b);
+ }
+ }
+ static void test_cp_scl(int[] a, int[] b) {
+ for (int i = 0; i*SCALE < ARRLEN; i+=1) {
+ unsafe.compareAndSwapInt(a, byte_offset(i*SCALE), -123, b[i*SCALE]);
+ }
+ }
+ static void test_2ci_scl(int[] a, int[] b) {
+ for (int i = 0; i*SCALE < ARRLEN; i+=1) {
+ unsafe.compareAndSwapInt(a, byte_offset(i*SCALE), 123, -123);
+ unsafe.compareAndSwapInt(b, byte_offset(i*SCALE), 123, -103);
+ }
+ }
+ static void test_2vi_scl(int[] a, int[] b, int c, int d) {
+ for (int i = 0; i*SCALE < ARRLEN; i+=1) {
+ unsafe.compareAndSwapInt(a, byte_offset(i*SCALE), -123, c);
+ unsafe.compareAndSwapInt(b, byte_offset(i*SCALE), -103, d);
+ }
+ }
+ static void test_cp_alndst(int[] a, int[] b) {
+ for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) {
+ unsafe.compareAndSwapInt(a, byte_offset(i+ALIGN_OFF), -1, b[i]);
+ }
+ }
+ static void test_cp_alnsrc(int[] a, int[] b) {
+ for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) {
+ int old = unsafe.getIntVolatile(a, byte_offset(i));
+ unsafe.compareAndSwapInt(a, byte_offset(i), old, b[i+ALIGN_OFF]);
+ }
+ }
+ static void test_2ci_aln(int[] a, int[] b) {
+ for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) {
+ unsafe.compareAndSwapInt(a, byte_offset(i+ALIGN_OFF), -1, -123);
+ int old = unsafe.getIntVolatile(b, byte_offset(i));
+ unsafe.compareAndSwapInt(b, byte_offset(i), old, -103);
+ }
+ }
+ static void test_2vi_aln(int[] a, int[] b, int c, int d) {
+ for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) {
+ int old = unsafe.getIntVolatile(a, byte_offset(i));
+ unsafe.compareAndSwapInt(a, byte_offset(i), old, c);
+ old = unsafe.getIntVolatile(b, byte_offset(i+ALIGN_OFF));
+ unsafe.compareAndSwapInt(b, byte_offset(i+ALIGN_OFF), old, d);
+ }
+ }
+ static void test_cp_unalndst(int[] a, int[] b) {
+ for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) {
+ unsafe.compareAndSwapInt(a, byte_offset(i+UNALIGN_OFF), -1, b[i]);
+ }
+ }
+ static void test_cp_unalnsrc(int[] a, int[] b) {
+ for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) {
+ int old = unsafe.getIntVolatile(a, byte_offset(i));
+ unsafe.compareAndSwapInt(a, byte_offset(i), old, b[i+UNALIGN_OFF]);
+ }
+ }
+ static void test_2ci_unaln(int[] a, int[] b) {
+ for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) {
+ unsafe.compareAndSwapInt(a, byte_offset(i+UNALIGN_OFF), -1, -123);
+ int old = unsafe.getIntVolatile(b, byte_offset(i));
+ unsafe.compareAndSwapInt(b, byte_offset(i), old, -103);
+ }
+ }
+ static void test_2vi_unaln(int[] a, int[] b, int c, int d) {
+ for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) {
+ int old = unsafe.getIntVolatile(a, byte_offset(i));
+ unsafe.compareAndSwapInt(a, byte_offset(i), old, c);
+ old = unsafe.getIntVolatile(b, byte_offset(i+UNALIGN_OFF));
+ unsafe.compareAndSwapInt(b, byte_offset(i+UNALIGN_OFF), old, d);
+ }
+ }
+
+ static int verify(String text, int i, int elem, int val) {
+ if (elem != val) {
+ System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+ return 1;
+ }
+ return 0;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/8004867/TestIntUnsafeOrdered.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,990 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8004867
+ * @summary VM crashing with assert "share/vm/opto/node.hpp:357 - assert(i < _max) failed: oob"
+ *
+ * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestIntUnsafeOrdered
+ * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:+OptimizeFill TestIntUnsafeOrdered
+ */
+
+import sun.misc.Unsafe;
+import java.lang.reflect.*;
+
+public class TestIntUnsafeOrdered {
+ private static final int ARRLEN = 97;
+ private static final int ITERS = 11000;
+ private static final int OFFSET = 3;
+ private static final int SCALE = 2;
+ private static final int ALIGN_OFF = 8;
+ private static final int UNALIGN_OFF = 5;
+
+ private static final Unsafe unsafe;
+ private static final int BASE;
+ static {
+ try {
+ Class c = TestIntUnsafeOrdered.class.getClassLoader().loadClass("sun.misc.Unsafe");
+ Field f = c.getDeclaredField("theUnsafe");
+ f.setAccessible(true);
+ unsafe = (Unsafe)f.get(c);
+ BASE = unsafe.arrayBaseOffset(int[].class);
+ } catch (Exception e) {
+ InternalError err = new InternalError();
+ err.initCause(e);
+ throw err;
+ }
+ }
+
+ public static void main(String args[]) {
+ System.out.println("Testing Integer array unsafe ordered operations");
+ int errn = test(false);
+ if (errn > 0) {
+ System.err.println("FAILED: " + errn + " errors");
+ System.exit(97);
+ }
+ System.out.println("PASSED");
+ }
+
+ static int test(boolean test_only) {
+ int[] a1 = new int[ARRLEN];
+ int[] a2 = new int[ARRLEN];
+ // Initialize
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ System.out.println("Warmup");
+ for (int i=0; i<ITERS; i++) {
+ test_ci(a1);
+ test_vi(a2, 123, -1);
+ test_cp(a1, a2);
+ test_2ci(a1, a2);
+ test_2vi(a1, a2, 123, 103);
+ test_ci_neg(a1, 123);
+ test_vi_neg(a2, 123, 103);
+ test_cp_neg(a1, a2);
+ test_2ci_neg(a1, a2);
+ test_2vi_neg(a1, a2, 123, 103);
+ test_ci_oppos(a1, 123);
+ test_vi_oppos(a2, 123, 103);
+ test_cp_oppos(a1, a2);
+ test_2ci_oppos(a1, a2);
+ test_2vi_oppos(a1, a2, 123, 103);
+ test_ci_off(a1, 123);
+ test_vi_off(a2, 123, 103);
+ test_cp_off(a1, a2);
+ test_2ci_off(a1, a2);
+ test_2vi_off(a1, a2, 123, 103);
+ test_ci_inv(a1, OFFSET, 123);
+ test_vi_inv(a2, 123, OFFSET, 103);
+ test_cp_inv(a1, a2, OFFSET);
+ test_2ci_inv(a1, a2, OFFSET);
+ test_2vi_inv(a1, a2, 123, 103, OFFSET);
+ test_ci_scl(a1, 123);
+ test_vi_scl(a2, 123, 103);
+ test_cp_scl(a1, a2);
+ test_2ci_scl(a1, a2);
+ test_2vi_scl(a1, a2, 123, 103);
+ test_cp_alndst(a1, a2);
+ test_cp_alnsrc(a1, a2);
+ test_2ci_aln(a1, a2);
+ test_2vi_aln(a1, a2, 123, 103);
+ test_cp_unalndst(a1, a2);
+ test_cp_unalnsrc(a1, a2);
+ test_2ci_unaln(a1, a2);
+ test_2vi_unaln(a1, a2, 123, 103);
+ }
+ // Initialize
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ // Test and verify results
+ System.out.println("Verification");
+ int errn = 0;
+ {
+ test_ci(a1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_ci: a1", i, a1[i], -123);
+ }
+ test_vi(a2, 123, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_vi: a2", i, a2[i], 123);
+ }
+ test_cp(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_cp: a1", i, a1[i], 123);
+ }
+ test_2ci(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_2ci: a1", i, a1[i], -123);
+ errn += verify("test_2ci: a2", i, a2[i], -103);
+ }
+ test_2vi(a1, a2, 123, 103);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_2vi: a1", i, a1[i], 123);
+ errn += verify("test_2vi: a2", i, a2[i], 103);
+ }
+ // Reset for negative stride
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ test_ci_neg(a1, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_ci_neg: a1", i, a1[i], -123);
+ }
+ test_vi_neg(a2, 123, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_vi_neg: a2", i, a2[i], 123);
+ }
+ test_cp_neg(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_cp_neg: a1", i, a1[i], 123);
+ }
+ test_2ci_neg(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_2ci_neg: a1", i, a1[i], -123);
+ errn += verify("test_2ci_neg: a2", i, a2[i], -103);
+ }
+ test_2vi_neg(a1, a2, 123, 103);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_2vi_neg: a1", i, a1[i], 123);
+ errn += verify("test_2vi_neg: a2", i, a2[i], 103);
+ }
+ // Reset for opposite stride
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ test_ci_oppos(a1, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_ci_oppos: a1", i, a1[i], -123);
+ }
+ test_vi_oppos(a2, 123, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_vi_oppos: a2", i, a2[i], 123);
+ }
+ test_cp_oppos(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_cp_oppos: a1", i, a1[i], 123);
+ }
+ test_2ci_oppos(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_2ci_oppos: a1", i, a1[i], -123);
+ errn += verify("test_2ci_oppos: a2", i, a2[i], -103);
+ }
+ test_2vi_oppos(a1, a2, 123, 103);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_2vi_oppos: a1", i, a1[i], 123);
+ errn += verify("test_2vi_oppos: a2", i, a2[i], 103);
+ }
+ // Reset for indexing with offset
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ test_ci_off(a1, -1);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_ci_off: a1", i, a1[i], -123);
+ }
+ test_vi_off(a2, 123, -1);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_vi_off: a2", i, a2[i], 123);
+ }
+ test_cp_off(a1, a2);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_cp_off: a1", i, a1[i], 123);
+ }
+ test_2ci_off(a1, a2);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_2ci_off: a1", i, a1[i], -123);
+ errn += verify("test_2ci_off: a2", i, a2[i], -103);
+ }
+ test_2vi_off(a1, a2, 123, 103);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_2vi_off: a1", i, a1[i], 123);
+ errn += verify("test_2vi_off: a2", i, a2[i], 103);
+ }
+ for (int i=0; i<OFFSET; i++) {
+ errn += verify("test_2vi_off: a1", i, a1[i], -1);
+ errn += verify("test_2vi_off: a2", i, a2[i], -1);
+ }
+ // Reset for indexing with invariant offset
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ test_ci_inv(a1, OFFSET, -1);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_ci_inv: a1", i, a1[i], -123);
+ }
+ test_vi_inv(a2, 123, OFFSET, -1);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_vi_inv: a2", i, a2[i], 123);
+ }
+ test_cp_inv(a1, a2, OFFSET);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_cp_inv: a1", i, a1[i], 123);
+ }
+ test_2ci_inv(a1, a2, OFFSET);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_2ci_inv: a1", i, a1[i], -123);
+ errn += verify("test_2ci_inv: a2", i, a2[i], -103);
+ }
+ test_2vi_inv(a1, a2, 123, 103, OFFSET);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_2vi_inv: a1", i, a1[i], 123);
+ errn += verify("test_2vi_inv: a2", i, a2[i], 103);
+ }
+ for (int i=0; i<OFFSET; i++) {
+ errn += verify("test_2vi_inv: a1", i, a1[i], -1);
+ errn += verify("test_2vi_inv: a2", i, a2[i], -1);
+ }
+ // Reset for indexing with scale
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ test_ci_scl(a1, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ int val = (i%SCALE != 0) ? -1 : -123;
+ errn += verify("test_ci_scl: a1", i, a1[i], val);
+ }
+ test_vi_scl(a2, 123, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ int val = (i%SCALE != 0) ? -1 : 123;
+ errn += verify("test_vi_scl: a2", i, a2[i], val);
+ }
+ test_cp_scl(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ int val = (i%SCALE != 0) ? -1 : 123;
+ errn += verify("test_cp_scl: a1", i, a1[i], val);
+ }
+ test_2ci_scl(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ if (i%SCALE != 0) {
+ errn += verify("test_2ci_scl: a1", i, a1[i], -1);
+ } else if (i*SCALE < ARRLEN) {
+ errn += verify("test_2ci_scl: a1", i*SCALE, a1[i*SCALE], -123);
+ }
+ if (i%SCALE != 0) {
+ errn += verify("test_2ci_scl: a2", i, a2[i], -1);
+ } else if (i*SCALE < ARRLEN) {
+ errn += verify("test_2ci_scl: a2", i*SCALE, a2[i*SCALE], -103);
+ }
+ }
+ test_2vi_scl(a1, a2, 123, 103);
+ for (int i=0; i<ARRLEN; i++) {
+ if (i%SCALE != 0) {
+ errn += verify("test_2vi_scl: a1", i, a1[i], -1);
+ } else if (i*SCALE < ARRLEN) {
+ errn += verify("test_2vi_scl: a1", i*SCALE, a1[i*SCALE], 123);
+ }
+ if (i%SCALE != 0) {
+ errn += verify("test_2vi_scl: a2", i, a2[i], -1);
+ } else if (i*SCALE < ARRLEN) {
+ errn += verify("test_2vi_scl: a2", i*SCALE, a2[i*SCALE], 103);
+ }
+ }
+ // Reset for 2 arrays with relative aligned offset
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ test_vi(a2, 123, -1);
+ test_cp_alndst(a1, a2);
+ for (int i=0; i<ALIGN_OFF; i++) {
+ errn += verify("test_cp_alndst: a1", i, a1[i], -1);
+ }
+ for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_cp_alndst: a1", i, a1[i], 123);
+ }
+ for (int i=0; i<ALIGN_OFF; i++) {
+ a1[i] = 123;
+ }
+ test_vi(a2, -123, 123);
+ test_cp_alnsrc(a1, a2);
+ for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+ errn += verify("test_cp_alnsrc: a1", i, a1[i], -123);
+ }
+ for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_cp_alnsrc: a1", i, a1[i], 123);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ test_2ci_aln(a1, a2);
+ for (int i=0; i<ALIGN_OFF; i++) {
+ errn += verify("test_2ci_aln: a1", i, a1[i], -1);
+ }
+ for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2ci_aln: a1", i, a1[i], -123);
+ }
+ for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+ errn += verify("test_2ci_aln: a2", i, a2[i], -103);
+ }
+ for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2ci_aln: a2", i, a2[i], -1);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ test_2vi_aln(a1, a2, 123, 103);
+ for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+ errn += verify("test_2vi_aln: a1", i, a1[i], 123);
+ }
+ for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2vi_aln: a1", i, a1[i], -1);
+ }
+ for (int i=0; i<ALIGN_OFF; i++) {
+ errn += verify("test_2vi_aln: a2", i, a2[i], -1);
+ }
+ for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2vi_aln: a2", i, a2[i], 103);
+ }
+
+ // Reset for 2 arrays with relative unaligned offset
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ test_vi(a2, 123, -1);
+ test_cp_unalndst(a1, a2);
+ for (int i=0; i<UNALIGN_OFF; i++) {
+ errn += verify("test_cp_unalndst: a1", i, a1[i], -1);
+ }
+ for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_cp_unalndst: a1", i, a1[i], 123);
+ }
+ test_vi(a2, -123, 123);
+ test_cp_unalnsrc(a1, a2);
+ for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+ errn += verify("test_cp_unalnsrc: a1", i, a1[i], -123);
+ }
+ for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_cp_unalnsrc: a1", i, a1[i], 123);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ test_2ci_unaln(a1, a2);
+ for (int i=0; i<UNALIGN_OFF; i++) {
+ errn += verify("test_2ci_unaln: a1", i, a1[i], -1);
+ }
+ for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2ci_unaln: a1", i, a1[i], -123);
+ }
+ for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+ errn += verify("test_2ci_unaln: a2", i, a2[i], -103);
+ }
+ for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2ci_unaln: a2", i, a2[i], -1);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ test_2vi_unaln(a1, a2, 123, 103);
+ for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+ errn += verify("test_2vi_unaln: a1", i, a1[i], 123);
+ }
+ for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2vi_unaln: a1", i, a1[i], -1);
+ }
+ for (int i=0; i<UNALIGN_OFF; i++) {
+ errn += verify("test_2vi_unaln: a2", i, a2[i], -1);
+ }
+ for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2vi_unaln: a2", i, a2[i], 103);
+ }
+
+ // Reset for aligned overlap initialization
+ for (int i=0; i<ALIGN_OFF; i++) {
+ a1[i] = i;
+ }
+ for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+ a1[i] = -1;
+ }
+ test_cp_alndst(a1, a1);
+ for (int i=0; i<ARRLEN; i++) {
+ int v = i%ALIGN_OFF;
+ errn += verify("test_cp_alndst_overlap: a1", i, a1[i], v);
+ }
+ for (int i=0; i<ALIGN_OFF; i++) {
+ a1[i+ALIGN_OFF] = -1;
+ }
+ test_cp_alnsrc(a1, a1);
+ for (int i=0; i<ALIGN_OFF; i++) {
+ errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], -1);
+ }
+ for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+ int v = i%ALIGN_OFF;
+ errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], v);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ }
+ test_2ci_aln(a1, a1);
+ for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+ errn += verify("test_2ci_aln_overlap: a1", i, a1[i], -103);
+ }
+ for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2ci_aln_overlap: a1", i, a1[i], -123);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ }
+ test_2vi_aln(a1, a1, 123, 103);
+ for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+ errn += verify("test_2vi_aln_overlap: a1", i, a1[i], 123);
+ }
+ for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2vi_aln_overlap: a1", i, a1[i], 103);
+ }
+
+ // Reset for unaligned overlap initialization
+ for (int i=0; i<UNALIGN_OFF; i++) {
+ a1[i] = i;
+ }
+ for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+ a1[i] = -1;
+ }
+ test_cp_unalndst(a1, a1);
+ for (int i=0; i<ARRLEN; i++) {
+ int v = i%UNALIGN_OFF;
+ errn += verify("test_cp_unalndst_overlap: a1", i, a1[i], v);
+ }
+ for (int i=0; i<UNALIGN_OFF; i++) {
+ a1[i+UNALIGN_OFF] = -1;
+ }
+ test_cp_unalnsrc(a1, a1);
+ for (int i=0; i<UNALIGN_OFF; i++) {
+ errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], -1);
+ }
+ for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+ int v = i%UNALIGN_OFF;
+ errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], v);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ }
+ test_2ci_unaln(a1, a1);
+ for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+ errn += verify("test_2ci_unaln_overlap: a1", i, a1[i], -103);
+ }
+ for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2ci_unaln_overlap: a1", i, a1[i], -123);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ }
+ test_2vi_unaln(a1, a1, 123, 103);
+ for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+ errn += verify("test_2vi_unaln_overlap: a1", i, a1[i], 123);
+ }
+ for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2vi_unaln_overlap: a1", i, a1[i], 103);
+ }
+
+ }
+
+ if (errn > 0 || test_only)
+ return errn;
+
+ // Initialize
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ System.out.println("Time");
+ long start, end;
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_ci(a1);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_ci: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_vi(a2, 123, -1);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_vi: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_ci_neg(a1, 123);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_ci_neg: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_vi_neg(a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_vi_neg: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_neg(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_neg: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_neg(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_neg: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_neg(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_neg: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_ci_oppos(a1, 123);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_ci_oppos: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_vi_oppos(a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_vi_oppos: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_oppos(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_oppos: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_oppos(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_oppos: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_oppos(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_oppos: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_ci_off(a1, 123);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_ci_off: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_vi_off(a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_vi_off: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_off(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_off: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_off(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_off: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_off(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_off: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_ci_inv(a1, OFFSET, 123);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_ci_inv: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_vi_inv(a2, 123, OFFSET, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_vi_inv: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_inv(a1, a2, OFFSET);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_inv: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_inv(a1, a2, OFFSET);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_inv: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_inv(a1, a2, 123, 103, OFFSET);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_inv: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_ci_scl(a1, 123);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_ci_scl: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_vi_scl(a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_vi_scl: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_scl(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_scl: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_scl(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_scl: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_scl(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_scl: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_alndst(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_alndst: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_alnsrc(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_alnsrc: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_aln(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_aln: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_aln(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_aln: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_unalndst(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_unalndst: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_unalnsrc(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_unalnsrc: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_unaln(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_unaln: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_unaln(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_unaln: " + (end - start));
+
+ return errn;
+ }
+
+ private final static long byte_offset(int i) {
+ return ((long)i << 2) + BASE;
+ }
+
+ static void test_ci(int[] a) {
+ for (int i = 0; i < ARRLEN; i+=1) {
+ unsafe.putOrderedInt(a, byte_offset(i), -123);
+ }
+ }
+ static void test_vi(int[] a, int b, int old) {
+ for (int i = 0; i < ARRLEN; i+=1) {
+ unsafe.putOrderedInt(a, byte_offset(i), b);
+ }
+ }
+ static void test_cp(int[] a, int[] b) {
+ for (int i = 0; i < ARRLEN; i+=1) {
+ unsafe.putOrderedInt(a, byte_offset(i), b[i]);
+ }
+ }
+ static void test_2ci(int[] a, int[] b) {
+ for (int i = 0; i < ARRLEN; i+=1) {
+ unsafe.putOrderedInt(a, byte_offset(i), -123);
+ unsafe.putOrderedInt(b, byte_offset(i), -103);
+ }
+ }
+ static void test_2vi(int[] a, int[] b, int c, int d) {
+ for (int i = 0; i < ARRLEN; i+=1) {
+ unsafe.putOrderedInt(a, byte_offset(i), c);
+ unsafe.putOrderedInt(b, byte_offset(i), d);
+ }
+ }
+ static void test_ci_neg(int[] a, int old) {
+ for (int i = ARRLEN-1; i >= 0; i-=1) {
+ unsafe.putOrderedInt(a, byte_offset(i), -123);
+ }
+ }
+ static void test_vi_neg(int[] a, int b, int old) {
+ for (int i = ARRLEN-1; i >= 0; i-=1) {
+ unsafe.putOrderedInt(a, byte_offset(i), b);
+ }
+ }
+ static void test_cp_neg(int[] a, int[] b) {
+ for (int i = ARRLEN-1; i >= 0; i-=1) {
+ unsafe.putOrderedInt(a, byte_offset(i), b[i]);
+ }
+ }
+ static void test_2ci_neg(int[] a, int[] b) {
+ for (int i = ARRLEN-1; i >= 0; i-=1) {
+ unsafe.putOrderedInt(a, byte_offset(i), -123);
+ unsafe.putOrderedInt(b, byte_offset(i), -103);
+ }
+ }
+ static void test_2vi_neg(int[] a, int[] b, int c, int d) {
+ for (int i = ARRLEN-1; i >= 0; i-=1) {
+ unsafe.putOrderedInt(a, byte_offset(i), c);
+ unsafe.putOrderedInt(b, byte_offset(i), d);
+ }
+ }
+ static void test_ci_oppos(int[] a, int old) {
+ int limit = ARRLEN-1;
+ for (int i = 0; i < ARRLEN; i+=1) {
+ unsafe.putOrderedInt(a, byte_offset(limit-i), -123);
+ }
+ }
+ static void test_vi_oppos(int[] a, int b, int old) {
+ int limit = ARRLEN-1;
+ for (int i = limit; i >= 0; i-=1) {
+ unsafe.putOrderedInt(a, byte_offset(limit-i), b);
+ }
+ }
+ static void test_cp_oppos(int[] a, int[] b) {
+ int limit = ARRLEN-1;
+ for (int i = 0; i < ARRLEN; i+=1) {
+ unsafe.putOrderedInt(a, byte_offset(i), b[limit-i]);
+ }
+ }
+ static void test_2ci_oppos(int[] a, int[] b) {
+ int limit = ARRLEN-1;
+ for (int i = 0; i < ARRLEN; i+=1) {
+ unsafe.putOrderedInt(a, byte_offset(limit-i), -123);
+ unsafe.putOrderedInt(b, byte_offset(i), -103);
+ }
+ }
+ static void test_2vi_oppos(int[] a, int[] b, int c, int d) {
+ int limit = ARRLEN-1;
+ for (int i = limit; i >= 0; i-=1) {
+ unsafe.putOrderedInt(a, byte_offset(i), c);
+ unsafe.putOrderedInt(b, byte_offset(limit-i), d);
+ }
+ }
+ static void test_ci_off(int[] a, int old) {
+ for (int i = 0; i < ARRLEN-OFFSET; i+=1) {
+ unsafe.putOrderedInt(a, byte_offset(i+OFFSET), -123);
+ }
+ }
+ static void test_vi_off(int[] a, int b, int old) {
+ for (int i = 0; i < ARRLEN-OFFSET; i+=1) {
+ unsafe.putOrderedInt(a, byte_offset(i+OFFSET), b);
+ }
+ }
+ static void test_cp_off(int[] a, int[] b) {
+ for (int i = 0; i < ARRLEN-OFFSET; i+=1) {
+ unsafe.putOrderedInt(a, byte_offset(i+OFFSET), b[i+OFFSET]);
+ }
+ }
+ static void test_2ci_off(int[] a, int[] b) {
+ for (int i = 0; i < ARRLEN-OFFSET; i+=1) {
+ unsafe.putOrderedInt(a, byte_offset(i+OFFSET), -123);
+ unsafe.putOrderedInt(b, byte_offset(i+OFFSET), -103);
+ }
+ }
+ static void test_2vi_off(int[] a, int[] b, int c, int d) {
+ for (int i = 0; i < ARRLEN-OFFSET; i+=1) {
+ unsafe.putOrderedInt(a, byte_offset(i+OFFSET), c);
+ unsafe.putOrderedInt(b, byte_offset(i+OFFSET), d);
+ }
+ }
+ static void test_ci_inv(int[] a, int k, int old) {
+ for (int i = 0; i < ARRLEN-k; i+=1) {
+ unsafe.putOrderedInt(a, byte_offset(i+k), -123);
+ }
+ }
+ static void test_vi_inv(int[] a, int b, int k, int old) {
+ for (int i = 0; i < ARRLEN-k; i+=1) {
+ unsafe.putOrderedInt(a, byte_offset(i+k), b);
+ }
+ }
+ static void test_cp_inv(int[] a, int[] b, int k) {
+ for (int i = 0; i < ARRLEN-k; i+=1) {
+ unsafe.putOrderedInt(a, byte_offset(i+k), b[i+k]);
+ }
+ }
+ static void test_2ci_inv(int[] a, int[] b, int k) {
+ for (int i = 0; i < ARRLEN-k; i+=1) {
+ unsafe.putOrderedInt(a, byte_offset(i+k), -123);
+ unsafe.putOrderedInt(b, byte_offset(i+k), -103);
+ }
+ }
+ static void test_2vi_inv(int[] a, int[] b, int c, int d, int k) {
+ for (int i = 0; i < ARRLEN-k; i+=1) {
+ unsafe.putOrderedInt(a, byte_offset(i+k), c);
+ unsafe.putOrderedInt(b, byte_offset(i+k), d);
+ }
+ }
+ static void test_ci_scl(int[] a, int old) {
+ for (int i = 0; i*SCALE < ARRLEN; i+=1) {
+ unsafe.putOrderedInt(a, byte_offset(i*SCALE), -123);
+ }
+ }
+ static void test_vi_scl(int[] a, int b, int old) {
+ for (int i = 0; i*SCALE < ARRLEN; i+=1) {
+ unsafe.putOrderedInt(a, byte_offset(i*SCALE), b);
+ }
+ }
+ static void test_cp_scl(int[] a, int[] b) {
+ for (int i = 0; i*SCALE < ARRLEN; i+=1) {
+ unsafe.putOrderedInt(a, byte_offset(i*SCALE), b[i*SCALE]);
+ }
+ }
+ static void test_2ci_scl(int[] a, int[] b) {
+ for (int i = 0; i*SCALE < ARRLEN; i+=1) {
+ unsafe.putOrderedInt(a, byte_offset(i*SCALE), -123);
+ unsafe.putOrderedInt(b, byte_offset(i*SCALE), -103);
+ }
+ }
+ static void test_2vi_scl(int[] a, int[] b, int c, int d) {
+ for (int i = 0; i*SCALE < ARRLEN; i+=1) {
+ unsafe.putOrderedInt(a, byte_offset(i*SCALE), c);
+ unsafe.putOrderedInt(b, byte_offset(i*SCALE), d);
+ }
+ }
+ static void test_cp_alndst(int[] a, int[] b) {
+ for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) {
+ unsafe.putOrderedInt(a, byte_offset(i+ALIGN_OFF), b[i]);
+ }
+ }
+ static void test_cp_alnsrc(int[] a, int[] b) {
+ for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) {
+ unsafe.putOrderedInt(a, byte_offset(i), b[i+ALIGN_OFF]);
+ }
+ }
+ static void test_2ci_aln(int[] a, int[] b) {
+ for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) {
+ unsafe.putOrderedInt(a, byte_offset(i+ALIGN_OFF), -123);
+ unsafe.putOrderedInt(b, byte_offset(i), -103);
+ }
+ }
+ static void test_2vi_aln(int[] a, int[] b, int c, int d) {
+ for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) {
+ unsafe.putOrderedInt(a, byte_offset(i), c);
+ unsafe.putOrderedInt(b, byte_offset(i+ALIGN_OFF), d);
+ }
+ }
+ static void test_cp_unalndst(int[] a, int[] b) {
+ for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) {
+ unsafe.putOrderedInt(a, byte_offset(i+UNALIGN_OFF), b[i]);
+ }
+ }
+ static void test_cp_unalnsrc(int[] a, int[] b) {
+ for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) {
+ unsafe.putOrderedInt(a, byte_offset(i), b[i+UNALIGN_OFF]);
+ }
+ }
+ static void test_2ci_unaln(int[] a, int[] b) {
+ for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) {
+ unsafe.putOrderedInt(a, byte_offset(i+UNALIGN_OFF), -123);
+ unsafe.putOrderedInt(b, byte_offset(i), -103);
+ }
+ }
+ static void test_2vi_unaln(int[] a, int[] b, int c, int d) {
+ for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) {
+ unsafe.putOrderedInt(a, byte_offset(i), c);
+ unsafe.putOrderedInt(b, byte_offset(i+UNALIGN_OFF), d);
+ }
+ }
+
+ static int verify(String text, int i, int elem, int val) {
+ if (elem != val) {
+ System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+ return 1;
+ }
+ return 0;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/8004867/TestIntUnsafeVolatile.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,990 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8004867
+ * @summary VM crashing with assert "share/vm/opto/node.hpp:357 - assert(i < _max) failed: oob"
+ *
+ * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestIntUnsafeVolatile
+ * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:+OptimizeFill TestIntUnsafeVolatile
+ */
+
+import sun.misc.Unsafe;
+import java.lang.reflect.*;
+
+public class TestIntUnsafeVolatile {
+ private static final int ARRLEN = 97;
+ private static final int ITERS = 11000;
+ private static final int OFFSET = 3;
+ private static final int SCALE = 2;
+ private static final int ALIGN_OFF = 8;
+ private static final int UNALIGN_OFF = 5;
+
+ private static final Unsafe unsafe;
+ private static final int BASE;
+ static {
+ try {
+ Class c = TestIntUnsafeVolatile.class.getClassLoader().loadClass("sun.misc.Unsafe");
+ Field f = c.getDeclaredField("theUnsafe");
+ f.setAccessible(true);
+ unsafe = (Unsafe)f.get(c);
+ BASE = unsafe.arrayBaseOffset(int[].class);
+ } catch (Exception e) {
+ InternalError err = new InternalError();
+ err.initCause(e);
+ throw err;
+ }
+ }
+
+ public static void main(String args[]) {
+ System.out.println("Testing Integer array unsafe volatile operations");
+ int errn = test(false);
+ if (errn > 0) {
+ System.err.println("FAILED: " + errn + " errors");
+ System.exit(97);
+ }
+ System.out.println("PASSED");
+ }
+
+ static int test(boolean test_only) {
+ int[] a1 = new int[ARRLEN];
+ int[] a2 = new int[ARRLEN];
+ // Initialize
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ System.out.println("Warmup");
+ for (int i=0; i<ITERS; i++) {
+ test_ci(a1);
+ test_vi(a2, 123, -1);
+ test_cp(a1, a2);
+ test_2ci(a1, a2);
+ test_2vi(a1, a2, 123, 103);
+ test_ci_neg(a1, 123);
+ test_vi_neg(a2, 123, 103);
+ test_cp_neg(a1, a2);
+ test_2ci_neg(a1, a2);
+ test_2vi_neg(a1, a2, 123, 103);
+ test_ci_oppos(a1, 123);
+ test_vi_oppos(a2, 123, 103);
+ test_cp_oppos(a1, a2);
+ test_2ci_oppos(a1, a2);
+ test_2vi_oppos(a1, a2, 123, 103);
+ test_ci_off(a1, 123);
+ test_vi_off(a2, 123, 103);
+ test_cp_off(a1, a2);
+ test_2ci_off(a1, a2);
+ test_2vi_off(a1, a2, 123, 103);
+ test_ci_inv(a1, OFFSET, 123);
+ test_vi_inv(a2, 123, OFFSET, 103);
+ test_cp_inv(a1, a2, OFFSET);
+ test_2ci_inv(a1, a2, OFFSET);
+ test_2vi_inv(a1, a2, 123, 103, OFFSET);
+ test_ci_scl(a1, 123);
+ test_vi_scl(a2, 123, 103);
+ test_cp_scl(a1, a2);
+ test_2ci_scl(a1, a2);
+ test_2vi_scl(a1, a2, 123, 103);
+ test_cp_alndst(a1, a2);
+ test_cp_alnsrc(a1, a2);
+ test_2ci_aln(a1, a2);
+ test_2vi_aln(a1, a2, 123, 103);
+ test_cp_unalndst(a1, a2);
+ test_cp_unalnsrc(a1, a2);
+ test_2ci_unaln(a1, a2);
+ test_2vi_unaln(a1, a2, 123, 103);
+ }
+ // Initialize
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ // Test and verify results
+ System.out.println("Verification");
+ int errn = 0;
+ {
+ test_ci(a1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_ci: a1", i, a1[i], -123);
+ }
+ test_vi(a2, 123, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_vi: a2", i, a2[i], 123);
+ }
+ test_cp(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_cp: a1", i, a1[i], 123);
+ }
+ test_2ci(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_2ci: a1", i, a1[i], -123);
+ errn += verify("test_2ci: a2", i, a2[i], -103);
+ }
+ test_2vi(a1, a2, 123, 103);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_2vi: a1", i, a1[i], 123);
+ errn += verify("test_2vi: a2", i, a2[i], 103);
+ }
+ // Reset for negative stride
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ test_ci_neg(a1, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_ci_neg: a1", i, a1[i], -123);
+ }
+ test_vi_neg(a2, 123, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_vi_neg: a2", i, a2[i], 123);
+ }
+ test_cp_neg(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_cp_neg: a1", i, a1[i], 123);
+ }
+ test_2ci_neg(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_2ci_neg: a1", i, a1[i], -123);
+ errn += verify("test_2ci_neg: a2", i, a2[i], -103);
+ }
+ test_2vi_neg(a1, a2, 123, 103);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_2vi_neg: a1", i, a1[i], 123);
+ errn += verify("test_2vi_neg: a2", i, a2[i], 103);
+ }
+ // Reset for opposite stride
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ test_ci_oppos(a1, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_ci_oppos: a1", i, a1[i], -123);
+ }
+ test_vi_oppos(a2, 123, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_vi_oppos: a2", i, a2[i], 123);
+ }
+ test_cp_oppos(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_cp_oppos: a1", i, a1[i], 123);
+ }
+ test_2ci_oppos(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_2ci_oppos: a1", i, a1[i], -123);
+ errn += verify("test_2ci_oppos: a2", i, a2[i], -103);
+ }
+ test_2vi_oppos(a1, a2, 123, 103);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_2vi_oppos: a1", i, a1[i], 123);
+ errn += verify("test_2vi_oppos: a2", i, a2[i], 103);
+ }
+ // Reset for indexing with offset
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ test_ci_off(a1, -1);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_ci_off: a1", i, a1[i], -123);
+ }
+ test_vi_off(a2, 123, -1);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_vi_off: a2", i, a2[i], 123);
+ }
+ test_cp_off(a1, a2);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_cp_off: a1", i, a1[i], 123);
+ }
+ test_2ci_off(a1, a2);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_2ci_off: a1", i, a1[i], -123);
+ errn += verify("test_2ci_off: a2", i, a2[i], -103);
+ }
+ test_2vi_off(a1, a2, 123, 103);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_2vi_off: a1", i, a1[i], 123);
+ errn += verify("test_2vi_off: a2", i, a2[i], 103);
+ }
+ for (int i=0; i<OFFSET; i++) {
+ errn += verify("test_2vi_off: a1", i, a1[i], -1);
+ errn += verify("test_2vi_off: a2", i, a2[i], -1);
+ }
+ // Reset for indexing with invariant offset
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ test_ci_inv(a1, OFFSET, -1);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_ci_inv: a1", i, a1[i], -123);
+ }
+ test_vi_inv(a2, 123, OFFSET, -1);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_vi_inv: a2", i, a2[i], 123);
+ }
+ test_cp_inv(a1, a2, OFFSET);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_cp_inv: a1", i, a1[i], 123);
+ }
+ test_2ci_inv(a1, a2, OFFSET);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_2ci_inv: a1", i, a1[i], -123);
+ errn += verify("test_2ci_inv: a2", i, a2[i], -103);
+ }
+ test_2vi_inv(a1, a2, 123, 103, OFFSET);
+ for (int i=OFFSET; i<ARRLEN; i++) {
+ errn += verify("test_2vi_inv: a1", i, a1[i], 123);
+ errn += verify("test_2vi_inv: a2", i, a2[i], 103);
+ }
+ for (int i=0; i<OFFSET; i++) {
+ errn += verify("test_2vi_inv: a1", i, a1[i], -1);
+ errn += verify("test_2vi_inv: a2", i, a2[i], -1);
+ }
+ // Reset for indexing with scale
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ test_ci_scl(a1, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ int val = (i%SCALE != 0) ? -1 : -123;
+ errn += verify("test_ci_scl: a1", i, a1[i], val);
+ }
+ test_vi_scl(a2, 123, -1);
+ for (int i=0; i<ARRLEN; i++) {
+ int val = (i%SCALE != 0) ? -1 : 123;
+ errn += verify("test_vi_scl: a2", i, a2[i], val);
+ }
+ test_cp_scl(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ int val = (i%SCALE != 0) ? -1 : 123;
+ errn += verify("test_cp_scl: a1", i, a1[i], val);
+ }
+ test_2ci_scl(a1, a2);
+ for (int i=0; i<ARRLEN; i++) {
+ if (i%SCALE != 0) {
+ errn += verify("test_2ci_scl: a1", i, a1[i], -1);
+ } else if (i*SCALE < ARRLEN) {
+ errn += verify("test_2ci_scl: a1", i*SCALE, a1[i*SCALE], -123);
+ }
+ if (i%SCALE != 0) {
+ errn += verify("test_2ci_scl: a2", i, a2[i], -1);
+ } else if (i*SCALE < ARRLEN) {
+ errn += verify("test_2ci_scl: a2", i*SCALE, a2[i*SCALE], -103);
+ }
+ }
+ test_2vi_scl(a1, a2, 123, 103);
+ for (int i=0; i<ARRLEN; i++) {
+ if (i%SCALE != 0) {
+ errn += verify("test_2vi_scl: a1", i, a1[i], -1);
+ } else if (i*SCALE < ARRLEN) {
+ errn += verify("test_2vi_scl: a1", i*SCALE, a1[i*SCALE], 123);
+ }
+ if (i%SCALE != 0) {
+ errn += verify("test_2vi_scl: a2", i, a2[i], -1);
+ } else if (i*SCALE < ARRLEN) {
+ errn += verify("test_2vi_scl: a2", i*SCALE, a2[i*SCALE], 103);
+ }
+ }
+ // Reset for 2 arrays with relative aligned offset
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ test_vi(a2, 123, -1);
+ test_cp_alndst(a1, a2);
+ for (int i=0; i<ALIGN_OFF; i++) {
+ errn += verify("test_cp_alndst: a1", i, a1[i], -1);
+ }
+ for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_cp_alndst: a1", i, a1[i], 123);
+ }
+ for (int i=0; i<ALIGN_OFF; i++) {
+ a1[i] = 123;
+ }
+ test_vi(a2, -123, 123);
+ test_cp_alnsrc(a1, a2);
+ for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+ errn += verify("test_cp_alnsrc: a1", i, a1[i], -123);
+ }
+ for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_cp_alnsrc: a1", i, a1[i], 123);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ test_2ci_aln(a1, a2);
+ for (int i=0; i<ALIGN_OFF; i++) {
+ errn += verify("test_2ci_aln: a1", i, a1[i], -1);
+ }
+ for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2ci_aln: a1", i, a1[i], -123);
+ }
+ for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+ errn += verify("test_2ci_aln: a2", i, a2[i], -103);
+ }
+ for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2ci_aln: a2", i, a2[i], -1);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ test_2vi_aln(a1, a2, 123, 103);
+ for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+ errn += verify("test_2vi_aln: a1", i, a1[i], 123);
+ }
+ for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2vi_aln: a1", i, a1[i], -1);
+ }
+ for (int i=0; i<ALIGN_OFF; i++) {
+ errn += verify("test_2vi_aln: a2", i, a2[i], -1);
+ }
+ for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2vi_aln: a2", i, a2[i], 103);
+ }
+
+ // Reset for 2 arrays with relative unaligned offset
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ test_vi(a2, 123, -1);
+ test_cp_unalndst(a1, a2);
+ for (int i=0; i<UNALIGN_OFF; i++) {
+ errn += verify("test_cp_unalndst: a1", i, a1[i], -1);
+ }
+ for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_cp_unalndst: a1", i, a1[i], 123);
+ }
+ test_vi(a2, -123, 123);
+ test_cp_unalnsrc(a1, a2);
+ for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+ errn += verify("test_cp_unalnsrc: a1", i, a1[i], -123);
+ }
+ for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_cp_unalnsrc: a1", i, a1[i], 123);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ test_2ci_unaln(a1, a2);
+ for (int i=0; i<UNALIGN_OFF; i++) {
+ errn += verify("test_2ci_unaln: a1", i, a1[i], -1);
+ }
+ for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2ci_unaln: a1", i, a1[i], -123);
+ }
+ for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+ errn += verify("test_2ci_unaln: a2", i, a2[i], -103);
+ }
+ for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2ci_unaln: a2", i, a2[i], -1);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ test_2vi_unaln(a1, a2, 123, 103);
+ for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+ errn += verify("test_2vi_unaln: a1", i, a1[i], 123);
+ }
+ for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2vi_unaln: a1", i, a1[i], -1);
+ }
+ for (int i=0; i<UNALIGN_OFF; i++) {
+ errn += verify("test_2vi_unaln: a2", i, a2[i], -1);
+ }
+ for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2vi_unaln: a2", i, a2[i], 103);
+ }
+
+ // Reset for aligned overlap initialization
+ for (int i=0; i<ALIGN_OFF; i++) {
+ a1[i] = i;
+ }
+ for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+ a1[i] = -1;
+ }
+ test_cp_alndst(a1, a1);
+ for (int i=0; i<ARRLEN; i++) {
+ int v = i%ALIGN_OFF;
+ errn += verify("test_cp_alndst_overlap: a1", i, a1[i], v);
+ }
+ for (int i=0; i<ALIGN_OFF; i++) {
+ a1[i+ALIGN_OFF] = -1;
+ }
+ test_cp_alnsrc(a1, a1);
+ for (int i=0; i<ALIGN_OFF; i++) {
+ errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], -1);
+ }
+ for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+ int v = i%ALIGN_OFF;
+ errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], v);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ }
+ test_2ci_aln(a1, a1);
+ for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+ errn += verify("test_2ci_aln_overlap: a1", i, a1[i], -103);
+ }
+ for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2ci_aln_overlap: a1", i, a1[i], -123);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ }
+ test_2vi_aln(a1, a1, 123, 103);
+ for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+ errn += verify("test_2vi_aln_overlap: a1", i, a1[i], 123);
+ }
+ for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2vi_aln_overlap: a1", i, a1[i], 103);
+ }
+
+ // Reset for unaligned overlap initialization
+ for (int i=0; i<UNALIGN_OFF; i++) {
+ a1[i] = i;
+ }
+ for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+ a1[i] = -1;
+ }
+ test_cp_unalndst(a1, a1);
+ for (int i=0; i<ARRLEN; i++) {
+ int v = i%UNALIGN_OFF;
+ errn += verify("test_cp_unalndst_overlap: a1", i, a1[i], v);
+ }
+ for (int i=0; i<UNALIGN_OFF; i++) {
+ a1[i+UNALIGN_OFF] = -1;
+ }
+ test_cp_unalnsrc(a1, a1);
+ for (int i=0; i<UNALIGN_OFF; i++) {
+ errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], -1);
+ }
+ for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+ int v = i%UNALIGN_OFF;
+ errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], v);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ }
+ test_2ci_unaln(a1, a1);
+ for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+ errn += verify("test_2ci_unaln_overlap: a1", i, a1[i], -103);
+ }
+ for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2ci_unaln_overlap: a1", i, a1[i], -123);
+ }
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ }
+ test_2vi_unaln(a1, a1, 123, 103);
+ for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+ errn += verify("test_2vi_unaln_overlap: a1", i, a1[i], 123);
+ }
+ for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+ errn += verify("test_2vi_unaln_overlap: a1", i, a1[i], 103);
+ }
+
+ }
+
+ if (errn > 0 || test_only)
+ return errn;
+
+ // Initialize
+ for (int i=0; i<ARRLEN; i++) {
+ a1[i] = -1;
+ a2[i] = -1;
+ }
+ System.out.println("Time");
+ long start, end;
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_ci(a1);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_ci: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_vi(a2, 123, -1);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_vi: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_ci_neg(a1, 123);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_ci_neg: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_vi_neg(a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_vi_neg: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_neg(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_neg: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_neg(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_neg: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_neg(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_neg: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_ci_oppos(a1, 123);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_ci_oppos: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_vi_oppos(a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_vi_oppos: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_oppos(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_oppos: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_oppos(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_oppos: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_oppos(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_oppos: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_ci_off(a1, 123);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_ci_off: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_vi_off(a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_vi_off: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_off(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_off: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_off(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_off: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_off(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_off: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_ci_inv(a1, OFFSET, 123);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_ci_inv: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_vi_inv(a2, 123, OFFSET, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_vi_inv: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_inv(a1, a2, OFFSET);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_inv: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_inv(a1, a2, OFFSET);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_inv: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_inv(a1, a2, 123, 103, OFFSET);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_inv: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_ci_scl(a1, 123);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_ci_scl: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_vi_scl(a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_vi_scl: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_scl(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_scl: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_scl(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_scl: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_scl(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_scl: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_alndst(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_alndst: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_alnsrc(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_alnsrc: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_aln(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_aln: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_aln(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_aln: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_unalndst(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_unalndst: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_cp_unalnsrc(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_cp_unalnsrc: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2ci_unaln(a1, a2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2ci_unaln: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_2vi_unaln(a1, a2, 123, 103);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_2vi_unaln: " + (end - start));
+
+ return errn;
+ }
+
+ private final static long byte_offset(int i) {
+ return ((long)i << 2) + BASE;
+ }
+
+ static void test_ci(int[] a) {
+ for (int i = 0; i < ARRLEN; i+=1) {
+ unsafe.putIntVolatile(a, byte_offset(i), -123);
+ }
+ }
+ static void test_vi(int[] a, int b, int old) {
+ for (int i = 0; i < ARRLEN; i+=1) {
+ unsafe.putIntVolatile(a, byte_offset(i), b);
+ }
+ }
+ static void test_cp(int[] a, int[] b) {
+ for (int i = 0; i < ARRLEN; i+=1) {
+ unsafe.putIntVolatile(a, byte_offset(i), b[i]);
+ }
+ }
+ static void test_2ci(int[] a, int[] b) {
+ for (int i = 0; i < ARRLEN; i+=1) {
+ unsafe.putIntVolatile(a, byte_offset(i), -123);
+ unsafe.putIntVolatile(b, byte_offset(i), -103);
+ }
+ }
+ static void test_2vi(int[] a, int[] b, int c, int d) {
+ for (int i = 0; i < ARRLEN; i+=1) {
+ unsafe.putIntVolatile(a, byte_offset(i), c);
+ unsafe.putIntVolatile(b, byte_offset(i), d);
+ }
+ }
+ static void test_ci_neg(int[] a, int old) {
+ for (int i = ARRLEN-1; i >= 0; i-=1) {
+ unsafe.putIntVolatile(a, byte_offset(i), -123);
+ }
+ }
+ static void test_vi_neg(int[] a, int b, int old) {
+ for (int i = ARRLEN-1; i >= 0; i-=1) {
+ unsafe.putIntVolatile(a, byte_offset(i), b);
+ }
+ }
+ static void test_cp_neg(int[] a, int[] b) {
+ for (int i = ARRLEN-1; i >= 0; i-=1) {
+ unsafe.putIntVolatile(a, byte_offset(i), b[i]);
+ }
+ }
+ static void test_2ci_neg(int[] a, int[] b) {
+ for (int i = ARRLEN-1; i >= 0; i-=1) {
+ unsafe.putIntVolatile(a, byte_offset(i), -123);
+ unsafe.putIntVolatile(b, byte_offset(i), -103);
+ }
+ }
+ static void test_2vi_neg(int[] a, int[] b, int c, int d) {
+ for (int i = ARRLEN-1; i >= 0; i-=1) {
+ unsafe.putIntVolatile(a, byte_offset(i), c);
+ unsafe.putIntVolatile(b, byte_offset(i), d);
+ }
+ }
+ static void test_ci_oppos(int[] a, int old) {
+ int limit = ARRLEN-1;
+ for (int i = 0; i < ARRLEN; i+=1) {
+ unsafe.putIntVolatile(a, byte_offset(limit-i), -123);
+ }
+ }
+ static void test_vi_oppos(int[] a, int b, int old) {
+ int limit = ARRLEN-1;
+ for (int i = limit; i >= 0; i-=1) {
+ unsafe.putIntVolatile(a, byte_offset(limit-i), b);
+ }
+ }
+ static void test_cp_oppos(int[] a, int[] b) {
+ int limit = ARRLEN-1;
+ for (int i = 0; i < ARRLEN; i+=1) {
+ unsafe.putIntVolatile(a, byte_offset(i), b[limit-i]);
+ }
+ }
+ static void test_2ci_oppos(int[] a, int[] b) {
+ int limit = ARRLEN-1;
+ for (int i = 0; i < ARRLEN; i+=1) {
+ unsafe.putIntVolatile(a, byte_offset(limit-i), -123);
+ unsafe.putIntVolatile(b, byte_offset(i), -103);
+ }
+ }
+ static void test_2vi_oppos(int[] a, int[] b, int c, int d) {
+ int limit = ARRLEN-1;
+ for (int i = limit; i >= 0; i-=1) {
+ unsafe.putIntVolatile(a, byte_offset(i), c);
+ unsafe.putIntVolatile(b, byte_offset(limit-i), d);
+ }
+ }
+ static void test_ci_off(int[] a, int old) {
+ for (int i = 0; i < ARRLEN-OFFSET; i+=1) {
+ unsafe.putIntVolatile(a, byte_offset(i+OFFSET), -123);
+ }
+ }
+ static void test_vi_off(int[] a, int b, int old) {
+ for (int i = 0; i < ARRLEN-OFFSET; i+=1) {
+ unsafe.putIntVolatile(a, byte_offset(i+OFFSET), b);
+ }
+ }
+ static void test_cp_off(int[] a, int[] b) {
+ for (int i = 0; i < ARRLEN-OFFSET; i+=1) {
+ unsafe.putIntVolatile(a, byte_offset(i+OFFSET), b[i+OFFSET]);
+ }
+ }
+ static void test_2ci_off(int[] a, int[] b) {
+ for (int i = 0; i < ARRLEN-OFFSET; i+=1) {
+ unsafe.putIntVolatile(a, byte_offset(i+OFFSET), -123);
+ unsafe.putIntVolatile(b, byte_offset(i+OFFSET), -103);
+ }
+ }
+ static void test_2vi_off(int[] a, int[] b, int c, int d) {
+ for (int i = 0; i < ARRLEN-OFFSET; i+=1) {
+ unsafe.putIntVolatile(a, byte_offset(i+OFFSET), c);
+ unsafe.putIntVolatile(b, byte_offset(i+OFFSET), d);
+ }
+ }
+ static void test_ci_inv(int[] a, int k, int old) {
+ for (int i = 0; i < ARRLEN-k; i+=1) {
+ unsafe.putIntVolatile(a, byte_offset(i+k), -123);
+ }
+ }
+ static void test_vi_inv(int[] a, int b, int k, int old) {
+ for (int i = 0; i < ARRLEN-k; i+=1) {
+ unsafe.putIntVolatile(a, byte_offset(i+k), b);
+ }
+ }
+ static void test_cp_inv(int[] a, int[] b, int k) {
+ for (int i = 0; i < ARRLEN-k; i+=1) {
+ unsafe.putIntVolatile(a, byte_offset(i+k), b[i+k]);
+ }
+ }
+ static void test_2ci_inv(int[] a, int[] b, int k) {
+ for (int i = 0; i < ARRLEN-k; i+=1) {
+ unsafe.putIntVolatile(a, byte_offset(i+k), -123);
+ unsafe.putIntVolatile(b, byte_offset(i+k), -103);
+ }
+ }
+ static void test_2vi_inv(int[] a, int[] b, int c, int d, int k) {
+ for (int i = 0; i < ARRLEN-k; i+=1) {
+ unsafe.putIntVolatile(a, byte_offset(i+k), c);
+ unsafe.putIntVolatile(b, byte_offset(i+k), d);
+ }
+ }
+ static void test_ci_scl(int[] a, int old) {
+ for (int i = 0; i*SCALE < ARRLEN; i+=1) {
+ unsafe.putIntVolatile(a, byte_offset(i*SCALE), -123);
+ }
+ }
+ static void test_vi_scl(int[] a, int b, int old) {
+ for (int i = 0; i*SCALE < ARRLEN; i+=1) {
+ unsafe.putIntVolatile(a, byte_offset(i*SCALE), b);
+ }
+ }
+ static void test_cp_scl(int[] a, int[] b) {
+ for (int i = 0; i*SCALE < ARRLEN; i+=1) {
+ unsafe.putIntVolatile(a, byte_offset(i*SCALE), b[i*SCALE]);
+ }
+ }
+ static void test_2ci_scl(int[] a, int[] b) {
+ for (int i = 0; i*SCALE < ARRLEN; i+=1) {
+ unsafe.putIntVolatile(a, byte_offset(i*SCALE), -123);
+ unsafe.putIntVolatile(b, byte_offset(i*SCALE), -103);
+ }
+ }
+ static void test_2vi_scl(int[] a, int[] b, int c, int d) {
+ for (int i = 0; i*SCALE < ARRLEN; i+=1) {
+ unsafe.putIntVolatile(a, byte_offset(i*SCALE), c);
+ unsafe.putIntVolatile(b, byte_offset(i*SCALE), d);
+ }
+ }
+ static void test_cp_alndst(int[] a, int[] b) {
+ for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) {
+ unsafe.putIntVolatile(a, byte_offset(i+ALIGN_OFF), b[i]);
+ }
+ }
+ static void test_cp_alnsrc(int[] a, int[] b) {
+ for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) {
+ unsafe.putIntVolatile(a, byte_offset(i), b[i+ALIGN_OFF]);
+ }
+ }
+ static void test_2ci_aln(int[] a, int[] b) {
+ for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) {
+ unsafe.putIntVolatile(a, byte_offset(i+ALIGN_OFF), -123);
+ unsafe.putIntVolatile(b, byte_offset(i), -103);
+ }
+ }
+ static void test_2vi_aln(int[] a, int[] b, int c, int d) {
+ for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) {
+ unsafe.putIntVolatile(a, byte_offset(i), c);
+ unsafe.putIntVolatile(b, byte_offset(i+ALIGN_OFF), d);
+ }
+ }
+ static void test_cp_unalndst(int[] a, int[] b) {
+ for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) {
+ unsafe.putIntVolatile(a, byte_offset(i+UNALIGN_OFF), b[i]);
+ }
+ }
+ static void test_cp_unalnsrc(int[] a, int[] b) {
+ for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) {
+ unsafe.putIntVolatile(a, byte_offset(i), b[i+UNALIGN_OFF]);
+ }
+ }
+ static void test_2ci_unaln(int[] a, int[] b) {
+ for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) {
+ unsafe.putIntVolatile(a, byte_offset(i+UNALIGN_OFF), -123);
+ unsafe.putIntVolatile(b, byte_offset(i), -103);
+ }
+ }
+ static void test_2vi_unaln(int[] a, int[] b, int c, int d) {
+ for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) {
+ unsafe.putIntVolatile(a, byte_offset(i), c);
+ unsafe.putIntVolatile(b, byte_offset(i+UNALIGN_OFF), d);
+ }
+ }
+
+ static int verify(String text, int i, int elem, int val) {
+ if (elem != val) {
+ System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+ return 1;
+ }
+ return 0;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/8007294/Test8007294.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8007294
+ * @summary ReduceFieldZeroing doesn't check for dependent load and can lead to incorrect execution
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline -XX:-UseOnStackReplacement -XX:-BackgroundCompilation Test8007294
+ *
+ */
+
+public class Test8007294 {
+
+ int i1;
+ int i2;
+
+ Test8007294(int i1, int i2) {
+ this.i1 = i1;
+ this.i2 = i2;
+ }
+
+ static int m(int v) {
+ return v;
+ }
+
+ static Test8007294 test1() {
+ Test8007294 obj = new Test8007294(10, 100);
+ int v1 = obj.i1;
+
+ int v3 = m(v1);
+ int v2 = obj.i2;
+ obj.i2 = v3;
+ obj.i1 = v2;
+
+ return obj;
+ }
+
+ static int test2(int i) {
+ int j = 0;
+ if (i > 0) {
+ j = 1;
+ }
+
+ int[] arr = new int[10];
+ arr[0] = 1;
+ arr[1] = 2;
+ int v1 = arr[j];
+ arr[0] = 3;
+ arr[1] = 4;
+
+ return v1;
+ }
+
+ static public void main(String[] args) {
+ boolean failed = false;
+ for (int i = 0; i < 20000; i++) {
+ Test8007294 obj = test1();
+ if (obj.i1 != 100 || obj.i2 != 10) {
+ System.out.println("FAILED test1 obj.i1 = " + obj.i1 +", obj.i2 = " + obj.i2);
+ failed = true;
+ break;
+ }
+ }
+ for (int i = 0; i < 20000; i++) {
+ int res = test2(1);
+ if (res != 2) {
+ System.out.println("FAILED test2 = " + res);
+ failed = true;
+ break;
+ }
+ }
+ if (failed) {
+ System.exit(97);
+ } else {
+ System.out.println("PASSED");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/8007722/Test8007722.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8007722
+ * @summary GetAndSetP's MachNode should capture bottom type
+ * @run main/othervm -XX:-UseOnStackReplacement -XX:-BackgroundCompilation Test8007722
+ *
+ */
+
+import java.util.concurrent.atomic.*;
+
+public class Test8007722 {
+
+ int i;
+ static AtomicReference<Test8007722> ref;
+
+ static int test(Test8007722 new_obj) {
+ Test8007722 o = ref.getAndSet(new_obj);
+ int ret = o.i;
+ o.i = 5;
+ return ret;
+ }
+
+ static public void main(String[] args) {
+ Test8007722 obj = new Test8007722();
+ ref = new AtomicReference<Test8007722>(obj);
+
+ for (int i = 0; i < 20000; i++) {
+ test(obj);
+ }
+
+ System.out.println("PASSED");
+ }
+}
--- a/hotspot/test/compiler/whitebox/DeoptimizeAllTest.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/test/compiler/whitebox/DeoptimizeAllTest.java Fri Mar 15 16:39:07 2013 -0700
@@ -23,9 +23,10 @@
/*
* @test DeoptimizeAllTest
- * @compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI CompilerWhiteBoxTest.java
- * @compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI DeoptimizeAllTest.java
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI DeoptimizeAllTest
+ * @library /testlibrary /testlibrary/whitebox
+ * @build DeoptimizeAllTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI DeoptimizeAllTest
* @author igor.ignatyev@oracle.com
*/
public class DeoptimizeAllTest extends CompilerWhiteBoxTest {
--- a/hotspot/test/compiler/whitebox/DeoptimizeMethodTest.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/test/compiler/whitebox/DeoptimizeMethodTest.java Fri Mar 15 16:39:07 2013 -0700
@@ -23,9 +23,10 @@
/*
* @test DeoptimizeMethodTest
- * @compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI CompilerWhiteBoxTest.java
- * @compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI DeoptimizeMethodTest.java
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI DeoptimizeMethodTest
+ * @library /testlibrary /testlibrary/whitebox
+ * @build DeoptimizeMethodTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI DeoptimizeMethodTest
* @author igor.ignatyev@oracle.com
*/
public class DeoptimizeMethodTest extends CompilerWhiteBoxTest {
--- a/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java Fri Mar 15 16:39:07 2013 -0700
@@ -24,9 +24,10 @@
/*
* @test IsMethodCompilableTest
* @bug 8007270
- * @compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI CompilerWhiteBoxTest.java
- * @compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI IsMethodCompilableTest.java
- * @run main/othervm/timeout=600 -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI IsMethodCompilableTest
+ * @library /testlibrary /testlibrary/whitebox
+ * @build IsMethodCompilableTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm/timeout=600 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI IsMethodCompilableTest
* @author igor.ignatyev@oracle.com
*/
public class IsMethodCompilableTest extends CompilerWhiteBoxTest {
--- a/hotspot/test/compiler/whitebox/MakeMethodNotCompilableTest.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/test/compiler/whitebox/MakeMethodNotCompilableTest.java Fri Mar 15 16:39:07 2013 -0700
@@ -23,9 +23,10 @@
/*
* @test MakeMethodNotCompilableTest
- * @compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI CompilerWhiteBoxTest.java
- * @compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI MakeMethodNotCompilableTest.java
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI MakeMethodNotCompilableTest
+ * @library /testlibrary /testlibrary/whitebox
+ * @build MakeMethodNotCompilableTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI MakeMethodNotCompilableTest
* @author igor.ignatyev@oracle.com
*/
public class MakeMethodNotCompilableTest extends CompilerWhiteBoxTest {
--- a/hotspot/test/compiler/whitebox/SetDontInlineMethodTest.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/test/compiler/whitebox/SetDontInlineMethodTest.java Fri Mar 15 16:39:07 2013 -0700
@@ -23,9 +23,10 @@
/*
* @test SetDontInlineMethodTest
- * @compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI CompilerWhiteBoxTest.java
- * @compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI SetDontInlineMethodTest.java
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI SetDontInlineMethodTest
+ * @library /testlibrary /testlibrary/whitebox
+ * @build SetDontInlineMethodTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI SetDontInlineMethodTest
* @author igor.ignatyev@oracle.com
*/
public class SetDontInlineMethodTest extends CompilerWhiteBoxTest {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/8000311/Test8000311.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test Test8000311
+ * @key gc
+ * @bug 8000311
+ * @summary G1: ParallelGCThreads==0 broken
+ * @run main/othervm -XX:+UseG1GC -XX:ParallelGCThreads=0 -XX:+ResizePLAB -XX:+ExplicitGCInvokesConcurrent Test8000311
+ * @author filipp.zhinkin@oracle.com
+ */
+
+import java.util.*;
+
+public class Test8000311 {
+ public static void main(String args[]) {
+ for(int i = 0; i<100; i++) {
+ byte[] garbage = new byte[1000];
+ System.gc();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/TestG1ZeroPGCTJcmdThreadPrint.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test TestG1ZeroPGCTJcmdThreadPrint
+ * @key gc
+ * @bug 8005875
+ * @summary Use jcmd to generate a thread dump of a Java program being run with PGCT=0 to verify 8005875
+ * @library /testlibrary
+ * @run main/othervm -XX:+UseG1GC -XX:ParallelGCThreads=0 -XX:+IgnoreUnrecognizedVMOptions TestG1ZeroPGCTJcmdThreadPrint
+ */
+
+import com.oracle.java.testlibrary.*;
+
+public class TestG1ZeroPGCTJcmdThreadPrint {
+ public static void main(String args[]) throws Exception {
+
+ // Grab the pid from the current java process
+ String pid = Integer.toString(ProcessTools.getProcessId());
+
+ // Create a ProcessBuilder
+ ProcessBuilder pb = new ProcessBuilder();
+
+ // Run jcmd <pid> Thread.print
+ pb.command(JDKToolFinder.getJDKTool("jcmd"), pid, "Thread.print");
+
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+ // There shouldn't be a work gang for concurrent marking.
+ output.shouldNotContain("G1 Parallel Marking Threads");
+
+ // Make sure we didn't crash
+ output.shouldHaveExitValue(0);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/metaspace/ClassMetaspaceSizeInJmapHeap.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test ClassMetaspaceSizeInJmapHeap
+ * @bug 8004924
+ * @summary Checks that jmap -heap contains the flag ClassMetaspaceSize
+ * @library /testlibrary
+ * @run main/othervm -XX:ClassMetaspaceSize=50m ClassMetaspaceSizeInJmapHeap
+ */
+
+import com.oracle.java.testlibrary.*;
+import java.nio.file.*;
+import java.io.File;
+import java.nio.charset.Charset;
+import java.util.List;
+
+public class ClassMetaspaceSizeInJmapHeap {
+ public static void main(String[] args) throws Exception {
+ String pid = Integer.toString(ProcessTools.getProcessId());
+
+ ProcessBuilder pb = new ProcessBuilder();
+ pb.command(JDKToolFinder.getJDKTool("jmap"), "-heap", pid);
+
+ File out = new File("ClassMetaspaceSizeInJmapHeap.stdout.txt");
+ pb.redirectOutput(out);
+
+ File err = new File("ClassMetaspaceSizeInJmapHeap.stderr.txt");
+ pb.redirectError(err);
+
+ run(pb);
+
+ OutputAnalyzer output = new OutputAnalyzer(read(out));
+ output.shouldContain("ClassMetaspaceSize = 52428800 (50.0MB)");
+ out.delete();
+ }
+
+ private static void run(ProcessBuilder pb) throws Exception {
+ Process p = pb.start();
+ p.waitFor();
+ int exitValue = p.exitValue();
+ if (exitValue != 0) {
+ throw new Exception("jmap -heap exited with error code: " + exitValue);
+ }
+ }
+
+ private static String read(File f) throws Exception {
+ Path p = f.toPath();
+ List<String> lines = Files.readAllLines(p, Charset.defaultCharset());
+
+ StringBuilder sb = new StringBuilder();
+ for (String line : lines) {
+ sb.append(line).append('\n');
+ }
+ return sb.toString();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/startup_warnings/TestCMS.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,46 @@
+/*
+* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+
+/*
+* @test TestCMS
+* @key gc
+* @bug 8006398
+* @summary Test that CMS does not print a warning message
+* @library /testlibrary
+*/
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.ProcessTools;
+
+
+public class TestCMS {
+
+ public static void main(String args[]) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseConcMarkSweepGC", "-version");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldNotContain("warning");
+ output.shouldNotContain("error");
+ output.shouldHaveExitValue(0);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/startup_warnings/TestCMSIncrementalMode.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,46 @@
+
+/*
+* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+
+/*
+* @test TestCMSIncrementalMode
+* @key gc
+* @bug 8006398
+* @summary Test that the deprecated CMSIncrementalMode print a warning message
+* @library /testlibrary
+*/
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.ProcessTools;
+
+public class TestCMSIncrementalMode {
+
+ public static void main(String args[]) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseConcMarkSweepGC", "-XX:+CMSIncrementalMode", "-version");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldContain("warning: Using incremental CMS is deprecated and will likely be removed in a future release");
+ output.shouldNotContain("error");
+ output.shouldHaveExitValue(0);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/startup_warnings/TestCMSNoIncrementalMode.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,45 @@
+/*
+* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+
+/*
+* @test TestCMSNoIncrementalMode
+* @key gc
+* @bug 8006398
+* @summary Test that CMS with incremental mode turned off does not print a warning message
+* @library /testlibrary
+*/
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.ProcessTools;
+
+public class TestCMSNoIncrementalMode {
+
+ public static void main(String args[]) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseConcMarkSweepGC", "-XX:-CMSIncrementalMode", "-version");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldNotContain("warning");
+ output.shouldNotContain("error");
+ output.shouldHaveExitValue(0);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/startup_warnings/TestDefNewCMS.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,45 @@
+/*
+* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+
+/*
+* @test TestDefNewCMS
+* @key gc
+* @bug 8006398
+* @summary Test that the deprecated DefNew+CMS combination print a warning message
+* @library /testlibrary
+*/
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.ProcessTools;
+
+public class TestDefNewCMS {
+
+ public static void main(String args[]) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:-UseParNewGC", "-XX:+UseConcMarkSweepGC", "-version");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldContain("warning: Using the DefNew young collector with the CMS collector is deprecated and will likely be removed in a future release");
+ output.shouldNotContain("error");
+ output.shouldHaveExitValue(0);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/startup_warnings/TestG1.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,45 @@
+/*
+* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+
+/*
+* @test TestG1
+* @key gc
+* @bug 8006398
+* @summary Test that the G1 collector does not print a warning message
+* @library /testlibrary
+*/
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.ProcessTools;
+
+public class TestG1 {
+
+ public static void main(String args[]) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC", "-version");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldNotContain("warning");
+ output.shouldNotContain("error");
+ output.shouldHaveExitValue(0);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/startup_warnings/TestIncGC.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,46 @@
+/*
+* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+
+/*
+* @test TestIncGC
+* @key gc
+* @bug 8006398
+* @summary Test that the deprecated -Xincgc print a warning message
+* @library /testlibrary
+*/
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.ProcessTools;
+
+
+public class TestIncGC {
+
+ public static void main(String args[]) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xincgc", "-version");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldContain("warning: Using incremental CMS is deprecated and will likely be removed in a future release");
+ output.shouldNotContain("error");
+ output.shouldHaveExitValue(0);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/startup_warnings/TestParNewCMS.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,46 @@
+/*
+* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+
+/*
+* @test TestParNewCMS
+* @key gc
+* @bug 8006398
+* @summary Test that the combination ParNew+CMS does not print a warning message
+* @library /testlibrary
+*/
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.ProcessTools;
+
+
+public class TestParNewCMS {
+
+ public static void main(String args[]) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseParNewGC", "-XX:+UseConcMarkSweepGC", "-version");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldNotContain("warning");
+ output.shouldNotContain("error");
+ output.shouldHaveExitValue(0);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/startup_warnings/TestParNewSerialOld.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,46 @@
+/*
+* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+
+/*
+* @test TestParNewSerialOld
+* @key gc
+* @bug 8006398
+* @summary Test that the deprecated ParNew+SerialOld combination print a warning message
+* @library /testlibrary
+*/
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.ProcessTools;
+
+
+public class TestParNewSerialOld {
+
+ public static void main(String args[]) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseParNewGC", "-version");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldContain("warning: Using the ParNew young collector with the Serial old collector is deprecated and will likely be removed in a future release");
+ output.shouldNotContain("error");
+ output.shouldHaveExitValue(0);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/startup_warnings/TestParallelGC.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,46 @@
+/*
+* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+
+/*
+* @test TestParallelGC
+* @key gc
+* @bug 8006398
+* @summary Test that ParallelGC does not print a warning message
+* @library /testlibrary
+*/
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.ProcessTools;
+
+
+public class TestParallelGC {
+
+ public static void main(String args[]) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseParallelGC", "-version");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldNotContain("warning");
+ output.shouldNotContain("error");
+ output.shouldHaveExitValue(0);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/startup_warnings/TestParallelScavengeSerialOld.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,46 @@
+/*
+* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+
+/*
+* @test TestParallelScavengeSerialOld
+* @key gc
+* @bug 8006398
+* @summary Test that the ParallelScavenge+SerialOld combination does not print a warning message
+* @library /testlibrary
+*/
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.ProcessTools;
+
+
+public class TestParallelScavengeSerialOld {
+
+ public static void main(String args[]) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseParallelGC", "-XX:-UseParallelOldGC", "-version");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldNotContain("warning");
+ output.shouldNotContain("error");
+ output.shouldHaveExitValue(0);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/startup_warnings/TestSerialGC.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,46 @@
+/*
+* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+
+/*
+* @test TestSerialGC
+* @key gc
+* @bug 8006398
+* @summary Test that SerialGC does not print a warning message
+* @library /testlibrary
+*/
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.ProcessTools;
+
+
+public class TestSerialGC {
+
+ public static void main(String args[]) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseSerialGC", "-version");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldNotContain("warning");
+ output.shouldNotContain("error");
+ output.shouldHaveExitValue(0);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/8007736/TestStaticIF.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * @test
+ * @bug 8007736
+ * @summary Test static interface method.
+ * @run main/othervm -Xverify:all TestStaticIF
+ */
+
+public class TestStaticIF implements StaticMethodInInterface {
+
+ public static void main(String[] args) {
+ System.out.printf("main: %s%n", StaticMethodInInterface.get());
+ }
+}
+
+interface StaticMethodInInterface {
+
+ public static String get() {
+ return "Hello from StaticMethodInInterface.get()";
+ }
+}
--- a/hotspot/test/runtime/NMT/AllocTestType.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/test/runtime/NMT/AllocTestType.java Fri Mar 15 16:39:07 2013 -0700
@@ -25,9 +25,10 @@
* @test
* @summary Test consistency of NMT by leaking a few select allocations of the Test type and then verify visibility with jcmd
* @key nmt jcmd
- * @library /testlibrary
- * @run compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI AllocTestType.java
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail AllocTestType
+ * @library /testlibrary /testlibrary/whitebox
+ * @build AllocTestType
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail AllocTestType
*/
import com.oracle.java.testlibrary.*;
--- a/hotspot/test/runtime/NMT/PrintNMTStatistics.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/test/runtime/NMT/PrintNMTStatistics.java Fri Mar 15 16:39:07 2013 -0700
@@ -26,8 +26,8 @@
* @key nmt regression
* @bug 8005936
* @summary Make sure PrintNMTStatistics works on normal JVM exit
- * @library /testlibrary
- * @run compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI PrintNMTStatistics.java
+ * @library /testlibrary /testlibrary/whitebox
+ * @run compile PrintNMTStatistics.java
*/
import com.oracle.java.testlibrary.*;
--- a/hotspot/test/runtime/NMT/SummarySanityCheck.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/test/runtime/NMT/SummarySanityCheck.java Fri Mar 15 16:39:07 2013 -0700
@@ -25,9 +25,10 @@
* @test
* @key nmt jcmd
* @summary Sanity check the output of NMT
- * @library /testlibrary
- * @run compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI SummarySanityCheck.java
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:NativeMemoryTracking=summary -XX:+WhiteBoxAPI SummarySanityCheck
+ * @library /testlibrary /testlibrary/whitebox
+ * @build SummarySanityCheck
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:NativeMemoryTracking=summary -XX:+WhiteBoxAPI SummarySanityCheck
*/
import com.oracle.java.testlibrary.*;
--- a/hotspot/test/sanity/WBApi.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/test/sanity/WBApi.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,8 +1,33 @@
+/*
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
/*
* @test WBApi
* @summary verify that whitebox functions can be linked and executed
- * @run compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI WBApi.java
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI WBApi
+ * @library /testlibrary /testlibrary/whitebox
+ * @build WBApi
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI WBApi
*/
import sun.hotspot.WhiteBox;
--- a/hotspot/test/serviceability/ParserTest.java Fri Mar 15 17:02:24 2013 +0400
+++ b/hotspot/test/serviceability/ParserTest.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,8 +1,33 @@
+/*
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
/*
* @test ParserTest
- * @summary verify that whitebox functions can be linked and executed
- * @run compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI ParserTest.java
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ParserTest
+ * @summary Test that the diagnostic command arguemnt parser works
+ * @library /testlibrary /testlibrary/whitebox
+ * @build ParserTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ParserTest
*/
import java.math.BigInteger;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/ClassFileInstaller.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+
+/**
+ * Dump a class file for a class on the class path in the current directory
+ */
+public class ClassFileInstaller {
+ /**
+ * @param args The names of the classes to dump
+ * @throws Exception
+ */
+ public static void main(String... args) throws Exception {
+ for (String arg : args) {
+ ClassLoader cl = ClassFileInstaller.class.getClassLoader();
+
+ // Convert dotted class name to a path to a class file
+ String pathName = arg.replace('.', '/').concat(".class");
+ InputStream is = cl.getResourceAsStream(pathName);
+
+ // Create the class file's package directory
+ Path p = Paths.get(pathName);
+ Files.createDirectories(p.getParent());
+ // Create the class file
+ Files.copy(is, p, StandardCopyOption.REPLACE_EXISTING);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.hotspot;
+
+import java.lang.reflect.Method;
+import java.security.BasicPermission;
+import sun.hotspot.parser.DiagnosticCommand;
+
+public class WhiteBox {
+
+ @SuppressWarnings("serial")
+ public static class WhiteBoxPermission extends BasicPermission {
+ public WhiteBoxPermission(String s) {
+ super(s);
+ }
+ }
+
+ private WhiteBox() {}
+ private static final WhiteBox instance = new WhiteBox();
+ private static native void registerNatives();
+
+ /**
+ * Returns the singleton WhiteBox instance.
+ *
+ * The returned WhiteBox object should be carefully guarded
+ * by the caller, since it can be used to read and write data
+ * at arbitrary memory addresses. It must never be passed to
+ * untrusted code.
+ */
+ public synchronized static WhiteBox getWhiteBox() {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(new WhiteBoxPermission("getInstance"));
+ }
+ return instance;
+ }
+
+ static {
+ registerNatives();
+ }
+
+ // Memory
+ public native long getObjectAddress(Object o);
+ public native int getHeapOopSize();
+
+ // Runtime
+ // Make sure class name is in the correct format
+ public boolean isClassAlive(String name) {
+ return isClassAlive0(name.replace('.', '/'));
+ }
+ private native boolean isClassAlive0(String name);
+
+ // G1
+ public native boolean g1InConcurrentMark();
+ public native boolean g1IsHumongous(Object o);
+ public native long g1NumFreeRegions();
+ public native int g1RegionSize();
+ public native Object[] parseCommandLine(String commandline, DiagnosticCommand[] args);
+
+ // NMT
+ public native boolean NMTAllocTest();
+ public native boolean NMTFreeTestMemory();
+ public native boolean NMTWaitForDataMerge();
+
+ // Compiler
+ public native void deoptimizeAll();
+ public native boolean isMethodCompiled(Method method);
+ public native boolean isMethodCompilable(Method method);
+ public native boolean isMethodQueuedForCompilation(Method method);
+ public native int deoptimizeMethod(Method method);
+ public native void makeMethodNotCompilable(Method method);
+ public native int getMethodCompilationLevel(Method method);
+ public native boolean setDontInlineMethod(Method method, boolean value);
+ public native int getCompileQueuesSize();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/whitebox/sun/hotspot/parser/DiagnosticCommand.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.hotspot.parser;
+
+public class DiagnosticCommand {
+
+ public enum DiagnosticArgumentType {
+ JLONG, BOOLEAN, STRING, NANOTIME, STRINGARRAY, MEMORYSIZE
+ }
+
+ private String name;
+ private String desc;
+ private DiagnosticArgumentType type;
+ private boolean mandatory;
+ private String defaultValue;
+
+ public DiagnosticCommand(String name, String desc, DiagnosticArgumentType type,
+ boolean mandatory, String defaultValue) {
+ this.name = name;
+ this.desc = desc;
+ this.type = type;
+ this.mandatory = mandatory;
+ this.defaultValue = defaultValue;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getDesc() {
+ return desc;
+ }
+
+ public DiagnosticArgumentType getType() {
+ return type;
+ }
+
+ public boolean isMandatory() {
+ return mandatory;
+ }
+
+ public String getDefaultValue() {
+ return defaultValue;
+ }
+}
--- a/jaxp/.hgtags Fri Mar 15 17:02:24 2013 +0400
+++ b/jaxp/.hgtags Fri Mar 15 16:39:07 2013 -0700
@@ -199,3 +199,6 @@
ff0b73a6b3f6cea644d37d56d746a37743419fa7 jdk8-b75
0c08593944d0cd30645f6e1e4946c51ff2b10c8c jdk8-b76
573e789c187a69a3ae00bffd26eb35c0f4a60636 jdk8-b77
+00958c5a7070bd578aa8b70773cb3f204a9c1be1 jdk8-b78
+58fa065dd5d663d62f85402461388fb7a92656fa jdk8-b79
+4873a0499bc3bd263b7dd3b551a2b4e275ab5a0b jdk8-b80
--- a/jaxws/.hgtags Fri Mar 15 17:02:24 2013 +0400
+++ b/jaxws/.hgtags Fri Mar 15 16:39:07 2013 -0700
@@ -199,3 +199,6 @@
966bf9f3c41a59ff5d86ff4275291c52f329f984 jdk8-b75
c4853f3f0e89ac60aa5b517f5f224f0f60e08577 jdk8-b76
64dfba1bad16433f609f17a42c3c5990367c5c0b jdk8-b77
+391de4c992d1960a09cdd340362ff936bac69323 jdk8-b78
+70d8658d2a3063bc13127f3452af017d838f1362 jdk8-b79
+b0224010e2f0c2474055ac592c8d3f37b9264690 jdk8-b80
--- a/jdk/.hgtags Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/.hgtags Fri Mar 15 16:39:07 2013 -0700
@@ -200,3 +200,6 @@
3a263052866137b645ab86498a43693ff5c19e69 jdk8-b76
b2fc8e31cecc35b76188e821d4c5dc0e0b74ac24 jdk8-b77
00b7535d743f83eda763c10b3c9ea19ba4b67f55 jdk8-b78
+c933505d75c2a0a671f06d6dac5d2237a9228d2d jdk8-b79
+dfb40f066c6ce129822f0f5dc2ac89173808781a jdk8-b80
+c0f8022eba536dcdc8aae659005b33f3982b9368 jdk8-b81
--- a/jdk/make/common/Defs-macosx.gmk Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/make/common/Defs-macosx.gmk Fri Mar 15 16:39:07 2013 -0700
@@ -406,10 +406,16 @@
LIB_LOCATION ?= $(LIBDIR)
-# Adding these macros will make it an error to link to mac APIs newer than OS version 10.7
-ifeq ($(MACOSX_REQUIRED_VERSION),)
- MACOSX_REQUIRED_VERSION:=1070
+# Setting these parameters makes it an error to link to macosx APIs that are
+# newer than the given OS version and makes the linked binaries compatible even
+# if built on a newer version of the OS.
+# The expected format is X.Y.Z
+ifeq ($(MACOSX_VERSION_MIN),)
+ MACOSX_VERSION_MIN=10.7.0
endif
-MACOSX_OS_VERSION_CFLAGS := -DMAC_OS_X_VERSION_MAX_ALLOWED=$(MACOSX_REQUIRED_VERSION) -DMAC_OS_X_VERSION_MIN_REQUIRED=$(MACOSX_REQUIRED_VERSION)
+# The macro takes the version with no dots, ex: 1070
+MACOSX_OS_VERSION_CFLAGS := -DMAC_OS_X_VERSION_MAX_ALLOWED=$(subst .,,$(MACOSX_VERSION_MIN)) \
+ -mmacosx-version-min=$(MACOSX_VERSION_MIN)
OTHER_CFLAGS += $(MACOSX_OS_VERSION_CFLAGS)
OTHER_CXXFLAGS += $(MACOSX_OS_VERSION_CFLAGS)
+OTHER_LDFLAGS += -mmacosx-version-min=$(MACOSX_VERSION_MIN)
--- a/jdk/make/common/Release.gmk Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/make/common/Release.gmk Fri Mar 15 16:39:07 2013 -0700
@@ -348,7 +348,6 @@
sun/tools/serialver \
sun/tools/tree \
sun/tools/util \
- sun/security/tools/jarsigner/JarBASE64Encoder.class \
sun/security/tools/jarsigner/Main.class \
sun/security/tools/jarsigner/JarSignerParameters.class \
sun/security/tools/jarsigner/Resources.class \
@@ -576,7 +575,6 @@
$(ECHO) "sun/tools/serialver/" >> $@
$(ECHO) "sun/tools/tree/" >> $@
$(ECHO) "sun/tools/util/" >> $@
- $(ECHO) "sun/security/tools/jarsigner/JarBASE64Encoder.class" >> $@
$(ECHO) "sun/security/tools/jarsigner/Main.class" >> $@
$(ECHO) "sun/security/tools/jarsigner/JarSignerParameters.class" >> $@
$(ECHO) "sun/security/tools/jarsigner/Resources.class" >> $@
--- a/jdk/make/common/shared/Compiler-msvc.gmk Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/make/common/shared/Compiler-msvc.gmk Fri Mar 15 16:39:07 2013 -0700
@@ -28,6 +28,7 @@
#
ifeq ($(PLATFORM), windows)
+ifndef CONFIGURE_BUILD
CC = $(COMPILER_PATH)cl
CPP = $(COMPILER_PATH)cl
CXX = $(COMPILER_PATH)cl
@@ -36,7 +37,7 @@
LINK = $(COMPILER_PATH)link
LINK32 = $(LINK)
DUMPBIN = $(COMPILER_PATH)dumpbin.exe
-
+
# Fill in unknown values
COMPILER_NAME=Unknown MSVC Compiler
COMPILER_VERSION=
@@ -87,6 +88,6 @@
SHARED_LIBRARY_FLAG = -LD
# RSC is always same as RC (Not sure who uses this RSC variable)
RSC = $(RC)
-
+endif
endif
--- a/jdk/make/common/shared/Defs-utils.gmk Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/make/common/shared/Defs-utils.gmk Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -74,22 +74,24 @@
UTILS_DEVTOOL_PATH=$(DEVTOOLS_PATH)
endif
-# Utilities
-ifdef CROSS_COMPILE_ARCH
- AR = $(COMPILER_PATH)ar
- AS = $(COMPILER_PATH)as
- LD = $(COMPILER_PATH)ld
- MCS = $(COMPILER_PATH)mcs
- NM = $(COMPILER_PATH)nm
- STRIP = $(COMPILER_PATH)strip
-else
- AR = $(UTILS_CCS_BIN_PATH)ar
- AS = $(UTILS_CCS_BIN_PATH)as
- LD = $(UTILS_CCS_BIN_PATH)ld
- MCS = $(UTILS_CCS_BIN_PATH)mcs
- NM = $(UTILS_CCS_BIN_PATH)nm
- STRIP = $(UTILS_CCS_BIN_PATH)strip
-endif
+ifndef CONFIGURE_BUILD
+ # Utilities
+ ifdef CROSS_COMPILE_ARCH
+ AR = $(COMPILER_PATH)ar
+ AS = $(COMPILER_PATH)as
+ LD = $(COMPILER_PATH)ld
+ MCS = $(COMPILER_PATH)mcs
+ NM = $(COMPILER_PATH)nm
+ STRIP = $(COMPILER_PATH)strip
+ else
+ AR = $(UTILS_CCS_BIN_PATH)ar
+ AS = $(UTILS_CCS_BIN_PATH)as
+ LD = $(UTILS_CCS_BIN_PATH)ld
+ MCS = $(UTILS_CCS_BIN_PATH)mcs
+ NM = $(UTILS_CCS_BIN_PATH)nm
+ STRIP = $(UTILS_CCS_BIN_PATH)strip
+ endif
+endif # CONFIGURE_BUILD
ADB = $(UTILS_COMMAND_PATH)adb
BASENAME = $(UTILS_COMMAND_PATH)basename
--- a/jdk/make/java/java/FILES_java.gmk Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/make/java/java/FILES_java.gmk Fri Mar 15 16:39:07 2013 -0700
@@ -257,6 +257,7 @@
sun/util/calendar/ZoneInfoFile.java \
java/util/TooManyListenersException.java \
java/util/Comparator.java \
+ java/util/Comparators.java \
java/util/Collections.java \
java/util/Iterator.java \
java/util/ListIterator.java \
--- a/jdk/make/java/zip/Makefile Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/make/java/zip/Makefile Fri Mar 15 16:39:07 2013 -0700
@@ -68,6 +68,16 @@
FILES_reorder += reorder-$(ARCH)
endif
endif
+
+#
+# Use mapfile unconditionally (even with fastdebug).
+# JDK's internal zlib is incompatible with stock zlib, because the
+# size of struct z_stream has been changed, so internal zlib
+# implementation must not be allowed to leak outside of libzip.so,
+# else you get hard to debug failures with fastdebug jdk when user
+# native code includes stock zlib.
+#
+FILES_m = mapfile-vers
include $(BUILDDIR)/common/Mapfile-vers.gmk
include $(BUILDDIR)/common/Library.gmk
--- a/jdk/make/launchers/Makefile Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/make/launchers/Makefile Fri Mar 15 16:39:07 2013 -0700
@@ -77,6 +77,7 @@
-J-Dsun.jvm.hotspot.debugger.useWindbgDebugger, )
$(call make-launcher, jps, sun.tools.jps.Jps, , )
$(call make-launcher, jrunscript, com.sun.tools.script.shell.Main, , )
+$(call make-launcher, jjs, jdk.nashorn.tools.Shell, , )
$(call make-launcher, jsadebugd, sun.jvm.hotspot.jdi.SADebugServer, , )
$(call make-launcher, jstack, sun.tools.jstack.JStack, \
-J-Dsun.jvm.hotspot.debugger.useProcDebugger \
--- a/jdk/make/sun/cmm/lcms/Makefile Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/make/sun/cmm/lcms/Makefile Fri Mar 15 16:39:07 2013 -0700
@@ -28,6 +28,9 @@
LIBRARY = lcms
PRODUCT = sun
+# Use highest level of optimization on this library
+OPTIMIZATION_LEVEL = HIGHEST
+
include $(BUILDDIR)/common/Defs.gmk
#
--- a/jdk/make/sun/cmm/lcms/mapfile-vers Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/make/sun/cmm/lcms/mapfile-vers Fri Mar 15 16:39:07 2013 -0700
@@ -27,13 +27,12 @@
SUNWprivate_1.1 {
global:
- Java_sun_java2d_cmm_lcms_LCMS_loadProfile;
- Java_sun_java2d_cmm_lcms_LCMS_freeProfile;
+ Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative;
+ Java_sun_java2d_cmm_lcms_LCMS_freeProfileNative;
Java_sun_java2d_cmm_lcms_LCMS_getProfileSize;
Java_sun_java2d_cmm_lcms_LCMS_getProfileData;
- Java_sun_java2d_cmm_lcms_LCMS_getTagSize;
- Java_sun_java2d_cmm_lcms_LCMS_getTagData;
- Java_sun_java2d_cmm_lcms_LCMS_setTagData;
+ Java_sun_java2d_cmm_lcms_LCMS_getTagNative;
+ Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative;
Java_sun_java2d_cmm_lcms_LCMS_colorConvert;
Java_sun_java2d_cmm_lcms_LCMS_getProfileID;
Java_sun_java2d_cmm_lcms_LCMS_initLCMS;
--- a/jdk/make/tools/javazic/Makefile Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-#
-# Copyright (c) 1998, 2005, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation. Oracle designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Oracle in the LICENSE file that accompanied this code.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-#
-# Makefile for building the javazic tool
-#
-
-BUILDDIR = ../..
-PACKAGE = build.tools.javazic
-PRODUCT = javazic
-PROGRAM = javazic
-include $(BUILDDIR)/common/Defs.gmk
-
-BUILDTOOL_SOURCE_ROOT = $(BUILDDIR)/tools/src
-BUILDTOOL_MAIN = $(PKGDIR)/Main.java
-
-#
-# Build tool jar rules.
-#
-include $(BUILDDIR)/common/BuildToolJar.gmk
-
--- a/jdk/make/tools/src/build/tools/deps/refs.allowed Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/make/tools/src/build/tools/deps/refs.allowed Fri Mar 15 16:39:07 2013 -0700
@@ -33,8 +33,3 @@
#
java.beans.PropertyChangeListener=java.util.logging.LogManager,sun.org.mozilla.javascript.internal.Context,compact1,compact2,compact3
java.beans.PropertyChangeEvent=sun.org.mozilla.javascript.internal.Context,compact3
-
-# JFR traces even in builds with JFR disabled
-com.oracle.jrockit.jfr.FlightRecorder: com.sun.management.MissionControl, compact3
-com.oracle.jrockit.jfr.management.FlightRecorderMBean: com.sun.management.MissionControl, compact3
-
--- a/jdk/make/tools/src/build/tools/javazic/BackEnd.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package build.tools.javazic;
-
-/**
- * <code>BackEnd</code> is an abstract base class for a back-end of compiling
- * Olson's zoneinfo database and generating Java zoneinfo database.
- *
- * @since 1.4
- */
-abstract class BackEnd {
-
- /**
- * Receives each zone's TimeZone information which was created by
- * {@link Zoneinfo#parse} in class <code>Zoneinfo</code>,
- * and processes it.
- *
- * @param tz Timezone object for each zone
- * @return 0 if no error occurred, otherwise 1.
- */
- abstract int processZoneinfo(Timezone tz);
-
- /**
- * Receives whole information which is generated by JavaZic's front-end
- * in the form of Mapping object and generates all Java zone information
- * files.
- *
- * @param m Mappings object which is generated by
- * {@link Main#compile() Main.compile()}.
- * @return 0 if no error occurred, otherwise 1.
- */
- abstract int generateSrc(Mappings m);
-
- /**
- * Decides which backend class should be used and returns its instance.
- * @return an instance of backend class
- */
- static BackEnd getBackEnd() {
- if (Zoneinfo.isYearForTimeZoneDataSpecified) {
- return new Simple();
- } else if (Main.outputDoc) {
- return new GenDoc();
- } else {
- return new Gen();
- }
- }
-}
--- a/jdk/make/tools/src/build/tools/javazic/Checksum.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package build.tools.javazic;
-
-import java.util.zip.CRC32;
-
-/**
- * Checksum provides methods for calculating a CRC32 value for a
- * transitions table.
- *
- * @since 1.4
- */
-public class Checksum extends CRC32
-{
- /**
- * Updates the CRC32 value from each byte of the given int
- * value. The bytes are used in the big endian order.
- * @param val the int value
- */
- public void update(int val) {
- byte[] b = new byte[4];
- b[0] = (byte)((val >>> 24) & 0xff);
- b[1] = (byte)((val >>> 16) & 0xff);
- b[2] = (byte)((val >>> 8) & 0xff);
- b[3] = (byte)(val & 0xff);
- update(b);
- }
-
- /**
- * Updates the CRC32 value from each byte of the given long
- * value. The bytes are used in the big endian order.
- * @param val the long value
- */
- void update(long val) {
- byte[] b = new byte[8];
- b[0] = (byte)((val >>> 56) & 0xff);
- b[1] = (byte)((val >>> 48) & 0xff);
- b[2] = (byte)((val >>> 40) & 0xff);
- b[3] = (byte)((val >>> 32) & 0xff);
- b[4] = (byte)((val >>> 24) & 0xff);
- b[5] = (byte)((val >>> 16) & 0xff);
- b[6] = (byte)((val >>> 8) & 0xff);
- b[7] = (byte)(val & 0xff);
- update(b);
- }
-}
--- a/jdk/make/tools/src/build/tools/javazic/DayOfWeek.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2004, 2006, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package build.tools.javazic;
-
-/**
- * Day of week enum.
- *
- * @since 1.6
- */
-
-enum DayOfWeek {
- SUNDAY("Sun"),
- MONDAY("Mon"),
- TUESDAY("Tue"),
- WEDNESDAY("Wed"),
- THURSDAY("Thu"),
- FRIDAY("Fri"),
- SATURDAY("Sat");
-
- private final String abbr;
-
- private DayOfWeek(String abbr) {
- this.abbr = abbr;
- }
-
- String getAbbr() {
- return abbr;
- }
-
- int value() {
- return ordinal() + 1;
- }
-}
--- a/jdk/make/tools/src/build/tools/javazic/Gen.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,347 +0,0 @@
-/*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package build.tools.javazic;
-
-import java.io.IOException;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.DataOutputStream;
-import java.io.RandomAccessFile;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import sun.util.calendar.ZoneInfoFile;
-
-/**
- * <code>Gen</code> is one of back-end classes of javazic, and generates
- * ZoneInfoMappings and zone-specific file for each zone.
- */
-class Gen extends BackEnd {
-
- /**
- * Generates datafile in binary TLV format for each time zone.
- * Regarding contents of output files, see {@link ZoneInfoFile}.
- *
- * @param Timezone
- * @return 0 if no errors, or 1 if error occurred.
- */
- int processZoneinfo(Timezone tz) {
- try {
- int size;
- String outputDir = Main.getOutputDir();
- String zonefile = ZoneInfoFile.getFileName(tz.getName());
-
- /* If outputDir doesn't end with file-separator, adds it. */
- if (!outputDir.endsWith(File.separator)) {
- outputDir += File.separatorChar;
- }
-
- /* If zonefile includes file-separator, it's treated as part of
- * pathname. And make directory if necessary.
- */
- int index = zonefile.lastIndexOf(File.separatorChar);
- if (index != -1) {
- outputDir += zonefile.substring(0, index+1);
- }
- File outD = new File(outputDir);
- outD.mkdirs();
-
- FileOutputStream fos =
- new FileOutputStream(outputDir + zonefile.substring(index+1));
- DataOutputStream dos = new DataOutputStream(fos);
-
- /* Output Label */
- dos.write(ZoneInfoFile.JAVAZI_LABEL, 0,
- ZoneInfoFile.JAVAZI_LABEL.length);
-
- /* Output Version of ZoneInfoFile */
- dos.writeByte(ZoneInfoFile.JAVAZI_VERSION);
-
- List<Long> transitions = tz.getTransitions();
- if (transitions != null) {
- List<Integer> dstOffsets = tz.getDstOffsets();
- List<Integer> offsets = tz.getOffsets();
-
- if ((dstOffsets == null && offsets != null) ||
- (dstOffsets != null && offsets == null)) {
- Main.panic("Data not exist. (dstOffsets or offsets)");
- return 1;
- }
-
- /* Output Transition records */
- dos.writeByte(ZoneInfoFile.TAG_Transition);
- size = transitions.size();
- dos.writeShort((size * 8) & 0xFFFF);
- int dstoffset;
- for (int i = 0; i < size; i++) {
- /* if DST offset is 0, this means DST isn't used.
- * (NOT: offset's index is 0.)
- */
- if ((dstoffset = dstOffsets.get(i).intValue()) == -1) {
- dstoffset = 0;
- }
-
- dos.writeLong((transitions.get(i).longValue() << 12)
- | (dstoffset << 4)
- | offsets.get(i).intValue());
-
- }
-
- /* Output data for GMTOffset */
- List<Integer> gmtoffset = tz.getGmtOffsets();
- dos.writeByte(ZoneInfoFile.TAG_Offset);
- size = gmtoffset.size();
- dos.writeShort((size * 4) & 0xFFFF);
- for (int i = 0; i < size; i++) {
- dos.writeInt(gmtoffset.get(i));
- }
- }
-
- /* Output data for SimpleTimeZone */
- List<RuleRec> stz = tz.getLastRules();
- if (stz != null) {
- RuleRec[] rr = new RuleRec[2];
- boolean wall = true;
-
- rr[0] = stz.get(0);
- rr[1] = stz.get(1);
-
- dos.writeByte(ZoneInfoFile.TAG_SimpleTimeZone);
- wall = rr[0].getTime().isWall() && rr[1].getTime().isWall();
- if (wall) {
- dos.writeShort(32);
- } else {
- dos.writeShort(40);
- }
-
- for (int i = 0; i < 2; i++) {
- dos.writeInt(rr[i].getMonthNum() - 1); // 0-based month number
- dos.writeInt(rr[i].getDay().getDayForSimpleTimeZone());
- dos.writeInt(rr[i].getDay().getDayOfWeekForSimpleTimeZoneInt());
- dos.writeInt((int)rr[i].getTime().getTime());
- if (!wall) {
- dos.writeInt((rr[i].getTime().getType() & 0xFF) - 1);
- }
- }
- }
-
- /* Output RawOffset */
- dos.writeByte(ZoneInfoFile.TAG_RawOffset);
- dos.writeShort(4);
- dos.writeInt(tz.getRawOffset());
-
- /* Output willGMTOffsetChange flag */
- if (tz.willGMTOffsetChange()) {
- dos.writeByte(ZoneInfoFile.TAG_GMTOffsetWillChange);
- dos.writeShort(1);
- dos.writeByte(1);
- }
-
- /* Output LastDSTSaving */
- dos.writeByte(ZoneInfoFile.TAG_LastDSTSaving);
- dos.writeShort(2);
- dos.writeShort(tz.getLastDSTSaving()/1000);
-
- /* Output checksum */
- dos.writeByte(ZoneInfoFile.TAG_CRC32);
- dos.writeShort(4);
- dos.writeInt(tz.getCRC32());
-
- fos.close();
- dos.close();
- } catch(IOException e) {
- Main.panic("IO error: "+e.getMessage());
- return 1;
- }
-
- return 0;
- }
-
- /**
- * Generates ZoneInfoMappings in binary TLV format for each zone.
- * Regarding contents of output files, see {@link ZoneInfoFile}.
- *
- * @param Mappings
- * @return 0 if no errors, or 1 if error occurred.
- */
- int generateSrc(Mappings map) {
- try {
- int index;
- int block_size;
- int roi_size;
- long fp;
- String outputDir = Main.getOutputDir();
-
- /* If outputDir doesn't end with file-separator, adds it. */
- if (!outputDir.endsWith(File.separator)) {
- outputDir += File.separatorChar;
- }
-
- File outD = new File(outputDir);
- outD.mkdirs();
-
- /* Open ZoneInfoMapping file to write. */
- RandomAccessFile raf =
- new RandomAccessFile(outputDir + ZoneInfoFile.JAVAZM_FILE_NAME, "rw");
-
- /* Whether rawOffsetIndex list exists or not. */
- List<Integer> roi = map.getRawOffsetsIndex();
- if (roi == null) {
- Main.panic("Data not exist. (rawOffsetsIndex)");
- return 1;
- }
- roi_size = roi.size();
-
- /* Whether rawOffsetIndexTable list exists or not. */
- List<Set<String>> roit = map.getRawOffsetsIndexTable();
- if (roit == null || roit.size() != roi_size) {
- Main.panic("Data not exist. (rawOffsetsIndexTable) Otherwise, Invalid size");
- return 1;
- }
-
- /* Output Label */
- raf.write(ZoneInfoFile.JAVAZM_LABEL, 0,
- ZoneInfoFile.JAVAZM_LABEL.length);
-
- /* Output Version */
- raf.writeByte(ZoneInfoFile.JAVAZM_VERSION);
-
- index = ZoneInfoFile.JAVAZM_LABEL.length + 2;
-
- /* Output Version of Olson's tzdata */
- byte[] b = Main.getVersionName().getBytes("UTF-8");
- raf.writeByte(ZoneInfoFile.TAG_TZDataVersion);
- raf.writeShort((b.length+1) & 0xFFFF);
- raf.write(b);
- raf.writeByte(0x00);
- index += b.length + 4;
-
- /* Output ID list. */
- raf.writeByte(ZoneInfoFile.TAG_ZoneIDs);
- block_size = 2;
- raf.writeShort(block_size & 0xFFFF);
- short nID = 0;
- raf.writeShort(nID & 0xFFFF);
- for (int i = 0; i < roi_size; i++) {
- for (String key : roit.get(i)) {
- byte size = (byte)key.getBytes("UTF-8").length;
- raf.writeByte(size & 0xFF);
- raf.write(key.getBytes("UTF-8"), 0, size);
- block_size += 1 + size;
- nID++;
- }
- }
- fp = raf.getFilePointer();
- raf.seek(index);
- raf.writeShort((block_size) & 0xFFFF);
- raf.writeShort(nID & 0xFFFF);
- raf.seek(fp);
-
- /* Output sorted rawOffset list. */
- raf.writeByte(ZoneInfoFile.TAG_RawOffsets);
- index += 3 + block_size;
- block_size = roi_size * 4;
- raf.writeShort(block_size & 0xFFFF);
- for (int i = 0; i < roi_size; i++) {
- raf.writeInt(Integer.parseInt(roi.get(i).toString()));
- }
-
- /* Output sorted rawOffsetIndex list. */
- raf.writeByte(ZoneInfoFile.TAG_RawOffsetIndices);
- index += 3 + block_size;
- block_size = 0;
- raf.writeShort(block_size & 0xFFFF);
- int num;
- for (int i = 0; i < roi_size; i++) {
- num = roit.get(i).size();
- block_size += num;
- for (int j = 0; j < num; j++) {
- raf.writeByte(i);
- }
- }
- fp = raf.getFilePointer();
- raf.seek(index);
- raf.writeShort((block_size) & 0xFFFF);
- raf.seek(fp);
-
- /* Whether alias list exists or not. */
- Map<String,String> a = map.getAliases();
- if (a == null) {
- Main.panic("Data not exist. (aliases)");
- return 0;
- }
-
- /* Output ID list. */
- raf.writeByte(ZoneInfoFile.TAG_ZoneAliases);
- index += 3 + block_size;
- block_size = 2;
- raf.writeShort(block_size & 0xFFFF);
- raf.writeShort(a.size() & 0xFFFF);
- for (String key : a.keySet()) {
- String alias = a.get(key);
- byte key_size = (byte)key.length();
- byte alias_size = (byte)alias.length();
- raf.writeByte(key_size & 0xFF);
- raf.write(key.getBytes("UTF-8"), 0, key_size);
- raf.writeByte(alias_size & 0xFF);
- raf.write(alias.getBytes("UTF-8"), 0, alias_size);
- block_size += 2 + key_size + alias_size;
- }
- fp = raf.getFilePointer();
- raf.seek(index);
- raf.writeShort((block_size) & 0xFFFF);
- raf.seek(fp);
-
- /* Output the exclude list if it exists. */
- List<String> excludedZones = map.getExcludeList();
- if (excludedZones != null) {
- raf.writeByte(ZoneInfoFile.TAG_ExcludedZones);
- index += 3 + block_size;
- block_size = 2;
- raf.writeShort(block_size & 0xFFFF); // place holder
- raf.writeShort(excludedZones.size()); // the number of excluded zones
- for (String name : excludedZones) {
- byte size = (byte) name.length();
- raf.writeByte(size); // byte length
- raf.write(name.getBytes("UTF-8"), 0, size); // zone name
- block_size += 1 + size;
- }
- fp = raf.getFilePointer();
- raf.seek(index);
- raf.writeShort(block_size & 0xFFFF);
- raf.seek(fp);
- }
-
- /* Close ZoneInfoMapping file. */
- raf.close();
- } catch(IOException e) {
- Main.panic("IO error: "+e.getMessage());
- return 1;
- }
-
- return 0;
- }
-}
--- a/jdk/make/tools/src/build/tools/javazic/GenDoc.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,781 +0,0 @@
-/*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package build.tools.javazic;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.StringTokenizer;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import sun.util.calendar.ZoneInfoFile;
-
-/**
- * <code>GenDoc</code> is one of back-end classes of javazic, and generates
- * index.html and other html files which prints the detailed time zone
- * information for each zone.
- */
-class GenDoc extends BackEnd {
-
- private static final String docDir = "doc";
-
- private static final String header1 =
- "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Frameset//EN\"" +
- "\"http://www.w3.org/TR/REC-html40/frameset.dtd\">\n" +
- "<HTML>\n<HEAD>\n<!-- Generated by javazic on ";
- private static final String header2 =
- "-->\n<TITLE>\n" +
- "Java Platform, Standard Edition - TimeZone information based on ";
- private static final String header3 =
- "-->\n<TITLE>\n" +
- "Java Platform, Standard Edition TimeZone - ";
- private static final String header4 =
- "</TITLE>\n" +
- "</HEAD>\n\n";
-
- private static final String body1 =
- "<BODY BGCOLOR=\"white\">\n";
- private static final String body2 =
- "</BODY>\n";
-
- private static final String footer =
- "</HTML>\n";
-
-
- // list of time zone name and zonefile name/real time zone name
- // e.g.
- // key (String) : value (String)
- // "America/Denver" : "America/Denver.html" (real time zone)
- // "America/Shiprock" : "America/Denver" (alias)
- TreeMap<String,String> timezoneList = new TreeMap<String,String>();
-
- // list of time zone's display name and time zone name
- // e.g.
- // key (String) : value (String)
- // "Tokyo, Asia" : "Asia/Tokyo"
- // "Marengo, Indiana, America" : "America/Indiana/Marengo"
- // (aliases included)
- TreeMap<String,String> displayNameList = new TreeMap<String,String>();
-
- // list of top level regions
- // e.g.
- // key (String) : value (String)
- // "America" : "America.html"
- // (including entries in America/Indiana/, America/Kentucky/, ...)
- TreeMap<String,String> regionList = new TreeMap<String,String>();
-
- // mapping list from zone name to latitude & longitude
- // This list is generated from zone.tab.
- // e.g.
- // key (String) : value (LatitudeAndLongitude object)
- // "Asia/Tokyo" : latitude=35.3916, longitude=13.9444
- // (aliases not included)
- HashMap<String,LatitudeAndLongitude> mapList = null;
-
- // SortedMap of zone IDs sorted by their GMT offsets. If zone's GMT
- // offset will change in the future, its last known offset is
- // used.
- SortedMap<Integer, Set<String>> zonesByOffset = new TreeMap<Integer, Set<String>>();
-
- /**
- * Generates HTML document for each zone.
- * @param Timezone
- * @return 0 if no errors, or 1 if error occurred.
- */
- int processZoneinfo(Timezone tz) {
- try {
- int size;
- int index;
- String outputDir = Main.getOutputDir();
- String zonename = tz.getName();
- String zonefile = ZoneInfoFile.getFileName(zonename) + ".html";
- List<RuleRec> stz = tz.getLastRules();
- timezoneList.put(zonename, zonefile);
- displayNameList.put(transform(zonename), zonename);
-
- // Populate zonesByOffset. (Zones that will change their
- // GMT offsets are also added to zonesByOffset here.)
- int lastKnownOffset = tz.getRawOffset();
- Set<String> set = zonesByOffset.get(lastKnownOffset);
- if (set == null) {
- set = new TreeSet<String>();
- zonesByOffset.put(lastKnownOffset, set);
- }
- set.add(zonename);
-
- /* If outputDir doesn't end with file-separator, adds it. */
- if (!outputDir.endsWith(File.separator)) {
- outputDir += File.separatorChar;
- }
- outputDir += docDir + File.separatorChar;
-
- index = zonename.indexOf('/');
- if (index != -1) {
- regionList.put(zonename.substring(0, index),
- zonename.substring(0, index) + ".html");
- }
-
- /* If zonefile includes file-separator, it's treated as part of
- * pathname. And make directory if necessary.
- */
- index = zonefile.lastIndexOf('/');
- if (index != -1) {
- zonefile.replace('/', File.separatorChar);
- outputDir += zonefile.substring(0, index+1);
- }
- File outD = new File(outputDir);
- outD.mkdirs();
-
- /* If mapfile is available, add a link to the appropriate map */
- if ((mapList == null) && (Main.getMapFile() != null)) {
- FileReader fr = new FileReader(Main.getMapFile());
- BufferedReader in = new BufferedReader(fr);
- mapList = new HashMap<String,LatitudeAndLongitude>();
- String line;
- while ((line = in.readLine()) != null) {
- // skip blank and comment lines
- if (line.length() == 0 || line.charAt(0) == '#') {
- continue;
- }
- StringTokenizer tokens = new StringTokenizer(line);
- String token = tokens.nextToken(); /* We don't use the first token. */
- token = tokens.nextToken();
- LatitudeAndLongitude location = new LatitudeAndLongitude(token);
- token = tokens.nextToken();
- mapList.put(token, location);
- }
- in.close();
- }
-
- /* Open zoneinfo file to write. */
- FileWriter fw = new FileWriter(outputDir + zonefile.substring(index+1));
- BufferedWriter out = new BufferedWriter(fw);
-
- out.write(header1 + new Date() + header3 + zonename + header4);
- out.write(body1 + "<FONT size=\"+2\"><B>" + zonename + "</B></FONT>");
- LatitudeAndLongitude location = mapList.get(zonename);
- if (location != null) {
- int deg, min, sec;
-
- deg = location.getLatDeg();
- min = location.getLatMin();
- sec = location.getLatSec();
- if (deg < 0) {
- min = -min;
- sec = -sec;
- } else if (min < 0) {
- sec = -sec;
- }
- out.write(" " +
- "<A HREF=\"http://www.mapquest.com/maps/map.adp?" +
- "latlongtype=degrees" +
- "&latdeg=" + deg +
- "&latmin=" + min +
- "&latsec=" + sec);
-
- deg = location.getLongDeg();
- min = location.getLongMin();
- sec = location.getLongSec();
- if (deg < 0) {
- min = -min;
- sec = -sec;
- } else if (min < 0) {
- sec = -sec;
- }
- out.write("&longdeg=" + deg +
- "&longmin=" + min +
- "&longsec=" + sec +
- "\" target=\"_blank\">[map]</A>");
- }
- out.write("\n<P>\n");
-
- List<ZoneRec> zone = tz.getZones();
- List<RuleRec> rule = tz.getRules();
- if (rule != null && zone != null) {
- out.write("<TABLE BORDER=\"0\" WIDTH=\"100%\" CELLPADDING=\"1\" CELLSPACING=\"0\">\n" +
- "<TR>\n" +
- "<TD BGCOLOR=\"#EEEEFF\" WIDTH=\"50%\" ALIGN=\"CENTER\"><BR>" +
- "<A HREF=\"#Rules\">Rules</A><BR></TD>\n" +
- "<TD BGCOLOR=\"#EEEEFF\" WIDTH=\"50%\" ALIGN=\"CENTER\">" +
- "<A HREF=\"#Zone\"><BR>Zone<BR></A></TD>\n" +
- "</TR>\n</TABLE>\n");
- }
-
- /* Output Rule records. */
- if (rule != null) {
- size = rule.size();
- out.write("<P>\n<A NAME=\"Rules\">" +
- "<FONT SIZE=\"+1\"><B>Rules</B></FONT></A>\n" +
- "<TABLE BORDER=\"1\" WIDTH=\"100%\" CELLPADDING=\"3\" CELLSPACING=\"0\">\n" +
- "<TR BGCOLOR=\"#CCCCFF\">\n" +
- "<TD>NAME</TD><TD>FROM</TD><TD>TO</TD><TD>TYPE</TD>" +
- "<TD>IN</TD><TD>ON</TD><TD>AT</TD><TD>SAVE</TD>" +
- "<TD>LETTER/S</TD><TD>NOTES</TD>\n</TR>\n");
- for (int i = 0; i < size; i++) {
- out.write("<TR BGCOLOR=\"#FFFFFF\">\n");
- StringTokenizer st = new StringTokenizer(rule.get(i).getLine());
- String s;
- if (st.hasMoreTokens()) { /* RULE - truncated */
- st.nextToken();
- }
- if (st.hasMoreTokens()) { /* NAME */
- out.write("<TD>" + st.nextToken() + "</TD>");
- }
- if (st.hasMoreTokens()) { /* FROM */
- out.write("<TD>" + st.nextToken() + "</TD>");
- }
- if (st.hasMoreTokens()) { /* TO */
- s = st.nextToken();
- if (s.equals("min") || s.equals("max")) {
- out.write("<TD><FONT COLOR=\"red\">" + s + "</FONT></TD>");
- } else {
- out.write("<TD>" + s + "</TD>");
- }
- }
- if (st.hasMoreTokens()) { /* TYPE */
- out.write("<TD>" + st.nextToken() + "</TD>");
- }
- if (st.hasMoreTokens()) { /* IN */
- out.write("<TD>" + st.nextToken() + "</TD>");
- }
- if (st.hasMoreTokens()) { /* ON */
- out.write("<TD>" + st.nextToken() + "</TD>");
- }
- if (st.hasMoreTokens()) { /* AT */
- out.write("<TD>" + st.nextToken() + "</TD>");
- }
- if (st.hasMoreTokens()) { /* SAVE */
- out.write("<TD>" + st.nextToken() + "</TD>");
- }
- if (st.hasMoreTokens()) { /* LETTER/S */
- out.write("<TD>" + st.nextToken() + "</TD>");
- }
- if (st.hasMoreTokens()) { /* NOTES */
- s = st.nextToken();
- while (st.hasMoreTokens()) {
- s += " " + st.nextToken();
- }
- index = s.indexOf('#');
- out.write("<TD>" + s.substring(index+1) + "</TD>\n");
- } else {
- out.write("<TD> </TD>\n");
- }
- out.write("</TR>\n");
- }
- out.write("</TABLE>\n<P> <P>\n");
- }
-
- /* Output Zone records. */
- if (zone != null) {
- size = zone.size();
- out.write("<P>\n<A NAME=\"Zone\">" +
- "<FONT SIZE=\"+1\"><B>Zone</B></FONT></A>\n" +
- "<TABLE BORDER=\"1\" WIDTH=\"100%\" CELLPADDING=\"3\" CELLSPACING=\"0\">\n" +
- "<TR BGCOLOR=\"#CCCCFF\">\n<TD>GMTOFF</TD>" +
- "<TD>RULES</TD><TD>FORMAT</TD><TD>UNTIL</TD>" +
- "<TD>NOTES</TD>\n</TR>\n");
- for (int i = 0; i < size; i++) {
- out.write("<TR>\n");
- StringTokenizer st = new StringTokenizer(zone.get(i).getLine());
- String s = st.nextToken();
- if (s.equals("Zone")) { /* NAME */
- s = st.nextToken();
- s = st.nextToken();
- }
- out.write("<TD>" + s + "</TD>"); /* GMTOFFSET */
- if (st.hasMoreTokens()) { /* RULES */
- out.write("<TD>" + st.nextToken() + "</TD>");
- }
- if (st.hasMoreTokens()) { /* FORMAT */
- s = st.nextToken();
- index = s.indexOf('#');
- if (index != -1) {
- if (index != 0) {
- out.write("<TD>" + s.substring(0, index-1) +
- "</TD>"); /* FORMAT */
- s = s.substring(index+1);
- } else {
- out.write("<TD> </TD>"); /* FORMAT */
- }
- while (st.hasMoreTokens()) {
- s += " " + st.nextToken();
- }
- out.write("<TD> </TD>"); /* UNTIL */
- out.write("<TD>" + s + "</TD>\n</TR>\n"); /* NOTES */
- continue;
- } else {
- out.write("<TD>" + s + "</TD>"); /* FORMAT */
- }
- }
-
- if (st.hasMoreTokens()) { /* UNTIL */
- s = st.nextToken();
- while (st.hasMoreTokens()) {
- s += " " + st.nextToken();
- }
- index = s.indexOf('#');
- if (index != -1) {
- if (index != 0) {
- out.write("<TD>" + s.substring(0, index-1) +
- "</TD>"); /* UNTIL */
- } else {
- out.write("<TD> </TD>"); /* UNTIL */
- }
- out.write("<TD>" + s.substring(index+1) +
- "</TD>\n"); /* NOTES */
- } else {
- out.write("<TD>" + s + "</TD>"); /* UNTIL */
- out.write("<TD> </TD>\n"); /* NOTES */
- }
- } else {
- out.write("<TD> </TD>"); /* UNTIL */
- out.write("<TD> </TD>\n"); /* NOTES */
- }
- out.write("</TR>\n");
- }
- out.write("</TABLE>\n");
- }
- out.write(body2 + footer);
-
- out.close();
- fw.close();
- } catch(IOException e) {
- Main.panic("IO error: "+e.getMessage());
- return 1;
- }
-
- return 0;
- }
-
- /**
- * Generates index.html and other top-level frame files.
- * @param Mappings
- * @return 0 if no errors, or 1 if error occurred.
- */
- int generateSrc(Mappings map) {
- try {
- int len;
- Object o[];
- String outputDir = Main.getOutputDir();
- FileWriter fw1, fw2;
- BufferedWriter out1, out2;
-
- /* Whether alias list exists or not. */
- Map<String,String> a = map.getAliases();
- if (a == null) {
- Main.panic("Data not exist. (aliases)");
- return 1;
- }
-
- timezoneList.putAll(a);
-
- /* If outputDir doesn't end with file-separator, adds it. */
- if (!outputDir.endsWith(File.separator)) {
- outputDir += File.separatorChar;
- }
- outputDir += docDir + File.separatorChar;
-
- File outD = new File(outputDir);
- outD.mkdirs();
-
- /* Creates index.html */
- fw1 = new FileWriter(outputDir + "index.html", false);
- out1 = new BufferedWriter(fw1);
-
- out1.write(header1 + new Date() + header2 + Main.getVersionName() +
- header4 +
- "<FRAMESET cols=\"20%,80%\">\n" +
- "<FRAMESET rows=\"30%,70%\">\n" +
- "<FRAME src=\"overview-frame.html\" name=\"TimeZoneListFrame\">\n" +
- "<FRAME src=\"allTimeZone-frame1.html\" name=\"allTimeZoneFrame\">\n" +
- "</FRAMESET>" +
- "<FRAME src=\"overview-summary.html\" name=\"rightFrame\">\n" +
- "</FRAMESET>\n" +
- "<NOFRAMES>\n" +
- "<H2>\nFrame Alert\n</H2>\n\n" +
- "<P>\n\n" +
- "This document is designed to be viewed using the frames feature. If you see this\n" +
- "message, you are using a non-frame-capable web client.\n" +
- "<BR>\n" +
- "Link to<A HREF=\"overview-summary.html\">Non-frame version.</A>\n" +
- "</NOFRAMES>\n" + footer);
-
- out1.close();
- fw1.close();
-
-
- /* Creates overview-frame.html */
- fw1 = new FileWriter(outputDir + "overview-frame.html", false);
- out1 = new BufferedWriter(fw1);
-
- out1.write(header1 + new Date() + header2 + Main.getVersionName() +
- header4 + body1 +
- "<TABLE BORDER=\"0\" WIDTH=\"100%\">\n<TR>\n" +
- "<TD NOWRAP><FONT size=\"+1\">\n" +
- "<B>Java<sup><font size=-2>TM</font></sup> Platform<br>Standard Ed.</B></FONT></TD>\n" +
- "</TR>\n</TABLE>\n\n" +
- "<TABLE BORDER=\"0\" WIDTH=\"100%\">\n<TR>\n<TD NOWRAP>" +
- "<P>\n<FONT size=\"+1\">\nAll Time Zones Sorted By:</FONT>\n<BR>\n" +
- " <A HREF=\"allTimeZone-frame1.html\" TARGET=\"allTimeZoneFrame\">GMT offsets</A></FONT>\n<BR>\n" +
- " <A HREF=\"allTimeZone-frame2.html\" TARGET=\"allTimeZoneFrame\">Zone names</A></FONT>\n<BR>" +
- " <A HREF=\"allTimeZone-frame3.html\" TARGET=\"allTimeZoneFrame\">City names</A></FONT>\n" +
- "<P>\n<FONT size=\"+1\">\nContinents and Oceans</FONT>\n<BR>\n");
-
- for (String regionKey : regionList.keySet()) {
- out1.write(" <A HREF=\"" + regionList.get(regionKey) +
- "\" TARGET=\"allTimeZoneFrame\">" + regionKey +
- "</A><BR>\n");
-
- fw2 = new FileWriter(outputDir + regionList.get(regionKey),
- false);
- out2 = new BufferedWriter(fw2);
-
- out2.write(header1 + new Date() + header3 + regionKey +
- header4 + body1 + "<FONT size=\"+1\"><B>" +
- regionKey + "</B></FONT>\n<BR>\n<TABLE>\n<TR>\n<TD>");
-
- boolean found = false;
- for (String timezoneKey : timezoneList.keySet()) {
- int regionIndex = timezoneKey.indexOf('/');
- if (regionIndex == -1 ||
- !regionKey.equals(timezoneKey.substring(0, regionIndex))) {
- if (found) {
- break;
- } else {
- continue;
- }
- }
-
- found = true;
- if (a.containsKey(timezoneKey)) {
- Object realName = a.get(timezoneKey);
- while (a.containsKey(realName)) {
- realName = a.get(realName);
- }
- out2.write(timezoneKey +
- " (alias for " + "<A HREF=\"" +
- timezoneList.get(realName) +
- "\" TARGET=\"rightFrame\">" +
- realName + "</A>)");
- } else {
- out2.write("<A HREF=\"" + timezoneList.get(timezoneKey) +
- "\" TARGET=\"rightFrame\">" + timezoneKey +
- "</A>");
- }
- out2.write("<BR>\n");
- }
- out2.write("</TD>\n</TR>\n</TABLE>\n" + body2 + footer);
-
- out2.close();
- fw2.close();
- }
- out1.write("</FONT></TD>\n</TR></TABLE>\n" + body2 + footer);
-
- out1.close();
- fw1.close();
-
-
- /* Creates allTimeZone-frame1.html (Sorted by GMT offsets) */
- fw1 = new FileWriter(outputDir + "allTimeZone-frame1.html", false);
- out1 = new BufferedWriter(fw1);
-
- out1.write(header1 + new Date() + header2 + Main.getVersionName() +
- header4 + body1 +
- "<FONT size=\"+1\"><B>Sorted by GMT offsets</B></FONT>\n" +
- "<BR>\n\n" + "<TABLE BORDER=\"0\" WIDTH=\"100%\">\n" +
- "<TR>\n<TD NOWRAP>\n");
-
- List<Integer> roi = map.getRawOffsetsIndex();
- List<Set<String>> roit = map.getRawOffsetsIndexTable();
-
- int index = 0;
- for (Integer offset : zonesByOffset.keySet()) {
- int off = roi.get(index);
- Set<String> perRO = zonesByOffset.get(offset);
- if (offset == off) {
- // Merge aliases into zonesByOffset
- perRO.addAll(roit.get(index));
- }
- index++;
-
- for (String timezoneKey : perRO) {
- out1.write("<TR>\n<TD><FONT SIZE=\"-1\">(" +
- Time.toGMTFormat(offset.toString()) +
- ")</FONT></TD>\n<TD>");
-
- if (a.containsKey(timezoneKey)) {
- Object realName = a.get(timezoneKey);
- while (a.containsKey(realName)) {
- realName = a.get(realName);
- }
- out1.write(timezoneKey +
- " (alias for " + "<A HREF=\"" +
- timezoneList.get(realName) +
- "\" TARGET=\"rightFrame\">" + realName +
- "</A>)");
- } else {
- out1.write("<A HREF=\"" + timezoneList.get(timezoneKey) +
- "\" TARGET=\"rightFrame\">" + timezoneKey +
- "</A>");
- }
- out1.write("</TD>\n</TR>\n");
- }
- }
- out1.write("</FONT></TD>\n</TR>\n</TABLE>\n" + body2 + footer);
-
- out1.close();
- fw1.close();
-
-
- /* Creates allTimeZone-frame2.html (Sorted by zone names) */
- fw1 = new FileWriter(outputDir + "allTimeZone-frame2.html", false);
- out1 = new BufferedWriter(fw1);
-
- out1.write(header1 + new Date() + header2 + Main.getVersionName() +
- header4 + body1 +
- "<FONT size=\"+1\"><B>Sorted by zone names</B></FONT>\n" +
- "<BR>\n\n" + "<TABLE BORDER=\"0\" WIDTH=\"100%\">\n" +
- "<TR>\n<TD NOWRAP>\n");
- o = timezoneList.keySet().toArray();
- len = timezoneList.size();
- for (int i = 0; i < len; i++) {
- Object timezoneKey = o[i];
- if (a.containsKey(timezoneKey)) {
- Object realName = a.get(timezoneKey);
- while (a.containsKey(realName)) {
- realName = a.get(realName);
- }
- out1.write(timezoneKey +
- " (alias for " +
- "<A HREF=\"" + timezoneList.get(realName) +
- "\" TARGET=\"rightFrame\">" + realName +
- "</A>)");
- } else {
- out1.write("<A HREF=\"" + timezoneList.get(timezoneKey) +
- "\" TARGET=\"rightFrame\">" + timezoneKey +
- "</A>");
- }
- out1.write("<BR> \n");
- }
- out1.write("</FONT></TD>\n</TR>\n</TABLE>\n" + body2 + footer);
-
- out1.close();
- fw1.close();
-
- /* Creates allTimeZone-frame3.html (Sorted by city names) */
- fw1 = new FileWriter(outputDir + "allTimeZone-frame3.html", false);
- out1 = new BufferedWriter(fw1);
-
- out1.write(header1 + new Date() + header2 + Main.getVersionName() +
- header4 + body1 +
- "<FONT size=\"+1\"><B>Sorted by city names</B></FONT>\n" +
- "<BR>\n\n" + "<TABLE BORDER=\"0\" WIDTH=\"100%\">\n" +
- "<TR>\n<TD NOWRAP>\n");
-
- Set<String> aliasSet = a.keySet();
- len = aliasSet.size();
- String aliasNames[] = aliasSet.toArray(new String[0]);
- for (int i = 0; i < len; i++) {
- displayNameList.put(transform(aliasNames[i]),
- aliasNames[i]);
- }
-
- o = displayNameList.keySet().toArray();
- len = displayNameList.size();
- for (int i = 0; i < len; i++) {
- Object displayName = o[i];
- Object timezoneKey = displayNameList.get(o[i]);
- if (a.containsKey(timezoneKey)) {
- Object realName = a.get(timezoneKey);
- while (a.containsKey(realName)) {
- realName = a.get(realName);
- }
- out1.write(displayName +
- " (alias for " +
- "<A HREF=\"" + timezoneList.get(realName) +
- "\" TARGET=\"rightFrame\">" + realName +
- "</A>)");
- } else {
- out1.write("<A HREF=\"" + timezoneList.get(timezoneKey) +
- "\" TARGET=\"rightFrame\">" + displayName +
- "</A>");
- }
- out1.write("<BR> \n");
- }
-
- out1.write("</FONT></TD>\n</TR>\n</TABLE>\n" + body2 + footer);
-
- out1.close();
- fw1.close();
-
- /* Creates overview-summary.html */
- fw1 = new FileWriter(outputDir + "overview-summary.html", false);
- out1 = new BufferedWriter(fw1);
-
- out1.write(header1 + new Date() + header2 + Main.getVersionName() +
- header4 + body1 +
- "<p>This is the list of time zones generated from <B>" +
- Main.getVersionName() + "</B> for Java Platform, " +
- "Standard Edition. The source code can be obtained " +
- "from ftp site <a href=\"ftp://elsie.nci.nih.gov/pub/\">" +
- "ftp://elsie.nci.nih.gov/pub/</a>. A total of <B>" +
- len +
- "</B> time zones and aliases are supported " +
- "in this edition. For the " +
- "format of rules and zones, refer to the zic " +
- "(zoneinfo compiler) man page on " +
- "Solaris or Linux.</p>\n" +
- "<p>Note that the time zone data is not " +
- "a public interface of the Java Platform. No " +
- "applications should rely on the time zone data of " +
- "this document. Time zone names and data " +
- "may change without any prior notice.</p>\n" +
- body2 + footer);
-
- out1.close();
- fw1.close();
- } catch(IOException e) {
- Main.panic("IO error: "+e.getMessage());
- return 1;
- }
-
- return 0;
- }
-
- String transform(String s) {
- int index = s.lastIndexOf("/");
-
- /* If the string doesn't include any delimiter, return */
- if (index == -1) {
- return s;
- }
-
- int lastIndex = index;
- String str = s.substring(index+1);
- do {
- index = s.substring(0, lastIndex).lastIndexOf('/');
- str += ", " + s.substring(index+1, lastIndex);
- lastIndex = index;
- } while (index > -1);
-
- return str;
- }
-
- static class LatitudeAndLongitude {
-
- private int latDeg, latMin, latSec, longDeg, longMin, longSec;
-
- LatitudeAndLongitude(String s) {
- try {
- // First of all, check the string has the correct format:
- // either +-DDMM+-DDDMM or +-DDMMSS+-DDDMMSS
-
- if (!s.startsWith("+") && !s.startsWith("-")) {
- Main.warning("Wrong latitude&longitude data: " + s);
- return;
- }
- int index;
- if (((index = s.lastIndexOf("+")) <= 0) &&
- ((index = s.lastIndexOf("-")) <= 0)) {
- Main.warning("Wrong latitude&longitude data: " + s);
- return;
- }
-
- if (index == 5) {
- latDeg = Integer.parseInt(s.substring(1, 3));
- latMin = Integer.parseInt(s.substring(3, 5));
- latSec = 0;
- } else if (index == 7) {
- latDeg = Integer.parseInt(s.substring(1, 3));
- latMin = Integer.parseInt(s.substring(3, 5));
- latSec = Integer.parseInt(s.substring(5, 7));
- } else {
- Main.warning("Wrong latitude&longitude data: " + s);
- return;
- }
- if (s.startsWith("-")){
- latDeg = -latDeg;
- latMin = -latMin;
- latSec = -latSec;
- }
-
- int len = s.length();
- if (index == 5 && len == 11) {
- longDeg = Integer.parseInt(s.substring(index+1, index+4));
- longMin = Integer.parseInt(s.substring(index+4, index+6));
- longSec = 0;
- } else if (index == 7 && len == 15) {
- longDeg = Integer.parseInt(s.substring(index+1, index+4));
- longMin = Integer.parseInt(s.substring(index+4, index+6));
- longSec = Integer.parseInt(s.substring(index+6, index+8));
- } else {
- Main.warning("Wrong latitude&longitude data: " + s);
- return;
- }
- if (s.charAt(index) == '-'){
- longDeg = -longDeg;
- longMin = -longMin;
- longSec = -longSec;
- }
- } catch(Exception e) {
- Main.warning("LatitudeAndLongitude() Parse error: " + s);
- }
- }
-
- int getLatDeg() {
- return latDeg;
- }
-
- int getLatMin() {
- return latMin;
- }
-
- int getLatSec() {
- return latSec;
- }
-
- int getLongDeg() {
- return longDeg;
- }
-
- int getLongMin() {
- return longMin;
- }
-
- int getLongSec() {
- return longSec;
- }
- }
-}
--- a/jdk/make/tools/src/build/tools/javazic/Main.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,238 +0,0 @@
-/*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package build.tools.javazic;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Main class for the javazic time zone data compiler.
- *
- * @since 1.4
- */
-public class Main {
-
- private static boolean verbose = false;
- static boolean outputDoc = false;
-
- private List<String> ziFiles = new ArrayList<String>();
- private static String zoneNamesFile = null;
- private static String versionName = "unknown";
- private static String outputDir = "zoneinfo";
- private static String mapFile = null;
-
- /**
- * Parses the specified arguments and sets up the variables.
- * @param argv the arguments
- */
- void processArgs(String[] argv) {
- for (int i = 0; i < argv.length; i++) {
- String arg = argv[i];
- if (arg.startsWith("-h")) {
- usage();
- System.exit(0);
- } else if (arg.equals("-d")) {
- outputDir = argv[++i];
- } else if (arg.equals("-v")) {
- verbose = true;
- } else if (arg.equals("-V")) {
- versionName = argv[++i];
- } else if (arg.equals("-doc")) {
- outputDoc = true;
- } else if (arg.equals("-map")) {
- outputDoc = true;
- mapFile = argv[++i];
- } else if (arg.equals("-f")) {
- zoneNamesFile = argv[++i];
- } else if (arg.equals("-S")) {
- try {
- Zoneinfo.setYear(Integer.parseInt(argv[++i]));
- } catch (Exception e) {
- error("invalid year: " + argv[i]);
- usage();
- System.exit(1);
- }
- } else {
- boolean isStartYear = arg.equals("-s");
- if (isStartYear || arg.equals("-e")) {
- try {
- int year = Integer.parseInt(argv[++i]);
- if (isStartYear) {
- Zoneinfo.setStartYear(year);
- } else {
- Zoneinfo.setEndYear(year);
- }
- } catch (Exception e) {
- error("invalid year: " + argv[i]);
- usage();
- System.exit(1);
- }
- } else {
- // the rest of args are zoneinfo source files
- while (i < argv.length) {
- ziFiles.add(argv[i++]);
- }
- }
- }
- }
- }
-
- /**
- * Parses zoneinfo source files
- */
- int compile() {
- int nFiles = ziFiles.size();
- int status = 0;
- Mappings maps = new Mappings();
- BackEnd backend = BackEnd.getBackEnd();
-
- for (int i = 0; i < nFiles; i++) {
- Zoneinfo frontend = Zoneinfo.parse(ziFiles.get(i));
-
- for (String key : frontend.getZones().keySet()) {
- info(key);
-
- Timezone tz = frontend.phase2(key);
- status |= backend.processZoneinfo(tz);
- }
-
- maps.add(frontend);
- }
-
- // special code for dealing with the conflicting name "MET"
- Zone.addMET();
-
- maps.resolve();
-
- status |= backend.generateSrc(maps);
-
- return status;
- }
-
- public static void main(String[] argv) {
- Main zic = new Main();
-
- /*
- * Parse args
- */
- zic.processArgs(argv);
-
- /*
- * Read target zone names
- */
- if (zoneNamesFile != null) {
- Zone.readZoneNames(zoneNamesFile);
- }
-
- int status = zic.compile();
-
- System.exit(status);
- }
-
- void usage() {
- System.err.println("Usage: javazic [options] file...\n"+
- " -f namefile file containing zone names\n"+
- " to be generated (ie, generating subset)\n"+
- " -d dir output directory\n"+
- " -v verbose\n"+
- " -V datavers specifies the tzdata version string\n"+
- " (eg, \"tzdata2000g\")"+
- " -S year output only SimleTimeZone data of that year\n"+
- " -s year start year (default: 1900)\n"+
- " -e year end year (default: 2037)\n"+
- " -doc generates HTML documents\n"+
- " -map mapfile generates HTML documents with map information\n"+
- " file... zoneinfo source file(s)");
- }
-
- /**
- * @return the output directory path name
- */
- static String getOutputDir() {
- return outputDir;
- }
-
- /**
- * @return the map file's path and name
- */
- static String getMapFile() {
- return mapFile;
- }
-
- /**
- * Returns the time zone data version string specified by the -V
- * option. If it is not specified, "unknown" is returned.
- * @return the time zone data version string
- */
- static String getVersionName() {
- return versionName;
- }
-
- /**
- * Prints out the specified fatal error message and calls {@link
- * java.lang.System#exit System.exit(1)}.
- * @param msg the fatal error message
- */
- static void panic(String msg) {
- printMessage("fatal error", msg);
- System.exit(1);
- }
-
- /**
- * Prints out the specified error message.
- * @param msg the error message
- */
- static void error(String msg) {
- printMessage("error", msg);
- }
-
- /**
- * Prints out the specified warning message.
- * @param msg the warning message
- */
- static void warning(String msg) {
- printMessage("warning", msg);
- }
-
- /**
- * Prints out the informative message.
- * @param msg the informative message
- */
- static void info(String msg) {
- if (verbose) {
- printMessage(null, msg);
- }
- }
-
- private static void printMessage(String type, String msg) {
- if (type != null) {
- type += ": ";
- } else {
- type = "";
- }
- System.err.println("javazic: " + type + msg);
- }
-}
--- a/jdk/make/tools/src/build/tools/javazic/Mappings.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,197 +0,0 @@
-/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package build.tools.javazic;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.TreeSet;
-
-/**
- * <code>Mappings</code> generates two Maps and a List which are used by
- * javazic BackEnd.
- *
- * @since 1.4
- */
-class Mappings {
- // All aliases specified by Link statements. It's alias name to
- // real name mappings.
- private Map<String,String> aliases;
-
- private List<Integer> rawOffsetsIndex;
-
- private List<Set<String>> rawOffsetsIndexTable;
-
- // Zone names to be excluded from rawOffset table. Those have GMT
- // offsets to change some future time.
- private List<String> excludeList;
-
- /**
- * Constructor creates some necessary instances.
- */
- Mappings() {
- aliases = new TreeMap<String,String>();
- rawOffsetsIndex = new LinkedList<Integer>();
- rawOffsetsIndexTable = new LinkedList<Set<String>>();
- }
-
- /**
- * Generates aliases and rawOffsets tables.
- * @param zi a Zoneinfo containing Zones
- */
- void add(Zoneinfo zi) {
- Map<String,Zone> zones = zi.getZones();
-
- for (String zoneName : zones.keySet()) {
- Zone zone = zones.get(zoneName);
- String zonename = zone.getName();
- int rawOffset = zone.get(zone.size()-1).getGmtOffset();
-
- // If the GMT offset of this Zone will change in some
- // future time, this Zone is added to the exclude list.
- boolean isExcluded = false;
- for (int i = 0; i < zone.size(); i++) {
- ZoneRec zrec = zone.get(i);
- if ((zrec.getGmtOffset() != rawOffset)
- && (zrec.getUntilTime(0) > Time.getCurrentTime())) {
- if (excludeList == null) {
- excludeList = new ArrayList<String>();
- }
- excludeList.add(zone.getName());
- isExcluded = true;
- break;
- }
- }
-
- if (!rawOffsetsIndex.contains(new Integer(rawOffset))) {
- // Find the index to insert this raw offset zones
- int n = rawOffsetsIndex.size();
- int i;
- for (i = 0; i < n; i++) {
- if (rawOffsetsIndex.get(i) > rawOffset) {
- break;
- }
- }
- rawOffsetsIndex.add(i, rawOffset);
-
- Set<String> perRawOffset = new TreeSet<String>();
- if (!isExcluded) {
- perRawOffset.add(zonename);
- }
- rawOffsetsIndexTable.add(i, perRawOffset);
- } else if (!isExcluded) {
- int i = rawOffsetsIndex.indexOf(new Integer(rawOffset));
- Set<String> perRawOffset = rawOffsetsIndexTable.get(i);
- perRawOffset.add(zonename);
- }
- }
-
- Map<String,String> a = zi.getAliases();
- // If there are time zone names which refer to any of the
- // excluded zones, add those names to the excluded list.
- if (excludeList != null) {
- for (String zoneName : a.keySet()) {
- String realname = a.get(zoneName);
- if (excludeList.contains(realname)) {
- excludeList.add(zoneName);
- }
- }
- }
- aliases.putAll(a);
- }
-
- /**
- * Adds valid aliases to one of per-RawOffset table and removes
- * invalid aliases from aliases List. Aliases referring to
- * excluded zones are not added to a per-RawOffset table.
- */
- void resolve() {
- int index = rawOffsetsIndexTable.size();
- List<String> toBeRemoved = new ArrayList<String>();
- for (String key : aliases.keySet()) {
- boolean validname = false;
- for (int j = 0; j < index; j++) {
- Set<String> perRO = rawOffsetsIndexTable.get(j);
- boolean isExcluded = (excludeList == null) ?
- false : excludeList.contains(key);
-
- if ((perRO.contains(aliases.get(key)) || isExcluded)
- && Zone.isTargetZone(key)) {
- validname = true;
- if (!isExcluded) {
- perRO.add(key);
- Main.info("Alias <"+key+"> added to the list.");
- }
- break;
- }
- }
-
- if (!validname) {
- Main.info("Alias <"+key+"> removed from the list.");
- toBeRemoved.add(key);
- }
- }
-
- // Remove zones, if any, from the list.
- for (String key : toBeRemoved) {
- aliases.remove(key);
- }
- // Eliminate any alias-to-alias mappings. For example, if
- // there are A->B and B->C, A->B is changed to A->C.
- Map<String, String> newMap = new HashMap<String, String>();
- for (String key : aliases.keySet()) {
- String realid = aliases.get(key);
- String leaf = realid;
- while (aliases.get(leaf) != null) {
- leaf = aliases.get(leaf);
- }
- if (!realid.equals(leaf)) {
- newMap.put(key, leaf);
- }
- }
- aliases.putAll(newMap);
- }
-
- Map<String,String> getAliases() {
- return(aliases);
- }
-
- List<Integer> getRawOffsetsIndex() {
- return(rawOffsetsIndex);
- }
-
- List<Set<String>> getRawOffsetsIndexTable() {
- return(rawOffsetsIndexTable);
- }
-
- List<String> getExcludeList() {
- return excludeList;
- }
-}
--- a/jdk/make/tools/src/build/tools/javazic/Month.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-/*
- * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package build.tools.javazic;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Month enum handles month related manipulation.
- *
- * @since 1.4
- */
-enum Month {
- JANUARY("Jan"),
- FEBRUARY("Feb"),
- MARCH("Mar"),
- APRIL("Apr"),
- MAY("May"),
- JUNE("Jun"),
- JULY("Jul"),
- AUGUST("Aug"),
- SEPTEMBER("Sep"),
- OCTOBER("Oct"),
- NOVEMBER("Nov"),
- DECEMBER("Dec");
-
- private final String abbr;
-
- private static final Map<String,Month> abbreviations
- = new HashMap<String,Month>(12);
-
- static {
- for (Month m : Month.values()) {
- abbreviations.put(m.abbr, m);
- }
- }
-
- private Month(String abbr) {
- this.abbr = abbr;
- }
-
- int value() {
- return ordinal() + 1;
- }
-
- /**
- * Parses the specified string as a month abbreviation.
- * @param name the month abbreviation
- * @return the Month value
- */
- static Month parse(String name) {
- Month m = abbreviations.get(name);
- if (m != null) {
- return m;
- }
- return null;
- }
-
- /**
- * @param month the nunmth number (1-based)
- * @return the month name in uppercase of the specified month
- */
- static String toString(int month) {
- if (month >= JANUARY.value() && month <= DECEMBER.value()) {
- return "Calendar." + Month.values()[month - 1];
- }
- throw new IllegalArgumentException("wrong month number: " + month);
- }
-}
--- a/jdk/make/tools/src/build/tools/javazic/Rule.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,184 +0,0 @@
-/*
- * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package build.tools.javazic;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.List;
-import java.util.StringTokenizer;
-
-/**
- * Rule manipulates Rule records.
- *
- * @since 1.4
- */
-class Rule {
-
- private List<RuleRec> list;
- private String name;
-
- /**
- * Constructs a Rule which consists of a Rule record list. The
- * specified name is given to this Rule.
- * @param name the Rule name
- */
- Rule(String name) {
- this.name = name;
- list = new ArrayList<RuleRec>();
- }
-
- /**
- * Added a RuleRec to the Rule record list.
- */
- void add(RuleRec rec) {
- list.add(rec);
- }
-
- /**
- * @return the Rule name
- */
- String getName() {
- return name;
- }
-
- /**
- * Gets all rule records that cover the given year.
- *
- * @param year the year number for which the rule is applicable.
- * @return rules in List that are collated in time. If no rule is found, an empty
- * List is returned.
- */
- List<RuleRec> getRules(int year) {
- List<RuleRec> rules = new ArrayList<RuleRec>(3);
- for (RuleRec rec : list) {
- if (year >= rec.getFromYear() && year <= rec.getToYear()) {
- if ((rec.isOdd() && year % 2 == 0) || (rec.isEven() && year % 2 == 1))
- continue;
- rules.add(rec);
- }
- }
- int n = rules.size();
- if (n <= 1) {
- return rules;
- }
- if (n == 2) {
- RuleRec rec1 = rules.get(0);
- RuleRec rec2 = rules.get(1);
- if (rec1.getMonthNum() > rec2.getMonthNum()) {
- rules.set(0, rec2);
- rules.set(1, rec1);
- } else if (rec1.getMonthNum() == rec2.getMonthNum()) {
- // TODO: it's not accurate to ignore time types (STD, WALL, UTC)
- long t1 = Time.getLocalTime(year, rec1.getMonth(),
- rec1.getDay(), rec1.getTime().getTime());
- long t2 = Time.getLocalTime(year, rec2.getMonth(),
- rec2.getDay(), rec2.getTime().getTime());
- if (t1 > t2) {
- rules.set(0, rec2);
- rules.set(1, rec1);
- }
- }
- return rules;
- }
-
- final int y = year;
- RuleRec[] recs = new RuleRec[rules.size()];
- rules.toArray(recs);
- Arrays.sort(recs, new Comparator<RuleRec>() {
- public int compare(RuleRec r1, RuleRec r2) {
- int n = r1.getMonthNum() - r2.getMonthNum();
- if (n != 0) {
- return n;
- }
- // TODO: it's not accurate to ignore time types (STD, WALL, UTC)
- long t1 = Time.getLocalTime(y, r1.getMonth(),
- r1.getDay(), r1.getTime().getTime());
- long t2 = Time.getLocalTime(y, r2.getMonth(),
- r2.getDay(), r2.getTime().getTime());
- return (int)(t1 - t2);
- }
- public boolean equals(Object o) {
- return this == o;
- }
- });
- rules.clear();
- for (int i = 0; i < n; i++) {
- rules.add(recs[i]);
- }
- return rules;
- }
-
- /**
- * Gets rule records that have either "max" or cover the endYear
- * value in its DST schedule.
- *
- * @return rules that contain last DST schedule. An empty
- * ArrayList is returned if no last rules are found.
- */
- List<RuleRec> getLastRules() {
- RuleRec start = null;
- RuleRec end = null;
-
- for (int i = 0; i < list.size(); i++) {
- RuleRec rec = list.get(i);
- if (rec.isLastRule()) {
- if (rec.getSave() > 0) {
- start = rec;
- } else {
- end = rec;
- }
- }
- }
- if (start == null || end == null) {
- int endYear = Zoneinfo.getEndYear();
- for (int i = 0; i < list.size(); i++) {
- RuleRec rec = list.get(i);
- if (endYear >= rec.getFromYear() && endYear <= rec.getToYear()) {
- if (start == null && rec.getSave() > 0) {
- start = rec;
- } else {
- if (end == null && rec.getSave() == 0) {
- end = rec;
- }
- }
- }
- }
- }
-
- List<RuleRec> r = new ArrayList<RuleRec>(2);
- if (start == null || end == null) {
- if (start != null || end != null) {
- Main.warning("found last rules for "+name+" inconsistent.");
- }
- return r;
- }
-
- r.add(start);
- r.add(end);
- return r;
- }
-}
--- a/jdk/make/tools/src/build/tools/javazic/RuleDay.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,190 +0,0 @@
-/*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package build.tools.javazic;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * RuleDay class represents the value of the "ON" field. The day of
- * week values start from 1 following the {@link java.util.Calendar}
- * convention.
- *
- * @since 1.4
- */
-class RuleDay {
- private static final Map<String,DayOfWeek> abbreviations = new HashMap<String,DayOfWeek>(7);
- static {
- for (DayOfWeek day : DayOfWeek.values()) {
- abbreviations.put(day.getAbbr(), day);
- }
- }
-
- private String dayName = null;
- private DayOfWeek dow;
- private boolean lastOne = false;
- private int soonerOrLater = 0;
- private int thanDayOfMonth; // day of month (e.g., 8 for "Sun>=8")
-
- RuleDay() {
- }
-
- RuleDay(int day) {
- thanDayOfMonth = day;
- }
-
- int getDay() {
- return thanDayOfMonth;
- }
-
- /**
- * @return the day of week value (1-based)
- */
- int getDayOfWeekNum() {
- return dow.value();
- }
-
- /**
- * @return true if this rule day represents the last day of
- * week. (e.g., lastSun).
- */
- boolean isLast() {
- return lastOne;
- }
-
- /**
- * @return true if this rule day represents the day of week on or
- * later than (after) the {@link #getDay}. (e.g., Sun>=1)
- */
- boolean isLater() {
- return soonerOrLater > 0;
- }
-
- /**
- * @return true if this rule day represents the day of week on or
- * earlier than (before) the {@link #getDay}. (e.g., Sun<=15)
- */
- boolean isEarlier() {
- return soonerOrLater < 0;
- }
-
- /**
- * @return true if this rule day represents an exact day.
- */
- boolean isExact() {
- return soonerOrLater == 0;
- }
-
- /**
- * Parses the "ON" field and constructs a RuleDay.
- * @param day an "ON" field string (e.g., "Sun>=1")
- * @return a RuleDay representing the given "ON" field
- */
- static RuleDay parse(String day) {
- RuleDay d = new RuleDay();
- if (day.startsWith("last")) {
- d.lastOne = true;
- d.dayName = day.substring(4);
- d.dow = getDOW(d.dayName);
- } else {
- int index;
- if ((index = day.indexOf(">=")) != -1) {
- d.dayName = day.substring(0, index);
- d.dow = getDOW(d.dayName);
- d.soonerOrLater = 1; // greater or equal
- d.thanDayOfMonth = Integer.parseInt(day.substring(index+2));
- } else if ((index = day.indexOf("<=")) != -1) {
- d.dayName = day.substring(0, index);
- d.dow = getDOW(d.dayName);
- d.soonerOrLater = -1; // less or equal
- d.thanDayOfMonth = Integer.parseInt(day.substring(index+2));
- } else {
- // it should be an integer value.
- d.thanDayOfMonth = Integer.parseInt(day);
- }
- }
- return d;
- }
-
- /**
- * Converts this RuleDay to the SimpleTimeZone day rule.
- * @return the converted SimpleTimeZone day rule
- */
- int getDayForSimpleTimeZone() {
- if (isLast()) {
- return -1;
- }
- return isEarlier() ? -getDay() : getDay();
- }
-
- /**
- * Converts this RuleDay to the SimpleTimeZone day-of-week rule.
- * @return the SimpleTimeZone day-of-week rule value
- */
- int getDayOfWeekForSimpleTimeZoneInt() {
- if (isEarlier() || isLater()) {
- return -getDayOfWeekNum();
- }
- return isLast() ? getDayOfWeekNum() : 0;
- }
-
- /**
- * @return the string representation of the {@link
- * #getDayOfWeekForSimpleTimeZoneInt} value
- */
- String getDayOfWeekForSimpleTimeZone() {
- int d = getDayOfWeekForSimpleTimeZoneInt();
- if (d == 0) {
- return "0";
- }
- String sign = "";
- if (d < 0) {
- sign = "-";
- d = -d;
- }
- return sign + toString(d);
- }
-
- private static DayOfWeek getDOW(String abbr) {
- return abbreviations.get(abbr);
- }
-
- /**
- * Converts the specified day of week value to the day-of-week
- * name defined in {@link java.util.Calenda}.
- * @param dow 1-based day of week value
- * @return the Calendar day of week name with "Calendar." prefix.
- * @throws IllegalArgumentException if the specified dow value is out of range.
- */
- static String toString(int dow) {
- if (dow >= DayOfWeek.SUNDAY.value() && dow <= DayOfWeek.SATURDAY.value()) {
- return "Calendar." + DayOfWeek.values()[dow - 1];
- }
- throw new IllegalArgumentException("wrong Day_of_Week number: " + dow);
- }
-}
--- a/jdk/make/tools/src/build/tools/javazic/RuleRec.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,232 +0,0 @@
-/*
- * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package build.tools.javazic;
-
-import java.util.StringTokenizer;
-
-/**
- * RuleRec class represents one record of the Rule set.
- *
- * @since 1.4
- */
-class RuleRec {
- private int fromYear;
- private int toYear;
- private String type;
- private Month inMonth;
- private RuleDay onDay;
- private Time atTime;
- private int save;
- private String letters;
- private String line;
- private boolean isLastRule;
-
- int getFromYear() {
- return fromYear;
- }
-
- int getToYear() {
- return toYear;
- }
-
- Month getMonth() {
- return inMonth;
- }
-
- int getMonthNum() {
- return inMonth.value();
- }
-
- RuleDay getDay() {
- return onDay;
- }
-
- Time getTime() {
- return atTime;
- }
-
- int getSave() {
- return save;
- }
-
- String getLine() {
- return line;
- }
-
- /**
- * Sets the line from the text file.
- * @param line the text of the line
- */
- void setLine(String line) {
- this.line = line;
- }
-
- /**
- * @return true if the rule type is "odd".
- */
- boolean isOdd() {
- return "odd".equals(type);
- }
-
- /**
- * @return true if the rule type is "even".
- */
- boolean isEven() {
- return "even".equals(type);
- }
-
- /**
- * Determines if this rule record is the last DST schedule rule.
- *
- * @return true if this rule record has "max" as TO (year).
- */
- boolean isLastRule() {
- return isLastRule;
- }
-
- /**
- * Determines if the unadjusted until time of the specified ZoneRec
- * is the same as the transition time of this rule in the same
- * year as the ZoneRec until year.
- *
- * @param zrec ZoneRec to compare to
- * @param save the amount of daylight saving in milliseconds
- * @param gmtOffset the GMT offset value in milliseconds
- * @return true if the unadjusted until time is the same as rule's
- * transition time.
- */
- boolean isSameTransition(ZoneRec zrec, int save, int gmtOffset) {
- long until, transition;
-
- if (zrec.getUntilTime().getType() != atTime.getType()) {
- until = zrec.getLocalUntilTime(save, gmtOffset);
- transition = Time.getLocalTime(zrec.getUntilYear(),
- getMonth(),
- getDay(),
- save,
- gmtOffset,
- atTime);
- } else {
- until = zrec.getLocalUntilTime();
- transition = Time.getLocalTime(zrec.getUntilYear(),
- getMonth(),
- getDay(),
- atTime.getTime());
- }
-
- return until == transition;
- }
-
- /**
- * Parses a Rule line and returns a RuleRec object.
- *
- * @param tokens a StringTokenizer object that should contain a
- * token for the "FROM" field and the rest.
- * @return a RuleRec object.
- */
- static RuleRec parse(StringTokenizer tokens) {
- RuleRec rec = new RuleRec();
- try {
- // FROM
- String token = tokens.nextToken();
- try {
- rec.fromYear = Integer.parseInt(token);
- } catch (NumberFormatException e) {
- // it's not integer
- if ("min".equals(token) || "minimum".equals(token)) {
- rec.fromYear = Zoneinfo.getMinYear();
- } else if ("max".equals(token) || "maximum".equals(token)) {
- rec.fromYear = Zoneinfo.getMaxYear();
- } else {
- Main.panic("invalid year value: "+token);
- }
- }
-
- // TO
- token = tokens.nextToken();
- rec.isLastRule = false;
- try {
- rec.toYear = Integer.parseInt(token);
- } catch (NumberFormatException e) {
- // it's not integer
- if ("min".equals(token) || "minimum".equals(token)) {
- rec.fromYear = Zoneinfo.getMinYear();
- } else if ("max".equals(token) || "maximum".equals(token)) {
- rec.toYear = Integer.MAX_VALUE;
- rec.isLastRule = true;
- } else if ("only".equals(token)) {
- rec.toYear = rec.fromYear;
- } else {
- Main.panic("invalid year value: "+token);
- }
- }
-
- // TYPE
- rec.type = tokens.nextToken();
-
- // IN
- rec.inMonth = Month.parse(tokens.nextToken());
-
- // ON
- rec.onDay = RuleDay.parse(tokens.nextToken());
-
- // AT
- rec.atTime = Time.parse(tokens.nextToken());
-
- // SAVE
- rec.save = (int) Time.parse(tokens.nextToken()).getTime();
-
- // LETTER/S
- rec.letters = tokens.nextToken();
- } catch (Exception e) {
- e.printStackTrace();
- }
- return rec;
- }
-
- /**
- * Calculates the transition time of the given year under this rule.
- * @param year the year value
- * @param gmtOffset the GMT offset value in milliseconds
- * @param save the amount of daylight save time
- * @return the transition time in milliseconds of the given year in UTC.
- */
- long getTransitionTime(int year, int gmtOffset, int save) {
- long time = Time.getLocalTime(year, getMonth(),
- getDay(), atTime.getTime());
- if (atTime.isSTD()) {
- time -= gmtOffset;
- } else if (atTime.isWall()) {
- time -= gmtOffset + save;
- }
- return time;
- }
-
- private static int getInt(StringTokenizer tokens) {
- String token = tokens.nextToken();
- return Integer.parseInt(token);
- }
-}
--- a/jdk/make/tools/src/build/tools/javazic/Simple.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,188 +0,0 @@
-/*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package build.tools.javazic;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.TreeMap;
-import java.util.TreeSet;
-
-/**
- * <code>Simple</code> generates TimeZoneData, which had been used as internal
- * data of TimeZone before J2SDK1.3.
- * Since J2SDK1.4 doesn't need TimeZoneData, this class is for maintenance
- * of old JDK release.
- */
-class Simple extends BackEnd {
-
- /**
- * Zone records which are applied for given year.
- */
- private static Map<String,ZoneRec> lastZoneRecs = new HashMap<>();
-
- /**
- * Rule records which are applied for given year.
- */
- private static Map<String,List<RuleRec>> lastRules = new TreeMap<>();
-
- /**
- * zone IDs sorted by their GMT offsets. If zone's GMT
- * offset will change in the future, its last known offset is
- * used.
- */
- private SortedMap<Integer, Set<String>> zonesByOffset = new TreeMap<>();
-
- /**
- * Sets last Rule records and Zone records for given timezone to
- * each Map.
- *
- * @param tz Timezone object for each zone
- * @return always 0
- */
- int processZoneinfo(Timezone tz) {
- String zonename = tz.getName();
-
- lastRules.put(zonename, tz.getLastRules());
- lastZoneRecs.put(zonename, tz.getLastZoneRec());
-
- // Populate zonesByOffset. (Zones that will change their
- // GMT offsets are also added to zonesByOffset here.)
- int lastKnownOffset = tz.getRawOffset();
- Set<String> set = zonesByOffset.get(lastKnownOffset);
- if (set == null) {
- set = new TreeSet<>();
- zonesByOffset.put(lastKnownOffset, set);
- }
- set.add(zonename);
-
- return 0;
- }
-
- /**
- * Generates TimeZoneData to output SimpleTimeZone data.
- * @param map Mappings object which is generated by {@link Main#compile}.
- * @return 0 if no error occurred, otherwise 1.
- */
- int generateSrc(Mappings map) {
- try {
- File outD = new File(Main.getOutputDir());
- outD.mkdirs();
-
- FileWriter fw =
- new FileWriter(new File(outD, "TimeZoneData.java"), false);
- BufferedWriter out = new BufferedWriter(fw);
-
- out.write("import java.util.SimpleTimeZone;\n\n");
- out.write(" static SimpleTimeZone zones[] = {\n");
-
- Map<String,String> a = map.getAliases();
- List<Integer> roi = map.getRawOffsetsIndex();
- List<Set<String>> roit = map.getRawOffsetsIndexTable();
-
- int index = 0;
- for (int offset : zonesByOffset.keySet()) {
- int o = roi.get(index);
- Set<String> set = zonesByOffset.get(offset);
- if (offset == o) {
- // Merge aliases into zonesByOffset
- set.addAll(roit.get(index));
- }
- index++;
-
- for (String key : set) {
- ZoneRec zrec;
- String realname;
- List<RuleRec> stz;
- if ((realname = a.get(key)) != null) {
- // if this alias is not targeted, ignore it.
- if (!Zone.isTargetZone(key)) {
- continue;
- }
- stz = lastRules.get(realname);
- zrec = lastZoneRecs.get(realname);
- } else {
- stz = lastRules.get(key);
- zrec = lastZoneRecs.get(key);
- }
-
- out.write("\t//--------------------------------------------------------------------\n");
- String s = Time.toFormedString(offset);
- out.write("\tnew SimpleTimeZone(" +
- Time.toFormedString(offset) + ", \"" + key + "\"");
- if (realname != null) {
- out.write(" /* " + realname + " */");
- }
-
- if (stz == null) {
- out.write("),\n");
- } else {
- RuleRec rr0 = stz.get(0);
- RuleRec rr1 = stz.get(1);
-
- out.write(",\n\t " + Month.toString(rr0.getMonthNum()) +
- ", " + rr0.getDay().getDayForSimpleTimeZone() + ", " +
- rr0.getDay().getDayOfWeekForSimpleTimeZone() + ", " +
- Time.toFormedString((int)rr0.getTime().getTime()) + ", " +
- rr0.getTime().getTypeForSimpleTimeZone() + ",\n" +
-
- "\t " + Month.toString(rr1.getMonthNum()) + ", " +
- rr1.getDay().getDayForSimpleTimeZone() + ", " +
- rr1.getDay().getDayOfWeekForSimpleTimeZone() + ", " +
- Time.toFormedString((int)rr1.getTime().getTime())+ ", " +
- rr1.getTime().getTypeForSimpleTimeZone() + ",\n" +
-
- "\t " + Time.toFormedString(rr0.getSave()) + "),\n");
-
- out.write("\t// " + rr0.getLine() + "\n");
- out.write("\t// " + rr1.getLine() + "\n");
- }
-
- String zline = zrec.getLine();
- if (zline.indexOf("Zone") == -1) {
- zline = "Zone " + key + "\t" + zline.trim();
- }
- out.write("\t// " + zline + "\n");
- }
- }
- out.write(" };\n");
-
- out.close();
- fw.close();
- } catch(IOException e) {
- Main.panic("IO error: "+e.getMessage());
- return 1;
- }
-
- return 0;
- }
-}
--- a/jdk/make/tools/src/build/tools/javazic/Time.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,343 +0,0 @@
-/*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package build.tools.javazic;
-
-import java.util.Locale;
-import sun.util.calendar.CalendarDate;
-import sun.util.calendar.CalendarSystem;
-import sun.util.calendar.Gregorian;
-
-/**
- * Time class represents the "AT" field and other time related information.
- *
- * @since 1.4
- */
-class Time {
-
- static final Gregorian gcal = CalendarSystem.getGregorianCalendar();
-
- // type is wall clock time
- private static final int WALL = 1;
-
- // type is standard time
- private static final int STD = 2;
-
- // type is UTC
- private static final int UTC = 3;
-
- // type of representing time
- private int type;
-
- /**
- * Time from the EPOCH in milliseconds
- */
- private long time;
-
- /**
- * Current time in milliseconds
- */
- private static final long currentTime = System.currentTimeMillis();
-
- Time() {
- time = 0L;
- }
-
- Time(long time) {
- this.time = time;
- }
-
- void setType(int type) {
- this.type = type;
- }
-
- long getTime() {
- return time;
- }
-
- int getType() {
- return type;
- }
-
- static long getCurrentTime() {
- return currentTime;
- }
-
- /**
- * @return true if the time is represented in wall-clock time.
- */
- boolean isWall() {
- return type == WALL;
- }
-
- /**
- * @return true if the time is represented in standard time.
- */
- boolean isSTD() {
- return type == STD;
- }
-
- /**
- * @return true if the time is represented in UTC time.
- */
- boolean isUTC() {
- return type == UTC;
- }
-
- /**
- * Converts the type to a string that represents the type in the
- * SimpleTimeZone time mode. (e.g., "SimpleTimeZone.WALL_TIME").
- * @return the converted string or null if the type is undefined.
- */
- String getTypeForSimpleTimeZone() {
- String stz = "SimpleTimeZone.";
- if (isWall()) {
- return stz+"WALL_TIME";
- }
- else if (isSTD()) {
- return stz+"STANDARD_TIME";
- }
- else if (isUTC()) {
- return stz+"UTC_TIME";
- }
- else {
- return null;
- }
- }
-
- /**
- * Converts the given Gregorian calendar field values to local time.
- * Local time is represented by the amount of milliseconds from
- * January 1, 1970 0:00 GMT.
- * @param year the year value
- * @param month the Month value
- * @param day the day represented by {@link RuleDay}
- * @param save the amount of daylight time in milliseconds
- * @param gmtOffset the GMT offset in milliseconds
- * @param time the time of the day represented by {@link Time}
- * @return local time
- */
- static long getLocalTime(int year, Month month, RuleDay day, int save,
- int gmtOffset, Time time) {
- long t = time.getTime();
-
- if (time.isSTD())
- t = time.getTime() + save;
- else if (time.isUTC())
- t = time.getTime() + save + gmtOffset;
-
- return getLocalTime(year, month, day, t);
- }
-
- /**
- * Converts the given Gregorian calendar field values to local time.
- * Local time is represented by the amount of milliseconds from
- * January 1, 1970 0:00 GMT.
- * @param year the year value
- * @param month the Month value
- * @param day the day value
- * @param time the time of the day in milliseconds
- * @return local time
- */
- static long getLocalTime(int year, Month month, int day, long time) {
- CalendarDate date = gcal.newCalendarDate(null);
- date.setDate(year, month.value(), day);
- long millis = gcal.getTime(date);
- return millis + time;
- }
-
- /**
- * Equivalent to <code>getLocalTime(year, month, day, (long)time)</code>.
- * @param year the year value
- * @param month the Month value
- * @param day the day value
- * @param time the time of the day in milliseconds
- * @return local time
- */
- static long getLocalTime(int year, Month month, int day, int time) {
- return getLocalTime(year, month, day, (long)time);
- }
-
- /**
- * Equivalent to {@link #getLocalTime(int, Month, RuleDay, int)
- * getLocalTime(year, month, day, (int) time)}.
- * @param year the year value
- * @param month the Month value
- * @param day the day represented by {@link RuleDay}
- * @param time the time of the day represented by {@link Time}
- * @return local time
- */
- static long getLocalTime(int year, Month month, RuleDay day, long time) {
- return getLocalTime(year, month, day, (int) time);
- }
-
- /**
- * Converts the given Gregorian calendar field values to local time.
- * Local time is represented by the amount of milliseconds from
- * January 1, 1970 0:00 GMT.
- * @param year the year value
- * @param month the Month value
- * @param day the day represented by {@link RuleDay}
- * @param time the time of the day represented by {@link Time}
- * @return local time
- */
- static long getLocalTime(int year, Month month, RuleDay day, int time) {
- CalendarDate cdate = gcal.newCalendarDate(null);
- int monthValue = month.value();
-
- if (day.isLast()) { // e.g., "lastSun"
- cdate.setDate(year, monthValue, 1);
- cdate.setDayOfMonth(gcal.getMonthLength(cdate));
- cdate = gcal.getNthDayOfWeek(-1, day.getDayOfWeekNum(), cdate);
- } else if (day.isLater()) { // e.g., "Sun>=1"
- cdate.setDate(year, monthValue, day.getDay());
- cdate = gcal.getNthDayOfWeek(1, day.getDayOfWeekNum(), cdate);
- } else if (day.isExact()) {
- cdate.setDate(year, monthValue, day.getDay());
- } else if (day.isEarlier()) { // e.g., "Sun<=15"
- cdate.setDate(year, monthValue, day.getDay());
- cdate = gcal.getNthDayOfWeek(-1, day.getDayOfWeekNum(), cdate);
- } else {
- Main.panic("invalid day type: " + day);
- }
- return gcal.getTime(cdate) + time;
- }
-
- /**
- * Parses the given "AT" field and constructs a Time object.
- * @param the "AT" field string
- * @return the Time object
- */
- static Time parse(String time) {
- int sign;
- int index = 0;
- Time tm;
-
- if (time.charAt(0) == '-') {
- sign = -1;
- index++;
- } else {
- sign = 1;
- }
- int val = 0;
- int num = 0;
- int countDelim = 0;
- while (index < time.length()) {
- char c = time.charAt(index++);
- if (c == ':') {
- val = val * 60 + num;
- countDelim++;
- num = 0;
- continue;
- }
- int d = Character.digit(c, 10);
- if (d == -1) {
- --index;
- break;
- }
- num = num * 10 + d;
- }
- val = val * 60 + num;
- // convert val to second
- for (; countDelim < 2; countDelim++) {
- val *= 60;
- }
- tm = new Time((long)val * 1000 * sign);
- if (index < time.length()) {
- char c = time.charAt(index++);
- if (c == 's') {
- tm.setType(Time.STD);
- } else if (c == 'u' || c == 'g' || c == 'z') {
- tm.setType(Time.UTC);
- } else if (c == 'w') {
- tm.setType(Time.WALL);
- } else {
- Main.panic("unknown time mode: "+c);
- }
- } else {
- tm.setType(Time.WALL);
- }
- return tm;
- }
-
- /**
- * Converts the given milliseconds string to a "[+-]hh:mm" string.
- * @param ms the milliseconds string
- */
- static String toGMTFormat(String ms) {
- long sec = Long.parseLong(ms) / 1000;
- char sign;
- if (sec < 0) {
- sign = '-';
- sec = -sec;
- } else {
- sign = '+';
- }
- return String.format((Locale)null, "%c%02d:%02d",
- sign, sec/3600, (sec%3600)/60);
- }
-
- /**
- * Converts the given millisecond value to a string for a
- * SimpleTimeZone parameter.
- * @param ms the millisecond value
- * @return the string in a human readable form
- */
- static String toFormedString(int ms) {
- StringBuilder s = new StringBuilder();
- boolean minus = false;
-
- if (ms < 0) {
- s.append("-");
- minus = true;
- ms = -ms;
- } else if (ms == 0) {
- return "0";
- }
-
- int hour = ms / (60 * 60 * 1000);
- ms %= (60 * 60 * 1000);
- int minute = ms / (60 * 1000);
-
- if (hour != 0) {
- if (minus && minute != 0) {
- s.append("(");
- }
- s.append(Integer.toString(hour) + "*ONE_HOUR");
- }
-
- if (minute != 0) {
- if (hour != 0) {
- s.append("+");
- }
- s.append(Integer.toString(minute) + "*ONE_MINUTE");
- if (minus && hour != 0) {
- s.append(")");
- }
- }
-
- return s.toString();
- }
-}
--- a/jdk/make/tools/src/build/tools/javazic/Timezone.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,454 +0,0 @@
-/*
- * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package build.tools.javazic;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Timezone represents all information of a single point of time to
- * generate its time zone database.
- *
- * @since 1.4
- */
-class Timezone {
- /**
- * zone name of this time zone
- */
- private String name;
-
- /**
- * transition time values in UTC (millisecond)
- */
- private List<Long> transitions;
-
- /**
- * All offset values in millisecond
- * @see sun.util.calendar.ZoneInfo
- */
- private List<Integer> offsets;
-
- /**
- * Indices of GMT offset values (both raw and raw+saving)
- * at transitions
- */
- private List<Integer> gmtOffsets;
-
- /**
- * Indices of regular or "direct" saving time values
- * at transitions
- */
- private List<Integer> dstOffsets;
-
- /**
- * Zone records of this time zone
- */
- private List<ZoneRec> usedZoneRecs;
-
- /**
- * Rule records referred to by this time zone
- */
- private List<RuleRec> usedRuleRecs;
-
- /**
- * Type of DST rules in this time zone
- */
- private int dstType;
- static final int UNDEF_DST = 0; // DST type not set yet
- static final int NO_DST = 1; // never observed DST
- static final int LAST_DST = 2; // last rule ends in DST (all year round DST-only)
- static final int X_DST = 3; // used to observe DST
- static final int DST = 4; // observing DST regularly
-
- /**
- * Raw GMT offset of this time zone in the last rule
- */
- private int rawOffset;
-
- /**
- * The CRC32 value of the transitions data
- */
- private int crc32;
-
- /**
- * The last ZoneRec
- */
- private ZoneRec lastZoneRec;
-
- /**
- * The last DST rules. lastRules[0] is the DST start
- * rule. lastRules[1] is the DST end rules.
- */
- private List<RuleRec> lastRules;
-
- /**
- * The amount of DST saving value (millisecond) in the last DST
- * rule.
- */
- private int lastSaving;
-
- /**
- * true if the raw offset will change in the future time.
- */
- private boolean willRawOffsetChange = false;
-
-
- /**
- * Constracts a Timezone object with the given zone name.
- * @param name the zone name
- */
- Timezone(String name) {
- this.name = name;
- }
-
- /**
- * @return the number of transitions
- */
- int getNTransitions() {
- if (transitions == null) {
- return 0;
- }
- return transitions.size();
- }
-
- /**
- * @return the zone name
- */
- String getName() {
- return name;
- }
-
- /**
- * Returns the list of all rule records that have been referred to
- * by this time zone.
- * @return the rule records list
- */
- List<RuleRec> getRules() {
- return usedRuleRecs;
- }
-
- /**
- * Returns the list of all zone records that have been referred to
- * by this time zone.
- * @return the zone records list
- */
- List<ZoneRec> getZones() {
- return usedZoneRecs;
- }
-
- /**
- * @return the transition table (list)
- */
- List<Long> getTransitions() {
- return transitions;
- }
-
- /**
- * @return the offsets list
- */
- List<Integer> getOffsets() {
- return offsets;
- }
-
- /**
- * @return the DST saving offsets list
- */
- List<Integer> getDstOffsets() {
- return dstOffsets;
- }
-
- /**
- * @return the GMT offsets list
- */
- List<Integer> getGmtOffsets() {
- return gmtOffsets;
- }
-
- /**
- * @return the checksum (crc32) value of the trasition table
- */
- int getCRC32() {
- return crc32;
- }
-
- /**
- * @return true if the GMT offset of this time zone would change
- * after the time zone database has been generated, false, otherwise.
- */
- boolean willGMTOffsetChange() {
- return willRawOffsetChange;
- }
-
- /**
- * @return the last known GMT offset value in milliseconds
- */
- int getRawOffset() {
- return rawOffset;
- }
-
- /**
- * Sets time zone's GMT offset to <code>offset</code>.
- * @param offset the GMT offset value in milliseconds
- */
- void setRawOffset(int offset) {
- rawOffset = offset;
- }
-
- /**
- * Sets time zone's GMT offset value to <code>offset</code>. If
- * <code>startTime</code> is future time, then the {@link
- * #willRawOffsetChange} value is set to true.
- * @param offset the GMT offset value in milliseconds
- * @param startTime the UTC time at which the GMT offset is in effective
- */
- void setRawOffset(int offset, long startTime) {
- // if this rawOffset is for the future time, let the run-time
- // look for the current GMT offset.
- if (startTime > Time.getCurrentTime()) {
- willRawOffsetChange = true;
- }
- setRawOffset(offset);
- }
-
- /**
- * Adds the specified transition information to the end of the transition table.
- * @param time the UTC time at which this transition happens
- * @param offset the total amount of the offset from GMT in milliseconds
- * @param dstOffset the amount of time in milliseconds saved at this transition
- */
- void addTransition(long time, int offset, int dstOffset) {
- if (transitions == null) {
- transitions = new ArrayList<Long>();
- offsets = new ArrayList<Integer>();
- dstOffsets = new ArrayList<Integer>();
- }
- transitions.add(time);
- offsets.add(offset);
- dstOffsets.add(dstOffset);
- }
-
- /**
- * Sets the type of historical daylight saving time
- * observation. For example, China used to observed daylight
- * saving time, but it no longer does. Then, X_DST is set to the
- * China time zone.
- * @param type the type of daylight saving time
- */
- void setDSTType(int type) {
- dstType = type;
- }
-
- /**
- * @return the type of historical daylight saving time
- * observation.
- */
- int getDSTType() {
- return dstType;
- }
-
- /**
- * Adds the specified zone record to the zone records list.
- * @param rec the zone record
- */
- void addUsedRec(ZoneRec rec) {
- if (usedZoneRecs == null) {
- usedZoneRecs = new ArrayList<ZoneRec>();
- }
- usedZoneRecs.add(rec);
- }
-
- /**
- * Adds the specified rule record to the rule records list.
- * @param rec the rule record
- */
- void addUsedRec(RuleRec rec) {
- if (usedRuleRecs == null) {
- usedRuleRecs = new ArrayList<RuleRec>();
- }
- // if the last used rec is the same as the given rec, avoid
- // putting the same rule.
- int n = usedRuleRecs.size();
- for (int i = 0; i < n; i++) {
- if (usedRuleRecs.get(i).equals(rec)) {
- return;
- }
- }
- usedRuleRecs.add(rec);
- }
-
- /**
- * Sets the last zone record for this time zone.
- * @param the last zone record
- */
- void setLastZoneRec(ZoneRec zrec) {
- lastZoneRec = zrec;
- }
-
- /**
- * @return the last zone record for this time zone.
- */
- ZoneRec getLastZoneRec() {
- return lastZoneRec;
- }
-
- /**
- * Sets the last rule records for this time zone. Those are used
- * for generating SimpleTimeZone parameters.
- * @param rules the last rule records
- */
- void setLastRules(List<RuleRec> rules) {
- int n = rules.size();
- if (n > 0) {
- lastRules = rules;
- RuleRec rec = rules.get(0);
- int offset = rec.getSave();
- if (offset > 0) {
- setLastDSTSaving(offset);
- } else {
- System.err.println("\t No DST starting rule in the last rules.");
- }
- }
- }
-
- /**
- * @return the last rule records for this time zone.
- */
- List<RuleRec> getLastRules() {
- return lastRules;
- }
-
- /**
- * Sets the last daylight saving amount.
- * @param the daylight saving amount
- */
- void setLastDSTSaving(int offset) {
- lastSaving = offset;
- }
-
- /**
- * @return the last daylight saving amount.
- */
- int getLastDSTSaving() {
- return lastSaving;
- }
-
- /**
- * Calculates the CRC32 value from the transition table and sets
- * the value to <code>crc32</code>.
- */
- void checksum() {
- if (transitions == null) {
- crc32 = 0;
- return;
- }
- Checksum sum = new Checksum();
- for (int i = 0; i < transitions.size(); i++) {
- int offset = offsets.get(i);
- // adjust back to make the transition in local time
- sum.update(transitions.get(i) + offset);
- sum.update(offset);
- sum.update(dstOffsets.get(i));
- }
- crc32 = (int)sum.getValue();
- }
-
- /**
- * Removes unnecessary transitions for Java time zone support.
- */
- void optimize() {
- // if there is only one offset, delete all transitions. This
- // could happen if only time zone abbreviations changed.
- if (gmtOffsets.size() == 1) {
- transitions = null;
- usedRuleRecs = null;
- setDSTType(NO_DST);
- return;
- }
- for (int i = 0; i < (transitions.size() - 2); i++) { // don't remove the last one
- if (transitions.get(i) == transitions.get(i+1)) {
- transitions.remove(i);
- offsets.remove(i);
- dstOffsets.remove(i);
- i--;
- }
- }
-
- for (int i = 0; i < (transitions.size() - 2); i++) { // don't remove the last one
- if (offsets.get(i) == offsets.get(i+1)
- && dstOffsets.get(i) == dstOffsets.get(i+1)) {
- transitions.remove(i+1);
- offsets.remove(i+1);
- dstOffsets.remove(i+1);
- i--;
- }
- }
- }
-
- /**
- * Stores the specified offset value from GMT in the GMT offsets
- * table and returns its index. The offset value includes the base
- * GMT offset and any additional daylight saving if applicable. If
- * the same value as the specified offset is already in the table,
- * its index is returned.
- * @param offset the offset value in milliseconds
- * @return the index to the offset value in the GMT offsets table.
- */
- int getOffsetIndex(int offset) {
- return getOffsetIndex(offset, 0);
- }
-
- /**
- * Stores the specified daylight saving value in the GMT offsets
- * table and returns its index. If the same value as the specified
- * offset is already in the table, its index is returned. If 0 is
- * specified, it's not stored in the table and -1 is returned.
- * @param offset the offset value in milliseconds
- * @return the index to the specified offset value in the GMT
- * offsets table, or -1 if 0 is specified.
- */
- int getDstOffsetIndex(int offset) {
- if (offset == 0) {
- return -1;
- }
- return getOffsetIndex(offset, 1);
- }
-
- private int getOffsetIndex(int offset, int index) {
- if (gmtOffsets == null) {
- gmtOffsets = new ArrayList<Integer>();
- }
- for (int i = index; i < gmtOffsets.size(); i++) {
- if (offset == gmtOffsets.get(i)) {
- return i;
- }
- }
- if (gmtOffsets.size() < index) {
- gmtOffsets.add(0);
- }
- gmtOffsets.add(offset);
- return gmtOffsets.size() - 1;
- }
-}
--- a/jdk/make/tools/src/build/tools/javazic/Zone.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,168 +0,0 @@
-/*
- * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package build.tools.javazic;
-
-import java.io.BufferedReader;
-import java.io.FileReader;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.StringTokenizer;
-
-/**
- * Zone holds information corresponding to a "Zone" part of a time
- * zone definition file.
- *
- * @since 1.4
- */
-class Zone {
- // zone name (e.g., "America/Los_Angeles")
- private String name;
-
- // zone records
- private List<ZoneRec> list;
-
- // target zone names for this compilation
- private static Set<String> targetZones;
-
- /**
- * Constructs a Zone with the specified zone name.
- * @param name the zone name
- */
- Zone(String name) {
- this.name = name;
- list = new ArrayList<ZoneRec>();
- }
-
- /**
- * Reads time zone names to be generated, called "target zone
- * name", from the specified text file and creats an internal hash
- * table to keep those names. It's assumed that one text line
- * contains a zone name or comments if it starts with
- * '#'. Comments can't follow a zone name in a single line.
- * @param fileName the text file name
- */
- static void readZoneNames(String fileName) {
- if (fileName == null) {
- return;
- }
- BufferedReader in = null;
- try {
- FileReader fr = new FileReader(fileName);
- in = new BufferedReader(fr);
- } catch (FileNotFoundException e) {
- Main.panic("can't open file: " + fileName);
- }
- targetZones = new HashSet<String>();
- String line;
-
- try {
- while ((line = in.readLine()) != null) {
- line = line.trim();
- if (line.length() == 0 || line.charAt(0) == '#') {
- continue;
- }
- if (!targetZones.add(line)) {
- Main.warning("duplicated target zone name: " + line);
- }
- }
- in.close();
- } catch (IOException e) {
- Main.panic("IO error: "+e.getMessage());
- }
- }
-
- /**
- * Determines whether the specified zone is one of the target zones.
- * If no target zones are specified, this method always returns
- * true for any zone name.
- * @param zoneName the zone name
- * @return true if the specified name is a target zone.
- */
- static boolean isTargetZone(String zoneName) {
- if (targetZones == null) {
- return true;
- }
- return targetZones.contains(zoneName);
- }
-
- /**
- * Forces to add "MET" to the target zone table. This is because
- * there is a conflict between Java zone name "WET" and Olson zone
- * name.
- */
- static void addMET() {
- if (targetZones != null) {
- targetZones.add("MET");
- }
- }
-
- /**
- * @return the zone name
- */
- String getName() {
- return name;
- }
-
- /**
- * Adds the specified zone record to the zone record list.
- */
- void add(ZoneRec rec) {
- list.add(rec);
- }
-
- /**
- * @param index the index at which the zone record in the list is returned.
- * @return the zone record specified by the index.
- */
- ZoneRec get(int index) {
- return list.get(index);
- }
-
- /**
- * @return the size of the zone record list
- */
- int size() {
- return list.size();
- }
-
- /**
- * Resolves the reference to a rule in each zone record.
- * @param zi the Zoneinfo object with which the rule reference is
- * resolved.
- */
- void resolve(Zoneinfo zi) {
- for (int i = 0; i < list.size(); i++) {
- ZoneRec rec = list.get(i);
- rec.resolve(zi);
- }
- }
-}
--- a/jdk/make/tools/src/build/tools/javazic/ZoneRec.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,252 +0,0 @@
-/*
- * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package build.tools.javazic;
-
-import java.io.BufferedReader;
-import java.io.FileReader;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.StringTokenizer;
-
-/**
- * ZoneRec hold information of time zone corresponding to each text
- * line of the "Zone" part.
- *
- * @since 1.4
- */
-class ZoneRec {
- private int gmtOffset;
- private String ruleName;
- private int directSave;
- private Rule ruleRef;
- private String format;
- private boolean hasUntil;
- private int untilYear;
- private Month untilMonth;
- private RuleDay untilDay;
- private Time untilTime;
- private long untilInMillis;
- private String line;
-
- /**
- * @return the "UNTIL" value in milliseconds
- */
- Time getUntilTime() {
- return untilTime;
- }
-
- /**
- * @return the GMT offset value in milliseconds
- */
- int getGmtOffset() {
- return gmtOffset;
- }
-
- /**
- * @return the rule name to which this zone record refers
- */
- String getRuleName() {
- return ruleName;
- }
-
- /**
- * @return the amount of saving time directly defined in the
- * "RULES/SAVE" field.
- */
- int getDirectSave() {
- return directSave;
- }
-
- /**
- * @return true if this zone record has a reference to a rule
- */
- boolean hasRuleReference() {
- return ruleRef != null;
- }
-
- /**
- * Returns the "FORMAT" field string of this zone record. This
- * @return the "FORMAT" field
- */
- String getFormat() {
- return format;
- }
-
- /**
- * @return the year in the "UNTIL" field
- */
- int getUntilYear() {
- return untilYear;
- }
-
- /**
- * Returns the "UNTIL" field value in milliseconds from Janurary
- * 1, 1970 0:00 GMT.
- * @param currentSave the amount of daylight saving in
- * milliseconds that is used to adjust wall-clock time.
- * @return the milliseconds value of the "UNTIL" field
- */
- long getUntilTime(int currentSave) {
- if (untilTime.isWall()) {
- return untilInMillis - currentSave;
- }
- return untilInMillis;
- }
-
- /**
- * Returns the "UNTIL" time in milliseconds without adjusting GMT
- * offsets or daylight saving.
- * @return local "UNTIL" time in milliseconds
- */
- long getLocalUntilTime() {
- return Time.getLocalTime(untilYear,
- untilMonth,
- untilDay,
- untilTime.getTime());
- }
-
- /**
- * Returns the "UNTIL" time in milliseconds with adjusting GMT offsets and daylight saving.
- * @return the "UNTIL" time after the adjustment
- */
- long getLocalUntilTime(int save, int gmtOffset) {
- return Time.getLocalTime(untilYear,
- untilMonth,
- untilDay,
- save,
- gmtOffset,
- untilTime);
- }
-
- /**
- * @return the text line of this zone record
- */
- String getLine() {
- return line;
- }
-
- /**
- * Sets the specified text line to this zone record
- */
- void setLine(String line) {
- this.line = line;
- }
-
- /**
- * @return true if this zone record has the "UNTIL" field
- */
- boolean hasUntil() {
- return this.hasUntil;
- }
-
- /**
- * Adjusts the "UNTIL" time to GMT offset if this zone record has
- * it. <code>untilTime</code> is not adjusted to daylight saving
- * in this method.
- */
- void adjustTime() {
- if (!hasUntil()) {
- return;
- }
- if (untilTime.isSTD() || untilTime.isWall()) {
- // adjust to gmt offset only here. adjust to real
- // wall-clock time when tracking rules
- untilInMillis -= gmtOffset;
- }
- }
-
- /**
- * @return the reference to the Rule object
- */
- Rule getRuleRef() {
- return ruleRef;
- }
-
- /**
- * Resolves the reference to a Rule and adjusts its "UNTIL" time
- * to GMT offset.
- */
- void resolve(Zoneinfo zi) {
- if (ruleName != null && (!"-".equals(ruleName))) {
- ruleRef = zi.getRule(ruleName);
- }
- adjustTime();
- }
-
- /**
- * Parses a Zone text line that is described by a StringTokenizer.
- * @param tokens represents tokens of a Zone text line
- * @return the zone record produced by parsing the text
- */
- static ZoneRec parse(StringTokenizer tokens) {
- ZoneRec rec = new ZoneRec();
- try {
- rec.gmtOffset = (int) Time.parse(tokens.nextToken()).getTime();
- String token = tokens.nextToken();
- char c = token.charAt(0);
- if (c >= '0' && c <= '9') {
- rec.directSave = (int) Time.parse(token).getTime();
- } else {
- rec.ruleName = token;
- }
- rec.format = tokens.nextToken();
- if (tokens.hasMoreTokens()) {
- rec.hasUntil = true;
- rec.untilYear = Integer.parseInt(tokens.nextToken());
- if (tokens.hasMoreTokens()) {
- rec.untilMonth = Month.parse(tokens.nextToken());
- } else {
- rec.untilMonth = Month.JANUARY;
- }
- if (tokens.hasMoreTokens()) {
- rec.untilDay = RuleDay.parse(tokens.nextToken());
- } else {
- rec.untilDay = new RuleDay(1);
- }
- if (tokens.hasMoreTokens()) {
- rec.untilTime = Time.parse(tokens.nextToken());
- } else {
- rec.untilTime = Time.parse("0:00");
- }
- rec.untilInMillis = rec.getLocalUntilTime();
- }
- } catch (Exception e) {
- // TODO: error reporting
- e.printStackTrace();
- }
- return rec;
- }
-
- private static void panic(String msg) {
- Main.panic(msg);
- }
-}
--- a/jdk/make/tools/src/build/tools/javazic/Zoneinfo.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,569 +0,0 @@
-/*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package build.tools.javazic;
-
-import java.io.BufferedReader;
-import java.io.FileReader;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.StringTokenizer;
-
-/**
- * Zoneinfo provides javazic compiler front-end functionality.
- * @since 1.4
- */
-class Zoneinfo {
-
- private static final int minYear = 1900;
- private static final int maxYear = 2037;
- private static final long minTime = Time.getLocalTime(minYear, Month.JANUARY, 1, 0);
- private static int startYear = minYear;
- private static int endYear = maxYear;
-
- /**
- * True if javazic should generate a list of SimpleTimeZone
- * instances for the SimpleTimeZone-based time zone support.
- */
- static boolean isYearForTimeZoneDataSpecified = false;
-
- /**
- * Zone name to Zone mappings
- */
- private Map<String,Zone> zones;
-
- /**
- * Rule name to Rule mappings
- */
- private Map<String,Rule> rules;
-
- /**
- * Alias name to real name mappings
- */
- private Map<String,String> aliases;
-
- /**
- * Constracts a Zoneinfo.
- */
- Zoneinfo() {
- zones = new HashMap<String,Zone>();
- rules = new HashMap<String,Rule>();
- aliases = new HashMap<String,String>();
- }
-
- /**
- * Adds the given zone to the list of Zones.
- * @param zone Zone to be added to the list.
- */
- void add(Zone zone) {
- String name = zone.getName();
- zones.put(name, zone);
- }
-
- /**
- * Adds the given rule to the list of Rules.
- * @param rule Rule to be added to the list.
- */
- void add(Rule rule) {
- String name = rule.getName();
- rules.put(name, rule);
- }
-
- /**
- * Puts the specifid name pair to the alias table.
- * @param name1 an alias time zone name
- * @param name2 the real time zone of the alias name
- */
- void putAlias(String name1, String name2) {
- aliases.put(name1, name2);
- }
-
- /**
- * Sets the given year for SimpleTimeZone list output.
- * This method is called when the -S option is specified.
- * @param year the year for which SimpleTimeZone list should be generated
- */
- static void setYear(int year) {
- setStartYear(year);
- setEndYear(year);
- isYearForTimeZoneDataSpecified = true;
- }
-
- /**
- * Sets the start year.
- * @param year the start year value
- * @throws IllegalArgumentException if the specified year value is
- * smaller than the minimum year or greater than the end year.
- */
- static void setStartYear(int year) {
- if (year < minYear || year > endYear) {
- throw new IllegalArgumentException("invalid start year specified: " + year);
- }
- startYear = year;
- }
-
- /**
- * @return the start year value
- */
- static int getStartYear() {
- return startYear;
- }
-
- /**
- * Sets the end year.
- * @param year the end year value
- * @throws IllegalArgumentException if the specified year value is
- * smaller than the start year or greater than the maximum year.
- */
- static void setEndYear(int year) {
- if (year < startYear || year > maxYear) {
- throw new IllegalArgumentException();
- }
- endYear = year;
- }
-
- /**
- * @return the end year value
- */
- static int getEndYear() {
- return endYear;
- }
-
- /**
- * @return the minimum year value
- */
- static int getMinYear() {
- return minYear;
- }
-
- /**
- * @return the maximum year value
- */
- static int getMaxYear() {
- return maxYear;
- }
-
- /**
- * @return the alias table
- */
- Map<String,String> getAliases() {
- return aliases;
- }
-
- /**
- * @return the Zone list
- */
- Map<String,Zone> getZones() {
- return zones;
- }
-
- /**
- * @return a Zone specified by name.
- * @param name a zone name
- */
- Zone getZone(String name) {
- return zones.get(name);
- }
-
- /**
- * @return a Rule specified by name.
- * @param name a rule name
- */
- Rule getRule(String name) {
- return rules.get(name);
- }
-
- private static String line;
-
- private static int lineNum;
-
- /**
- * Parses the specified time zone data file and creates a Zoneinfo
- * that has all Rules, Zones and Links (aliases) information.
- * @param fname the time zone data file name
- * @return a Zoneinfo object
- */
- static Zoneinfo parse(String fname) {
- BufferedReader in = null;
- try {
- FileReader fr = new FileReader(fname);
- in = new BufferedReader(fr);
- } catch (FileNotFoundException e) {
- panic("can't open file: "+fname);
- }
- Zoneinfo zi = new Zoneinfo();
- boolean continued = false;
- Zone zone = null;
- String l;
- lineNum = 0;
-
- try {
- while ((line = in.readLine()) != null) {
- lineNum++;
- // skip blank and comment lines
- if (line.length() == 0 || line.charAt(0) == '#') {
- continue;
- }
-
- // trim trailing comments
- int rindex = line.lastIndexOf('#');
- if (rindex != -1) {
- // take the data part of the line
- l = line.substring(0, rindex);
- } else {
- l = line;
- }
-
- StringTokenizer tokens = new StringTokenizer(l);
- if (!tokens.hasMoreTokens()) {
- continue;
- }
- String token = tokens.nextToken();
-
- if (continued || "Zone".equals(token)) {
- if (zone == null) {
- if (!tokens.hasMoreTokens()) {
- panic("syntax error: zone no more token");
- }
- token = tokens.nextToken();
- // if the zone name is in "GMT+hh" or "GMT-hh"
- // format, ignore it due to spec conflict.
- if (token.startsWith("GMT+") || token.startsWith("GMT-")) {
- continue;
- }
- zone = new Zone(token);
- } else {
- // no way to push the current token back...
- tokens = new StringTokenizer(l);
- }
-
- ZoneRec zrec = ZoneRec.parse(tokens);
- zrec.setLine(line);
- zone.add(zrec);
- if ((continued = zrec.hasUntil()) == false) {
- if (Zone.isTargetZone(zone.getName())) {
- // zone.resolve(zi);
- zi.add(zone);
- }
- zone = null;
- }
- } else if ("Rule".equals(token)) {
- if (!tokens.hasMoreTokens()) {
- panic("syntax error: rule no more token");
- }
- token = tokens.nextToken();
- Rule rule = zi.getRule(token);
- if (rule == null) {
- rule = new Rule(token);
- zi.add(rule);
- }
- RuleRec rrec = RuleRec.parse(tokens);
- rrec.setLine(line);
- rule.add(rrec);
- } else if ("Link".equals(token)) {
- // Link <newname> <oldname>
- try {
- String name1 = tokens.nextToken();
- String name2 = tokens.nextToken();
-
- // if the zone name is in "GMT+hh" or "GMT-hh"
- // format, ignore it due to spec conflict with
- // custom time zones. Also, ignore "ROC" for
- // PC-ness.
- if (name2.startsWith("GMT+") || name2.startsWith("GMT-")
- || "ROC".equals(name2)) {
- continue;
- }
- zi.putAlias(name2, name1);
- } catch (Exception e) {
- panic("syntax error: no more token for Link");
- }
- }
- }
- in.close();
- } catch (IOException ex) {
- panic("IO error: " + ex.getMessage());
- }
-
- return zi;
- }
-
- /**
- * Interprets a zone and constructs a Timezone object that
- * contains enough information on GMT offsets and DST schedules to
- * generate a zone info database.
- *
- * @param zoneName the zone name for which a Timezone object is
- * constructed.
- *
- * @return a Timezone object that contains all GMT offsets and DST
- * rules information.
- */
- Timezone phase2(String zoneName) {
- Timezone tz = new Timezone(zoneName);
- Zone zone = getZone(zoneName);
- zone.resolve(this);
-
- // TODO: merge phase2's for the regular and SimpleTimeZone ones.
- if (isYearForTimeZoneDataSpecified) {
- ZoneRec zrec = zone.get(zone.size()-1);
- tz.setLastZoneRec(zrec);
- tz.setRawOffset(zrec.getGmtOffset());
- if (zrec.hasRuleReference()) {
- /*
- * This part assumes that the specified year is covered by
- * the rules referred to by the last zone record.
- */
- List<RuleRec> rrecs = zrec.getRuleRef().getRules(startYear);
-
- if (rrecs.size() == 2) {
- // make sure that one is a start rule and the other is
- // an end rule.
- RuleRec r0 = rrecs.get(0);
- RuleRec r1 = rrecs.get(1);
- if (r0.getSave() == 0 && r1.getSave() > 0) {
- rrecs.set(0, r1);
- rrecs.set(1, r0);
- } else if (!(r0.getSave() > 0 && r1.getSave() == 0)) {
- rrecs = null;
- Main.error(zoneName + ": rules for " + startYear + " not found.");
- }
- } else {
- rrecs = null;
- }
- if (rrecs != null) {
- tz.setLastRules(rrecs);
- }
- }
- return tz;
- }
-
- int gmtOffset;
- int year = minYear;
- int fromYear = year;
- long fromTime = Time.getLocalTime(startYear,
- Month.JANUARY,
- 1, 0);
-
- // take the index 0 for the GMT offset of the last zone record
- ZoneRec zrec = zone.get(zone.size()-1);
- tz.getOffsetIndex(zrec.getGmtOffset());
-
- int currentSave = 0;
- boolean usedZone;
- for (int zindex = 0; zindex < zone.size(); zindex++) {
- zrec = zone.get(zindex);
- usedZone = false;
- gmtOffset = zrec.getGmtOffset();
- int stdOffset = zrec.getDirectSave();
-
- // If this is the last zone record, take the last rule info.
- if (!zrec.hasUntil()) {
- tz.setRawOffset(gmtOffset, fromTime);
- if (zrec.hasRuleReference()) {
- tz.setLastRules(zrec.getRuleRef().getLastRules());
- } else if (stdOffset != 0) {
- // in case the last rule is all year round DST-only
- // (Asia/Amman once announced this rule.)
- tz.setLastDSTSaving(stdOffset);
- }
- }
- if (!zrec.hasRuleReference()) {
- if (!zrec.hasUntil() || zrec.getUntilTime(stdOffset) >= fromTime) {
- tz.addTransition(fromTime,
- tz.getOffsetIndex(gmtOffset+stdOffset),
- tz.getDstOffsetIndex(stdOffset));
- usedZone = true;
- }
- currentSave = stdOffset;
- // optimization in case the last rule is fixed.
- if (!zrec.hasUntil()) {
- if (tz.getNTransitions() > 0) {
- if (stdOffset == 0) {
- tz.setDSTType(Timezone.X_DST);
- } else {
- tz.setDSTType(Timezone.LAST_DST);
- }
- long time = Time.getLocalTime(maxYear,
- Month.JANUARY, 1, 0);
- time -= zrec.getGmtOffset();
- tz.addTransition(time,
- tz.getOffsetIndex(gmtOffset+stdOffset),
- tz.getDstOffsetIndex(stdOffset));
- tz.addUsedRec(zrec);
- } else {
- tz.setDSTType(Timezone.NO_DST);
- }
- break;
- }
- } else {
- Rule rule = zrec.getRuleRef();
- boolean fromTimeUsed = false;
- currentSave = 0;
- year_loop:
- for (year = getMinYear(); year <= endYear; year++) {
- if (zrec.hasUntil() && year > zrec.getUntilYear()) {
- break;
- }
- List<RuleRec> rules = rule.getRules(year);
- if (rules.size() > 0) {
- for (int i = 0; i < rules.size(); i++) {
- RuleRec rrec = rules.get(i);
- long transition = rrec.getTransitionTime(year,
- gmtOffset,
- currentSave);
- if (zrec.hasUntil()) {
- if (transition >= zrec.getUntilTime(currentSave)) {
- break year_loop;
- }
- }
-
- if (fromTimeUsed == false) {
- if (fromTime <= transition) {
- fromTimeUsed = true;
-
- if (fromTime != minTime) {
- int prevsave;
-
- ZoneRec prevzrec = zone.get(zindex - 1);
-
- // See if until time in the previous
- // ZoneRec is the same thing as the
- // local time in the next rule.
- // (examples are Asia/Ashkhabad in 1991,
- // Europe/Riga in 1989)
-
- if (i > 0) {
- prevsave = rules.get(i-1).getSave();
- } else {
- List<RuleRec> prevrules = rule.getRules(year-1);
-
- if (prevrules.size() > 0) {
- prevsave = prevrules.get(prevrules.size()-1).getSave();
- } else {
- prevsave = 0;
- }
- }
-
- if (rrec.isSameTransition(prevzrec, prevsave, gmtOffset)) {
- currentSave = rrec.getSave();
- tz.addTransition(fromTime,
- tz.getOffsetIndex(gmtOffset+currentSave),
- tz.getDstOffsetIndex(currentSave));
- tz.addUsedRec(rrec);
- usedZone = true;
- continue;
- }
- if (!prevzrec.hasRuleReference()
- || rule != prevzrec.getRuleRef()
- || (rule == prevzrec.getRuleRef()
- && gmtOffset != prevzrec.getGmtOffset())) {
- int save = (fromTime == transition) ? rrec.getSave() : currentSave;
- tz.addTransition(fromTime,
- tz.getOffsetIndex(gmtOffset+save),
- tz.getDstOffsetIndex(save));
- tz.addUsedRec(rrec);
- usedZone = true;
- }
- } else { // fromTime == minTime
- int save = rrec.getSave();
- tz.addTransition(minTime,
- tz.getOffsetIndex(gmtOffset),
- tz.getDstOffsetIndex(0));
-
- tz.addTransition(transition,
- tz.getOffsetIndex(gmtOffset+save),
- tz.getDstOffsetIndex(save));
-
- tz.addUsedRec(rrec);
- usedZone = true;
- }
- } else if (year == fromYear && i == rules.size()-1) {
- int save = rrec.getSave();
- tz.addTransition(fromTime,
- tz.getOffsetIndex(gmtOffset+save),
- tz.getDstOffsetIndex(save));
- }
- }
-
- currentSave = rrec.getSave();
- if (fromTime < transition) {
- tz.addTransition(transition,
- tz.getOffsetIndex(gmtOffset+currentSave),
- tz.getDstOffsetIndex(currentSave));
- tz.addUsedRec(rrec);
- usedZone = true;
- }
- }
- } else {
- if (year == fromYear) {
- tz.addTransition(fromTime,
- tz.getOffsetIndex(gmtOffset+currentSave),
- tz.getDstOffsetIndex(currentSave));
- fromTimeUsed = true;
- }
- if (year == endYear && !zrec.hasUntil()) {
- if (tz.getNTransitions() > 0) {
- // Assume that this Zone stopped DST
- tz.setDSTType(Timezone.X_DST);
- long time = Time.getLocalTime(maxYear, Month.JANUARY,
- 1, 0);
- time -= zrec.getGmtOffset();
- tz.addTransition(time,
- tz.getOffsetIndex(gmtOffset),
- tz.getDstOffsetIndex(0));
- usedZone = true;
- } else {
- tz.setDSTType(Timezone.NO_DST);
- }
- }
- }
- }
- }
- if (usedZone) {
- tz.addUsedRec(zrec);
- }
- if (zrec.hasUntil() && zrec.getUntilTime(currentSave) > fromTime) {
- fromTime = zrec.getUntilTime(currentSave);
- fromYear = zrec.getUntilYear();
- year = zrec.getUntilYear();
- }
- }
-
- if (tz.getDSTType() == Timezone.UNDEF_DST) {
- tz.setDSTType(Timezone.DST);
- }
- tz.optimize();
- tz.checksum();
- return tz;
- }
-
- private static void panic(String msg) {
- Main.panic(msg);
- }
-}
--- a/jdk/makefiles/CompileLaunchers.gmk Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/makefiles/CompileLaunchers.gmk Fri Mar 15 16:39:07 2013 -0700
@@ -311,6 +311,9 @@
$(eval $(call SetupLauncher,jrunscript,\
-DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.script.shell.Main"$(COMMA) }'))
+$(eval $(call SetupLauncher,jjs,\
+ -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "jdk.nashorn.tools.Shell"$(COMMA) }'))
+
$(eval $(call SetupLauncher,jsadebugd,\
-DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "sun.jvm.hotspot.jdi.SADebugServer"$(COMMA) }' \
-DAPP_CLASSPATH='{ "/lib/tools.jar"$(COMMA) "/lib/sa-jdi.jar"$(COMMA) "/classes" }' \
--- a/jdk/makefiles/CompileNativeLibraries.gmk Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/makefiles/CompileNativeLibraries.gmk Fri Mar 15 16:39:07 2013 -0700
@@ -464,12 +464,13 @@
$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/windows \
$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/windows \
$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/d3d
+ LIBAWT_CFLAGS+=-I$(DXSDK_INCLUDE_PATH)
else
LIBAWT_DIRS+=\
$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/x11
endif
-LIBAWT_CFLAGS:=-D__MEDIALIB_OLD_NAMES -D__USE_J2D_NAMES \
+LIBAWT_CFLAGS+=-D__MEDIALIB_OLD_NAMES -D__USE_J2D_NAMES \
$(X_CFLAGS) \
$(foreach dir,$(LIBAWT_DIRS),-I$(dir))
@@ -1218,7 +1219,7 @@
OUTPUT_DIR:=$(INSTALL_LIBRARIES_HERE),\
SRC:=$(JDK_TOPDIR)/src/share/native/sun/java2d/cmm/lcms,\
LANG:=C,\
- OPTIMIZATION:=LOW, \
+ OPTIMIZATION:=HIGHEST, \
CFLAGS:=$(filter-out -xc99=%none,$(CFLAGS_JDKLIB)) \
$(SHARED_LIBRARY_FLAGS) \
-I$(JDK_TOPDIR)/src/share/native/sun/java2d \
@@ -1461,7 +1462,8 @@
-I$(JDK_TOPDIR)/src/share/native/sun/awt/debug \
-I$(JDK_TOPDIR)/src/share/native/sun/java2d \
-I$(JDK_TOPDIR)/src/share/native/sun/awt/image/cvutils \
- -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/windows, \
+ -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/windows \
+ -I$(DXSDK_INCLUDE_PATH), \
LDFLAGS:=$(LDFLAGS_JDKLIB) $(KERNEL32_LIB) $(LDFLAGS_CXX_JDK) \
advapi32.lib $(WIN_AWT_LIB),\
LDFLAGS_SUFFIX:=$(LDFLAGS_JDKLIB_SUFFIX),\
@@ -2907,7 +2909,8 @@
OPTIMIZATION:=LOW, \
CFLAGS:=$(CFLAGS_JDKLIB) \
$(LIBJSOUND_CFLAGS) \
- -DUSE_DAUDIO=TRUE, \
+ -DUSE_DAUDIO=TRUE \
+ -I$(DXSDK_INCLUDE_PATH), \
LDFLAGS:=$(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK) \
$(call SET_SHARED_LIBRARY_ORIGIN),\
LDFLAGS_SUFFIX:=$(LDFLAGS_JDKLIB_SUFFIX) dsound.lib winmm.lib user32.lib ole32.lib,\
--- a/jdk/makefiles/CreateJars.gmk Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/makefiles/CreateJars.gmk Fri Mar 15 16:39:07 2013 -0700
@@ -213,28 +213,28 @@
org/relaxng/datatype \
sun/awt/HKSCS.class \
sun/awt/motif/X11GB2312.class \
- sun/awt/motif/X11GB2312\$$$$Decoder.class \
- sun/awt/motif/X11GB2312\$$$$Encoder.class \
+ sun/awt/motif/X11GB2312\$$Decoder.class \
+ sun/awt/motif/X11GB2312\$$Encoder.class \
sun/awt/motif/X11GBK.class \
- sun/awt/motif/X11GBK\$$$$Encoder.class \
+ sun/awt/motif/X11GBK\$$Encoder.class \
sun/awt/motif/X11KSC5601.class \
- sun/awt/motif/X11KSC5601\$$$$Decoder.class \
- sun/awt/motif/X11KSC5601\$$$$Encoder.class \
+ sun/awt/motif/X11KSC5601\$$Decoder.class \
+ sun/awt/motif/X11KSC5601\$$Encoder.class \
sun/jvmstat \
sun/net/spi/nameservice/dns \
sun/nio/cs/ext \
sun/rmi/rmic \
sun/security/ec/ECDHKeyAgreement.class \
sun/security/ec/ECDSASignature.class \
- sun/security/ec/ECDSASignature\$$$$Raw.class \
- sun/security/ec/ECDSASignature\$$$$SHA1.class \
- sun/security/ec/ECDSASignature\$$$$SHA224.class \
- sun/security/ec/ECDSASignature\$$$$SHA256.class \
- sun/security/ec/ECDSASignature\$$$$SHA384.class \
- sun/security/ec/ECDSASignature\$$$$SHA512.class \
+ sun/security/ec/ECDSASignature\$$Raw.class \
+ sun/security/ec/ECDSASignature\$$SHA1.class \
+ sun/security/ec/ECDSASignature\$$SHA224.class \
+ sun/security/ec/ECDSASignature\$$SHA256.class \
+ sun/security/ec/ECDSASignature\$$SHA384.class \
+ sun/security/ec/ECDSASignature\$$SHA512.class \
sun/security/ec/ECKeyFactory.class \
sun/security/ec/ECKeyPairGenerator.class \
- sun/security/ec/SunEC\$$$$1.class \
+ sun/security/ec/SunEC\$$1.class \
sun/security/ec/SunEC.class \
sun/security/ec/SunECEntries.class \
sun/security/internal \
@@ -1119,6 +1119,14 @@
##########################################################################################
+# Import nashorn.jar from nashorn dist dir.
+$(IMAGES_OUTPUTDIR)/lib/ext/nashorn.jar: $(NASHORN_DIST)/nashorn.jar
+ $(install-file)
+
+JARS += $(IMAGES_OUTPUTDIR)/lib/ext/nashorn.jar
+
+##########################################################################################
+
-include $(CUSTOM_MAKE_DIR)/CreateJars.gmk
##########################################################################################
--- a/jdk/makefiles/Images.gmk Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/makefiles/Images.gmk Fri Mar 15 16:39:07 2013 -0700
@@ -59,7 +59,7 @@
$(ECHO) $(LOG_INFO) Processing $(patsubst $(OUTPUT_ROOT)/%,%,$@)
$(MKDIR) -p $(@D)
$(RM) $@
- $(SED) 's/$$//g' $< > $@
+ LC_ALL=C $(SED) 's/$$//g' $< > $@
$(CHMOD) 444 $@
endef
@@ -264,6 +264,13 @@
$(foreach f,$(filter $(JDK_OUTPUTDIR)/lib$(OPENJDK_TARGET_CPU_ISADIR)/%,$(JDKJRE_JDKOUT_LIB_LIST)),\
$(eval $(call AddFileToCopy,$(JDK_OUTPUTDIR),$(JDK_OVERLAY_IMAGE_DIR)/jre,$f,JDKJRE_OVERLAY_LIB_TARGETS)))
+ifneq ($(PROFILE),)
+# Files in lib$(PROFILE) are excluded from the generic copying routines so
+# we have to add them back in here
+$(foreach f,$(CUSTOM_PROFILE_JARS),\
+ $(eval $(call AddFileToCopy,$(IMAGES_OUTPUTDIR)/lib$(PROFILE),$(JRE_IMAGE_DIR)/lib,$f,JRE_LIB_TARGETS)))
+endif
+
# CTE plugin security change require new empty directory lib/applet
$(JRE_IMAGE_DIR)/lib/applet:
$(ECHO) $(LOG_INFO) Creating $(patsubst $(OUTPUT_ROOT)/%,%,$@)
@@ -602,6 +609,7 @@
$(call info-file-item, "OS_NAME", "$(REQUIRED_OS_NAME)")
$(call info-file-item, "OS_VERSION", "$(REQUIRED_OS_VERSION)")
$(call info-file-item, "OS_ARCH", "$(OPENJDK_TARGET_CPU_LEGACY)")
+ if [ -n "$(JDK_ARCH_ABI_PROP_NAME)" ]; then $(call info-file-item, "SUN_ARCH_ABI", "$(JDK_ARCH_ABI_PROP_NAME)"); fi
$(call info-file-item, "SOURCE", "$(ALL_SOURCE_TIPS)")
endef
@@ -738,11 +746,6 @@
$(JDKJRE_OVERLAY_STRIP_LIST) $(JDK_OVERLAY_BIN_STRIP_LIST)
ifneq ($(PROFILE),)
-# Files in lib$(PROFILE) are excluded from the generic copying routines so
-# we have to add them back in here
-$(foreach f,$(CUSTOM_PROFILE_JARS),\
- $(eval $(call AddFileToCopy,$(IMAGES_OUTPUTDIR)/lib$(PROFILE),$(JRE_IMAGE_DIR)/lib,$f,JRE_LIB_TARGETS)))
-
PROFILE_IMAGE_JARS := $(filter %.jar, $(JRE_LIB_TARGETS))
PROFILE_IMAGE_JARS_CHECKED := $(IMAGES_OUTPUTDIR)/lib$(PROFILE)/_jars_checked
--- a/jdk/makefiles/mapfiles/liblcms/mapfile-vers Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/makefiles/mapfiles/liblcms/mapfile-vers Fri Mar 15 16:39:07 2013 -0700
@@ -27,13 +27,12 @@
SUNWprivate_1.1 {
global:
- Java_sun_java2d_cmm_lcms_LCMS_loadProfile;
- Java_sun_java2d_cmm_lcms_LCMS_freeProfile;
+ Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative;
+ Java_sun_java2d_cmm_lcms_LCMS_freeProfileNative;
Java_sun_java2d_cmm_lcms_LCMS_getProfileSize;
Java_sun_java2d_cmm_lcms_LCMS_getProfileData;
- Java_sun_java2d_cmm_lcms_LCMS_getTagSize;
- Java_sun_java2d_cmm_lcms_LCMS_getTagData;
- Java_sun_java2d_cmm_lcms_LCMS_setTagData;
+ Java_sun_java2d_cmm_lcms_LCMS_getTagNative;
+ Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative;
Java_sun_java2d_cmm_lcms_LCMS_colorConvert;
Java_sun_java2d_cmm_lcms_LCMS_getProfileID;
Java_sun_java2d_cmm_lcms_LCMS_initLCMS;
--- a/jdk/makefiles/profile-rtjar-includes.txt Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/makefiles/profile-rtjar-includes.txt Fri Mar 15 16:39:07 2013 -0700
@@ -349,6 +349,7 @@
com/sun/rowset/providers \
com/sun/script/javascript \
com/sun/script/util \
+ com/sun/security/auth \
com/sun/security/auth/callback \
com/sun/security/auth/login \
com/sun/security/auth/module \
@@ -448,8 +449,7 @@
sun/tracing \
sun/tracing/dtrace
-PROFILE_3_RTJAR_INCLUDE_TYPES := \
- com/sun/security/auth/*.class
+PROFILE_3_RTJAR_INCLUDE_TYPES :=
PROFILE_3_RTJAR_EXCLUDE_TYPES := \
javax/management/remote/rmi/_RMIConnectionImpl_Tie.class \
@@ -457,10 +457,10 @@
javax/management/remote/rmi/_RMIServerImpl_Tie.class \
javax/management/remote/rmi/_RMIServer_Stub.class \
com/sun/security/auth/callback/DialogCallbackHandler.class \
- com/sun/security/auth/callback/DialogCallbackHandler\$$$$1.class \
- com/sun/security/auth/callback/DialogCallbackHandler\$$$$2.class \
- com/sun/security/auth/callback/DialogCallbackHandler\$$$$Action.class \
- com/sun/security/auth/callback/DialogCallbackHandler\$$$$ConfirmationInfo.class
+ com/sun/security/auth/callback/DialogCallbackHandler\$$1.class \
+ com/sun/security/auth/callback/DialogCallbackHandler\$$2.class \
+ com/sun/security/auth/callback/DialogCallbackHandler\$$Action.class \
+ com/sun/security/auth/callback/DialogCallbackHandler\$$ConfirmationInfo.class
PROFILE_3_INCLUDE_METAINF_SERVICES := \
META-INF/services/javax.script.ScriptEngineFactory
--- a/jdk/src/macosx/classes/sun/font/CStrike.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/macosx/classes/sun/font/CStrike.java Fri Mar 15 16:39:07 2013 -0700
@@ -500,7 +500,10 @@
final Iterator<Long> i = generalCache.values().iterator();
while (i.hasNext()) {
final long longValue = i.next().longValue();
- if (longValue != -1 && longValue != 0) StrikeCache.freeLongPointer(longValue);
+ if (longValue != -1 && longValue != 0) {
+ removeGlyphInfoFromCache(longValue);
+ StrikeCache.freeLongPointer(longValue);
+ }
}
}
@@ -512,7 +515,10 @@
private static void disposeLongArray(final long[] longArray) {
for (int i = 0; i < longArray.length; i++) {
final long ptr = longArray[i];
- if (ptr != 0 && ptr != -1) StrikeCache.freeLongPointer(ptr); // free's the native struct pointer
+ if (ptr != 0 && ptr != -1) {
+ removeGlyphInfoFromCache(ptr);
+ StrikeCache.freeLongPointer(ptr); // free's the native struct pointer
+ }
}
}
--- a/jdk/src/macosx/classes/sun/font/CStrikeDisposer.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/macosx/classes/sun/font/CStrikeDisposer.java Fri Mar 15 16:39:07 2013 -0700
@@ -85,4 +85,6 @@
}
private native void freeNativeScalerContext(long pContext);
+
+ protected static native void removeGlyphInfoFromCache(long glyphInfo);
}
--- a/jdk/src/macosx/native/sun/font/AWTStrike.m Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/macosx/native/sun/font/AWTStrike.m Fri Mar 15 16:39:07 2013 -0700
@@ -27,11 +27,13 @@
#import "java_awt_geom_PathIterator.h"
#import "sun_awt_SunHints.h"
#import "sun_font_CStrike.h"
+#import "sun_font_CStrikeDisposer.h"
#import "CGGlyphImages.h"
#import "CGGlyphOutlines.h"
#import "AWTStrike.h"
#import "CoreTextSupport.h"
//#import "jni_util.h"
+#include "fontscalerdefs.h"
/* Use THIS_FILE when it is available. */
#ifndef THIS_FILE
@@ -423,3 +425,19 @@
return metrics;
}
+
+extern void AccelGlyphCache_RemoveAllInfos(GlyphInfo* glyph);
+/*
+ * Class: sun_font_CStrikeDisposer
+ * Method: removeGlyphInfoFromCache
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_sun_font_CStrikeDisposer_removeGlyphInfoFromCache
+(JNIEnv *env, jclass cls, jlong glyphInfo)
+{
+ JNF_COCOA_ENTER(env);
+
+ AccelGlyphCache_RemoveAllCellInfos((GlyphInfo*)jlong_to_ptr(glyphInfo));
+
+ JNF_COCOA_EXIT(env);
+}
--- a/jdk/src/share/back/transport.c Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/back/transport.c Fri Mar 15 16:39:07 2013 -0700
@@ -117,6 +117,9 @@
/* Construct library name (simple name or full path) */
dbgsysBuildLibName(libname, sizeof(libname), plibdir, name);
+ if (strlen(libname) == 0) {
+ return NULL;
+ }
/* dlopen (unix) / LoadLibrary (windows) the transport library */
handle = dbgsysLoadLibrary(libname, buf, sizeof(buf));
--- a/jdk/src/share/bin/jli_util.h Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/bin/jli_util.h Fri Mar 15 16:39:07 2013 -0700
@@ -66,7 +66,7 @@
#include <io.h>
#define JLI_StrCaseCmp(p1, p2) stricmp((p1), (p2))
#define JLI_StrNCaseCmp(p1, p2, p3) strnicmp((p1), (p2), (p3))
-#define JLI_Snprintf _snprintf
+int JLI_Snprintf(char *buffer, size_t size, const char *format, ...);
void JLI_CmdToArgs(char *cmdline);
#define JLI_Lseek _lseeki64
#else /* NIXES */
--- a/jdk/src/share/bin/parse_manifest.c Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/bin/parse_manifest.c Fri Mar 15 16:39:07 2013 -0700
@@ -569,9 +569,9 @@
#ifdef O_BINARY
| O_BINARY /* use binary mode on windows */
#endif
- )) == -1)
+ )) == -1) {
return (-1);
-
+ }
info->manifest_version = NULL;
info->main_class = NULL;
info->jre_version = NULL;
@@ -618,15 +618,17 @@
zentry entry;
void *data = NULL;
- fd = open(jarfile, O_RDONLY
+ if ((fd = open(jarfile, O_RDONLY
#ifdef O_LARGEFILE
| O_LARGEFILE /* large file mode */
#endif
#ifdef O_BINARY
| O_BINARY /* use binary mode on windows */
#endif
- );
- if (fd != -1 && find_file(fd, &entry, filename) == 0) {
+ )) == -1) {
+ return NULL;
+ }
+ if (find_file(fd, &entry, filename) == 0) {
data = inflate_file(fd, &entry, size);
}
close(fd);
@@ -671,8 +673,9 @@
#ifdef O_BINARY
| O_BINARY /* use binary mode on windows */
#endif
- )) == -1)
+ )) == -1) {
return (-1);
+ }
if (rc = find_file(fd, &entry, manifest_name) != 0) {
close(fd);
--- a/jdk/src/share/classes/com/sun/beans/finder/MethodFinder.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/com/sun/beans/finder/MethodFinder.java Fri Mar 15 16:39:07 2013 -0700
@@ -66,11 +66,14 @@
Signature signature = new Signature(type, name, args);
Method method = CACHE.get(signature);
- if (method != null) {
+ boolean cached = method != null;
+ if (cached && isPackageAccessible(method.getDeclaringClass())) {
return method;
}
method = findAccessibleMethod(new MethodFinder(name, args).find(type.getMethods()));
- CACHE.put(signature, method);
+ if (!cached) {
+ CACHE.put(signature, method);
+ }
return method;
}
--- a/jdk/src/share/classes/com/sun/crypto/provider/DHKeyAgreement.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/com/sun/crypto/provider/DHKeyAgreement.java Fri Mar 15 16:39:07 2013 -0700
@@ -41,6 +41,8 @@
import javax.crypto.SecretKey;
import javax.crypto.spec.*;
+import sun.security.util.KeyUtil;
+
/**
* This class implements the Diffie-Hellman key agreement protocol between
* any number of parties.
@@ -200,6 +202,9 @@
throw new InvalidKeyException("Incompatible parameters");
}
+ // validate the Diffie-Hellman public key
+ KeyUtil.validate(dhPubKey);
+
// store the y value
this.y = dhPubKey.getY();
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Attribute.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Attribute.java Fri Mar 15 16:39:07 2013 -0700
@@ -177,7 +177,7 @@
define(sd, ATTR_CONTEXT_METHOD, "Synthetic", "");
define(sd, ATTR_CONTEXT_METHOD, "Deprecated", "");
define(sd, ATTR_CONTEXT_METHOD, "Exceptions", "NH[RCH]");
- define(sd, ATTR_CONTEXT_METHOD, "MethodParameters", "NB[RUNHI]");
+ define(sd, ATTR_CONTEXT_METHOD, "MethodParameters", "NB[RUNHFH]");
//define(sd, ATTR_CONTEXT_METHOD, "Code", "HHNI[B]NH[PHPOHPOHRCNH]NH[RUHNI[B]]");
define(sd, ATTR_CONTEXT_CODE, "StackMapTable",
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java Fri Mar 15 16:39:07 2013 -0700
@@ -1000,7 +1000,6 @@
/** Write a constant pool reference. */
public void putRef(Entry e) {
- assert(index != null);
addValue(encodeRefOrNull(e, index));
}
public void putRef(Entry e, Index index) {
@@ -1052,6 +1051,8 @@
int encodeRef(Entry e, Index ix) {
+ if (ix == null)
+ throw new RuntimeException("null index for " + e.stringValue());
int coding = ix.indexOf(e);
if (verbose > 2)
Utils.log.fine("putRef "+coding+" => "+e);
@@ -1505,7 +1506,7 @@
// band for predefine method parameters
IntBand method_MethodParameters_NB = method_attr_bands.newIntBand("method_MethodParameters_NB", BYTE1);
CPRefBand method_MethodParameters_name_RUN = method_attr_bands.newCPRefBand("method_MethodParameters_name_RUN", UNSIGNED5, CONSTANT_Utf8, NULL_IS_OK);
- IntBand method_MethodParameters_flag_I = method_attr_bands.newIntBand("method_MethodParameters_flag_I");
+ IntBand method_MethodParameters_flag_FH = method_attr_bands.newIntBand("method_MethodParameters_flag_FH");
MultiBand class_attr_bands = class_bands.newMultiBand("(class_attr_bands)", UNSIGNED5);
IntBand class_flags_hi = class_attr_bands.newIntBand("class_flags_hi");
@@ -1776,9 +1777,9 @@
new Band[]{
method_MethodParameters_NB,
method_MethodParameters_name_RUN,
- method_MethodParameters_flag_I
+ method_MethodParameters_flag_FH
},
- "MethodParameters", "NB[RUNHI]");
+ "MethodParameters", "NB[RUNHFH]");
assert(attrCodeEmpty == Package.attrCodeEmpty);
predefineAttribute(X_ATTR_Signature, ATTR_CONTEXT_METHOD,
new Band[] { method_Signature_RS },
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java Fri Mar 15 16:39:07 2013 -0700
@@ -564,7 +564,7 @@
code.bytes = new byte[readInt()];
in.readFully(code.bytes);
Entry[] cpMap = cls.getCPMap();
- Instruction.opcodeChecker(code.bytes, cpMap);
+ Instruction.opcodeChecker(code.bytes, cpMap, this.cls.version);
int nh = readUnsignedShort();
code.setHandlerCount(nh);
for (int i = 0; i < nh; i++) {
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java Fri Mar 15 16:39:07 2013 -0700
@@ -207,6 +207,10 @@
return tag;
}
+ public final boolean tagEquals(int tag) {
+ return getTag() == tag;
+ }
+
public Entry getRef(int i) {
return null;
}
@@ -1405,6 +1409,8 @@
/** Index of all CP entries of a given tag and class. */
public Index getMemberIndex(byte tag, ClassEntry classRef) {
+ if (classRef == null)
+ throw new RuntimeException("missing class reference for " + tagName(tag));
if (indexByTagAndClass == null)
indexByTagAndClass = new Index[CONSTANT_Limit][];
Index allClasses = getIndexByTag(CONSTANT_Class);
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Constants.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Constants.java Fri Mar 15 16:39:07 2013 -0700
@@ -479,4 +479,10 @@
public final static int _qldc = _xldc_op+7;
public final static int _qldc_w = _xldc_op+8;
public final static int _xldc_limit = _xldc_op+9;
+
+ // handling of InterfaceMethodRef
+ public final static int _invoke_int_op = _xldc_limit;
+ public final static int _invokespecial_int = _invoke_int_op+0;
+ public final static int _invokestatic_int = _invoke_int_op+1;
+ public final static int _invoke_int_limit = _invoke_int_op+2;
}
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Instruction.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Instruction.java Fri Mar 15 16:39:07 2013 -0700
@@ -446,12 +446,14 @@
public static boolean isCPRefOp(int bc) {
if (bc < BC_INDEX[0].length && BC_INDEX[0][bc] > 0) return true;
if (bc >= _xldc_op && bc < _xldc_limit) return true;
+ if (bc == _invokespecial_int || bc == _invokestatic_int) return true;
return false;
}
public static byte getCPRefOpTag(int bc) {
if (bc < BC_INDEX[0].length && BC_INDEX[0][bc] > 0) return BC_TAG[0][bc];
if (bc >= _xldc_op && bc < _xldc_limit) return CONSTANT_LoadableValue;
+ if (bc == _invokestatic_int || bc == _invokespecial_int) return CONSTANT_InterfaceMethodref;
return CONSTANT_None;
}
@@ -647,7 +649,8 @@
}
}
- public static void opcodeChecker(byte[] code, ConstantPool.Entry[] cpMap) throws FormatException {
+ public static void opcodeChecker(byte[] code, ConstantPool.Entry[] cpMap,
+ Package.Version clsVersion) throws FormatException {
Instruction i = at(code, 0);
while (i != null) {
int opcode = i.getBC();
@@ -658,10 +661,17 @@
ConstantPool.Entry e = i.getCPRef(cpMap);
if (e != null) {
byte tag = i.getCPTag();
- if (!e.tagMatches(tag)) {
- String message = "illegal reference, expected type=" +
- ConstantPool.tagName(tag) + ": " +
- i.toString(cpMap);
+ boolean match = e.tagMatches(tag);
+ if (!match &&
+ (i.bc == _invokespecial || i.bc == _invokestatic) &&
+ e.tagMatches(CONSTANT_InterfaceMethodref) &&
+ clsVersion.greaterThan(Constants.JAVA7_MAX_CLASS_VERSION)) {
+ match = true;
+ }
+ if (!match) {
+ String message = "illegal reference, expected type="
+ + ConstantPool.tagName(tag) + ": "
+ + i.toString(cpMap);
throw new FormatException(message);
}
}
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java Fri Mar 15 16:39:07 2013 -0700
@@ -109,6 +109,10 @@
return (p200 == null)? null: p200._nunp;
}
+ private synchronized long getUnpackerPtr() {
+ return unpackerPtr;
+ }
+
// Callback from the unpacker engine to get more data.
private long readInputFn(ByteBuffer pbuf, long minlen) throws IOException {
if (in == null) return 0; // nothing is readable
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/PackageReader.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/PackageReader.java Fri Mar 15 16:39:07 2013 -0700
@@ -1521,7 +1521,7 @@
// *method_Exceptions_RC :UNSIGNED5 (cp_Class)
// *method_MethodParameters_NB: BYTE1
// *method_MethodParameters_RUN: UNSIGNED5 (cp_Utf8)
- // *method_MethodParameters_I: UNSIGNED5 (flag)
+ // *method_MethodParameters_FH: UNSIGNED5 (flag)
//
// code_attr_bands:
// *code_flags :UNSIGNED5
@@ -2256,6 +2256,12 @@
int origBC = bc;
int size = 2;
switch (bc) {
+ case _invokestatic_int:
+ origBC = _invokestatic;
+ break;
+ case _invokespecial_int:
+ origBC = _invokespecial;
+ break;
case _ildc:
case _cldc:
case _fldc:
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/PackageWriter.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/PackageWriter.java Fri Mar 15 16:39:07 2013 -0700
@@ -1409,6 +1409,10 @@
int bc = i.getBC();
if (!(bc >= _first_linker_op && bc <= _last_linker_op)) return -1;
MemberEntry ref = (MemberEntry) i.getCPRef(curCPMap);
+ // do not optimize this case, simply fall back to regular coding
+ if ((bc == _invokespecial || bc == _invokestatic) &&
+ ref.tagEquals(CONSTANT_InterfaceMethodref))
+ return -1;
ClassEntry refClass = ref.classRef;
int self_bc = _self_linker_op + (bc - _first_linker_op);
if (refClass == curClass.thisClass)
@@ -1609,7 +1613,16 @@
case CONSTANT_Fieldref:
bc_which = bc_fieldref; break;
case CONSTANT_Methodref:
- bc_which = bc_methodref; break;
+ if (ref.tagEquals(CONSTANT_InterfaceMethodref)) {
+ if (bc == _invokespecial)
+ vbc = _invokespecial_int;
+ if (bc == _invokestatic)
+ vbc = _invokestatic_int;
+ bc_which = bc_imethodref;
+ } else {
+ bc_which = bc_methodref;
+ }
+ break;
case CONSTANT_InterfaceMethodref:
bc_which = bc_imethodref; break;
case CONSTANT_InvokeDynamic:
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java Fri Mar 15 16:39:07 2013 -0700
@@ -83,7 +83,7 @@
* @param out an OutputStream
* @exception IOException if an error is encountered.
*/
- public void pack(JarFile in, OutputStream out) throws IOException {
+ public synchronized void pack(JarFile in, OutputStream out) throws IOException {
assert(Utils.currentInstance.get() == null);
TimeZone tz = (props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE))
? null
@@ -118,7 +118,7 @@
* @param out an OutputStream
* @exception IOException if an error is encountered.
*/
- public void pack(JarInputStream in, OutputStream out) throws IOException {
+ public synchronized void pack(JarInputStream in, OutputStream out) throws IOException {
assert(Utils.currentInstance.get() == null);
TimeZone tz = (props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null :
TimeZone.getDefault();
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/UnpackerImpl.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/UnpackerImpl.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -106,7 +106,7 @@
* @param out a JarOutputStream.
* @exception IOException if an error is encountered.
*/
- public void unpack(InputStream in, JarOutputStream out) throws IOException {
+ public synchronized void unpack(InputStream in, JarOutputStream out) throws IOException {
if (in == null) {
throw new NullPointerException("null input");
}
@@ -151,7 +151,7 @@
* @param out a JarOutputStream.
* @exception IOException if an error is encountered.
*/
- public void unpack(File in, JarOutputStream out) throws IOException {
+ public synchronized void unpack(File in, JarOutputStream out) throws IOException {
if (in == null) {
throw new NullPointerException("null input");
}
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/ClassLoaderRepositorySupport.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/ClassLoaderRepositorySupport.java Fri Mar 15 16:39:07 2013 -0700
@@ -36,6 +36,7 @@
import javax.management.ObjectName;
import javax.management.loading.PrivateClassLoader;
+import sun.reflect.misc.ReflectUtil;
/**
* This class keeps the list of Class Loaders registered in the MBean Server.
@@ -192,6 +193,7 @@
final ClassLoader without,
final ClassLoader stop)
throws ClassNotFoundException {
+ ReflectUtil.checkPackageAccess(className);
final int size = list.length;
for(int i=0; i<size; i++) {
try {
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java Fri Mar 15 16:39:07 2013 -0700
@@ -54,6 +54,8 @@
import java.lang.reflect.InvocationTargetException;
import javax.management.AttributeNotFoundException;
import javax.management.openmbean.CompositeData;
+import sun.reflect.misc.MethodUtil;
+import sun.reflect.misc.ReflectUtil;
/**
* This class contains the methods for performing all the tests needed to verify
@@ -526,8 +528,10 @@
// to locate method
readMethod = SimpleIntrospector.getReadMethod(clazz, element);
}
- if (readMethod != null)
- return readMethod.invoke(complex);
+ if (readMethod != null) {
+ ReflectUtil.checkPackageAccess(readMethod.getDeclaringClass());
+ return MethodUtil.invoke(readMethod, complex, new Class[0]);
+ }
throw new AttributeNotFoundException(
"Could not find the getter method for the property " +
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/JmxMBeanServer.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/JmxMBeanServer.java Fri Mar 15 16:39:07 2013 -0700
@@ -51,6 +51,7 @@
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MBeanServerDelegate;
+import javax.management.MBeanServerPermission;
import javax.management.NotCompliantMBeanException;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;
@@ -1409,6 +1410,8 @@
// Default is true.
final boolean fairLock = DEFAULT_FAIR_LOCK_POLICY;
+ checkNewMBeanServerPermission();
+
// This constructor happens to disregard the value of the interceptors
// flag - that is, it always uses the default value - false.
// This is admitedly a bug, but we chose not to fix it for now
@@ -1494,4 +1497,11 @@
}
}
+ private static void checkNewMBeanServerPermission() {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ Permission perm = new MBeanServerPermission("newMBeanServer");
+ sm.checkPermission(perm);
+ }
+ }
}
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanInstantiator.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanInstantiator.java Fri Mar 15 16:39:07 2013 -0700
@@ -32,11 +32,13 @@
import java.io.ObjectInputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
+import java.security.Permission;
import java.util.Map;
import java.util.logging.Level;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
+import javax.management.MBeanPermission;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;
import javax.management.OperationsException;
@@ -44,7 +46,7 @@
import javax.management.RuntimeErrorException;
import javax.management.RuntimeMBeanException;
import javax.management.RuntimeOperationsException;
-
+import sun.reflect.misc.ConstructorUtil;
import sun.reflect.misc.ReflectUtil;
/**
@@ -56,7 +58,6 @@
* @since 1.5
*/
public class MBeanInstantiator {
-
private final ModifiableClassLoaderRepository clr;
// private MetaData meta = null;
@@ -88,6 +89,7 @@
"Exception occurred during object instantiation");
}
+ ReflectUtil.checkPackageAccess(className);
try {
if (clr == null) throw new ClassNotFoundException(className);
theClass = clr.loadClass(className);
@@ -162,6 +164,7 @@
continue;
}
+ ReflectUtil.checkPackageAccess(signature[i]);
// Ok we do not have a primitive type ! We need to build
// the signature of the method
//
@@ -205,6 +208,9 @@
*/
public Object instantiate(Class<?> theClass)
throws ReflectionException, MBeanException {
+
+ checkMBeanPermission(theClass, null, null, "instantiate");
+
Object moi;
@@ -260,6 +266,9 @@
public Object instantiate(Class<?> theClass, Object params[],
String signature[], ClassLoader loader)
throws ReflectionException, MBeanException {
+
+ checkMBeanPermission(theClass, null, null, "instantiate");
+
// Instantiate the new object
// ------------------------------
@@ -407,6 +416,8 @@
throw new RuntimeOperationsException(new
IllegalArgumentException(), "Null className passed in parameter");
}
+
+ ReflectUtil.checkPackageAccess(className);
Class<?> theClass;
if (loaderName == null) {
// Load the class using the agent class loader
@@ -619,13 +630,13 @@
**/
static Class<?> loadClass(String className, ClassLoader loader)
throws ReflectionException {
-
Class<?> theClass;
if (className == null) {
throw new RuntimeOperationsException(new
IllegalArgumentException("The class name cannot be null"),
"Exception occurred during object instantiation");
}
+ ReflectUtil.checkPackageAccess(className);
try {
if (loader == null)
loader = MBeanInstantiator.class.getClassLoader();
@@ -676,6 +687,7 @@
// We need to load the class through the class
// loader of the target object.
//
+ ReflectUtil.checkPackageAccess(signature[i]);
tab[i] = Class.forName(signature[i], false, aLoader);
}
} catch (ClassNotFoundException e) {
@@ -701,7 +713,7 @@
private Constructor<?> findConstructor(Class<?> c, Class<?>[] params) {
try {
- return c.getConstructor(params);
+ return ConstructorUtil.getConstructor(c, params);
} catch (Exception e) {
return null;
}
@@ -715,4 +727,18 @@
char.class, boolean.class})
primitiveClasses.put(c.getName(), c);
}
+
+ private static void checkMBeanPermission(Class<?> clazz,
+ String member,
+ ObjectName objectName,
+ String actions) {
+ SecurityManager sm = System.getSecurityManager();
+ if (clazz != null && sm != null) {
+ Permission perm = new MBeanPermission(clazz.getName(),
+ member,
+ objectName,
+ actions);
+ sm.checkPermission(perm);
+ }
+ }
}
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanSupport.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanSupport.java Fri Mar 15 16:39:07 2013 -0700
@@ -38,6 +38,7 @@
import javax.management.ObjectName;
import javax.management.ReflectionException;
import com.sun.jmx.mbeanserver.MXBeanMappingFactory;
+import sun.reflect.misc.ReflectUtil;
/**
* Base class for MBeans. There is one instance of this class for
@@ -131,6 +132,7 @@
" is not an instance of " + mbeanInterfaceType.getName();
throw new NotCompliantMBeanException(msg);
}
+ ReflectUtil.checkPackageAccess(mbeanInterfaceType);
this.resource = resource;
MBeanIntrospector<M> introspector = getMBeanIntrospector();
this.perInterface = introspector.getPerInterface(mbeanInterfaceType);
--- a/jdk/src/share/classes/java/awt/Dialog.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/awt/Dialog.java Fri Mar 15 16:39:07 2013 -0700
@@ -39,6 +39,7 @@
import sun.awt.util.IdentityArrayList;
import sun.awt.util.IdentityLinkedList;
import sun.security.util.SecurityConstants;
+import java.security.AccessControlException;
/**
* A Dialog is a top-level window with a title and a border
@@ -128,6 +129,8 @@
*/
boolean undecorated = false;
+ private transient boolean initialized = false;
+
/**
* Modal dialogs block all input to some top-level windows.
* Whether a particular window is blocked depends on dialog's type
@@ -671,6 +674,7 @@
this.title = title;
setModalityType(modalityType);
SunToolkit.checkAndSetPolicy(this);
+ initialized = true;
}
/**
@@ -722,6 +726,7 @@
this.title = title;
setModalityType(modalityType);
SunToolkit.checkAndSetPolicy(this);
+ initialized = true;
}
/**
@@ -851,12 +856,9 @@
if (modalityType == type) {
return;
}
- if (type == ModalityType.TOOLKIT_MODAL) {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- sm.checkPermission(SecurityConstants.AWT.TOOLKIT_MODALITY_PERMISSION);
- }
- }
+
+ checkModalityPermission(type);
+
modalityType = type;
modal = (modalityType != ModalityType.MODELESS);
}
@@ -1025,6 +1027,11 @@
*/
@Deprecated
public void show() {
+ if (!initialized) {
+ throw new IllegalStateException("The dialog component " +
+ "has not been initialized properly");
+ }
+
beforeFirstShow = false;
if (!isModal()) {
conditionalShow(null, null);
@@ -1600,18 +1607,51 @@
}
}
+ private void checkModalityPermission(ModalityType mt) {
+ if (mt == ModalityType.TOOLKIT_MODAL) {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(
+ SecurityConstants.AWT.TOOLKIT_MODALITY_PERMISSION
+ );
+ }
+ }
+ }
+
private void readObject(ObjectInputStream s)
throws ClassNotFoundException, IOException, HeadlessException
{
GraphicsEnvironment.checkHeadless();
- s.defaultReadObject();
+
+ java.io.ObjectInputStream.GetField fields =
+ s.readFields();
+
+ ModalityType localModalityType = (ModalityType)fields.get("modalityType", null);
+
+ try {
+ checkModalityPermission(localModalityType);
+ } catch (AccessControlException ace) {
+ localModalityType = DEFAULT_MODALITY_TYPE;
+ }
// in 1.5 or earlier modalityType was absent, so use "modal" instead
- if (modalityType == null) {
+ if (localModalityType == null) {
+ this.modal = fields.get("modal", false);
setModal(modal);
+ } else {
+ this.modalityType = localModalityType;
}
+ this.resizable = fields.get("resizable", true);
+ this.undecorated = fields.get("undecorated", false);
+ this.title = (String)fields.get("title", "");
+
blockedWindows = new IdentityArrayList<>();
+
+ SunToolkit.checkAndSetPolicy(this);
+
+ initialized = true;
+
}
/*
--- a/jdk/src/share/classes/java/awt/EventQueue.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/awt/EventQueue.java Fri Mar 15 16:39:07 2013 -0700
@@ -194,7 +194,8 @@
}
public void removeSourceEvents(EventQueue eventQueue,
Object source,
- boolean removeAllEvents) {
+ boolean removeAllEvents)
+ {
eventQueue.removeSourceEvents(source, removeAllEvents);
}
public boolean noEvents(EventQueue eventQueue) {
@@ -203,6 +204,11 @@
public void wakeup(EventQueue eventQueue, boolean isShutdown) {
eventQueue.wakeup(isShutdown);
}
+ public void invokeAndWait(Object source, Runnable r)
+ throws InterruptedException, InvocationTargetException
+ {
+ EventQueue.invokeAndWait(source, r);
+ }
});
}
@@ -1245,8 +1251,14 @@
* @since 1.2
*/
public static void invokeAndWait(Runnable runnable)
- throws InterruptedException, InvocationTargetException {
+ throws InterruptedException, InvocationTargetException
+ {
+ invokeAndWait(Toolkit.getDefaultToolkit(), runnable);
+ }
+ static void invokeAndWait(Object source, Runnable runnable)
+ throws InterruptedException, InvocationTargetException
+ {
if (EventQueue.isDispatchThread()) {
throw new Error("Cannot call invokeAndWait from the event dispatcher thread");
}
@@ -1255,8 +1267,7 @@
Object lock = new AWTInvocationLock();
InvocationEvent event =
- new InvocationEvent(Toolkit.getDefaultToolkit(), runnable, lock,
- true);
+ new InvocationEvent(source, runnable, lock, true);
synchronized (lock) {
Toolkit.getEventQueue().postEvent(event);
--- a/jdk/src/share/classes/java/awt/TextComponent.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/awt/TextComponent.java Fri Mar 15 16:39:07 2013 -0700
@@ -109,12 +109,6 @@
// the background color of non-editable TextComponents.
boolean backgroundSetByClientCode = false;
- /**
- * True if this <code>TextComponent</code> has access
- * to the System clipboard.
- */
- transient private boolean canAccessClipboard;
-
transient protected TextListener textListener;
/*
@@ -139,7 +133,6 @@
GraphicsEnvironment.checkHeadless();
this.text = (text != null) ? text : "";
setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
- checkSystemClipboardAccess();
}
private void enableInputMethodsIfNecessary() {
@@ -734,17 +727,14 @@
/**
* Assigns a valid value to the canAccessClipboard instance variable.
*/
- private void checkSystemClipboardAccess() {
- canAccessClipboard = true;
+ private boolean canAccessClipboard() {
SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- try {
- sm.checkSystemClipboardAccess();
- }
- catch (SecurityException e) {
- canAccessClipboard = false;
- }
- }
+ if (sm == null) return true;
+ try {
+ sm.checkSystemClipboardAccess();
+ return true;
+ } catch (SecurityException e) {}
+ return false;
}
/*
@@ -827,7 +817,6 @@
}
}
enableInputMethodsIfNecessary();
- checkSystemClipboardAccess();
}
--- a/jdk/src/share/classes/java/awt/Window.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/awt/Window.java Fri Mar 15 16:39:07 2013 -0700
@@ -1206,7 +1206,7 @@
}
else {
try {
- EventQueue.invokeAndWait(action);
+ EventQueue.invokeAndWait(this, action);
}
catch (InterruptedException e) {
System.err.println("Disposal was interrupted:");
--- a/jdk/src/share/classes/java/io/ObjectInputStream.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/io/ObjectInputStream.java Fri Mar 15 16:39:07 2013 -0700
@@ -1752,6 +1752,12 @@
ObjectStreamClass desc = readClassDesc(false);
desc.checkDeserialize();
+ Class<?> cl = desc.forClass();
+ if (cl == String.class || cl == Class.class
+ || cl == ObjectStreamClass.class) {
+ throw new InvalidClassException("invalid class descriptor");
+ }
+
Object obj;
try {
obj = desc.isInstantiable() ? desc.newInstance() : null;
--- a/jdk/src/share/classes/java/lang/Class.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/lang/Class.java Fri Mar 15 16:39:07 2013 -0700
@@ -25,6 +25,7 @@
package java.lang;
+import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Array;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.Member;
@@ -63,7 +64,9 @@
import sun.reflect.generics.scope.ClassScope;
import sun.security.util.SecurityConstants;
import java.lang.annotation.Annotation;
+import java.lang.reflect.Proxy;
import sun.reflect.annotation.*;
+import sun.reflect.misc.ReflectUtil;
/**
* Instances of the class {@code Class} represent classes and
@@ -250,11 +253,11 @@
ClassLoader loader)
throws ClassNotFoundException
{
- if (loader == null) {
+ if (sun.misc.VM.isSystemDomainLoader(loader)) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
ClassLoader ccl = ClassLoader.getCallerClassLoader();
- if (ccl != null) {
+ if (!sun.misc.VM.isSystemDomainLoader(ccl)) {
sm.checkPermission(
SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
@@ -319,7 +322,7 @@
throws InstantiationException, IllegalAccessException
{
if (System.getSecurityManager() != null) {
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), false);
}
return newInstance0();
}
@@ -1299,7 +1302,7 @@
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), false);
// Privileged so this implementation can look at DECLARED classes,
// something the caller might not have privilege to do. The code here
@@ -1374,7 +1377,7 @@
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
return copyFields(privateGetPublicFields(null));
}
@@ -1425,7 +1428,7 @@
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
return copyMethods(privateGetPublicMethods());
}
@@ -1474,7 +1477,7 @@
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
return copyConstructors(privateGetDeclaredConstructors(true));
}
@@ -1533,7 +1536,7 @@
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
Field field = getField0(name);
if (field == null) {
throw new NoSuchFieldException(name);
@@ -1618,7 +1621,7 @@
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
Method method = getMethod0(name, parameterTypes);
if (method == null) {
throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
@@ -1672,7 +1675,7 @@
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
return getConstructor0(parameterTypes, Member.PUBLIC);
}
@@ -1714,7 +1717,7 @@
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), false);
return getDeclaredClasses0();
}
@@ -1758,7 +1761,7 @@
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
return copyFields(privateGetDeclaredFields(false));
}
@@ -1806,7 +1809,7 @@
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
return copyMethods(privateGetDeclaredMethods(false));
}
@@ -1851,7 +1854,7 @@
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
return copyConstructors(privateGetDeclaredConstructors(false));
}
@@ -1895,7 +1898,7 @@
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
Field field = searchFields(privateGetDeclaredFields(false), name);
if (field == null) {
throw new NoSuchFieldException(name);
@@ -1950,7 +1953,7 @@
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes);
if (method == null) {
throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
@@ -2000,7 +2003,7 @@
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
return getConstructor0(parameterTypes, Member.DECLARED);
}
@@ -2170,18 +2173,26 @@
* <p> Default policy: allow all clients access with normal Java access
* control.
*/
- private void checkMemberAccess(int which, ClassLoader ccl) {
+ private void checkMemberAccess(int which, ClassLoader ccl, boolean checkProxyInterfaces) {
SecurityManager s = System.getSecurityManager();
if (s != null) {
s.checkMemberAccess(this, which);
ClassLoader cl = getClassLoader0();
- if (sun.reflect.misc.ReflectUtil.needsPackageAccessCheck(ccl, cl)) {
+ if (ReflectUtil.needsPackageAccessCheck(ccl, cl)) {
String name = this.getName();
int i = name.lastIndexOf('.');
if (i != -1) {
- s.checkPackageAccess(name.substring(0, i));
+ // skip the package access check on a proxy class in default proxy package
+ String pkg = name.substring(0, i);
+ if (!Proxy.isProxyClass(this) || !pkg.equals(ReflectUtil.PROXY_PACKAGE)) {
+ s.checkPackageAccess(pkg);
+ }
}
}
+ // check package access on the proxy interfaces
+ if (checkProxyInterfaces && Proxy.isProxyClass(this)) {
+ ReflectUtil.checkProxyPackageAccess(ccl, this.getInterfaces());
+ }
}
}
@@ -3084,6 +3095,16 @@
}
/**
+ * {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ * @since 1.5
+ */
+ @Override
+ public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
+ return AnnotatedElement.super.isAnnotationPresent(annotationClass);
+ }
+
+ /**
* @throws NullPointerException {@inheritDoc}
* @since 1.8
*/
--- a/jdk/src/share/classes/java/lang/ClassLoader.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/lang/ClassLoader.java Fri Mar 15 16:39:07 2013 -0700
@@ -51,7 +51,6 @@
import java.util.Hashtable;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
-import sun.misc.ClassFileTransformer;
import sun.misc.CompoundEnumeration;
import sun.misc.Resource;
import sun.misc.URLClassPath;
@@ -669,41 +668,6 @@
return source;
}
- private Class<?> defineTransformedClass(String name, byte[] b, int off, int len,
- ProtectionDomain pd,
- ClassFormatError cfe, String source)
- throws ClassFormatError
- {
- // Class format error - try to transform the bytecode and
- // define the class again
- //
- ClassFileTransformer[] transformers =
- ClassFileTransformer.getTransformers();
- Class<?> c = null;
-
- if (transformers != null) {
- for (ClassFileTransformer transformer : transformers) {
- try {
- // Transform byte code using transformer
- byte[] tb = transformer.transform(b, off, len);
- c = defineClass1(name, tb, 0, tb.length,
- pd, source);
- break;
- } catch (ClassFormatError cfe2) {
- // If ClassFormatError occurs, try next transformer
- }
- }
- }
-
- // Rethrow original ClassFormatError if unable to transform
- // bytecode to well-formed
- //
- if (c == null)
- throw cfe;
-
- return c;
- }
-
private void postDefineClass(Class<?> c, ProtectionDomain pd)
{
if (pd.getCodeSource() != null) {
@@ -783,17 +747,8 @@
throws ClassFormatError
{
protectionDomain = preDefineClass(name, protectionDomain);
-
- Class<?> c = null;
String source = defineClassSourceLocation(protectionDomain);
-
- try {
- c = defineClass1(name, b, off, len, protectionDomain, source);
- } catch (ClassFormatError cfe) {
- c = defineTransformedClass(name, b, off, len, protectionDomain, cfe,
- source);
- }
-
+ Class<?> c = defineClass1(name, b, off, len, protectionDomain, source);
postDefineClass(c, protectionDomain);
return c;
}
@@ -881,20 +836,8 @@
}
protectionDomain = preDefineClass(name, protectionDomain);
-
- Class<?> c = null;
String source = defineClassSourceLocation(protectionDomain);
-
- try {
- c = defineClass2(name, b, b.position(), len, protectionDomain,
- source);
- } catch (ClassFormatError cfe) {
- byte[] tb = new byte[len];
- b.get(tb); // get bytes out of byte buffer.
- c = defineTransformedClass(name, tb, 0, len, protectionDomain, cfe,
- source);
- }
-
+ Class<?> c = defineClass2(name, b, b.position(), len, protectionDomain, source);
postDefineClass(c, protectionDomain);
return c;
}
--- a/jdk/src/share/classes/java/lang/Deprecated.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/lang/Deprecated.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -36,6 +36,7 @@
*
* @author Neal Gafter
* @since 1.5
+ * @jls 9.6.3.6 @Deprecated
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
--- a/jdk/src/share/classes/java/lang/Override.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/lang/Override.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -43,7 +43,7 @@
*
* @author Peter von der Ahé
* @author Joshua Bloch
- * @jls 9.6.1.4 Override
+ * @jls 9.6.1.4 @Override
* @since 1.5
*/
@Target(ElementType.METHOD)
--- a/jdk/src/share/classes/java/lang/Package.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/lang/Package.java Fri Mar 15 16:39:07 2013 -0700
@@ -25,6 +25,7 @@
package java.lang;
+import java.lang.reflect.AnnotatedElement;
import java.io.InputStream;
import java.util.Enumeration;
@@ -386,6 +387,16 @@
}
/**
+ * {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ * @since 1.5
+ */
+ @Override
+ public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
+ return AnnotatedElement.super.isAnnotationPresent(annotationClass);
+ }
+
+ /**
* @throws NullPointerException {@inheritDoc}
* @since 1.8
*/
--- a/jdk/src/share/classes/java/lang/SafeVarargs.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/lang/SafeVarargs.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -85,6 +85,7 @@
* @since 1.7
* @jls 4.7 Reifiable Types
* @jls 8.4.1 Formal Parameters
+ * @jls 9.6.3.7 @SafeVarargs
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
--- a/jdk/src/share/classes/java/lang/SecurityManager.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/lang/SecurityManager.java Fri Mar 15 16:39:07 2013 -0700
@@ -1320,6 +1320,9 @@
* <code>AWTPermission("showWindowWithoutWarningBanner")</code> permission,
* and returns <code>true</code> if a SecurityException is not thrown,
* otherwise it returns <code>false</code>.
+ * In the case of subset Profiles of Java SE that do not include the
+ * {@code java.awt} package, {@code checkPermission} is instead called
+ * to check the permission {@code java.security.AllPermission}.
* <p>
* If you override this method, then you should make a call to
* <code>super.checkTopLevelWindow</code>
@@ -1340,8 +1343,12 @@
if (window == null) {
throw new NullPointerException("window can't be null");
}
+ Permission perm = SecurityConstants.AWT.TOPLEVEL_WINDOW_PERMISSION;
+ if (perm == null) {
+ perm = SecurityConstants.ALL_PERMISSION;
+ }
try {
- checkPermission(SecurityConstants.AWT.TOPLEVEL_WINDOW_PERMISSION);
+ checkPermission(perm);
return true;
} catch (SecurityException se) {
// just return false
@@ -1379,6 +1386,9 @@
* This method calls <code>checkPermission</code> with the
* <code>AWTPermission("accessClipboard")</code>
* permission.
+ * In the case of subset Profiles of Java SE that do not include the
+ * {@code java.awt} package, {@code checkPermission} is instead called
+ * to check the permission {@code java.security.AllPermission}.
* <p>
* If you override this method, then you should make a call to
* <code>super.checkSystemClipboardAccess</code>
@@ -1391,7 +1401,11 @@
* @see #checkPermission(java.security.Permission) checkPermission
*/
public void checkSystemClipboardAccess() {
- checkPermission(SecurityConstants.AWT.ACCESS_CLIPBOARD_PERMISSION);
+ Permission perm = SecurityConstants.AWT.ACCESS_CLIPBOARD_PERMISSION;
+ if (perm == null) {
+ perm = SecurityConstants.ALL_PERMISSION;
+ }
+ checkPermission(perm);
}
/**
@@ -1400,6 +1414,10 @@
* <p>
* This method calls <code>checkPermission</code> with the
* <code>AWTPermission("accessEventQueue")</code> permission.
+ * In the case of subset Profiles of Java SE that do not include the
+ * {@code java.awt} package, {@code checkPermission} is instead called
+ * to check the permission {@code java.security.AllPermission}.
+ *
* <p>
* If you override this method, then you should make a call to
* <code>super.checkAwtEventQueueAccess</code>
@@ -1412,7 +1430,11 @@
* @see #checkPermission(java.security.Permission) checkPermission
*/
public void checkAwtEventQueueAccess() {
- checkPermission(SecurityConstants.AWT.CHECK_AWT_EVENTQUEUE_PERMISSION);
+ Permission perm = SecurityConstants.AWT.CHECK_AWT_EVENTQUEUE_PERMISSION;
+ if (perm == null) {
+ perm = SecurityConstants.ALL_PERMISSION;
+ }
+ checkPermission(perm);
}
/*
--- a/jdk/src/share/classes/java/lang/SuppressWarnings.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/lang/SuppressWarnings.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -41,8 +41,13 @@
* suppress a warning in a particular method, you should annotate that
* method rather than its class.
*
+ * @author Josh Bloch
* @since 1.5
- * @author Josh Bloch
+ * @jls 4.8 Raw Types
+ * @jls 4.12.2 Variables of Reference Type
+ * @jls 5.1.9 Unchecked Conversion
+ * @jls 5.5.2 Checked Casts and Unchecked Casts
+ * @jls 9.6.3.5 @SuppressWarnings
*/
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
@@ -56,9 +61,11 @@
* free to emit a warning if an annotation contains an unrecognized
* warning name.
*
- * <p>Compiler vendors should document the warning names they support in
- * conjunction with this annotation type. They are encouraged to cooperate
- * to ensure that the same names work across multiple compilers.
+ * <p> The string {@code "unchecked"} is used to suppress
+ * unchecked warnings. Compiler vendors should document the
+ * additional warning names they support in conjunction with this
+ * annotation type. They are encouraged to cooperate to ensure
+ * that the same names work across multiple compilers.
*/
String[] value();
}
--- a/jdk/src/share/classes/java/lang/annotation/Inherited.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/lang/annotation/Inherited.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -44,6 +44,7 @@
*
* @author Joshua Bloch
* @since 1.5
+ * @jls 9.6.3.3 @Inherited
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
--- a/jdk/src/share/classes/java/lang/annotation/InvalidContainerAnnotationError.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +0,0 @@
-/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package java.lang.annotation;
-
-import java.util.Objects;
-
-/**
- * Thrown to indicate that an annotation type expected to act as a
- * container for another annotation type by virture of an @Repeatable
- * annotation, does not act as a container.
- *
- * @see java.lang.reflect.AnnotatedElement
- * @since 1.8
- * @jls 9.6 Annotation Types
- * @jls 9.7 Annotations
- */
-public class InvalidContainerAnnotationError extends AnnotationFormatError {
- private static final long serialVersionUID = 5023L;
-
- /**
- * The instance of the erroneous container.
- */
- private transient Annotation container;
-
- /**
- * The type of the annotation that should be contained in the
- * container.
- */
- private transient Class<? extends Annotation> annotationType;
-
- /**
- * Constructs a new InvalidContainerAnnotationError with the
- * specified detail message.
- *
- * @param message the detail message.
- */
- public InvalidContainerAnnotationError(String message) {
- super(message);
- }
-
- /**
- * Constructs a new InvalidContainerAnnotationError with the specified
- * detail message and cause. Note that the detail message associated
- * with {@code cause} is <i>not</i> automatically incorporated in
- * this error's detail message.
- *
- * @param message the detail message
- * @param cause the cause, may be {@code null}
- */
- public InvalidContainerAnnotationError(String message, Throwable cause) {
- super(message, cause);
- }
-
- /**
- * Constructs a new InvalidContainerAnnotationError with the
- * specified cause and a detail message of {@code (cause == null ?
- * null : cause.toString())} (which typically contains the class
- * and detail message of {@code cause}).
- *
- * @param cause the cause, may be {@code null}
- */
- public InvalidContainerAnnotationError(Throwable cause) {
- super(cause);
- }
-
- /**
- * Constructs InvalidContainerAnnotationError for the specified
- * container instance and contained annotation type.
- *
- * @param message the detail message
- * @param cause the cause, may be {@code null}
- * @param container the erroneous container instance, may be
- * {@code null}
- * @param annotationType the annotation type intended to be
- * contained, may be {@code null}
- */
- public InvalidContainerAnnotationError(String message,
- Throwable cause,
- Annotation container,
- Class<? extends Annotation> annotationType) {
- super(message, cause);
- this.container = container;
- this.annotationType = annotationType;
- }
-
- /**
- * Returns the erroneous container.
- *
- * @return the erroneous container, may return {@code null}
- */
- public Annotation getContainer() {
- return container;
- }
-
- /**
- * Returns the annotation type intended to be contained. Returns
- * {@code null} if the annotation type intended to be contained
- * could not be determined.
- *
- * @return the annotation type intended to be contained, or {@code
- * null} if unknown
- */
- public Class<? extends Annotation> getAnnotationType() {
- return annotationType;
- }
-}
--- a/jdk/src/share/classes/java/lang/annotation/Retention.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/lang/annotation/Retention.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -38,6 +38,7 @@
*
* @author Joshua Bloch
* @since 1.5
+ * @jls 9.6.3.2 @Retention
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
--- a/jdk/src/share/classes/java/lang/annotation/Target.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/lang/annotation/Target.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -59,6 +59,9 @@
* ...
* }
* </pre>
+ *
+ * @since 1.5
+ * @jls 9.6.3.1 @Target
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
--- a/jdk/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java Fri Mar 15 16:39:07 2013 -0700
@@ -34,11 +34,11 @@
import static sun.invoke.util.Wrapper.*;
/**
- * Abstract implementation of a meta-factory which provides parameter unrolling and input validation.
+ * Abstract implementation of a lambda metafactory which provides parameter unrolling and input validation.
*
- * @author Robert Field
+ * @see LambdaMetafactory
*/
-/*non-public*/ abstract class AbstractValidatingLambdaMetafactory {
+/* package */ abstract class AbstractValidatingLambdaMetafactory {
/*
* For context, the comments for the following fields are marked in quotes with their values, given this program:
@@ -54,16 +54,19 @@
final Class<?> targetClass; // The class calling the meta-factory via invokedynamic "class X"
final MethodType invokedType; // The type of the invoked method "(CC)II"
final Class<?> samBase; // The type of the returned instance "interface JJ"
- final boolean isSerializable; // Should the returned instance be serializable
+ final MethodHandle samMethod; // Raw method handle for the functional interface method
final MethodHandleInfo samInfo; // Info about the SAM method handle "MethodHandleInfo[9 II.foo(Object)Object]"
final Class<?> samClass; // Interface containing the SAM method "interface II"
final MethodType samMethodType; // Type of the SAM method "(Object)Object"
+ final MethodHandle implMethod; // Raw method handle for the implementation method
final MethodHandleInfo implInfo; // Info about the implementation method handle "MethodHandleInfo[5 CC.impl(int)String]"
final int implKind; // Invocation kind for implementation "5"=invokevirtual
final boolean implIsInstanceMethod; // Is the implementation an instance method "true"
final Class<?> implDefiningClass; // Type defining the implementation "class CC"
final MethodType implMethodType; // Type of the implementation method "(int)String"
final MethodType instantiatedMethodType; // Instantiated erased functional interface method type "(Integer)Object"
+ final boolean isSerializable; // Should the returned instance be serializable
+ final Class<?>[] markerInterfaces; // Additional marker interfaces to be implemented
/**
@@ -80,27 +83,35 @@
* @param implMethod The implementation method which should be called (with suitable adaptation of argument
* types, return types, and adjustment for captured arguments) when methods of the resulting
* functional interface instance are invoked.
- * @param instantiatedMethodType The signature of the SAM method from the functional interface's perspective
+ * @param instantiatedMethodType The signature of the primary functional interface method after type variables
+ * are substituted with their instantiation from the capture site
* @throws ReflectiveOperationException
+ * @throws LambdaConversionException If any of the meta-factory protocol invariants are violated
*/
AbstractValidatingLambdaMetafactory(MethodHandles.Lookup caller,
MethodType invokedType,
MethodHandle samMethod,
MethodHandle implMethod,
- MethodType instantiatedMethodType)
- throws ReflectiveOperationException {
+ MethodType instantiatedMethodType,
+ int flags,
+ Class<?>[] markerInterfaces)
+ throws ReflectiveOperationException, LambdaConversionException {
this.targetClass = caller.lookupClass();
this.invokedType = invokedType;
this.samBase = invokedType.returnType();
- this.isSerializable = Serializable.class.isAssignableFrom(samBase);
+ this.samMethod = samMethod;
this.samInfo = new MethodHandleInfo(samMethod);
this.samClass = samInfo.getDeclaringClass();
this.samMethodType = samInfo.getMethodType();
+ this.implMethod = implMethod;
this.implInfo = new MethodHandleInfo(implMethod);
- this.implKind = implInfo.getReferenceKind() == MethodHandleInfo.REF_invokeSpecial? MethodHandleInfo.REF_invokeVirtual : implInfo.getReferenceKind(); // @@@ Temp work-around to hotspot incorrectly converting to invokespecial
+ // @@@ Temporary work-around pending resolution of 8005119
+ this.implKind = (implInfo.getReferenceKind() == MethodHandleInfo.REF_invokeSpecial)
+ ? MethodHandleInfo.REF_invokeVirtual
+ : implInfo.getReferenceKind();
this.implIsInstanceMethod =
implKind == MethodHandleInfo.REF_invokeVirtual ||
implKind == MethodHandleInfo.REF_invokeSpecial ||
@@ -109,6 +120,30 @@
this.implMethodType = implInfo.getMethodType();
this.instantiatedMethodType = instantiatedMethodType;
+
+ if (!samClass.isInterface()) {
+ throw new LambdaConversionException(String.format(
+ "Functional interface %s is not an interface",
+ samClass.getName()));
+ }
+
+ boolean foundSerializableSupertype = Serializable.class.isAssignableFrom(samBase);
+ for (Class<?> c : markerInterfaces) {
+ if (!c.isInterface()) {
+ throw new LambdaConversionException(String.format(
+ "Marker interface %s is not an interface",
+ c.getName()));
+ }
+ foundSerializableSupertype |= Serializable.class.isAssignableFrom(c);
+ }
+ this.isSerializable = ((flags & LambdaMetafactory.FLAG_SERIALIZABLE) != 0)
+ || foundSerializableSupertype;
+
+ if (isSerializable && !foundSerializableSupertype) {
+ markerInterfaces = Arrays.copyOf(markerInterfaces, markerInterfaces.length + 1);
+ markerInterfaces[markerInterfaces.length-1] = Serializable.class;
+ }
+ this.markerInterfaces = markerInterfaces;
}
/**
@@ -127,8 +162,9 @@
void validateMetafactoryArgs() throws LambdaConversionException {
// Check target type is a subtype of class where SAM method is defined
if (!samClass.isAssignableFrom(samBase)) {
- throw new LambdaConversionException(String.format("Invalid target type %s for lambda conversion; not a subtype of functional interface %s",
- samBase.getName(), samClass.getName()));
+ throw new LambdaConversionException(
+ String.format("Invalid target type %s for lambda conversion; not a subtype of functional interface %s",
+ samBase.getName(), samClass.getName()));
}
switch (implKind) {
@@ -149,14 +185,16 @@
final int samArity = samMethodType.parameterCount();
final int instantiatedArity = instantiatedMethodType.parameterCount();
if (implArity + receiverArity != capturedArity + samArity) {
- throw new LambdaConversionException(String.format("Incorrect number of parameters for %s method %s; %d captured parameters, %d functional interface parameters, %d implementation parameters",
- implIsInstanceMethod ? "instance" : "static", implInfo,
- capturedArity, samArity, implArity));
+ throw new LambdaConversionException(
+ String.format("Incorrect number of parameters for %s method %s; %d captured parameters, %d functional interface method parameters, %d implementation parameters",
+ implIsInstanceMethod ? "instance" : "static", implInfo,
+ capturedArity, samArity, implArity));
}
if (instantiatedArity != samArity) {
- throw new LambdaConversionException(String.format("Incorrect number of parameters for %s method %s; %d functional interface parameters, %d SAM method parameters",
- implIsInstanceMethod ? "instance" : "static", implInfo,
- instantiatedArity, samArity));
+ throw new LambdaConversionException(
+ String.format("Incorrect number of parameters for %s method %s; %d instantiated parameters, %d functional interface method parameters",
+ implIsInstanceMethod ? "instance" : "static", implInfo,
+ instantiatedArity, samArity));
}
// If instance: first captured arg (receiver) must be subtype of class where impl method is defined
@@ -180,8 +218,9 @@
// check receiver type
if (!implDefiningClass.isAssignableFrom(receiverClass)) {
- throw new LambdaConversionException(String.format("Invalid receiver type %s; not a subtype of implementation type %s",
- receiverClass, implDefiningClass));
+ throw new LambdaConversionException(
+ String.format("Invalid receiver type %s; not a subtype of implementation type %s",
+ receiverClass, implDefiningClass));
}
} else {
// no receiver
@@ -196,7 +235,8 @@
Class<?> capturedParamType = invokedType.parameterType(i + capturedStart);
if (!capturedParamType.equals(implParamType)) {
throw new LambdaConversionException(
- String.format("Type mismatch in captured lambda parameter %d: expecting %s, found %s", i, capturedParamType, implParamType));
+ String.format("Type mismatch in captured lambda parameter %d: expecting %s, found %s",
+ i, capturedParamType, implParamType));
}
}
// Check for adaptation match on SAM arguments
@@ -206,7 +246,8 @@
Class<?> instantiatedParamType = instantiatedMethodType.parameterType(i + samOffset);
if (!isAdaptableTo(instantiatedParamType, implParamType, true)) {
throw new LambdaConversionException(
- String.format("Type mismatch for lambda argument %d: %s is not convertible to %s", i, instantiatedParamType, implParamType));
+ String.format("Type mismatch for lambda argument %d: %s is not convertible to %s",
+ i, instantiatedParamType, implParamType));
}
}
@@ -218,7 +259,8 @@
: implMethodType.returnType();
if (!isAdaptableToAsReturn(actualReturnType, expectedType)) {
throw new LambdaConversionException(
- String.format("Type mismatch for lambda return: %s is not convertible to %s", actualReturnType, expectedType));
+ String.format("Type mismatch for lambda return: %s is not convertible to %s",
+ actualReturnType, expectedType));
}
}
@@ -274,8 +316,8 @@
}
- /*********** Logging support -- for debugging only
- static final Executor logPool = Executors.newSingleThreadExecutor(); // @@@ For debugging only
+ /*********** Logging support -- for debugging only, uncomment as needed
+ static final Executor logPool = Executors.newSingleThreadExecutor();
protected static void log(final String s) {
MethodHandleProxyLambdaMetafactory.logPool.execute(new Runnable() {
@Override
@@ -297,17 +339,21 @@
***********************/
/**
- * Find the SAM method and corresponding methods which should be bridged. SAM method and those to be bridged
- * will have the same name and number of parameters. Check for matching default methods (non-abstract), they
- * should not be bridged-over and indicate a complex bridging situation.
+ * Find the functional interface method and corresponding abstract methods
+ * which should be bridged. The functional interface method and those to be
+ * bridged will have the same name and number of parameters. Check for
+ * matching default methods (non-abstract), the VM will create bridges for
+ * default methods; We don't have enough readily available type information
+ * to distinguish between where the functional interface method should be
+ * bridged and where the default method should be bridged; This situation is
+ * flagged.
*/
class MethodAnalyzer {
private final Method[] methods = samBase.getMethods();
- private final List<Method> methodsFound = new ArrayList<>(methods.length);
private Method samMethod = null;
private final List<Method> methodsToBridge = new ArrayList<>(methods.length);
- private boolean defaultMethodFound = false;
+ private boolean conflictFoundBetweenDefaultAndBridge = false;
MethodAnalyzer() {
String samMethodName = samInfo.getName();
@@ -315,31 +361,36 @@
int samParamLength = samParamTypes.length;
Class<?> samReturnType = samMethodType.returnType();
Class<?> objectClass = Object.class;
+ List<Method> defaultMethods = new ArrayList<>(methods.length);
for (Method m : methods) {
if (m.getName().equals(samMethodName) && m.getDeclaringClass() != objectClass) {
Class<?>[] mParamTypes = m.getParameterTypes();
if (mParamTypes.length == samParamLength) {
+ // Method matches name and parameter length -- and is not Object
if (Modifier.isAbstract(m.getModifiers())) {
- // Exclude methods with duplicate signatures
- if (methodUnique(m)) {
- if (m.getReturnType().equals(samReturnType) && Arrays.equals(mParamTypes, samParamTypes)) {
- // Exact match, this is the SAM method signature
- samMethod = m;
- } else {
- methodsToBridge.add(m);
- }
+ // Method is abstract
+ if (m.getReturnType().equals(samReturnType)
+ && Arrays.equals(mParamTypes, samParamTypes)) {
+ // Exact match, this is the SAM method signature
+ samMethod = m;
+ } else if (!hasMatchingBridgeSignature(m)) {
+ // Record bridges, exclude methods with duplicate signatures
+ methodsToBridge.add(m);
}
} else {
- // This is a default method, flag for special processing
- defaultMethodFound = true;
- // Ignore future matching abstracts.
- // Note, due to reabstraction, this is really a punt, hence pass-off to VM
- methodUnique(m);
+ // Record default methods for conflict testing
+ defaultMethods.add(m);
}
}
}
}
+ for (Method dm : defaultMethods) {
+ if (hasMatchingBridgeSignature(dm)) {
+ conflictFoundBetweenDefaultAndBridge = true;
+ break;
+ }
+ }
}
Method getSamMethod() {
@@ -350,27 +401,26 @@
return methodsToBridge;
}
- boolean wasDefaultMethodFound() {
- return defaultMethodFound;
+ boolean conflictFoundBetweenDefaultAndBridge() {
+ return conflictFoundBetweenDefaultAndBridge;
}
/**
- * Search the list of previously found methods to determine if there is a method with the same signature
- * (return and parameter types) as the specified method. If it wasn't found before, add to the found list.
+ * Search the list of previously found bridge methods to determine if there is a method with the same signature
+ * (return and parameter types) as the specified method.
*
* @param m The method to match
- * @return False if the method was found, True otherwise
+ * @return True if the method was found, False otherwise
*/
- private boolean methodUnique(Method m) {
+ private boolean hasMatchingBridgeSignature(Method m) {
Class<?>[] ptypes = m.getParameterTypes();
Class<?> rtype = m.getReturnType();
- for (Method md : methodsFound) {
+ for (Method md : methodsToBridge) {
if (md.getReturnType().equals(rtype) && Arrays.equals(ptypes, md.getParameterTypes())) {
+ return true;
+ }
+ }
return false;
}
}
- methodsFound.add(m);
- return true;
- }
- }
}
--- a/jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -51,12 +51,21 @@
private DirectMethodHandle(MethodType mtype, LambdaForm form, MemberName member) {
super(mtype, form);
if (!member.isResolved()) throw new InternalError();
+
+ if (member.getDeclaringClass().isInterface() && !member.isAbstract()) {
+ // Check for corner case: invokeinterface of Object method
+ MemberName m = new MemberName(Object.class, member.getName(), member.getMethodType(), member.getReferenceKind());
+ m = MemberName.getFactory().resolveOrNull(m.getReferenceKind(), m, null);
+ if (m != null && m.isPublic()) {
+ member = m;
+ }
+ }
+
this.member = member;
}
// Factory methods:
-
- static DirectMethodHandle make(Class<?> receiver, MemberName member) {
+ static DirectMethodHandle make(byte refKind, Class<?> receiver, MemberName member) {
MethodType mtype = member.getMethodOrFieldType();
if (!member.isStatic()) {
if (!member.getDeclaringClass().isAssignableFrom(receiver) || member.isConstructor())
@@ -64,8 +73,14 @@
mtype = mtype.insertParameterTypes(0, receiver);
}
if (!member.isField()) {
- LambdaForm lform = preparedLambdaForm(member);
- return new DirectMethodHandle(mtype, lform, member);
+ if (refKind == REF_invokeSpecial) {
+ member = member.asSpecial();
+ LambdaForm lform = preparedLambdaForm(member);
+ return new Special(mtype, lform, member);
+ } else {
+ LambdaForm lform = preparedLambdaForm(member);
+ return new DirectMethodHandle(mtype, lform, member);
+ }
} else {
LambdaForm lform = preparedFieldLambdaForm(member);
if (member.isStatic()) {
@@ -79,6 +94,12 @@
}
}
}
+ static DirectMethodHandle make(Class<?> receiver, MemberName member) {
+ byte refKind = member.getReferenceKind();
+ if (refKind == REF_invokeSpecial)
+ refKind = REF_invokeVirtual;
+ return make(refKind, receiver, member);
+ }
static DirectMethodHandle make(MemberName member) {
if (member.isConstructor())
return makeAllocator(member);
@@ -114,6 +135,10 @@
//// Implementation methods.
@Override
+ MethodHandle viewAsType(MethodType newType) {
+ return new DirectMethodHandle(newType, form, member);
+ }
+ @Override
@ForceInline
MemberName internalMemberName() {
return member;
@@ -357,6 +382,21 @@
((DirectMethodHandle)mh).ensureInitialized();
}
+ /** This subclass represents invokespecial instructions. */
+ static class Special extends DirectMethodHandle {
+ private Special(MethodType mtype, LambdaForm form, MemberName member) {
+ super(mtype, form, member);
+ }
+ @Override
+ boolean isInvokeSpecial() {
+ return true;
+ }
+ @Override
+ MethodHandle viewAsType(MethodType newType) {
+ return new Special(newType, form, member);
+ }
+ }
+
/** This subclass handles constructor references. */
static class Constructor extends DirectMethodHandle {
final MemberName initMethod;
@@ -369,6 +409,10 @@
this.instanceClass = instanceClass;
assert(initMethod.isResolved());
}
+ @Override
+ MethodHandle viewAsType(MethodType newType) {
+ return new Constructor(newType, form, member, initMethod, instanceClass);
+ }
}
/*non-public*/ static Object constructorMethod(Object mh) {
@@ -395,6 +439,10 @@
@Override Object checkCast(Object obj) {
return fieldType.cast(obj);
}
+ @Override
+ MethodHandle viewAsType(MethodType newType) {
+ return new Accessor(newType, form, member, fieldOffset);
+ }
}
@ForceInline
@@ -434,6 +482,10 @@
@Override Object checkCast(Object obj) {
return fieldType.cast(obj);
}
+ @Override
+ MethodHandle viewAsType(MethodType newType) {
+ return new StaticAccessor(newType, form, member, staticBase, staticOffset);
+ }
}
@ForceInline
--- a/jdk/src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java Fri Mar 15 16:39:07 2013 -0700
@@ -36,21 +36,28 @@
import java.security.PrivilegedAction;
/**
- * InnerClassLambdaMetafactory
+ * Lambda metafactory implementation which dynamically creates an inner-class-like class per lambda callsite.
+ *
+ * @see LambdaMetafactory
*/
-/*non-public*/ final class InnerClassLambdaMetafactory extends AbstractValidatingLambdaMetafactory {
+/* package */ final class InnerClassLambdaMetafactory extends AbstractValidatingLambdaMetafactory {
private static final int CLASSFILE_VERSION = 51;
- private static final Type TYPE_VOID = Type.getType(void.class);
private static final String METHOD_DESCRIPTOR_VOID = Type.getMethodDescriptor(Type.VOID_TYPE);
private static final String NAME_MAGIC_ACCESSOR_IMPL = "java/lang/invoke/MagicLambdaImpl";
- private static final String NAME_SERIALIZABLE = "java/io/Serializable";
private static final String NAME_CTOR = "<init>";
//Serialization support
- private static final String NAME_SERIALIZED_LAMBDA = "com/oracle/java/lang/invoke/SerializedLambdaImpl";
+ private static final String NAME_SERIALIZED_LAMBDA = "java/lang/invoke/SerializedLambda";
private static final String DESCR_METHOD_WRITE_REPLACE = "()Ljava/lang/Object;";
private static final String NAME_METHOD_WRITE_REPLACE = "writeReplace";
private static final String NAME_OBJECT = "java/lang/Object";
+ private static final String DESCR_CTOR_SERIALIZED_LAMBDA
+ = MethodType.methodType(void.class,
+ Class.class,
+ int.class, String.class, String.class, String.class,
+ int.class, String.class, String.class, String.class,
+ String.class,
+ Object[].class).toMethodDescriptorString();
// Used to ensure that each spun class name is unique
private static final AtomicInteger counter = new AtomicInteger(0);
@@ -70,7 +77,7 @@
private final Type[] instantiatedArgumentTypes; // ASM types for the functional interface arguments
/**
- * Meta-factory constructor.
+ * General meta-factory constructor, standard cases and allowing for uncommon options such as serialization.
*
* @param caller Stacked automatically by VM; represents a lookup context with the accessibility privileges
* of the caller.
@@ -83,16 +90,23 @@
* @param implMethod The implementation method which should be called (with suitable adaptation of argument
* types, return types, and adjustment for captured arguments) when methods of the resulting
* functional interface instance are invoked.
- * @param instantiatedMethodType The signature of the SAM method from the functional interface's perspective
+ * @param instantiatedMethodType The signature of the primary functional interface method after type variables
+ * are substituted with their instantiation from the capture site
+ * @param flags A bitmask containing flags that may influence the translation of this lambda expression. Defined
+ * fields include FLAG_SERIALIZABLE.
+ * @param markerInterfaces Additional interfaces which the lambda object should implement.
* @throws ReflectiveOperationException
+ * @throws LambdaConversionException If any of the meta-factory protocol invariants are violated
*/
public InnerClassLambdaMetafactory(MethodHandles.Lookup caller,
MethodType invokedType,
MethodHandle samMethod,
MethodHandle implMethod,
- MethodType instantiatedMethodType)
- throws ReflectiveOperationException {
- super(caller, invokedType, samMethod, implMethod, instantiatedMethodType);
+ MethodType instantiatedMethodType,
+ int flags,
+ Class<?>[] markerInterfaces)
+ throws ReflectiveOperationException, LambdaConversionException {
+ super(caller, invokedType, samMethod, implMethod, instantiatedMethodType, flags, markerInterfaces);
implMethodClassName = implDefiningClass.getName().replace('.', '/');
implMethodName = implInfo.getName();
implMethodDesc = implMethodType.toMethodDescriptorString();
@@ -109,7 +123,6 @@
argNames[i] = "arg$" + (i + 1);
}
instantiatedArgumentTypes = Type.getArgumentTypes(instantiatedMethodType.toMethodDescriptorString());
-
}
/**
@@ -120,7 +133,8 @@
*
* @return a CallSite, which, when invoked, will return an instance of the
* functional interface
- * @throws ReflectiveOperationException, LambdaConversionException
+ * @throws ReflectiveOperationException
+ * @throws LambdaConversionException If properly formed functional interface is not found
*/
@Override
CallSite buildCallSite() throws ReflectiveOperationException, LambdaConversionException {
@@ -151,8 +165,8 @@
} else {
return new ConstantCallSite(
MethodHandles.Lookup.IMPL_LOOKUP
- .findConstructor(innerClass, constructorType)
- .asType(constructorType.changeReturnType(samBase)));
+ .findConstructor(innerClass, constructorType)
+ .asType(constructorType.changeReturnType(samBase)));
}
}
@@ -161,16 +175,23 @@
* interface, define and return the class.
*
* @return a Class which implements the functional interface
+ * @throws LambdaConversionException If properly formed functional interface is not found
*/
- private <T> Class<? extends T> spinInnerClass() throws LambdaConversionException {
+ private Class<?> spinInnerClass() throws LambdaConversionException {
String samName = samBase.getName().replace('.', '/');
-
- cw.visit(CLASSFILE_VERSION, ACC_SUPER, lambdaClassName, null, NAME_MAGIC_ACCESSOR_IMPL,
- isSerializable ? new String[]{samName, NAME_SERIALIZABLE} : new String[]{samName});
+ String[] interfaces = new String[markerInterfaces.length + 1];
+ interfaces[0] = samName;
+ for (int i=0; i<markerInterfaces.length; i++) {
+ interfaces[i+1] = markerInterfaces[i].getName().replace('.', '/');
+ }
+ cw.visit(CLASSFILE_VERSION, ACC_SUPER,
+ lambdaClassName, null,
+ NAME_MAGIC_ACCESSOR_IMPL, interfaces);
// Generate final fields to be filled in by constructor
for (int i = 0; i < argTypes.length; i++) {
- FieldVisitor fv = cw.visitField(ACC_PRIVATE + ACC_FINAL, argNames[i], argTypes[i].getDescriptor(), null, null);
+ FieldVisitor fv = cw.visitField(ACC_PRIVATE + ACC_FINAL, argNames[i], argTypes[i].getDescriptor(),
+ null, null);
fv.visitEnd();
}
@@ -180,26 +201,24 @@
// Forward the SAM method
if (ma.getSamMethod() == null) {
- throw new LambdaConversionException(String.format("SAM method not found: %s", samMethodType));
+ throw new LambdaConversionException(String.format("Functional interface method not found: %s", samMethodType));
} else {
generateForwardingMethod(ma.getSamMethod(), false);
}
// Forward the bridges
- // @@@ Once the VM can do fail-over, uncomment the default method test
- if (!ma.getMethodsToBridge().isEmpty() /* && !ma.wasDefaultMethodFound() */) {
+ // @@@ The commented-out code is temporary, pending the VM's ability to bridge all methods on request
+ // @@@ Once the VM can do fail-over, uncomment the !ma.wasDefaultMethodFound() test, and emit the appropriate
+ // @@@ classfile attribute to request custom bridging. See 8002092.
+ if (!ma.getMethodsToBridge().isEmpty() /* && !ma.conflictFoundBetweenDefaultAndBridge() */ ) {
for (Method m : ma.getMethodsToBridge()) {
generateForwardingMethod(m, true);
}
}
- /***** Serialization not yet supported
if (isSerializable) {
- String samMethodName = samInfo.getName();
- Type samType = Type.getType(samBase);
- generateSerializationMethod(samType, samMethodName);
+ generateWriteReplace();
}
- ******/
cw.visitEnd();
@@ -212,7 +231,7 @@
try (FileOutputStream fos = new FileOutputStream(lambdaClassName.replace('/', '.') + ".class")) {
fos.write(classBytes);
} catch (IOException ex) {
- Logger.getLogger(InnerClassLambdaMetafactory.class.getName()).log(Level.SEVERE, null, ex);
+ PlatformLogger.getLogger(InnerClassLambdaMetafactory.class.getName()).severe(ex.getMessage(), ex);
}
***/
@@ -228,7 +247,8 @@
}
);
- return (Class<? extends T>) Unsafe.getUnsafe().defineClass(lambdaClassName, classBytes, 0, classBytes.length, loader, pd);
+ return (Class<?>) Unsafe.getUnsafe().defineClass(lambdaClassName, classBytes, 0, classBytes.length,
+ loader, pd);
}
/**
@@ -253,40 +273,44 @@
}
/**
- * Generate the serialization method (if needed)
+ * Generate the writeReplace method (if needed for serialization)
*/
- /****** This code is out of date -- known to be wrong -- and not currently used ******
- private void generateSerializationMethod(Type samType, String samMethodName) {
- String samMethodDesc = samMethodType.toMethodDescriptorString();
- TypeConvertingMethodAdapter mv = new TypeConvertingMethodAdapter(cw.visitMethod(ACC_PRIVATE + ACC_FINAL, NAME_METHOD_WRITE_REPLACE, DESCR_METHOD_WRITE_REPLACE, null, null));
+ private void generateWriteReplace() {
+ TypeConvertingMethodAdapter mv
+ = new TypeConvertingMethodAdapter(cw.visitMethod(ACC_PRIVATE + ACC_FINAL,
+ NAME_METHOD_WRITE_REPLACE, DESCR_METHOD_WRITE_REPLACE,
+ null, null));
mv.visitCode();
mv.visitTypeInsn(NEW, NAME_SERIALIZED_LAMBDA);
- mv.dup();
- mv.visitLdcInsn(samType);
- mv.visitLdcInsn(samMethodName);
- mv.visitLdcInsn(samMethodDesc);
- mv.visitLdcInsn(Type.getType(implDefiningClass));
- mv.visitLdcInsn(implMethodName);
- mv.visitLdcInsn(implMethodDesc);
+ mv.visitInsn(DUP);;
+ mv.visitLdcInsn(Type.getType(targetClass));
+ mv.visitLdcInsn(samInfo.getReferenceKind());
+ mv.visitLdcInsn(invokedType.returnType().getName().replace('.', '/'));
+ mv.visitLdcInsn(samInfo.getName());
+ mv.visitLdcInsn(samInfo.getMethodType().toMethodDescriptorString());
+ mv.visitLdcInsn(implInfo.getReferenceKind());
+ mv.visitLdcInsn(implInfo.getDeclaringClass().getName().replace('.', '/'));
+ mv.visitLdcInsn(implInfo.getName());
+ mv.visitLdcInsn(implInfo.getMethodType().toMethodDescriptorString());
+ mv.visitLdcInsn(instantiatedMethodType.toMethodDescriptorString());
mv.iconst(argTypes.length);
mv.visitTypeInsn(ANEWARRAY, NAME_OBJECT);
for (int i = 0; i < argTypes.length; i++) {
- mv.dup();
+ mv.visitInsn(DUP);
mv.iconst(i);
mv.visitVarInsn(ALOAD, 0);
- mv.getfield(lambdaClassName, argNames[i], argTypes[i].getDescriptor());
- mv.boxIfPrimitive(argTypes[i]);
+ mv.visitFieldInsn(GETFIELD, lambdaClassName, argNames[i], argTypes[i].getDescriptor());
+ mv.boxIfTypePrimitive(argTypes[i]);
mv.visitInsn(AASTORE);
}
- mv.invokespecial(NAME_SERIALIZED_LAMBDA, NAME_CTOR,
- "(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V");
+ mv.visitMethodInsn(INVOKESPECIAL, NAME_SERIALIZED_LAMBDA, NAME_CTOR,
+ DESCR_CTOR_SERIALIZED_LAMBDA);
mv.visitInsn(ARETURN);
mv.visitMaxs(-1, -1); // Maxs computed by ClassWriter.COMPUTE_MAXS, these arguments ignored
mv.visitEnd();
}
- ********/
/**
* Generate a method which calls the lambda implementation method,
@@ -321,11 +345,11 @@
if (implKind == MethodHandleInfo.REF_newInvokeSpecial) {
visitTypeInsn(NEW, implMethodClassName);
- dup();
+ visitInsn(DUP);;
}
for (int i = 0; i < argTypes.length; i++) {
visitVarInsn(ALOAD, 0);
- getfield(lambdaClassName, argNames[i], argTypes[i].getDescriptor());
+ visitFieldInsn(GETFIELD, lambdaClassName, argNames[i], argTypes[i].getDescriptor());
}
convertArgumentTypes(Type.getArgumentTypes(m));
@@ -337,7 +361,7 @@
// Note: if adapting from non-void to void, the 'return' instruction will pop the unneeded result
Type samReturnType = Type.getReturnType(m);
convertType(implMethodReturnType, samReturnType, samReturnType);
- areturn(samReturnType);
+ visitInsn(samReturnType.getOpcode(Opcodes.IRETURN));
visitMaxs(-1, -1); // Maxs computed by ClassWriter.COMPUTE_MAXS, these arguments ignored
visitEnd();
@@ -352,7 +376,7 @@
Type rcvrType = samArgumentTypes[0];
Type instantiatedRcvrType = instantiatedArgumentTypes[0];
- load(lvIndex + 1, rcvrType);
+ visitVarInsn(rcvrType.getOpcode(ILOAD), lvIndex + 1);
lvIndex += rcvrType.getSize();
convertType(rcvrType, Type.getType(implDefiningClass), instantiatedRcvrType);
}
@@ -362,7 +386,7 @@
Type targetType = implMethodArgumentTypes[argOffset + i];
Type instantiatedArgType = instantiatedArgumentTypes[i];
- load(lvIndex + 1, argType);
+ visitVarInsn(argType.getOpcode(ILOAD), lvIndex + 1);
lvIndex += argType.getSize();
convertType(argType, targetType, instantiatedArgType);
}
@@ -388,45 +412,5 @@
throw new InternalError("Unexpected invocation kind: " + implKind);
}
}
-
- /**
- * The following methods are copied from
- * org.objectweb.asm.commons.InstructionAdapter. Part of ASM: a very
- * small and fast Java bytecode manipulation framework. Copyright (c)
- * 2000-2005 INRIA, France Telecom All rights reserved.
- *
- * Subclass with that (removing these methods) if that package/class is
- * ever added to the JDK.
- */
- private void iconst(final int cst) {
- if (cst >= -1 && cst <= 5) {
- mv.visitInsn(Opcodes.ICONST_0 + cst);
- } else if (cst >= Byte.MIN_VALUE && cst <= Byte.MAX_VALUE) {
- mv.visitIntInsn(Opcodes.BIPUSH, cst);
- } else if (cst >= Short.MIN_VALUE && cst <= Short.MAX_VALUE) {
- mv.visitIntInsn(Opcodes.SIPUSH, cst);
- } else {
- mv.visitLdcInsn(cst);
- }
- }
-
- private void load(final int var, final Type type) {
- mv.visitVarInsn(type.getOpcode(Opcodes.ILOAD), var);
- }
-
- private void dup() {
- mv.visitInsn(Opcodes.DUP);
- }
-
- private void areturn(final Type t) {
- mv.visitInsn(t.getOpcode(Opcodes.IRETURN));
- }
-
- private void getfield(
- final String owner,
- final String name,
- final String desc) {
- mv.visitFieldInsn(Opcodes.GETFIELD, owner, name, desc);
- }
}
}
--- a/jdk/src/share/classes/java/lang/invoke/LambdaMetafactory.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/lang/invoke/LambdaMetafactory.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -42,14 +42,13 @@
* method, and the static types of the captured lambda arguments, and link a call site which, when invoked,
* produces the lambda object.
*
- * <p>Two pieces of information are needed about the functional interface: the SAM method and the type of the SAM
- * method in the functional interface. The type can be different when parameterized types are used. For example,
- * consider
- * <code>interface I<T> { int m(T x); }</code> if this SAM type is used in a lambda
- * <code>I<Byte> v = ...</code>, we need both the actual SAM method which has the signature
- * <code>(Object)int</code> and the functional interface type of the method, which has signature
- * <code>(Byte)int</code>. The latter is the instantiated erased functional interface method type, or
- * simply <I>instantiated method type</I>.
+ * <p>When parameterized types are used, the instantiated type of the functional interface method may be different
+ * from that in the functional interface. For example, consider
+ * <code>interface I<T> { int m(T x); }</code> if this functional interface type is used in a lambda
+ * <code>I<Byte> v = ...</code>, we need both the actual functional interface method which has the signature
+ * <code>(Object)int</code> and the erased instantiated type of the functional interface method (or simply
+ * <I>instantiated method type</I>), which has signature
+ * <code>(Byte)int</code>.
*
* <p>While functional interfaces only have a single abstract method from the language perspective (concrete
* methods in Object are and default methods may be present), at the bytecode level they may actually have multiple
@@ -138,11 +137,25 @@
* </tr>
* </table>
*
+ * The default bootstrap ({@link #metaFactory}) represents the common cases and uses an optimized protocol.
+ * Alternate bootstraps (e.g., {@link #altMetaFactory}) exist to support uncommon cases such as serialization
+ * or additional marker superinterfaces.
*
*/
public class LambdaMetafactory {
+ /** Flag for alternate metafactories indicating the lambda object is must to be serializable */
+ public static final int FLAG_SERIALIZABLE = 1 << 0;
+
/**
+ * Flag for alternate metafactories indicating the lambda object implements other marker interfaces
+ * besides Serializable
+ */
+ public static final int FLAG_MARKERS = 1 << 1;
+
+ private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[0];
+
+/**
* Standard meta-factory for conversion of lambda expressions or method references to functional interfaces.
*
* @param caller Stacked automatically by VM; represents a lookup context with the accessibility privileges
@@ -158,7 +171,8 @@
* @param implMethod The implementation method which should be called (with suitable adaptation of argument
* types, return types, and adjustment for captured arguments) when methods of the resulting
* functional interface instance are invoked.
- * @param instantiatedMethodType The signature of the SAM method from the functional interface's perspective
+ * @param instantiatedMethodType The signature of the primary functional interface method after type variables
+ * are substituted with their instantiation from the capture site
* @return a CallSite, which, when invoked, will return an instance of the functional interface
* @throws ReflectiveOperationException
* @throws LambdaConversionException If any of the meta-factory protocol invariants are violated
@@ -171,7 +185,72 @@
MethodType instantiatedMethodType)
throws ReflectiveOperationException, LambdaConversionException {
AbstractValidatingLambdaMetafactory mf;
- mf = new InnerClassLambdaMetafactory(caller, invokedType, samMethod, implMethod, instantiatedMethodType);
+ mf = new InnerClassLambdaMetafactory(caller, invokedType, samMethod, implMethod, instantiatedMethodType,
+ 0, EMPTY_CLASS_ARRAY);
+ mf.validateMetafactoryArgs();
+ return mf.buildCallSite();
+ }
+
+ /**
+ * Alternate meta-factory for conversion of lambda expressions or method references to functional interfaces,
+ * which supports serialization and other uncommon options.
+ *
+ * The declared argument list for this method is:
+ *
+ * CallSite altMetaFactory(MethodHandles.Lookup caller,
+ * String invokedName,
+ * MethodType invokedType,
+ * Object... args)
+ *
+ * but it behaves as if the argument list is:
+ *
+ * CallSite altMetaFactory(MethodHandles.Lookup caller,
+ * String invokedName,
+ * MethodType invokedType,
+ * MethodHandle samMethod
+ * MethodHandle implMethod,
+ * MethodType instantiatedMethodType,
+ * int flags,
+ * int markerInterfaceCount, // IF flags has MARKERS set
+ * Class... markerInterfaces // IF flags has MARKERS set
+ * )
+ *
+ *
+ * @param caller Stacked automatically by VM; represents a lookup context with the accessibility privileges
+ * of the caller.
+ * @param invokedName Stacked automatically by VM; the name of the invoked method as it appears at the call site.
+ * Currently unused.
+ * @param invokedType Stacked automatically by VM; the signature of the invoked method, which includes thefu
+ * expected static type of the returned lambda object, and the static types of the captured
+ * arguments for the lambda. In the event that the implementation method is an instance method,
+ * the first argument in the invocation signature will correspond to the receiver.
+ * @param args argument to pass, flags, marker interface count, and marker interfaces as described above
+ * @return a CallSite, which, when invoked, will return an instance of the functional interface
+ * @throws ReflectiveOperationException
+ * @throws LambdaConversionException If any of the meta-factory protocol invariants are violated
+ */
+ public static CallSite altMetaFactory(MethodHandles.Lookup caller,
+ String invokedName,
+ MethodType invokedType,
+ Object... args)
+ throws ReflectiveOperationException, LambdaConversionException {
+ MethodHandle samMethod = (MethodHandle)args[0];
+ MethodHandle implMethod = (MethodHandle)args[1];
+ MethodType instantiatedMethodType = (MethodType)args[2];
+ int flags = (Integer) args[3];
+ Class<?>[] markerInterfaces;
+ int argIndex = 4;
+ if ((flags & FLAG_MARKERS) != 0) {
+ int markerCount = (Integer) args[argIndex++];
+ markerInterfaces = new Class<?>[markerCount];
+ System.arraycopy(args, argIndex, markerInterfaces, 0, markerCount);
+ argIndex += markerCount;
+ }
+ else
+ markerInterfaces = EMPTY_CLASS_ARRAY;
+ AbstractValidatingLambdaMetafactory mf;
+ mf = new InnerClassLambdaMetafactory(caller, invokedType, samMethod, implMethod, instantiatedMethodType,
+ flags, markerInterfaces);
mf.validateMetafactoryArgs();
return mf.buildCallSite();
}
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandle.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandle.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1250,8 +1250,6 @@
/*non-public*/
MethodHandle viewAsType(MethodType newType) {
// No actual conversions, just a new view of the same method.
- if (!type.isViewableAs(newType))
- throw new InternalError();
return MethodHandleImpl.makePairwiseConvert(this, newType, 0);
}
@@ -1268,6 +1266,11 @@
}
/*non-public*/
+ boolean isInvokeSpecial() {
+ return false; // DMH.Special returns true
+ }
+
+ /*non-public*/
Object internalValues() {
return null;
}
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -367,11 +367,11 @@
@Override
MethodHandle viewAsType(MethodType newType) {
- MethodHandle mh = super.viewAsType(newType);
+ if (newType.lastParameterType() != type().lastParameterType())
+ throw new InternalError();
+ MethodHandle newTarget = asFixedArity().viewAsType(newType);
// put back the varargs bit:
- MethodType type = mh.type();
- int arity = type.parameterCount();
- return mh.asVarargsCollector(type.parameterType(arity-1));
+ return new AsVarargsCollector(newTarget, newType, arrayType);
}
@Override
@@ -379,6 +379,12 @@
return asFixedArity().internalMemberName();
}
+ /*non-public*/
+ @Override
+ boolean isInvokeSpecial() {
+ return asFixedArity().isInvokeSpecial();
+ }
+
@Override
MethodHandle bindArgument(int pos, char basicType, Object value) {
@@ -801,12 +807,11 @@
static
MethodHandle bindCaller(MethodHandle mh, Class<?> hostClass) {
// Do not use this function to inject calls into system classes.
- if (hostClass == null) {
- hostClass = C_Trampoline;
- } else if (hostClass.isArray() ||
+ if (hostClass == null
+ || (hostClass.isArray() ||
hostClass.isPrimitive() ||
hostClass.getName().startsWith("java.") ||
- hostClass.getName().startsWith("sun.")) {
+ hostClass.getName().startsWith("sun."))) {
throw new InternalError(); // does not happen, and should not anyway
}
// For simplicity, convert mh to a varargs-like method.
@@ -816,23 +821,6 @@
return restoreToType(bccInvoker.bindTo(vamh), mh.type());
}
- // This class ("Trampoline") is known to be inside a dead-end class loader.
- // Inject all doubtful calls into this class.
- private static Class<?> C_Trampoline;
- static {
- Class<?> tramp = null;
- try {
- final int FRAME_COUNT_ARG = 1; // [0] Reflection [1] Trampoline
- java.lang.reflect.Method gcc = sun.reflect.Reflection.class.getMethod("getCallerClass", int.class);
- tramp = (Class<?>) sun.reflect.misc.MethodUtil.invoke(gcc, null, new Object[]{ FRAME_COUNT_ARG });
- if (tramp.getClassLoader() == BindCaller.class.getClassLoader())
- throw new RuntimeException(tramp.getName()+" class loader");
- } catch (Throwable ex) {
- throw new InternalError(ex);
- }
- C_Trampoline = tramp;
- }
-
private static MethodHandle makeInjectedInvoker(Class<?> hostClass) {
Class<?> bcc = UNSAFE.defineAnonymousClass(hostClass, T_BYTES, null);
if (hostClass.getClassLoader() != bcc.getClassLoader())
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleInfo.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleInfo.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,10 +26,12 @@
package java.lang.invoke;
import java.lang.invoke.MethodHandleNatives.Constants;
-//Not yet public: public
-class MethodHandleInfo {
+/**
+ * Cracking (reflecting) method handles back into their constituent symbolic parts.
+ *
+ */
+final class MethodHandleInfo {
public static final int
- REF_NONE = Constants.REF_NONE,
REF_getField = Constants.REF_getField,
REF_getStatic = Constants.REF_getStatic,
REF_putField = Constants.REF_putField,
@@ -45,12 +47,17 @@
private final MethodType methodType;
private final int referenceKind;
- public MethodHandleInfo(MethodHandle mh) throws ReflectiveOperationException {
+ public MethodHandleInfo(MethodHandle mh) {
MemberName mn = mh.internalMemberName();
+ if (mn == null) throw new IllegalArgumentException("not a direct method handle");
this.declaringClass = mn.getDeclaringClass();
this.name = mn.getName();
- this.methodType = mn.getMethodType();
- this.referenceKind = mn.getReferenceKind();
+ this.methodType = mn.getMethodOrFieldType();
+ byte refKind = mn.getReferenceKind();
+ if (refKind == REF_invokeSpecial && !mh.isInvokeSpecial())
+ // Devirtualized method invocation is usually formally virtual.
+ refKind = REF_invokeVirtual;
+ this.referenceKind = refKind;
}
public Class<?> getDeclaringClass() {
@@ -65,7 +72,32 @@
return methodType;
}
+ public int getModifiers() {
+ return -1; //TODO
+ }
+
public int getReferenceKind() {
return referenceKind;
}
+
+ static String getReferenceKindString(int referenceKind) {
+ switch (referenceKind) {
+ case REF_getField: return "getfield";
+ case REF_getStatic: return "getstatic";
+ case REF_putField: return "putfield";
+ case REF_putStatic: return "putstatic";
+ case REF_invokeVirtual: return "invokevirtual";
+ case REF_invokeStatic: return "invokestatic";
+ case REF_invokeSpecial: return "invokespecial";
+ case REF_newInvokeSpecial: return "newinvokespecial";
+ case REF_invokeInterface: return "invokeinterface";
+ default: return "UNKNOWN_REFENCE_KIND" + "[" + referenceKind + "]";
+ }
+ }
+
+ @Override
+ public String toString() {
+ return String.format("%s %s.%s:%s", getReferenceKindString(referenceKind),
+ declaringClass.getName(), name, methodType);
+ }
}
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java Fri Mar 15 16:39:07 2013 -0700
@@ -393,15 +393,33 @@
*/
// FIXME: Replace this pattern match by an annotation @sun.reflect.CallerSensitive.
static boolean isCallerSensitive(MemberName mem) {
- assert(mem.isInvocable());
+ if (!mem.isInvocable()) return false; // fields are not caller sensitive
Class<?> defc = mem.getDeclaringClass();
switch (mem.getName()) {
case "doPrivileged":
+ case "doPrivilegedWithCombiner":
return defc == java.security.AccessController.class;
+ case "checkMemberAccess":
+ return canBeCalledVirtual(mem, java.lang.SecurityManager.class);
case "getUnsafe":
return defc == sun.misc.Unsafe.class;
case "lookup":
return defc == java.lang.invoke.MethodHandles.class;
+ case "findStatic":
+ case "findVirtual":
+ case "findConstructor":
+ case "findSpecial":
+ case "findGetter":
+ case "findSetter":
+ case "findStaticGetter":
+ case "findStaticSetter":
+ case "bind":
+ case "unreflect":
+ case "unreflectSpecial":
+ case "unreflectConstructor":
+ case "unreflectGetter":
+ case "unreflectSetter":
+ return defc == java.lang.invoke.MethodHandles.Lookup.class;
case "invoke":
return defc == java.lang.reflect.Method.class;
case "get":
@@ -455,7 +473,7 @@
if (defc == java.util.concurrent.atomic.AtomicReferenceFieldUpdater.class) return true;
break;
case "getContextClassLoader":
- return defc == java.lang.Thread.class;
+ return canBeCalledVirtual(mem, java.lang.Thread.class);
case "getPackage":
case "getPackages":
return defc == java.lang.Package.class;
@@ -473,9 +491,13 @@
break;
case "getCallerClassLoader":
return defc == java.lang.ClassLoader.class;
+ case "registerAsParallelCapable":
+ return canBeCalledVirtual(mem, java.lang.ClassLoader.class);
case "getProxyClass":
case "newProxyInstance":
return defc == java.lang.reflect.Proxy.class;
+ case "asInterfaceInstance":
+ return defc == java.lang.invoke.MethodHandleProxies.class;
case "getBundle":
case "clearCache":
return defc == java.util.ResourceBundle.class;
@@ -492,4 +514,11 @@
throw new InternalError(e);
}
}
+ static boolean canBeCalledVirtual(MemberName symbolicRef, Class<?> definingClass) {
+ Class<?> symbolicRefClass = symbolicRef.getDeclaringClass();
+ if (symbolicRefClass == definingClass) return true;
+ if (symbolicRef.isStatic() || symbolicRef.isPrivate()) return false;
+ return (definingClass.isAssignableFrom(symbolicRefClass) || // Msym overrides Mdef
+ symbolicRefClass.isInterface()); // Mdef implements Msym
+ }
}
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleProxies.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleProxies.java Fri Mar 15 16:39:07 2013 -0700
@@ -26,8 +26,12 @@
package java.lang.invoke;
import java.lang.reflect.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import sun.invoke.WrapperInstance;
import java.util.ArrayList;
+import sun.reflect.Reflection;
+import sun.reflect.misc.ReflectUtil;
/**
* This class consists exclusively of static methods that help adapt
@@ -137,6 +141,21 @@
<T> T asInterfaceInstance(final Class<T> intfc, final MethodHandle target) {
if (!intfc.isInterface() || !Modifier.isPublic(intfc.getModifiers()))
throw new IllegalArgumentException("not a public interface: "+intfc.getName());
+ final MethodHandle mh;
+ if (System.getSecurityManager() != null) {
+ final int CALLER_FRAME = 2; // 0: Reflection, 1: asInterfaceInstance, 2: caller
+ final Class<?> caller = Reflection.getCallerClass(CALLER_FRAME);
+ final ClassLoader ccl = caller != null ? caller.getClassLoader() : null;
+ ReflectUtil.checkProxyPackageAccess(ccl, intfc);
+ mh = ccl != null ? bindCaller(target, caller) : target;
+ } else {
+ mh = target;
+ }
+ ClassLoader proxyLoader = intfc.getClassLoader();
+ if (proxyLoader == null) {
+ ClassLoader cl = Thread.currentThread().getContextClassLoader(); // avoid use of BCP
+ proxyLoader = cl != null ? cl : ClassLoader.getSystemClassLoader();
+ }
final Method[] methods = getSingleNameMethods(intfc);
if (methods == null)
throw new IllegalArgumentException("not a single-method interface: "+intfc.getName());
@@ -144,31 +163,58 @@
for (int i = 0; i < methods.length; i++) {
Method sm = methods[i];
MethodType smMT = MethodType.methodType(sm.getReturnType(), sm.getParameterTypes());
- MethodHandle checkTarget = target.asType(smMT); // make throw WMT
+ MethodHandle checkTarget = mh.asType(smMT); // make throw WMT
checkTarget = checkTarget.asType(checkTarget.type().changeReturnType(Object.class));
vaTargets[i] = checkTarget.asSpreader(Object[].class, smMT.parameterCount());
}
- return intfc.cast(Proxy.newProxyInstance(
- intfc.getClassLoader(),
- new Class<?>[]{ intfc, WrapperInstance.class },
- new InvocationHandler() {
- private Object getArg(String name) {
- if ((Object)name == "getWrapperInstanceTarget") return target;
- if ((Object)name == "getWrapperInstanceType") return intfc;
- throw new AssertionError();
+ final InvocationHandler ih = new InvocationHandler() {
+ private Object getArg(String name) {
+ if ((Object)name == "getWrapperInstanceTarget") return target;
+ if ((Object)name == "getWrapperInstanceType") return intfc;
+ throw new AssertionError();
+ }
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ for (int i = 0; i < methods.length; i++) {
+ if (method.equals(methods[i]))
+ return vaTargets[i].invokeExact(args);
}
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- for (int i = 0; i < methods.length; i++) {
- if (method.equals(methods[i]))
- return vaTargets[i].invokeExact(args);
- }
- if (method.getDeclaringClass() == WrapperInstance.class)
- return getArg(method.getName());
- if (isObjectMethod(method))
- return callObjectMethod(proxy, method, args);
- throw new InternalError("bad proxy method: "+method);
- }
- }));
+ if (method.getDeclaringClass() == WrapperInstance.class)
+ return getArg(method.getName());
+ if (isObjectMethod(method))
+ return callObjectMethod(proxy, method, args);
+ throw new InternalError("bad proxy method: "+method);
+ }
+ };
+
+ final Object proxy;
+ if (System.getSecurityManager() != null) {
+ // sun.invoke.WrapperInstance is a restricted interface not accessible
+ // by any non-null class loader.
+ final ClassLoader loader = proxyLoader;
+ proxy = AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ public Object run() {
+ return Proxy.newProxyInstance(
+ loader,
+ new Class<?>[]{ intfc, WrapperInstance.class },
+ ih);
+ }
+ });
+ } else {
+ proxy = Proxy.newProxyInstance(proxyLoader,
+ new Class<?>[]{ intfc, WrapperInstance.class },
+ ih);
+ }
+ return intfc.cast(proxy);
+ }
+
+ private static MethodHandle bindCaller(MethodHandle target, Class<?> hostClass) {
+ MethodHandle cbmh = MethodHandleImpl.bindCaller(target, hostClass);
+ if (target.isVarargsCollector()) {
+ MethodType type = cbmh.type();
+ int arity = type.parameterCount();
+ return cbmh.asVarargsCollector(type.parameterType(arity-1));
+ }
+ return cbmh;
}
/**
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -598,7 +598,8 @@
MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
MemberName method = resolveOrFail(REF_invokeStatic, refc, name, type);
checkSecurityManager(refc, method); // stack walk magic: do not refactor
- return getDirectMethod(REF_invokeStatic, refc, method);
+ Class<?> callerClass = findBoundCallerClass(method); // stack walk magic: do not refactor
+ return getDirectMethod(REF_invokeStatic, refc, method, callerClass);
}
/**
@@ -652,7 +653,8 @@
byte refKind = (refc.isInterface() ? REF_invokeInterface : REF_invokeVirtual);
MemberName method = resolveOrFail(refKind, refc, name, type);
checkSecurityManager(refc, method); // stack walk magic: do not refactor
- return getDirectMethod(refKind, refc, method);
+ Class<?> callerClass = findBoundCallerClass(method);
+ return getDirectMethod(refKind, refc, method, callerClass);
}
private MethodHandle findVirtualForMH(String name, MethodType type) {
// these names require special lookups because of the implicit MethodType argument
@@ -736,7 +738,8 @@
Lookup specialLookup = this.in(specialCaller);
MemberName method = specialLookup.resolveOrFail(REF_invokeSpecial, refc, name, type);
checkSecurityManager(refc, method); // stack walk magic: do not refactor
- return specialLookup.getDirectMethod(REF_invokeSpecial, refc, method);
+ Class<?> callerClass = findBoundCallerClass(method);
+ return specialLookup.getDirectMethod(REF_invokeSpecial, refc, method, callerClass);
}
/**
@@ -879,7 +882,8 @@
Class<? extends Object> refc = receiver.getClass(); // may get NPE
MemberName method = resolveOrFail(REF_invokeSpecial, refc, name, type);
checkSecurityManager(refc, method); // stack walk magic: do not refactor
- MethodHandle mh = getDirectMethodNoRestrict(REF_invokeSpecial, refc, method);
+ Class<?> callerClass = findBoundCallerClass(method); // stack walk magic: do not refactor
+ MethodHandle mh = getDirectMethodNoRestrict(REF_invokeSpecial, refc, method, callerClass);
return mh.bindReceiver(receiver).setVarargs(method);
}
@@ -910,8 +914,9 @@
if (refKind == REF_invokeSpecial)
refKind = REF_invokeVirtual;
assert(method.isMethod());
+ Class<?> callerClass = findBoundCallerClass(method); // stack walk magic: do not refactor
Lookup lookup = m.isAccessible() ? IMPL_LOOKUP : this;
- return lookup.getDirectMethod(refKind, method.getDeclaringClass(), method);
+ return lookup.getDirectMethod(refKind, method.getDeclaringClass(), method, callerClass);
}
/**
@@ -940,8 +945,9 @@
Lookup specialLookup = this.in(specialCaller);
MemberName method = new MemberName(m, true);
assert(method.isMethod());
+ Class<?> callerClass = findBoundCallerClass(method); // stack walk magic: do not refactor
// ignore m.isAccessible: this is a new kind of access
- return specialLookup.getDirectMethod(REF_invokeSpecial, method.getDeclaringClass(), method);
+ return specialLookup.getDirectMethod(REF_invokeSpecial, method.getDeclaringClass(), method, callerClass);
}
/**
@@ -1040,7 +1046,29 @@
}
/**
+ * Find my trustable caller class if m is a caller sensitive method.
+ * If this lookup object has private access, then the caller class is the lookupClass.
+ * Otherwise, it is the caller of the currently executing public API method (e.g., findVirtual).
+ * This is the same caller class as is used by checkSecurityManager.
+ * This function performs stack walk magic: do not refactor it.
+ */
+ Class<?> findBoundCallerClass(MemberName m) {
+ Class<?> callerClass = null;
+ if (MethodHandleNatives.isCallerSensitive(m)) {
+ // Do not refactor this to a more "logical" place, since it is stack walk magic.
+ // Note that this is the same expression as in Step 2 below in checkSecurityManager.
+ callerClass = ((allowedModes & PRIVATE) != 0
+ ? lookupClass // for strong access modes, no extra check
+ // next line does stack walk magic; do not refactor:
+ : getCallerClassAtEntryPoint(true));
+ }
+ return callerClass;
+ }
+ /**
* Perform necessary <a href="MethodHandles.Lookup.html#secmgr">access checks</a>.
+ * Determines a trustable caller class to compare with refc, the symbolic reference class.
+ * If this lookup object has private access, then the caller class is the lookupClass.
+ * Otherwise, it is the caller of the currently executing public API method (e.g., findVirtual).
* This function performs stack walk magic: do not refactor it.
*/
void checkSecurityManager(Class<?> refc, MemberName m) {
@@ -1195,22 +1223,22 @@
return mh.viewAsType(narrowType);
}
- private MethodHandle getDirectMethod(byte refKind, Class<?> refc, MemberName method) throws IllegalAccessException {
+ private MethodHandle getDirectMethod(byte refKind, Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
return getDirectMethodCommon(refKind, refc, method,
(refKind == REF_invokeSpecial ||
(MethodHandleNatives.refKindHasReceiver(refKind) &&
- restrictProtectedReceiver(method))));
+ restrictProtectedReceiver(method))), callerClass);
}
- private MethodHandle getDirectMethodNoRestrict(byte refKind, Class<?> refc, MemberName method) throws IllegalAccessException {
- return getDirectMethodCommon(refKind, refc, method, false);
+ private MethodHandle getDirectMethodNoRestrict(byte refKind, Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
+ return getDirectMethodCommon(refKind, refc, method, false, callerClass);
}
private MethodHandle getDirectMethodCommon(byte refKind, Class<?> refc, MemberName method,
- boolean doRestrict) throws IllegalAccessException {
+ boolean doRestrict, Class<?> callerClass) throws IllegalAccessException {
checkMethod(refKind, refc, method);
if (method.isMethodHandleInvoke())
return fakeMethodHandleInvoke(method);
- MethodHandle mh = DirectMethodHandle.make(refc, method);
- mh = maybeBindCaller(method, mh);
+ MethodHandle mh = DirectMethodHandle.make(refKind, refc, method);
+ mh = maybeBindCaller(method, mh, callerClass);
mh = mh.setVarargs(method);
if (doRestrict)
mh = restrictReceiver(method, mh, lookupClass());
@@ -1219,12 +1247,14 @@
private MethodHandle fakeMethodHandleInvoke(MemberName method) {
return throwException(method.getReturnType(), UnsupportedOperationException.class);
}
- private MethodHandle maybeBindCaller(MemberName method, MethodHandle mh) throws IllegalAccessException {
+ private MethodHandle maybeBindCaller(MemberName method, MethodHandle mh,
+ Class<?> callerClass)
+ throws IllegalAccessException {
if (allowedModes == TRUSTED || !MethodHandleNatives.isCallerSensitive(method))
return mh;
Class<?> hostClass = lookupClass;
if ((allowedModes & PRIVATE) == 0) // caller must use full-power lookup
- hostClass = null;
+ hostClass = callerClass; // callerClass came from a security manager style stack walk
MethodHandle cbmh = MethodHandleImpl.bindCaller(mh, hostClass);
// Note: caller will apply varargs after this step happens.
return cbmh;
@@ -1262,7 +1292,7 @@
} else if (MethodHandleNatives.refKindIsMethod(refKind)) {
MemberName method = (resolved != null) ? resolved
: resolveOrFail(refKind, defc, name, (MethodType) type);
- return getDirectMethod(refKind, defc, method);
+ return getDirectMethod(refKind, defc, method, lookupClass);
} else if (refKind == REF_newInvokeSpecial) {
assert(name == null || name.equals("<init>"));
MemberName ctor = (resolved != null) ? resolved
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/SerializedLambda.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.lang.invoke;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.Objects;
+
+/**
+ * Serialized form of a lambda expression. The properties of this class represent the information that is present
+ * at the lambda factory site, including the identity of the primary functional interface method, the identity of the
+ * implementation method, and any variables captured from the local environment at the time of lambda capture.
+ *
+ * @see LambdaMetafactory
+ */
+public final class SerializedLambda implements Serializable {
+ private static final long serialVersionUID = 8025925345765570181L;
+ private final Class<?> capturingClass;
+ private final String functionalInterfaceClass;
+ private final String functionalInterfaceMethodName;
+ private final String functionalInterfaceMethodSignature;
+ private final int functionalInterfaceMethodKind;
+ private final String implClass;
+ private final String implMethodName;
+ private final String implMethodSignature;
+ private final int implMethodKind;
+ private final String instantiatedMethodType;
+ private final Object[] capturedArgs;
+
+ /**
+ * Create a {@code SerializedLambda} from the low-level information present at the lambda factory site.
+ *
+ * @param capturingClass The class in which the lambda expression appears
+ * @param functionalInterfaceMethodKind Method handle kind (see {@link MethodHandleInfo}) for the
+ * functional interface method handle present at the lambda factory site
+ * @param functionalInterfaceClass Name, in slash-delimited form, for the functional interface class present at the
+ * lambda factory site
+ * @param functionalInterfaceMethodName Name of the primary method for the functional interface present at the
+ * lambda factory site
+ * @param functionalInterfaceMethodSignature Signature of the primary method for the functional interface present
+ * at the lambda factory site
+ * @param implMethodKind Method handle kind for the implementation method
+ * @param implClass Name, in slash-delimited form, for the class holding the implementation method
+ * @param implMethodName Name of the implementation method
+ * @param implMethodSignature Signature of the implementation method
+ * @param instantiatedMethodType The signature of the primary functional interface method after type variables
+ * are substituted with their instantiation from the capture site
+ * @param capturedArgs The dynamic arguments to the lambda factory site, which represent variables captured by
+ * the lambda
+ */
+ public SerializedLambda(Class<?> capturingClass,
+ int functionalInterfaceMethodKind,
+ String functionalInterfaceClass,
+ String functionalInterfaceMethodName,
+ String functionalInterfaceMethodSignature,
+ int implMethodKind,
+ String implClass,
+ String implMethodName,
+ String implMethodSignature,
+ String instantiatedMethodType,
+ Object[] capturedArgs) {
+ this.capturingClass = capturingClass;
+ this.functionalInterfaceMethodKind = functionalInterfaceMethodKind;
+ this.functionalInterfaceClass = functionalInterfaceClass;
+ this.functionalInterfaceMethodName = functionalInterfaceMethodName;
+ this.functionalInterfaceMethodSignature = functionalInterfaceMethodSignature;
+ this.implMethodKind = implMethodKind;
+ this.implClass = implClass;
+ this.implMethodName = implMethodName;
+ this.implMethodSignature = implMethodSignature;
+ this.instantiatedMethodType = instantiatedMethodType;
+ this.capturedArgs = Objects.requireNonNull(capturedArgs).clone();
+ }
+
+ /** Get the name of the class that captured this lambda */
+ public String getCapturingClass() {
+ return capturingClass.getName().replace('.', '/');
+ }
+
+ /** Get the name of the functional interface class to which this lambda has been converted */
+ public String getFunctionalInterfaceClass() {
+ return functionalInterfaceClass;
+ }
+
+ /** Get the name of the primary method for the functional interface to which this lambda has been converted */
+ public String getFunctionalInterfaceMethodName() {
+ return functionalInterfaceMethodName;
+ }
+
+ /** Get the signature of the primary method for the functional interface to which this lambda has been converted */
+ public String getFunctionalInterfaceMethodSignature() {
+ return functionalInterfaceMethodSignature;
+ }
+
+ /** Get the method handle kind (see {@link MethodHandleInfo}) of the primary method for the functional interface
+ * to which this lambda has been converted */
+ public int getFunctionalInterfaceMethodKind() {
+ return functionalInterfaceMethodKind;
+ }
+
+ /** Get the name of the class containing the implementation method */
+ public String getImplClass() {
+ return implClass;
+ }
+
+ /** Get the name of the implementation method */
+ public String getImplMethodName() {
+ return implMethodName;
+ }
+
+ /** Get the signature of the implementation method */
+ public String getImplMethodSignature() {
+ return implMethodSignature;
+ }
+
+ /** Get the method handle kind (see {@link MethodHandleInfo}) of the implementation method */
+ public int getImplMethodKind() {
+ return implMethodKind;
+ }
+
+ /**
+ * Get the signature of the primary functional interface method after type variables are substituted with
+ * their instantiation from the capture site
+ */
+ public final String getInstantiatedMethodType() {
+ return instantiatedMethodType;
+ }
+
+ /** Get the count of dynamic arguments to the lambda capture site */
+ public int getCapturedArgCount() {
+ return capturedArgs.length;
+ }
+
+ /** Get a dynamic argument to the lambda capture site */
+ public Object getCapturedArg(int i) {
+ return capturedArgs[i];
+ }
+
+ private Object readResolve() throws ReflectiveOperationException {
+ try {
+ Method deserialize = AccessController.doPrivileged(new PrivilegedExceptionAction<Method>() {
+ @Override
+ public Method run() throws Exception {
+ Method m = capturingClass.getDeclaredMethod("$deserializeLambda$", SerializedLambda.class);
+ m.setAccessible(true);
+ return m;
+ }
+ });
+
+ return deserialize.invoke(null, this);
+ }
+ catch (PrivilegedActionException e) {
+ Exception cause = e.getException();
+ if (cause instanceof ReflectiveOperationException)
+ throw (ReflectiveOperationException) cause;
+ else if (cause instanceof RuntimeException)
+ throw (RuntimeException) cause;
+ else
+ throw new RuntimeException("Exception in SerializedLambda.readResolve", e);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return String.format("SerializedLambda[capturingClass=%s, functionalInterfaceMethod=%s %s.%s:%s, " +
+ "implementation=%s %s.%s:%s, instantiatedMethodType=%s, numCaptured=%d]",
+ capturingClass, MethodHandleInfo.getReferenceKindString(functionalInterfaceMethodKind),
+ functionalInterfaceClass, functionalInterfaceMethodName, functionalInterfaceMethodSignature,
+ MethodHandleInfo.getReferenceKindString(implMethodKind), implClass, implMethodName,
+ implMethodSignature, instantiatedMethodType, capturedArgs.length);
+ }
+}
--- a/jdk/src/share/classes/java/lang/invoke/TypeConvertingMethodAdapter.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/lang/invoke/TypeConvertingMethodAdapter.java Fri Mar 15 16:39:07 2013 -0700
@@ -27,6 +27,7 @@
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.org.objectweb.asm.Type;
import sun.invoke.util.Wrapper;
import static sun.invoke.util.Wrapper.*;
@@ -49,6 +50,9 @@
private static final Wrapper[] FROM_WRAPPER_NAME = new Wrapper[16];
+ // Table of wrappers for primitives, indexed by ASM type sorts
+ private static final Wrapper[] FROM_TYPE_SORT = new Wrapper[16];
+
static {
for (Wrapper w : Wrapper.values()) {
if (w.basicTypeChar() != 'L') {
@@ -71,6 +75,15 @@
initWidening(DOUBLE, Opcodes.I2D, BYTE, SHORT, INT, CHAR);
initWidening(DOUBLE, Opcodes.F2D, FLOAT);
initWidening(DOUBLE, Opcodes.L2D, LONG);
+
+ FROM_TYPE_SORT[Type.BYTE] = Wrapper.BYTE;
+ FROM_TYPE_SORT[Type.SHORT] = Wrapper.SHORT;
+ FROM_TYPE_SORT[Type.INT] = Wrapper.INT;
+ FROM_TYPE_SORT[Type.LONG] = Wrapper.LONG;
+ FROM_TYPE_SORT[Type.CHAR] = Wrapper.CHAR;
+ FROM_TYPE_SORT[Type.FLOAT] = Wrapper.FLOAT;
+ FROM_TYPE_SORT[Type.DOUBLE] = Wrapper.DOUBLE;
+ FROM_TYPE_SORT[Type.BOOLEAN] = Wrapper.BOOLEAN;
}
private static void initWidening(Wrapper to, int opcode, Wrapper... from) {
@@ -124,8 +137,9 @@
return "()" + w.basicTypeChar();
}
- void boxIfPrimitive(Wrapper w) {
- if (w.zero() != null) {
+ void boxIfTypePrimitive(Type t) {
+ Wrapper w = FROM_TYPE_SORT[t.getSort()];
+ if (w != null) {
box(w);
}
}
@@ -264,4 +278,22 @@
}
}
}
+
+ /**
+ * The following method is copied from
+ * org.objectweb.asm.commons.InstructionAdapter. Part of ASM: a very small
+ * and fast Java bytecode manipulation framework.
+ * Copyright (c) 2000-2005 INRIA, France Telecom All rights reserved.
+ */
+ void iconst(final int cst) {
+ if (cst >= -1 && cst <= 5) {
+ mv.visitInsn(Opcodes.ICONST_0 + cst);
+ } else if (cst >= Byte.MIN_VALUE && cst <= Byte.MAX_VALUE) {
+ mv.visitIntInsn(Opcodes.BIPUSH, cst);
+ } else if (cst >= Short.MIN_VALUE && cst <= Short.MAX_VALUE) {
+ mv.visitIntInsn(Opcodes.SIPUSH, cst);
+ } else {
+ mv.visitLdcInsn(cst);
+ }
+ }
}
--- a/jdk/src/share/classes/java/lang/management/ManagementFactory.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/lang/management/ManagementFactory.java Fri Mar 15 16:39:07 2013 -0700
@@ -802,20 +802,20 @@
*/
private static void addMXBean(final MBeanServer mbs, final PlatformManagedObject pmo) {
// Make DynamicMBean out of MXBean by wrapping it with a StandardMBean
- final DynamicMBean dmbean;
- if (pmo instanceof DynamicMBean) {
- dmbean = DynamicMBean.class.cast(pmo);
- } else if (pmo instanceof NotificationEmitter) {
- dmbean = new StandardEmitterMBean(pmo, null, true, (NotificationEmitter) pmo);
- } else {
- dmbean = new StandardMBean(pmo, null, true);
- }
-
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
public Void run() throws InstanceAlreadyExistsException,
MBeanRegistrationException,
NotCompliantMBeanException {
+ final DynamicMBean dmbean;
+ if (pmo instanceof DynamicMBean) {
+ dmbean = DynamicMBean.class.cast(pmo);
+ } else if (pmo instanceof NotificationEmitter) {
+ dmbean = new StandardEmitterMBean(pmo, null, true, (NotificationEmitter) pmo);
+ } else {
+ dmbean = new StandardMBean(pmo, null, true);
+ }
+
mbs.registerMBean(dmbean, pmo.getObjectName());
return null;
}
--- a/jdk/src/share/classes/java/lang/reflect/AccessibleObject.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/lang/reflect/AccessibleObject.java Fri Mar 15 16:39:07 2013 -0700
@@ -181,6 +181,16 @@
}
/**
+ * {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ * @since 1.5
+ */
+ @Override
+ public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
+ return AnnotatedElement.super.isAnnotationPresent(annotationClass);
+ }
+
+ /**
* @throws NullPointerException {@inheritDoc}
* @since 1.8
*/
--- a/jdk/src/share/classes/java/lang/reflect/AnnotatedElement.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/lang/reflect/AnnotatedElement.java Fri Mar 15 16:39:07 2013 -0700
@@ -26,6 +26,7 @@
package java.lang.reflect;
import java.lang.annotation.Annotation;
+import java.lang.annotation.AnnotationFormatError;
/**
* Represents an annotated element of the program currently running in this
@@ -86,8 +87,8 @@
*
* <p>Attempting to read annotations of a repeatable annotation type T
* that are contained in an annotation whose type is not, in fact, the
- * containing annotation type of T will result in an
- * InvalidContainerAnnotationError.
+ * containing annotation type of T, will result in an {@link
+ * AnnotationFormatError}.
*
* <p>Finally, attempting to read a member whose definition has evolved
* incompatibly will result in a {@link
@@ -96,10 +97,9 @@
*
* @see java.lang.EnumConstantNotPresentException
* @see java.lang.TypeNotPresentException
- * @see java.lang.annotation.AnnotationFormatError
+ * @see AnnotationFormatError
* @see java.lang.annotation.AnnotationTypeMismatchException
* @see java.lang.annotation.IncompleteAnnotationException
- * @see java.lang.annotation.InvalidContainerAnnotationError
* @since 1.5
* @author Josh Bloch
*/
--- a/jdk/src/share/classes/java/lang/reflect/Constructor.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/lang/reflect/Constructor.java Fri Mar 15 16:39:07 2013 -0700
@@ -532,6 +532,7 @@
* {@inheritDoc}
* @since 1.8
*/
+ @Override
public AnnotatedType getAnnotatedReturnType() {
return getAnnotatedReturnType0(getDeclaringClass());
}
--- a/jdk/src/share/classes/java/lang/reflect/Executable.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/lang/reflect/Executable.java Fri Mar 15 16:39:07 2013 -0700
@@ -476,6 +476,20 @@
return declaredAnnotations;
}
+ /**
+ * Returns an AnnotatedType object that represents the potentially
+ * annotated return type of the method/constructor represented by this
+ * Executable.
+ *
+ * If this Executable represents a constructor, the AnnotatedType object
+ * represents the type of the constructed object.
+ *
+ * If this Executable represents a method, the AnnotatedType object
+ * represents the use of a type to specify the return type of the method.
+ *
+ * @since 1.8
+ */
+ public abstract AnnotatedType getAnnotatedReturnType();
/* Helper for subclasses of Executable.
*
--- a/jdk/src/share/classes/java/lang/reflect/Method.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/lang/reflect/Method.java Fri Mar 15 16:39:07 2013 -0700
@@ -629,6 +629,7 @@
* {@inheritDoc}
* @since 1.8
*/
+ @Override
public AnnotatedType getAnnotatedReturnType() {
return getAnnotatedReturnType0(getGenericReturnType());
}
--- a/jdk/src/share/classes/java/lang/reflect/Parameter.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/lang/reflect/Parameter.java Fri Mar 15 16:39:07 2013 -0700
@@ -115,7 +115,9 @@
(type.toString());
sb.append(Modifier.toString(getModifiers()));
- sb.append(" ");
+
+ if(0 != modifiers)
+ sb.append(" ");
if(isVarArgs())
sb.append(typename.replaceFirst("\\[\\]$", "..."));
--- a/jdk/src/share/classes/java/lang/reflect/Proxy.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/lang/reflect/Proxy.java Fri Mar 15 16:39:07 2013 -0700
@@ -27,6 +27,9 @@
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
+import java.security.AccessController;
+import java.security.Permission;
+import java.security.PrivilegedAction;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
@@ -36,6 +39,9 @@
import java.util.List;
import java.util.WeakHashMap;
import sun.misc.ProxyGenerator;
+import sun.reflect.Reflection;
+import sun.reflect.misc.ReflectUtil;
+import sun.security.util.SecurityConstants;
/**
* {@code Proxy} provides static methods for creating dynamic proxy
@@ -265,9 +271,69 @@
* @param h the invocation handler for this proxy instance
*/
protected Proxy(InvocationHandler h) {
+ doNewInstanceCheck();
this.h = h;
}
+ private static class ProxyAccessHelper {
+ // The permission is implementation specific.
+ static final Permission PROXY_PERMISSION =
+ new ReflectPermission("proxyConstructorNewInstance");
+ // These system properties are defined to provide a short-term
+ // workaround if customers need to disable the new security checks.
+ static final boolean allowNewInstance;
+ static final boolean allowNullLoader;
+ static {
+ allowNewInstance = getBooleanProperty("sun.reflect.proxy.allowsNewInstance");
+ allowNullLoader = getBooleanProperty("sun.reflect.proxy.allowsNullLoader");
+ }
+
+ private static boolean getBooleanProperty(final String key) {
+ String s = AccessController.doPrivileged(new PrivilegedAction<String>() {
+ public String run() {
+ return System.getProperty(key);
+ }
+ });
+ return Boolean.valueOf(s);
+ }
+
+ static boolean needsNewInstanceCheck(Class<?> proxyClass) {
+ if (!Proxy.isProxyClass(proxyClass) || allowNewInstance) {
+ return false;
+ }
+
+ if (proxyClass.getName().startsWith(ReflectUtil.PROXY_PACKAGE + ".")) {
+ // all proxy interfaces are public
+ return false;
+ }
+ for (Class<?> intf : proxyClass.getInterfaces()) {
+ if (!Modifier.isPublic(intf.getModifiers())) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ /*
+ * Access check on a proxy class that implements any non-public interface.
+ *
+ * @throws SecurityException if a security manager exists, and
+ * the caller does not have the permission.
+ */
+ private void doNewInstanceCheck() {
+ SecurityManager sm = System.getSecurityManager();
+ Class<?> proxyClass = this.getClass();
+ if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(proxyClass)) {
+ try {
+ sm.checkPermission(ProxyAccessHelper.PROXY_PERMISSION);
+ } catch (SecurityException e) {
+ throw new SecurityException("Not allowed to construct a Proxy "
+ + "instance that implements a non-public interface", e);
+ }
+ }
+ }
+
/**
* Returns the {@code java.lang.Class} object for a proxy class
* given a class loader and an array of interfaces. The proxy class
@@ -346,6 +412,51 @@
Class<?>... interfaces)
throws IllegalArgumentException
{
+ return getProxyClass0(loader, interfaces); // stack walk magic: do not refactor
+ }
+
+ private static void checkProxyLoader(ClassLoader ccl,
+ ClassLoader loader)
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ if (loader == null && ccl != null) {
+ if (!ProxyAccessHelper.allowNullLoader) {
+ sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
+ }
+ }
+ }
+ }
+
+ /*
+ * Generate a proxy class (caller-sensitive).
+ *
+ * To define a proxy class, it performs the access checks as in
+ * Class.forName (VM will invoke ClassLoader.checkPackageAccess):
+ * 1. "getClassLoader" permission check if loader == null
+ * 2. checkPackageAccess on the interfaces it implements
+ *
+ * To get a constructor and new instance of a proxy class, it performs
+ * the package access check on the interfaces it implements
+ * as in Class.getConstructor.
+ *
+ * If an interface is non-public, the proxy class must be defined by
+ * the defining loader of the interface. If the caller's class loader
+ * is not the same as the defining loader of the interface, the VM
+ * will throw IllegalAccessError when the generated proxy class is
+ * being defined via the defineClass0 method.
+ */
+ private static Class<?> getProxyClass0(ClassLoader loader,
+ Class<?>... interfaces) {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ final int CALLER_FRAME = 3; // 0: Reflection, 1: getProxyClass0 2: Proxy 3: caller
+ final Class<?> caller = Reflection.getCallerClass(CALLER_FRAME);
+ final ClassLoader ccl = caller.getClassLoader();
+ checkProxyLoader(ccl, loader);
+ ReflectUtil.checkProxyPackageAccess(ccl, interfaces);
+ }
+
if (interfaces.length > 65535) {
throw new IllegalArgumentException("interface limit exceeded");
}
@@ -497,8 +608,9 @@
}
}
- if (proxyPkg == null) { // if no non-public proxy interfaces,
- proxyPkg = ""; // use the unnamed package
+ if (proxyPkg == null) {
+ // if no non-public proxy interfaces, use com.sun.proxy package
+ proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
}
{
@@ -598,22 +710,46 @@
/*
* Look up or generate the designated proxy class.
*/
- Class<?> cl = getProxyClass(loader, interfaces);
+ Class<?> cl = getProxyClass0(loader, interfaces); // stack walk magic: do not refactor
/*
* Invoke its constructor with the designated invocation handler.
*/
try {
- Constructor<?> cons = cl.getConstructor(constructorParams);
- return cons.newInstance(new Object[] { h });
- } catch (NoSuchMethodException |
- IllegalAccessException |
- InstantiationException |
- InvocationTargetException e) {
+ final Constructor<?> cons = cl.getConstructor(constructorParams);
+ final InvocationHandler ih = h;
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(cl)) {
+ // create proxy instance with doPrivilege as the proxy class may
+ // implement non-public interfaces that requires a special permission
+ return AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ public Object run() {
+ return newInstance(cons, ih);
+ }
+ });
+ } else {
+ return newInstance(cons, ih);
+ }
+ } catch (NoSuchMethodException e) {
throw new InternalError(e.toString(), e);
}
}
+ private static Object newInstance(Constructor<?> cons, InvocationHandler h) {
+ try {
+ return cons.newInstance(new Object[] {h} );
+ } catch (IllegalAccessException | InstantiationException e) {
+ throw new InternalError(e.toString(), e);
+ } catch (InvocationTargetException e) {
+ Throwable t = e.getCause();
+ if (t instanceof RuntimeException) {
+ throw (RuntimeException) t;
+ } else {
+ throw new InternalError(t.toString(), t);
+ }
+ }
+ }
+
/**
* Returns true if and only if the specified class was dynamically
* generated to be a proxy class using the {@code getProxyClass}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/net/HttpConnectSocketImpl.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Basic SocketImpl that relies on the internal HTTP protocol handler
+ * implementation to perform the HTTP tunneling and authentication. The
+ * sockets impl is swapped out and replaced with the socket from the HTTP
+ * handler after the tunnel is successfully setup.
+ *
+ * @since 1.8
+ */
+
+/*package*/ class HttpConnectSocketImpl extends PlainSocketImpl {
+
+ private static final String httpURLClazzStr =
+ "sun.net.www.protocol.http.HttpURLConnection";
+ private static final String netClientClazzStr = "sun.net.NetworkClient";
+ private static final String doTunnelingStr = "doTunneling";
+ private static final Field httpField;
+ private static final Field serverSocketField;
+ private static final Method doTunneling;
+
+ private final String server;
+ private InetSocketAddress external_address;
+ private HashMap<Integer, Object> optionsMap = new HashMap<>();
+
+ static {
+ try {
+ Class<?> httpClazz = Class.forName(httpURLClazzStr, true, null);
+ httpField = httpClazz.getDeclaredField("http");
+ doTunneling = httpClazz.getDeclaredMethod(doTunnelingStr);
+ Class<?> netClientClazz = Class.forName(netClientClazzStr, true, null);
+ serverSocketField = netClientClazz.getDeclaredField("serverSocket");
+
+ java.security.AccessController.doPrivileged(
+ new java.security.PrivilegedAction<Void>() {
+ public Void run() {
+ httpField.setAccessible(true);
+ serverSocketField.setAccessible(true);
+ return null;
+ }
+ });
+ } catch (ReflectiveOperationException x) {
+ throw new InternalError("Should not reach here", x);
+ }
+ }
+
+ HttpConnectSocketImpl(String server, int port) {
+ this.server = server;
+ this.port = port;
+ }
+
+ HttpConnectSocketImpl(Proxy proxy) {
+ SocketAddress a = proxy.address();
+ if ( !(a instanceof InetSocketAddress) )
+ throw new IllegalArgumentException("Unsupported address type");
+
+ InetSocketAddress ad = (InetSocketAddress) a;
+ server = ad.getHostString();
+ port = ad.getPort();
+ }
+
+ @Override
+ protected void connect(SocketAddress endpoint, int timeout)
+ throws IOException
+ {
+ if (endpoint == null || !(endpoint instanceof InetSocketAddress))
+ throw new IllegalArgumentException("Unsupported address type");
+ final InetSocketAddress epoint = (InetSocketAddress)endpoint;
+ final String destHost = epoint.isUnresolved() ? epoint.getHostName()
+ : epoint.getAddress().getHostAddress();
+ final int destPort = epoint.getPort();
+
+ SecurityManager security = System.getSecurityManager();
+ if (security != null)
+ security.checkConnect(destHost, destPort);
+
+ // Connect to the HTTP proxy server
+ String urlString = "http://" + destHost + ":" + destPort;
+ Socket httpSocket = privilegedDoTunnel(urlString, timeout);
+
+ // Success!
+ external_address = epoint;
+
+ // close the original socket impl and release its descriptor
+ close();
+
+ // update the Sockets impl to the impl from the http Socket
+ AbstractPlainSocketImpl psi = (AbstractPlainSocketImpl) httpSocket.impl;
+ this.getSocket().impl = psi;
+
+ // best effort is made to try and reset options previously set
+ Set<Map.Entry<Integer,Object>> options = optionsMap.entrySet();
+ try {
+ for(Map.Entry<Integer,Object> entry : options) {
+ psi.setOption(entry.getKey(), entry.getValue());
+ }
+ } catch (IOException x) { /* gulp! */ }
+ }
+
+ @Override
+ public void setOption(int opt, Object val) throws SocketException {
+ super.setOption(opt, val);
+
+ if (external_address != null)
+ return; // we're connected, just return
+
+ // store options so that they can be re-applied to the impl after connect
+ optionsMap.put(opt, val);
+ }
+
+ private Socket privilegedDoTunnel(final String urlString,
+ final int timeout)
+ throws IOException
+ {
+ try {
+ return java.security.AccessController.doPrivileged(
+ new java.security.PrivilegedExceptionAction<Socket>() {
+ public Socket run() throws IOException {
+ return doTunnel(urlString, timeout);
+ }
+ });
+ } catch (java.security.PrivilegedActionException pae) {
+ throw (IOException) pae.getException();
+ }
+ }
+
+ private Socket doTunnel(String urlString, int connectTimeout)
+ throws IOException
+ {
+ Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(server, port));
+ URL destURL = new URL(urlString);
+ HttpURLConnection conn = (HttpURLConnection) destURL.openConnection(proxy);
+ conn.setConnectTimeout(connectTimeout);
+ conn.setReadTimeout(this.timeout);
+ conn.connect();
+ doTunneling(conn);
+ try {
+ Object httpClient = httpField.get(conn);
+ return (Socket) serverSocketField.get(httpClient);
+ } catch (IllegalAccessException x) {
+ throw new InternalError("Should not reach here", x);
+ }
+ }
+
+ private void doTunneling(HttpURLConnection conn) {
+ try {
+ doTunneling.invoke(conn);
+ } catch (ReflectiveOperationException x) {
+ throw new InternalError("Should not reach here", x);
+ }
+ }
+
+ @Override
+ protected InetAddress getInetAddress() {
+ if (external_address != null)
+ return external_address.getAddress();
+ else
+ return super.getInetAddress();
+ }
+
+ @Override
+ protected int getPort() {
+ if (external_address != null)
+ return external_address.getPort();
+ else
+ return super.getPort();
+ }
+
+ @Override
+ protected int getLocalPort() {
+ if (socket != null)
+ return super.getLocalPort();
+ if (external_address != null)
+ return external_address.getPort();
+ else
+ return super.getLocalPort();
+ }
+}
--- a/jdk/src/share/classes/java/net/InetSocketAddress.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/net/InetSocketAddress.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,9 +24,12 @@
*/
package java.net;
-import java.io.ObjectInputStream;
import java.io.IOException;
import java.io.InvalidObjectException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamException;
+import java.io.ObjectStreamField;
/**
*
@@ -46,23 +49,105 @@
* @see java.net.ServerSocket
* @since 1.4
*/
-public class InetSocketAddress extends SocketAddress {
- /* The hostname of the Socket Address
- * @serial
- */
- private String hostname = null;
- /* The IP address of the Socket Address
- * @serial
- */
- private InetAddress addr = null;
- /* The port number of the Socket Address
- * @serial
- */
- private int port;
+public class InetSocketAddress
+ extends SocketAddress
+{
+ // Private implementation class pointed to by all public methods.
+ private static class InetSocketAddressHolder {
+ // The hostname of the Socket Address
+ private String hostname;
+ // The IP address of the Socket Address
+ private InetAddress addr;
+ // The port number of the Socket Address
+ private int port;
+
+ private InetSocketAddressHolder(String hostname, InetAddress addr, int port) {
+ this.hostname = hostname;
+ this.addr = addr;
+ this.port = port;
+ }
+
+ private int getPort() {
+ return port;
+ }
+
+ private InetAddress getAddress() {
+ return addr;
+ }
+
+ private String getHostName() {
+ if (hostname != null)
+ return hostname;
+ if (addr != null)
+ return addr.getHostName();
+ return null;
+ }
+
+ private String getHostString() {
+ if (hostname != null)
+ return hostname;
+ if (addr != null) {
+ if (addr.hostName != null)
+ return addr.hostName;
+ else
+ return addr.getHostAddress();
+ }
+ return null;
+ }
+
+ private boolean isUnresolved() {
+ return addr == null;
+ }
+
+ @Override
+ public String toString() {
+ if (isUnresolved()) {
+ return hostname + ":" + port;
+ } else {
+ return addr.toString() + ":" + port;
+ }
+ }
+
+ @Override
+ public final boolean equals(Object obj) {
+ if (obj == null || !(obj instanceof InetSocketAddressHolder))
+ return false;
+ InetSocketAddressHolder that = (InetSocketAddressHolder)obj;
+ boolean sameIP;
+ if (addr != null)
+ sameIP = addr.equals(that.addr);
+ else if (hostname != null)
+ sameIP = (that.addr == null) &&
+ hostname.equalsIgnoreCase(that.hostname);
+ else
+ sameIP = (that.addr == null) && (that.hostname == null);
+ return sameIP && (port == that.port);
+ }
+
+ @Override
+ public final int hashCode() {
+ if (addr != null)
+ return addr.hashCode() + port;
+ if (hostname != null)
+ return hostname.toLowerCase().hashCode() + port;
+ return port;
+ }
+ }
+
+ private final transient InetSocketAddressHolder holder;
private static final long serialVersionUID = 5076001401234631237L;
- private InetSocketAddress() {
+ private static int checkPort(int port) {
+ if (port < 0 || port > 0xFFFF)
+ throw new IllegalArgumentException("port out of range:" + port);
+ return port;
+ }
+
+ private static String checkHost(String hostname) {
+ if (hostname == null)
+ throw new IllegalArgumentException("hostname can't be null");
+ return hostname;
}
/**
@@ -97,14 +182,10 @@
* range of valid port values.
*/
public InetSocketAddress(InetAddress addr, int port) {
- if (port < 0 || port > 0xFFFF) {
- throw new IllegalArgumentException("port out of range:" + port);
- }
- this.port = port;
- if (addr == null)
- this.addr = InetAddress.anyLocalAddress();
- else
- this.addr = addr;
+ holder = new InetSocketAddressHolder(
+ null,
+ addr == null ? InetAddress.anyLocalAddress() : addr,
+ checkPort(port));
}
/**
@@ -132,19 +213,20 @@
* @see #isUnresolved()
*/
public InetSocketAddress(String hostname, int port) {
- if (port < 0 || port > 0xFFFF) {
- throw new IllegalArgumentException("port out of range:" + port);
- }
- if (hostname == null) {
- throw new IllegalArgumentException("hostname can't be null");
- }
+ checkHost(hostname);
+ InetAddress addr = null;
+ String host = null;
try {
addr = InetAddress.getByName(hostname);
} catch(UnknownHostException e) {
- this.hostname = hostname;
- addr = null;
+ host = hostname;
}
- this.port = port;
+ holder = new InetSocketAddressHolder(host, addr, checkPort(port));
+ }
+
+ // private constructor for creating unresolved instances
+ private InetSocketAddress(int port, String hostname) {
+ holder = new InetSocketAddressHolder(hostname, null, port);
}
/**
@@ -169,31 +251,67 @@
* @since 1.5
*/
public static InetSocketAddress createUnresolved(String host, int port) {
- if (port < 0 || port > 0xFFFF) {
- throw new IllegalArgumentException("port out of range:" + port);
- }
- if (host == null) {
- throw new IllegalArgumentException("hostname can't be null");
- }
- InetSocketAddress s = new InetSocketAddress();
- s.port = port;
- s.hostname = host;
- s.addr = null;
- return s;
+ return new InetSocketAddress(checkPort(port), checkHost(host));
}
- private void readObject(ObjectInputStream s)
- throws IOException, ClassNotFoundException {
- s.defaultReadObject();
+ /**
+ * @serialField hostname String
+ * @serialField addr InetAddress
+ * @serialField port int
+ */
+ private static final ObjectStreamField[] serialPersistentFields = {
+ new ObjectStreamField("hostname", String.class),
+ new ObjectStreamField("addr", InetAddress.class),
+ new ObjectStreamField("port", int.class)};
+
+ private void writeObject(ObjectOutputStream out)
+ throws IOException
+ {
+ // Don't call defaultWriteObject()
+ ObjectOutputStream.PutField pfields = out.putFields();
+ pfields.put("hostname", holder.hostname);
+ pfields.put("addr", holder.addr);
+ pfields.put("port", holder.port);
+ out.writeFields();
+ }
+
+ private void readObject(ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ // Don't call defaultReadObject()
+ ObjectInputStream.GetField oisFields = in.readFields();
+ final String oisHostname = (String)oisFields.get("hostname", null);
+ final InetAddress oisAddr = (InetAddress)oisFields.get("addr", null);
+ final int oisPort = oisFields.get("port", -1);
// Check that our invariants are satisfied
- if (port < 0 || port > 0xFFFF) {
- throw new InvalidObjectException("port out of range:" + port);
- }
-
- if (hostname == null && addr == null) {
+ checkPort(oisPort);
+ if (oisHostname == null && oisAddr == null)
throw new InvalidObjectException("hostname and addr " +
"can't both be null");
+
+ InetSocketAddressHolder h = new InetSocketAddressHolder(oisHostname,
+ oisAddr,
+ oisPort);
+ UNSAFE.putObject(this, FIELDS_OFFSET, h);
+ }
+
+ private void readObjectNoData()
+ throws ObjectStreamException
+ {
+ throw new InvalidObjectException("Stream data required");
+ }
+
+ private static final long FIELDS_OFFSET;
+ private static final sun.misc.Unsafe UNSAFE;
+ static {
+ try {
+ sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
+ FIELDS_OFFSET = unsafe.objectFieldOffset(
+ InetSocketAddress.class.getDeclaredField("holder"));
+ UNSAFE = unsafe;
+ } catch (ReflectiveOperationException e) {
+ throw new Error(e);
}
}
@@ -203,7 +321,7 @@
* @return the port number.
*/
public final int getPort() {
- return port;
+ return holder.getPort();
}
/**
@@ -213,7 +331,7 @@
* @return the InetAdress or <code>null</code> if it is unresolved.
*/
public final InetAddress getAddress() {
- return addr;
+ return holder.getAddress();
}
/**
@@ -224,31 +342,19 @@
* @return the hostname part of the address.
*/
public final String getHostName() {
- if (hostname != null)
- return hostname;
- if (addr != null)
- return addr.getHostName();
- return null;
+ return holder.getHostName();
}
/**
* Returns the hostname, or the String form of the address if it
* doesn't have a hostname (it was created using a literal).
- * This has the benefit of <b>not</b> attemptimg a reverse lookup.
+ * This has the benefit of <b>not</b> attempting a reverse lookup.
*
* @return the hostname, or String representation of the address.
* @since 1.7
*/
public final String getHostString() {
- if (hostname != null)
- return hostname;
- if (addr != null) {
- if (addr.hostName != null)
- return addr.hostName;
- else
- return addr.getHostAddress();
- }
- return null;
+ return holder.getHostString();
}
/**
@@ -258,7 +364,7 @@
* an <code>InetAddress</code>.
*/
public final boolean isUnresolved() {
- return addr == null;
+ return holder.isUnresolved();
}
/**
@@ -269,12 +375,9 @@
*
* @return a string representation of this object.
*/
+ @Override
public String toString() {
- if (isUnresolved()) {
- return hostname + ":" + port;
- } else {
- return addr.toString() + ":" + port;
- }
+ return holder.toString();
}
/**
@@ -297,19 +400,11 @@
* <code>false</code> otherwise.
* @see java.net.InetAddress#equals(java.lang.Object)
*/
+ @Override
public final boolean equals(Object obj) {
if (obj == null || !(obj instanceof InetSocketAddress))
return false;
- InetSocketAddress sockAddr = (InetSocketAddress) obj;
- boolean sameIP = false;
- if (this.addr != null)
- sameIP = this.addr.equals(sockAddr.addr);
- else if (this.hostname != null)
- sameIP = (sockAddr.addr == null) &&
- this.hostname.equalsIgnoreCase(sockAddr.hostname);
- else
- sameIP = (sockAddr.addr == null) && (sockAddr.hostname == null);
- return sameIP && (this.port == sockAddr.port);
+ return holder.equals(((InetSocketAddress) obj).holder);
}
/**
@@ -317,11 +412,8 @@
*
* @return a hash code value for this socket address.
*/
+ @Override
public final int hashCode() {
- if (addr != null)
- return addr.hashCode() + port;
- if (hostname != null)
- return hostname.toLowerCase().hashCode() + port;
- return port;
+ return holder.hashCode();
}
}
--- a/jdk/src/share/classes/java/net/Socket.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/net/Socket.java Fri Mar 15 16:39:07 2013 -0700
@@ -117,8 +117,10 @@
if (proxy == null) {
throw new IllegalArgumentException("Invalid Proxy");
}
- Proxy p = proxy == Proxy.NO_PROXY ? Proxy.NO_PROXY : sun.net.ApplicationProxy.create(proxy);
- if (p.type() == Proxy.Type.SOCKS) {
+ Proxy p = proxy == Proxy.NO_PROXY ? Proxy.NO_PROXY
+ : sun.net.ApplicationProxy.create(proxy);
+ Proxy.Type type = p.type();
+ if (type == Proxy.Type.SOCKS || type == Proxy.Type.HTTP) {
SecurityManager security = System.getSecurityManager();
InetSocketAddress epoint = (InetSocketAddress) p.address();
if (epoint.getAddress() != null) {
@@ -133,7 +135,8 @@
security.checkConnect(epoint.getAddress().getHostAddress(),
epoint.getPort());
}
- impl = new SocksSocketImpl(p);
+ impl = type == Proxy.Type.SOCKS ? new SocksSocketImpl(p)
+ : new HttpConnectSocketImpl(p);
impl.setSocket(this);
} else {
if (p == Proxy.NO_PROXY) {
--- a/jdk/src/share/classes/java/net/URL.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/net/URL.java Fri Mar 15 16:39:07 2013 -0700
@@ -661,8 +661,8 @@
* @param file the file on the host
* @param ref the internal reference in the URL
*/
- protected void set(String protocol, String host,
- int port, String file, String ref) {
+ void set(String protocol, String host, int port,
+ String file, String ref) {
synchronized (this) {
this.protocol = protocol;
this.host = host;
@@ -698,9 +698,9 @@
* @param query the query part of this URL
* @since 1.3
*/
- protected void set(String protocol, String host, int port,
- String authority, String userInfo, String path,
- String query, String ref) {
+ void set(String protocol, String host, int port,
+ String authority, String userInfo, String path,
+ String query, String ref) {
synchronized (this) {
this.protocol = protocol;
this.host = host;
--- a/jdk/src/share/classes/java/net/URLStreamHandler.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/net/URLStreamHandler.java Fri Mar 15 16:39:07 2013 -0700
@@ -509,8 +509,8 @@
/**
* Sets the fields of the <code>URL</code> argument to the indicated values.
- * Only classes derived from URLStreamHandler are supposed to be able
- * to call the set method on a URL.
+ * Only classes derived from URLStreamHandler are able
+ * to use this method to set the values of the URL fields.
*
* @param u the URL to modify.
* @param protocol the protocol name.
@@ -539,8 +539,8 @@
/**
* Sets the fields of the <code>URL</code> argument to the indicated values.
- * Only classes derived from URLStreamHandler are supposed to be able
- * to call the set method on a URL.
+ * Only classes derived from URLStreamHandler are able
+ * to use this method to set the values of the URL fields.
*
* @param u the URL to modify.
* @param protocol the protocol name. This value is ignored since 1.2.
--- a/jdk/src/share/classes/java/nio/file/Files.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/nio/file/Files.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1152,7 +1152,7 @@
* and file system dependent and therefore unspecified. Minimally, the
* {@link BasicFileAttributes#lastModifiedTime last-modified-time} is
* copied to the target file if supported by both the source and target
- * file store. Copying of file timestamps may result in precision
+ * file stores. Copying of file timestamps may result in precision
* loss. </td>
* </tr>
* <tr>
@@ -1169,12 +1169,12 @@
* implementation specific options.
*
* <p> Copying a file is not an atomic operation. If an {@link IOException}
- * is thrown then it possible that the target file is incomplete or some of
- * its file attributes have not been copied from the source file. When the
- * {@code REPLACE_EXISTING} option is specified and the target file exists,
- * then the target file is replaced. The check for the existence of the file
- * and the creation of the new file may not be atomic with respect to other
- * file system activities.
+ * is thrown, then it is possible that the target file is incomplete or some
+ * of its file attributes have not been copied from the source file. When
+ * the {@code REPLACE_EXISTING} option is specified and the target file
+ * exists, then the target file is replaced. The check for the existence of
+ * the file and the creation of the new file may not be atomic with respect
+ * to other file system activities.
*
* <p> <b>Usage Example:</b>
* Suppose we want to copy a file into a directory, giving it the same file
@@ -1279,15 +1279,16 @@
* <p> An implementation of this interface may support additional
* implementation specific options.
*
- * <p> Where the move requires that the file be copied then the {@link
- * BasicFileAttributes#lastModifiedTime last-modified-time} is copied to the
- * new file. An implementation may also attempt to copy other file
- * attributes but is not required to fail if the file attributes cannot be
- * copied. When the move is performed as a non-atomic operation, and a {@code
- * IOException} is thrown, then the state of the files is not defined. The
- * original file and the target file may both exist, the target file may be
- * incomplete or some of its file attributes may not been copied from the
- * original file.
+ * <p> Moving a file will copy the {@link
+ * BasicFileAttributes#lastModifiedTime last-modified-time} to the target
+ * file if supported by both source and target file stores. Copying of file
+ * timestamps may result in precision loss. An implementation may also
+ * attempt to copy other file attributes but is not required to fail if the
+ * file attributes cannot be copied. When the move is performed as
+ * a non-atomic operation, and an {@code IOException} is thrown, then the
+ * state of the files is not defined. The original file and the target file
+ * may both exist, the target file may be incomplete or some of its file
+ * attributes may not been copied from the original file.
*
* <p> <b>Usage Examples:</b>
* Suppose we want to rename a file to "newname", keeping the file in the
--- a/jdk/src/share/classes/java/sql/CallableStatement.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/sql/CallableStatement.java Fri Mar 15 16:39:07 2013 -0700
@@ -2621,7 +2621,7 @@
* parameter determines the Java type that must be used
* in the {@code get} method to read the value of that parameter.
* <p>
- * This version of {@code registrOutParameter} should be
+ * This version of {@code registerOutParameter} should be
* used when the parameter is of JDBC type {@code JDBCType.NUMERIC}
* or {@code JDBCType.DECIMAL}.
*<P>
@@ -2649,7 +2649,7 @@
/**
* Registers the designated output parameter.
* This version of
- * the method {@code registrOutParameter}
+ * the method {@code registerOutParameter}
* should be used for a user-defined or {@code REF} output parameter.
* Examples
* of user-defined types include: {@code STRUCT}, {@code DISTINCT},
@@ -2717,7 +2717,7 @@
* register the OUT Parameter.
* If the parameter is of JDBC type {@code JDBCType.NUMERIC}
* or {@code JDBCType.DECIMAL}, the version of
- * {@code registrOutParameter} that accepts a scale value
+ * {@code registerOutParameter} that accepts a scale value
* should be used.
* @exception SQLException if parameterName does not correspond to a named
* parameter; if a database access error occurs or
@@ -2745,7 +2745,7 @@
* parameter determines the Java type that must be used
* in the {@code get} method to read the value of that parameter.
* <p>
- * This version of {@code registrOutParameter} should be
+ * This version of {@code registerOutParameter} should be
* used when the parameter is of JDBC type {@code JDBCType.NUMERIC}
* or {@code JDBCType.DECIMAL}.
*<P>
@@ -2774,7 +2774,7 @@
/**
* Registers the designated output parameter. This version of
- * the method {@code registrOutParameter}
+ * the method {@code registerOutParameter}
* should be used for a user-named or REF output parameter. Examples
* of user-named types include: STRUCT, DISTINCT, JAVA_OBJECT, and
* named array types.
--- a/jdk/src/share/classes/java/text/DateFormat.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/text/DateFormat.java Fri Mar 15 16:39:07 2013 -0700
@@ -439,7 +439,12 @@
/**
* Gets the time formatter with the default formatting style
- * for the default locale.
+ * for the default {@link java.util.Locale.Category#FORMAT FORMAT} locale.
+ * <p>This is equivalent to calling
+ * {@link #getTimeInstance(int, Locale) getTimeInstance(DEFAULT,
+ * Locale.getDefault(Locale.Category.FORMAT))}.
+ * @see java.util.Locale#getDefault(java.util.Locale.Category)
+ * @see java.util.Locale.Category#FORMAT
* @return a time formatter.
*/
public final static DateFormat getTimeInstance()
@@ -449,7 +454,12 @@
/**
* Gets the time formatter with the given formatting style
- * for the default locale.
+ * for the default {@link java.util.Locale.Category#FORMAT FORMAT} locale.
+ * <p>This is equivalent to calling
+ * {@link #getTimeInstance(int, Locale) getTimeInstance(style,
+ * Locale.getDefault(Locale.Category.FORMAT))}.
+ * @see java.util.Locale#getDefault(java.util.Locale.Category)
+ * @see java.util.Locale.Category#FORMAT
* @param style the given formatting style. For example,
* SHORT for "h:mm a" in the US locale.
* @return a time formatter.
@@ -475,7 +485,12 @@
/**
* Gets the date formatter with the default formatting style
- * for the default locale.
+ * for the default {@link java.util.Locale.Category#FORMAT FORMAT} locale.
+ * <p>This is equivalent to calling
+ * {@link #getDateInstance(int, Locale) getDateInstance(DEFAULT,
+ * Locale.getDefault(Locale.Category.FORMAT))}.
+ * @see java.util.Locale#getDefault(java.util.Locale.Category)
+ * @see java.util.Locale.Category#FORMAT
* @return a date formatter.
*/
public final static DateFormat getDateInstance()
@@ -485,7 +500,12 @@
/**
* Gets the date formatter with the given formatting style
- * for the default locale.
+ * for the default {@link java.util.Locale.Category#FORMAT FORMAT} locale.
+ * <p>This is equivalent to calling
+ * {@link #getDateInstance(int, Locale) getDateInstance(style,
+ * Locale.getDefault(Locale.Category.FORMAT))}.
+ * @see java.util.Locale#getDefault(java.util.Locale.Category)
+ * @see java.util.Locale.Category#FORMAT
* @param style the given formatting style. For example,
* SHORT for "M/d/yy" in the US locale.
* @return a date formatter.
@@ -511,7 +531,12 @@
/**
* Gets the date/time formatter with the default formatting style
- * for the default locale.
+ * for the default {@link java.util.Locale.Category#FORMAT FORMAT} locale.
+ * <p>This is equivalent to calling
+ * {@link #getDateTimeInstance(int, int, Locale) getDateTimeInstance(DEFAULT,
+ * DEFAULT, Locale.getDefault(Locale.Category.FORMAT))}.
+ * @see java.util.Locale#getDefault(java.util.Locale.Category)
+ * @see java.util.Locale.Category#FORMAT
* @return a date/time formatter.
*/
public final static DateFormat getDateTimeInstance()
@@ -521,7 +546,12 @@
/**
* Gets the date/time formatter with the given date and time
- * formatting styles for the default locale.
+ * formatting styles for the default {@link java.util.Locale.Category#FORMAT FORMAT} locale.
+ * <p>This is equivalent to calling
+ * {@link #getDateTimeInstance(int, int, Locale) getDateTimeInstance(dateStyle,
+ * timeStyle, Locale.getDefault(Locale.Category.FORMAT))}.
+ * @see java.util.Locale#getDefault(java.util.Locale.Category)
+ * @see java.util.Locale.Category#FORMAT
* @param dateStyle the given date formatting style. For example,
* SHORT for "M/d/yy" in the US locale.
* @param timeStyle the given time formatting style. For example,
--- a/jdk/src/share/classes/java/text/DateFormatSymbols.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/text/DateFormatSymbols.java Fri Mar 15 16:39:07 2013 -0700
@@ -104,14 +104,19 @@
/**
* Construct a DateFormatSymbols object by loading format data from
- * resources for the default locale. This constructor can only
+ * resources for the default {@link java.util.Locale.Category#FORMAT FORMAT}
+ * locale. This constructor can only
* construct instances for the locales supported by the Java
* runtime environment, not for those supported by installed
* {@link java.text.spi.DateFormatSymbolsProvider DateFormatSymbolsProvider}
* implementations. For full locale coverage, use the
* {@link #getInstance(Locale) getInstance} method.
- *
+ * <p>This is equivalent to calling
+ * {@link #DateFormatSymbols(Locale)
+ * DateFormatSymbols(Locale.getDefault(Locale.Category.FORMAT))}.
* @see #getInstance()
+ * @see java.util.Locale#getDefault(java.util.Locale.Category)
+ * @see java.util.Locale.Category#FORMAT
* @exception java.util.MissingResourceException
* if the resources for the default locale cannot be
* found or cannot be loaded.
@@ -302,6 +307,10 @@
* as for those supported by installed
* {@link java.text.spi.DateFormatSymbolsProvider DateFormatSymbolsProvider}
* implementations.
+ * <p>This is equivalent to calling {@link #getInstance(Locale)
+ * getInstance(Locale.getDefault(Locale.Category.FORMAT))}.
+ * @see java.util.Locale#getDefault(java.util.Locale.Category)
+ * @see java.util.Locale.Category#FORMAT
* @return a <code>DateFormatSymbols</code> instance.
* @since 1.6
*/
--- a/jdk/src/share/classes/java/text/DecimalFormat.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/text/DecimalFormat.java Fri Mar 15 16:39:07 2013 -0700
@@ -381,7 +381,8 @@
/**
* Creates a DecimalFormat using the default pattern and symbols
- * for the default locale. This is a convenient way to obtain a
+ * for the default {@link java.util.Locale.Category#FORMAT FORMAT} locale.
+ * This is a convenient way to obtain a
* DecimalFormat when internationalization is not the main concern.
* <p>
* To obtain standard formats for a given locale, use the factory methods
@@ -411,7 +412,8 @@
/**
* Creates a DecimalFormat using the given pattern and the symbols
- * for the default locale. This is a convenient way to obtain a
+ * for the default {@link java.util.Locale.Category#FORMAT FORMAT} locale.
+ * This is a convenient way to obtain a
* DecimalFormat when internationalization is not the main concern.
* <p>
* To obtain standard formats for a given locale, use the factory methods
--- a/jdk/src/share/classes/java/text/DecimalFormatSymbols.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/text/DecimalFormatSymbols.java Fri Mar 15 16:39:07 2013 -0700
@@ -71,13 +71,19 @@
public class DecimalFormatSymbols implements Cloneable, Serializable {
/**
- * Create a DecimalFormatSymbols object for the default locale.
+ * Create a DecimalFormatSymbols object for the default
+ * {@link java.util.Locale.Category#FORMAT FORMAT} locale.
* This constructor can only construct instances for the locales
* supported by the Java runtime environment, not for those
* supported by installed
* {@link java.text.spi.DecimalFormatSymbolsProvider DecimalFormatSymbolsProvider}
* implementations. For full locale coverage, use the
* {@link #getInstance(Locale) getInstance} method.
+ * <p>This is equivalent to calling
+ * {@link #DecimalFormatSymbols(Locale)
+ * DecimalFormatSymbols(Locale.getDefault(Locale.Category.FORMAT))}.
+ * @see java.util.Locale#getDefault(java.util.Locale.Category)
+ * @see java.util.Locale.Category#FORMAT
*/
public DecimalFormatSymbols() {
initialize( Locale.getDefault(Locale.Category.FORMAT) );
@@ -133,6 +139,11 @@
* as for those supported by installed
* {@link java.text.spi.DecimalFormatSymbolsProvider
* DecimalFormatSymbolsProvider} implementations.
+ * <p>This is equivalent to calling
+ * {@link #getInstance(Locale)
+ * getInstance(Locale.getDefault(Locale.Category.FORMAT))}.
+ * @see java.util.Locale#getDefault(java.util.Locale.Category)
+ * @see java.util.Locale.Category#FORMAT
* @return a <code>DecimalFormatSymbols</code> instance.
* @since 1.6
*/
--- a/jdk/src/share/classes/java/text/MessageFormat.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/text/MessageFormat.java Fri Mar 15 16:39:07 2013 -0700
@@ -348,7 +348,8 @@
private static final long serialVersionUID = 6479157306784022952L;
/**
- * Constructs a MessageFormat for the default locale and the
+ * Constructs a MessageFormat for the default
+ * {@link java.util.Locale.Category#FORMAT FORMAT} locale and the
* specified pattern.
* The constructor first sets the locale, then parses the pattern and
* creates a list of subformats for the format elements contained in it.
--- a/jdk/src/share/classes/java/text/NumberFormat.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/text/NumberFormat.java Fri Mar 15 16:39:07 2013 -0700
@@ -389,7 +389,8 @@
//============== Locale Stuff =====================
/**
- * Returns a general-purpose number format for the current default locale.
+ * Returns a general-purpose number format for the current default
+ * {@link java.util.Locale.Category#FORMAT FORMAT} locale.
* This is the same as calling
* {@link #getNumberInstance() getNumberInstance()}.
*/
@@ -407,7 +408,13 @@
}
/**
- * Returns a general-purpose number format for the current default locale.
+ * Returns a general-purpose number format for the current default
+ * {@link java.util.Locale.Category#FORMAT FORMAT} locale.
+ * <p>This is equivalent to calling
+ * {@link #getNumberInstance(Locale)
+ * getNumberInstance(Locale.getDefault(Locale.Category.FORMAT))}.
+ * @see java.util.Locale#getDefault(java.util.Locale.Category)
+ * @see java.util.Locale.Category#FORMAT
*/
public final static NumberFormat getNumberInstance() {
return getInstance(Locale.getDefault(Locale.Category.FORMAT), NUMBERSTYLE);
@@ -421,14 +428,20 @@
}
/**
- * Returns an integer number format for the current default locale. The
+ * Returns an integer number format for the current default
+ * {@link java.util.Locale.Category#FORMAT FORMAT} locale. The
* returned number format is configured to round floating point numbers
* to the nearest integer using half-even rounding (see {@link
* java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}) for formatting,
* and to parse only the integer part of an input string (see {@link
* #isParseIntegerOnly isParseIntegerOnly}).
+ * <p>This is equivalent to calling
+ * {@link #getIntegerInstance(Locale)
+ * getIntegerInstance(Locale.getDefault(Locale.Category.FORMAT))}.
*
* @see #getRoundingMode()
+ * @see java.util.Locale#getDefault(java.util.Locale.Category)
+ * @see java.util.Locale.Category#FORMAT
* @return a number format for integer values
* @since 1.4
*/
@@ -453,7 +466,14 @@
}
/**
- * Returns a currency format for the current default locale.
+ * Returns a currency format for the current default
+ * {@link java.util.Locale.Category#FORMAT FORMAT} locale.
+ * <p>This is equivalent to calling
+ * {@link #getCurrencyInstance(Locale)
+ * getCurrencyInstance(Locale.getDefault(Locale.Category.FORMAT))}.
+ *
+ * @see java.util.Locale#getDefault(java.util.Locale.Category)
+ * @see java.util.Locale.Category#FORMAT
*/
public final static NumberFormat getCurrencyInstance() {
return getInstance(Locale.getDefault(Locale.Category.FORMAT), CURRENCYSTYLE);
@@ -467,7 +487,14 @@
}
/**
- * Returns a percentage format for the current default locale.
+ * Returns a percentage format for the current default
+ * {@link java.util.Locale.Category#FORMAT FORMAT} locale.
+ * <p>This is equivalent to calling
+ * {@link #getPercentInstance(Locale)
+ * getPercentInstance(Locale.getDefault(Locale.Category.FORMAT))}.
+ *
+ * @see java.util.Locale#getDefault(java.util.Locale.Category)
+ * @see java.util.Locale.Category#FORMAT
*/
public final static NumberFormat getPercentInstance() {
return getInstance(Locale.getDefault(Locale.Category.FORMAT), PERCENTSTYLE);
--- a/jdk/src/share/classes/java/text/SimpleDateFormat.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/text/SimpleDateFormat.java Fri Mar 15 16:39:07 2013 -0700
@@ -547,7 +547,8 @@
/**
* Constructs a <code>SimpleDateFormat</code> using the default pattern and
- * date format symbols for the default locale.
+ * date format symbols for the default
+ * {@link java.util.Locale.Category#FORMAT FORMAT} locale.
* <b>Note:</b> This constructor may not support all locales.
* For full coverage, use the factory methods in the {@link DateFormat}
* class.
@@ -560,11 +561,17 @@
/**
* Constructs a <code>SimpleDateFormat</code> using the given pattern and
- * the default date format symbols for the default locale.
+ * the default date format symbols for the default
+ * {@link java.util.Locale.Category#FORMAT FORMAT} locale.
* <b>Note:</b> This constructor may not support all locales.
* For full coverage, use the factory methods in the {@link DateFormat}
* class.
+ * <p>This is equivalent to calling
+ * {@link #SimpleDateFormat(String, Locale)
+ * SimpleDateFormat(pattern, Locale.getDefault(Locale.Category.FORMAT))}.
*
+ * @see java.util.Locale#getDefault(java.util.Locale.Category)
+ * @see java.util.Locale.Category#FORMAT
* @param pattern the pattern describing the date and time format
* @exception NullPointerException if the given pattern is null
* @exception IllegalArgumentException if the given pattern is invalid
--- a/jdk/src/share/classes/java/time/chrono/HijrahDeviationReader.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/time/chrono/HijrahDeviationReader.java Fri Mar 15 16:39:07 2013 -0700
@@ -70,7 +70,7 @@
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoField;
import java.util.Arrays;
-import java.util.function.Block;
+import java.util.function.Consumer;
/**
* A reader for Hijrah Deviation files.
@@ -126,13 +126,13 @@
* @param typeId the name of the calendar
* @param calendarType the calendar type
* @return {@code true} if the file was read and each entry accepted by the
- * Block; else {@code false} no configuration was done
+ * Consumer; else {@code false} no configuration was done
*
* @throws IOException for zip/jar file handling exception.
* @throws ParseException if the format of the configuration file is wrong.
*/
static boolean readDeviation(String typeId, String calendarType,
- Block<HijrahChronology.Deviation> block) throws IOException, ParseException {
+ Consumer<HijrahChronology.Deviation> consumer) throws IOException, ParseException {
InputStream is = getConfigFileInputStream(typeId);
if (is != null) {
try (BufferedReader br = new BufferedReader(new InputStreamReader(is))) {
@@ -142,7 +142,7 @@
num++;
HijrahChronology.Deviation entry = parseLine(line, num);
if (entry != null) {
- block.accept(entry);
+ consumer.accept(entry);
}
}
}
--- a/jdk/src/share/classes/java/time/format/DateTimeFormatSymbols.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/time/format/DateTimeFormatSymbols.java Fri Mar 15 16:39:07 2013 -0700
@@ -121,10 +121,16 @@
}
/**
- * Obtains symbols for the default locale.
+ * Obtains symbols for the default
+ * {@link java.util.Locale.Category#FORMAT FORMAT} locale.
* <p>
* This method provides access to locale sensitive symbols.
+ * <p>
+ * This is equivalent to calling
+ * {@link #of(Locale)
+ * of(Locale.getDefault(Locale.Category.FORMAT))}.
*
+ * @see java.util.Locale.Category#FORMAT
* @return the info, not null
*/
public static DateTimeFormatSymbols ofDefaultLocale() {
--- a/jdk/src/share/classes/java/time/format/DateTimeFormatterBuilder.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/time/format/DateTimeFormatterBuilder.java Fri Mar 15 16:39:07 2013 -0700
@@ -1007,7 +1007,7 @@
* is used, with {@code IsoChronology} as the fallback.
* <p>
* Note that this method provides similar functionality to methods on
- * {@code DateFormat} such as {@link DateFormat#getDateTimeInstance(int, int)}.
+ * {@code DateFormat} such as {@link java.text.DateFormat#getDateTimeInstance(int, int)}.
*
* @param dateStyle the date style to use, null means no date required
* @param timeStyle the time style to use, null means no time required
--- a/jdk/src/share/classes/java/util/Calendar.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/Calendar.java Fri Mar 15 16:39:07 2013 -0700
@@ -1572,7 +1572,8 @@
/**
* Constructs a Calendar with the default time zone
- * and locale.
+ * and the default {@link java.util.Locale.Category#FORMAT FORMAT}
+ * locale.
* @see TimeZone#getDefault
*/
protected Calendar()
@@ -1600,7 +1601,8 @@
/**
* Gets a calendar using the default time zone and locale. The
* <code>Calendar</code> returned is based on the current time
- * in the default time zone with the default locale.
+ * in the default time zone with the default
+ * {@link Locale.Category#FORMAT FORMAT} locale.
*
* @return a Calendar.
*/
@@ -1614,7 +1616,8 @@
/**
* Gets a calendar using the specified time zone and default locale.
* The <code>Calendar</code> returned is based on the current time
- * in the given time zone with the default locale.
+ * in the given time zone with the default
+ * {@link Locale.Category#FORMAT FORMAT} locale.
*
* @param zone the time zone to use
* @return a Calendar.
--- a/jdk/src/share/classes/java/util/Collections.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/Collections.java Fri Mar 15 16:39:07 2013 -0700
@@ -3759,7 +3759,7 @@
return c2.compareTo(c1);
}
- private Object readResolve() { return reverseOrder(); }
+ private Object readResolve() { return Collections.reverseOrder(); }
}
/**
--- a/jdk/src/share/classes/java/util/Comparator.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/Comparator.java Fri Mar 15 16:39:07 2013 -0700
@@ -25,6 +25,11 @@
package java.util;
+import java.util.function.Function;
+import java.util.function.ToIntFunction;
+import java.util.function.ToLongFunction;
+import java.util.function.ToDoubleFunction;
+
/**
* A comparison function, which imposes a <i>total ordering</i> on some
* collection of objects. Comparators can be passed to a sort method (such
@@ -165,4 +170,93 @@
* @see Object#hashCode()
*/
boolean equals(Object obj);
+
+ /**
+ * Returns a comparator that imposes the reverse ordering of this
+ * comparator.
+ *
+ * @return A comparator that imposes the reverse ordering of this
+ * comparator.
+ * @since 1.8
+ */
+ default Comparator<T> reverseOrder() {
+ return Collections.reverseOrder(this);
+ }
+
+ /**
+ * Constructs a lexicographic order comparator with another comparator.
+ * For example, a {@code Comparator<Person> byLastName} can be composed
+ * with another {@code Comparator<Person> byFirstName}, then {@code
+ * byLastName.thenComparing(byFirstName)} creates a {@code
+ * Comparator<Person>} which sorts by last name, and for equal last names
+ * sorts by first name.
+ *
+ * @param other the other comparator used when equals on this.
+ * @throws NullPointerException if the argument is null.
+ * @since 1.8
+ */
+ default Comparator<T> thenComparing(Comparator<? super T> other) {
+ return Comparators.compose(this, other);
+ }
+
+ /**
+ * Constructs a lexicographic order comparator with a function that
+ * extracts a {@code Comparable} key. This default implementation calls
+ * {@code thenComparing(this, Comparators.comparing(keyExtractor))}.
+ *
+ * @param <U> the {@link Comparable} type for comparison
+ * @param keyExtractor the function used to extract the {@link Comparable} sort key
+ * @throws NullPointerException if the argument is null.
+ * @see Comparators#comparing(Function)
+ * @see #thenComparing(Comparator)
+ * @since 1.8
+ */
+ default <U extends Comparable<? super U>> Comparator<T> thenComparing(Function<? super T, ? extends U> keyExtractor) {
+ return thenComparing(Comparators.comparing(keyExtractor));
+ }
+
+ /**
+ * Constructs a lexicographic order comparator with a function that
+ * extracts a {@code int} value. This default implementation calls {@code
+ * thenComparing(this, Comparators.comparing(keyExtractor))}.
+ *
+ * @param keyExtractor the function used to extract the integer value
+ * @throws NullPointerException if the argument is null.
+ * @see Comparators#comparing(ToIntFunction)
+ * @see #thenComparing(Comparator)
+ * @since 1.8
+ */
+ default Comparator<T> thenComparing(ToIntFunction<? super T> keyExtractor) {
+ return thenComparing(Comparators.comparing(keyExtractor));
+ }
+
+ /**
+ * Constructs a lexicographic order comparator with a function that
+ * extracts a {@code long} value. This default implementation calls
+ * {@code thenComparing(this, Comparators.comparing(keyExtractor))}.
+ *
+ * @param keyExtractor the function used to extract the long value
+ * @throws NullPointerException if the argument is null.
+ * @see Comparators#comparing(ToLongFunction)
+ * @see #thenComparing(Comparator)
+ * @since 1.8
+ */
+ default Comparator<T> thenComparing(ToLongFunction<? super T> keyExtractor) {
+ return thenComparing(Comparators.comparing(keyExtractor));
+ }
+
+ /**
+ * Constructs a lexicographic order comparator with a function that
+ * extracts a {@code double} value. This default implementation calls
+ * {@code thenComparing(this, Comparators.comparing(keyExtractor))}.
+ *
+ * @param keyExtractor the function used to extract the double value
+ * @throws NullPointerException if the argument is null.
+ * @see Comparators#comparing(ToDoubleFunction)
+ * @see #thenComparing(Comparator)
+ * @since 1.8
+ */
+ default Comparator<T> thenComparing(ToDoubleFunction<? super T> keyExtractor) {
+ return thenComparing(Comparators.comparing(keyExtractor));
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/util/Comparators.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,279 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util;
+
+import java.io.Serializable;
+import java.util.function.BinaryOperator;
+import java.util.function.Function;
+import java.util.function.ToDoubleFunction;
+import java.util.function.ToIntFunction;
+import java.util.function.ToLongFunction;
+
+/**
+ * This class consists of {@code static} utility methods for comparators. Mostly
+ * factory method that returns a {@link Comparator}.
+ *
+ * <p> Unless otherwise noted, passing a {@code null} argument to a method in
+ * this class will cause a {@link NullPointerException} to be thrown.
+ *
+ * @see Comparator
+ * @since 1.8
+ */
+public class Comparators {
+ private Comparators() {
+ throw new AssertionError("no instances");
+ }
+
+ /**
+ * Compares {@link Comparable} objects in natural order.
+ *
+ * @see Comparable
+ */
+ private enum NaturalOrderComparator implements Comparator<Comparable<Object>> {
+ INSTANCE;
+
+ @Override
+ public int compare(Comparable<Object> c1, Comparable<Object> c2) {
+ return c1.compareTo(c2);
+ }
+ }
+
+ /**
+ * Returns a comparator that imposes the reverse of the <em>natural
+ * ordering</em>.
+ *
+ * <p>The returned comparator is serializable.
+ *
+ * @param <T> {@link Comparable} type
+ *
+ * @return A comparator that imposes the reverse of the <i>natural
+ * ordering</i> on a collection of objects that implement
+ * the {@link Comparable} interface.
+ * @see Comparable
+ */
+ public static <T extends Comparable<? super T>> Comparator<T> reverseOrder() {
+ return Collections.reverseOrder();
+ }
+
+ /**
+ * Returns a comparator that imposes the reverse ordering of the specified
+ * {@link Comparator}.
+ *
+ * <p>The returned comparator is serializable (assuming the specified
+ * comparator is also serializable).
+ *
+ * @param <T> the element type to be compared
+ * @param cmp a comparator whose ordering is to be reversed by the returned
+ * comparator
+ * @return A comparator that imposes the reverse ordering of the
+ * specified comparator.
+ */
+ public static <T> Comparator<T> reverseOrder(Comparator<T> cmp) {
+ Objects.requireNonNull(cmp);
+ return Collections.reverseOrder(cmp);
+ }
+
+ /**
+ * Gets a comparator compares {@link Comparable} type in natural order.
+ *
+ * @param <T> {@link Comparable} type
+ */
+ public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() {
+ return (Comparator<T>) NaturalOrderComparator.INSTANCE;
+ }
+
+ /**
+ * Gets a comparator compares {@link Map.Entry} in natural order on key.
+ *
+ * @param <K> {@link Comparable} key type
+ * @param <V> value type
+ */
+ public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K,V>> naturalOrderKeys() {
+ return (Comparator<Map.Entry<K, V>> & Serializable)
+ (c1, c2) -> c1.getKey().compareTo(c2.getKey());
+ }
+
+ /**
+ * Gets a comparator compares {@link Map.Entry} in natural order on value.
+ *
+ * @param <K> key type
+ * @param <V> {@link Comparable} value type
+ */
+ public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K,V>> naturalOrderValues() {
+ return (Comparator<Map.Entry<K, V>> & Serializable)
+ (c1, c2) -> c1.getValue().compareTo(c2.getValue());
+ }
+
+ /**
+ * Gets a comparator compares {@link Map.Entry} by key using the given
+ * {@link Comparator}.
+ *
+ * <p>The returned comparator is serializable assuming the specified
+ * comparators are also serializable.
+ *
+ * @param <K> key type
+ * @param <V> value type
+ * @param cmp the key {@link Comparator}
+ */
+ public static <K, V> Comparator<Map.Entry<K, V>> byKey(Comparator<? super K> cmp) {
+ Objects.requireNonNull(cmp);
+ return (Comparator<Map.Entry<K, V>> & Serializable)
+ (c1, c2) -> cmp.compare(c1.getKey(), c2.getKey());
+ }
+
+ /**
+ * Gets a comparator compares {@link Map.Entry} by value using the given
+ * {@link Comparator}.
+ *
+ * @param <K> key type
+ * @param <V> value type
+ * @param cmp the value {@link Comparator}
+ */
+ public static <K, V> Comparator<Map.Entry<K, V>> byValue(Comparator<? super V> cmp) {
+ Objects.requireNonNull(cmp);
+ return (Comparator<Map.Entry<K, V>> & Serializable)
+ (c1, c2) -> cmp.compare(c1.getValue(), c2.getValue());
+ }
+
+ /**
+ * Accepts a function that extracts a {@link java.lang.Comparable
+ * Comparable} sort key from a type {@code T}, and returns a {@code
+ * Comparator<T>} that compares by that sort key. For example, if a class
+ * {@code Person} has a {@code String}-valued getter {@code getLastName},
+ * then {@code comparing(Person::getLastName)} would return a {@code
+ * Comparator<Person>} that compares {@code Person} objects by their last
+ * name.
+ *
+ * @param <T> the original element type
+ * @param <U> the {@link Comparable} type for comparison
+ * @param keyExtractor the function used to extract the {@link Comparable} sort key
+ */
+ public static <T, U extends Comparable<? super U>> Comparator<T> comparing(Function<? super T, ? extends U> keyExtractor) {
+ Objects.requireNonNull(keyExtractor);
+ return (Comparator<T> & Serializable)
+ (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
+ }
+
+ /**
+ * Accepts a function that extracts an {@code int} value from a type {@code
+ * T}, and returns a {@code Comparator<T>} that compares by that value.
+ *
+ * <p>The returned comparator is serializable assuming the specified
+ * function is also serializable.
+ *
+ * @see #comparing(Function)
+ * @param <T> the original element type
+ * @param keyExtractor the function used to extract the integer value
+ */
+ public static <T> Comparator<T> comparing(ToIntFunction<? super T> keyExtractor) {
+ Objects.requireNonNull(keyExtractor);
+ return (Comparator<T> & Serializable)
+ (c1, c2) -> Integer.compare(keyExtractor.applyAsInt(c1), keyExtractor.applyAsInt(c2));
+ }
+
+ /**
+ * Accepts a function that extracts a {@code long} value from a type {@code
+ * T}, and returns a {@code Comparator<T>} that compares by that value.
+ *
+ * <p>The returned comparator is serializable assuming the specified
+ * function is also serializable.
+ *
+ * @see #comparing(Function)
+ * @param <T> the original element type
+ * @param keyExtractor the function used to extract the long value
+ */
+ public static <T> Comparator<T> comparing(ToLongFunction<? super T> keyExtractor) {
+ Objects.requireNonNull(keyExtractor);
+ return (Comparator<T> & Serializable)
+ (c1, c2) -> Long.compare(keyExtractor.applyAsLong(c1), keyExtractor.applyAsLong(c2));
+ }
+
+ /**
+ * Accepts a function that extracts a {@code double} value from a type
+ * {@code T}, and returns a {@code Comparator<T>} that compares by that
+ * value.
+ *
+ * <p>The returned comparator is serializable assuming the specified
+ * function is also serializable.
+ *
+ * @see #comparing(Function)
+ * @param <T> the original element type
+ * @param keyExtractor the function used to extract the double value
+ */
+ public static<T> Comparator<T> comparing(ToDoubleFunction<? super T> keyExtractor) {
+ Objects.requireNonNull(keyExtractor);
+ return (Comparator<T> & Serializable)
+ (c1, c2) -> Double.compare(keyExtractor.applyAsDouble(c1), keyExtractor.applyAsDouble(c2));
+ }
+
+ /**
+ * Constructs a lexicographic order from two {@link Comparator}s. For
+ * example, if you have comparators {@code byLastName} and {@code
+ * byFirstName}, each of type {@code Comparator<Person>}, then {@code
+ * compose(byLastName, byFirstName)} creates a {@code Comparator<Person>}
+ * which sorts by last name, and for equal last names sorts by first name.
+ *
+ * <p>The returned comparator is serializable assuming the specified
+ * comparators are also serializable.
+ *
+ * @param <T> the element type to be compared
+ * @param first the first comparator
+ * @param second the secondary comparator used when equals on the first
+ */
+ public static<T> Comparator<T> compose(Comparator<? super T> first, Comparator<? super T> second) {
+ Objects.requireNonNull(first);
+ Objects.requireNonNull(second);
+ return (Comparator<T> & Serializable) (c1, c2) -> {
+ int res = first.compare(c1, c2);
+ return (res != 0) ? res : second.compare(c1, c2);
+ };
+ }
+
+ /**
+ * Constructs a {@link BinaryOperator} which returns the lesser of two elements
+ * according to the specified {@code Comparator}
+ *
+ * @param comparator A {@code Comparator} for comparing the two values
+ * @param <T> the type of the elements to be compared
+ * @return a {@code BinaryOperator} which returns the lesser of its operands,
+ * according to the supplied {@code Comparator}
+ */
+ public static<T> BinaryOperator<T> lesserOf(Comparator<? super T> comparator) {
+ return (a, b) -> comparator.compare(a, b) <= 0 ? a : b;
+ }
+
+ /**
+ * Constructs a {@link BinaryOperator} which returns the greater of two elements
+ * according to the specified {@code Comparator}
+ *
+ * @param comparator A {@code Comparator} for comparing the two values
+ * @param <T> the type of the elements to be compared
+ * @return a {@code BinaryOperator} which returns the greater of its operands,
+ * according to the supplied {@code Comparator}
+ */
+ public static<T> BinaryOperator<T> greaterOf(Comparator<? super T> comparator) {
+ return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
+ }
+}
--- a/jdk/src/share/classes/java/util/Currency.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/Currency.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -472,12 +472,18 @@
}
/**
- * Gets the symbol of this currency for the default locale.
+ * Gets the symbol of this currency for the default
+ * {@link Locale.Category#DISPLAY DISPLAY} locale.
* For example, for the US Dollar, the symbol is "$" if the default
* locale is the US, while for other locales it may be "US$". If no
* symbol can be determined, the ISO 4217 currency code is returned.
+ * <p>
+ * This is equivalent to calling
+ * {@link #getSymbol(Locale)
+ * getSymbol(Locale.getDefault(Locale.Category.DISPLAY))}.
*
- * @return the symbol of this currency for the default locale
+ * @return the symbol of this currency for the default
+ * {@link Locale.Category#DISPLAY DISPLAY} locale
*/
public String getSymbol() {
return getSymbol(Locale.getDefault(Locale.Category.DISPLAY));
@@ -533,10 +539,16 @@
/**
* Gets the name that is suitable for displaying this currency for
- * the default locale. If there is no suitable display name found
+ * the default {@link Locale.Category#DISPLAY DISPLAY} locale.
+ * If there is no suitable display name found
* for the default locale, the ISO 4217 currency code is returned.
+ * <p>
+ * This is equivalent to calling
+ * {@link #getDisplayName(Locale)
+ * getDisplayName(Locale.getDefault(Locale.Category.DISPLAY))}.
*
- * @return the display name of this currency for the default locale
+ * @return the display name of this currency for the default
+ * {@link Locale.Category#DISPLAY DISPLAY} locale
* @since 1.7
*/
public String getDisplayName() {
@@ -702,7 +714,7 @@
" ignored since cutover date has not passed :" + curdata, null);
return;
}
- } catch (IndexOutOfBoundsException | NullPointerException | ParseException ex) {
+ } catch (ParseException ex) {
info("currency.properties entry for " + ctry +
" ignored since exception encountered :" + ex.getMessage(), null);
return;
@@ -732,8 +744,7 @@
setMainTableEntry(ctry.charAt(0), ctry.charAt(1), entry);
}
- private static boolean isPastCutoverDate(String s)
- throws IndexOutOfBoundsException, NullPointerException, ParseException {
+ private static boolean isPastCutoverDate(String s) throws ParseException {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ROOT);
format.setTimeZone(TimeZone.getTimeZone("UTC"));
format.setLenient(false);
--- a/jdk/src/share/classes/java/util/Formatter.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/Formatter.java Fri Mar 15 16:39:07 2013 -0700
@@ -1900,7 +1900,8 @@
* which may be retrieved by invoking {@link #out out()} and whose
* current content may be converted into a string by invoking {@link
* #toString toString()}. The locale used is the {@linkplain
- * Locale#getDefault() default locale} for this instance of the Java
+ * Locale#getDefault(Locale.Category) default locale} for
+ * {@linkplain Locale.Category#FORMAT formatting} for this instance of the Java
* virtual machine.
*/
public Formatter() {
@@ -1910,8 +1911,10 @@
/**
* Constructs a new formatter with the specified destination.
*
- * <p> The locale used is the {@linkplain Locale#getDefault() default
- * locale} for this instance of the Java virtual machine.
+ * <p> The locale used is the {@linkplain
+ * Locale#getDefault(Locale.Category) default locale} for
+ * {@linkplain Locale.Category#FORMAT formatting} for this instance of the Java
+ * virtual machine.
*
* @param a
* Destination for the formatted output. If {@code a} is
@@ -1961,8 +1964,10 @@
* java.nio.charset.Charset#defaultCharset() default charset} for this
* instance of the Java virtual machine.
*
- * <p> The locale used is the {@linkplain Locale#getDefault() default
- * locale} for this instance of the Java virtual machine.
+ * <p> The locale used is the {@linkplain
+ * Locale#getDefault(Locale.Category) default locale} for
+ * {@linkplain Locale.Category#FORMAT formatting} for this instance of the Java
+ * virtual machine.
*
* @param fileName
* The name of the file to use as the destination of this
@@ -1989,8 +1994,10 @@
/**
* Constructs a new formatter with the specified file name and charset.
*
- * <p> The locale used is the {@linkplain Locale#getDefault default
- * locale} for this instance of the Java virtual machine.
+ * <p> The locale used is the {@linkplain
+ * Locale#getDefault(Locale.Category) default locale} for
+ * {@linkplain Locale.Category#FORMAT formatting} for this instance of the Java
+ * virtual machine.
*
* @param fileName
* The name of the file to use as the destination of this
@@ -2068,8 +2075,10 @@
* java.nio.charset.Charset#defaultCharset() default charset} for this
* instance of the Java virtual machine.
*
- * <p> The locale used is the {@linkplain Locale#getDefault() default
- * locale} for this instance of the Java virtual machine.
+ * <p> The locale used is the {@linkplain
+ * Locale#getDefault(Locale.Category) default locale} for
+ * {@linkplain Locale.Category#FORMAT formatting} for this instance of the Java
+ * virtual machine.
*
* @param file
* The file to use as the destination of this formatter. If the
@@ -2096,8 +2105,10 @@
/**
* Constructs a new formatter with the specified file and charset.
*
- * <p> The locale used is the {@linkplain Locale#getDefault default
- * locale} for this instance of the Java virtual machine.
+ * <p> The locale used is the {@linkplain
+ * Locale#getDefault(Locale.Category) default locale} for
+ * {@linkplain Locale.Category#FORMAT formatting} for this instance of the Java
+ * virtual machine.
*
* @param file
* The file to use as the destination of this formatter. If the
@@ -2171,8 +2182,10 @@
/**
* Constructs a new formatter with the specified print stream.
*
- * <p> The locale used is the {@linkplain Locale#getDefault() default
- * locale} for this instance of the Java virtual machine.
+ * <p> The locale used is the {@linkplain
+ * Locale#getDefault(Locale.Category) default locale} for
+ * {@linkplain Locale.Category#FORMAT formatting} for this instance of the Java
+ * virtual machine.
*
* <p> Characters are written to the given {@link java.io.PrintStream
* PrintStream} object and are therefore encoded using that object's
@@ -2193,8 +2206,10 @@
* java.nio.charset.Charset#defaultCharset() default charset} for this
* instance of the Java virtual machine.
*
- * <p> The locale used is the {@linkplain Locale#getDefault() default
- * locale} for this instance of the Java virtual machine.
+ * <p> The locale used is the {@linkplain
+ * Locale#getDefault(Locale.Category) default locale} for
+ * {@linkplain Locale.Category#FORMAT formatting} for this instance of the Java
+ * virtual machine.
*
* @param os
* The output stream to use as the destination of this formatter.
@@ -2209,8 +2224,10 @@
* Constructs a new formatter with the specified output stream and
* charset.
*
- * <p> The locale used is the {@linkplain Locale#getDefault default
- * locale} for this instance of the Java virtual machine.
+ * <p> The locale used is the {@linkplain
+ * Locale#getDefault(Locale.Category) default locale} for
+ * {@linkplain Locale.Category#FORMAT formatting} for this instance of the Java
+ * virtual machine.
*
* @param os
* The output stream to use as the destination of this formatter.
--- a/jdk/src/share/classes/java/util/GregorianCalendar.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/GregorianCalendar.java Fri Mar 15 16:39:07 2013 -0700
@@ -587,7 +587,8 @@
/**
* Constructs a default <code>GregorianCalendar</code> using the current time
- * in the default time zone with the default locale.
+ * in the default time zone with the default
+ * {@link Locale.Category#FORMAT FORMAT} locale.
*/
public GregorianCalendar() {
this(TimeZone.getDefaultRef(), Locale.getDefault(Locale.Category.FORMAT));
@@ -596,7 +597,8 @@
/**
* Constructs a <code>GregorianCalendar</code> based on the current time
- * in the given time zone with the default locale.
+ * in the given time zone with the default
+ * {@link Locale.Category#FORMAT FORMAT} locale.
*
* @param zone the given time zone.
*/
--- a/jdk/src/share/classes/java/util/IdentityHashMap.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/IdentityHashMap.java Fri Mar 15 16:39:07 2013 -0700
@@ -25,6 +25,7 @@
package java.util;
import java.io.*;
+import java.lang.reflect.Array;
/**
* This class implements the <tt>Map</tt> interface with a hash table, using
@@ -1010,6 +1011,37 @@
result += System.identityHashCode(key);
return result;
}
+ public Object[] toArray() {
+ return toArray(new Object[size()]);
+ }
+ @SuppressWarnings("unchecked")
+ public <T> T[] toArray(T[] a) {
+ int expectedModCount = modCount;
+ int size = size();
+ if (a.length < size)
+ a = (T[]) Array.newInstance(a.getClass().getComponentType(), size);
+ Object[] tab = table;
+ int ti = 0;
+ for (int si = 0; si < tab.length; si += 2) {
+ Object key;
+ if ((key = tab[si]) != null) { // key present ?
+ // more elements than expected -> concurrent modification from other thread
+ if (ti >= size) {
+ throw new ConcurrentModificationException();
+ }
+ a[ti++] = (T) unmaskNull(key); // unmask key
+ }
+ }
+ // fewer elements than expected or concurrent modification from other thread detected
+ if (ti < size || expectedModCount != modCount) {
+ throw new ConcurrentModificationException();
+ }
+ // final null marker as per spec
+ if (ti < a.length) {
+ a[ti] = null;
+ }
+ return a;
+ }
}
/**
@@ -1062,6 +1094,36 @@
public void clear() {
IdentityHashMap.this.clear();
}
+ public Object[] toArray() {
+ return toArray(new Object[size()]);
+ }
+ @SuppressWarnings("unchecked")
+ public <T> T[] toArray(T[] a) {
+ int expectedModCount = modCount;
+ int size = size();
+ if (a.length < size)
+ a = (T[]) Array.newInstance(a.getClass().getComponentType(), size);
+ Object[] tab = table;
+ int ti = 0;
+ for (int si = 0; si < tab.length; si += 2) {
+ if (tab[si] != null) { // key present ?
+ // more elements than expected -> concurrent modification from other thread
+ if (ti >= size) {
+ throw new ConcurrentModificationException();
+ }
+ a[ti++] = (T) tab[si+1]; // copy value
+ }
+ }
+ // fewer elements than expected or concurrent modification from other thread detected
+ if (ti < size || expectedModCount != modCount) {
+ throw new ConcurrentModificationException();
+ }
+ // final null marker as per spec
+ if (ti < a.length) {
+ a[ti] = null;
+ }
+ return a;
+ }
}
/**
@@ -1149,25 +1211,35 @@
}
public Object[] toArray() {
- int size = size();
- Object[] result = new Object[size];
- Iterator<Map.Entry<K,V>> it = iterator();
- for (int i = 0; i < size; i++)
- result[i] = new AbstractMap.SimpleEntry<>(it.next());
- return result;
+ return toArray(new Object[size()]);
}
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
+ int expectedModCount = modCount;
int size = size();
if (a.length < size)
- a = (T[])java.lang.reflect.Array
- .newInstance(a.getClass().getComponentType(), size);
- Iterator<Map.Entry<K,V>> it = iterator();
- for (int i = 0; i < size; i++)
- a[i] = (T) new AbstractMap.SimpleEntry<>(it.next());
- if (a.length > size)
- a[size] = null;
+ a = (T[]) Array.newInstance(a.getClass().getComponentType(), size);
+ Object[] tab = table;
+ int ti = 0;
+ for (int si = 0; si < tab.length; si += 2) {
+ Object key;
+ if ((key = tab[si]) != null) { // key present ?
+ // more elements than expected -> concurrent modification from other thread
+ if (ti >= size) {
+ throw new ConcurrentModificationException();
+ }
+ a[ti++] = (T) new AbstractMap.SimpleEntry(unmaskNull(key), tab[si + 1]);
+ }
+ }
+ // fewer elements than expected or concurrent modification from other thread detected
+ if (ti < size || expectedModCount != modCount) {
+ throw new ConcurrentModificationException();
+ }
+ // final null marker as per spec
+ if (ti < a.length) {
+ a[ti] = null;
+ }
return a;
}
}
--- a/jdk/src/share/classes/java/util/Locale.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/Locale.java Fri Mar 15 16:39:07 2013 -0700
@@ -351,7 +351,8 @@
* you can use <code>getDisplayLanguage</code> to get the name of
* the language suitable for displaying to the user. Interestingly,
* the <code>getDisplayXXX</code> methods are themselves locale-sensitive
- * and have two versions: one that uses the default locale and one
+ * and have two versions: one that uses the default
+ * {@link Locale.Category#DISPLAY DISPLAY} locale and one
* that uses the locale specified as an argument.
*
* <p>The Java Platform provides a number of classes that perform locale-sensitive
@@ -369,7 +370,8 @@
* </pre>
* </blockquote>
* Each of these methods has two variants; one with an explicit locale
- * and one without; the latter uses the default locale:
+ * and one without; the latter uses the default
+ * {@link Locale.Category#FORMAT FORMAT} locale:
* <blockquote>
* <pre>
* NumberFormat.getInstance(myLocale)
@@ -1645,11 +1647,15 @@
/**
* Returns a name for the locale's language that is appropriate for display to the
* user.
- * If possible, the name returned will be localized for the default locale.
- * For example, if the locale is fr_FR and the default locale
+ * If possible, the name returned will be localized for the default
+ * {@link Locale.Category#DISPLAY DISPLAY} locale.
+ * For example, if the locale is fr_FR and the default
+ * {@link Locale.Category#DISPLAY DISPLAY} locale
* is en_US, getDisplayLanguage() will return "French"; if the locale is en_US and
- * the default locale is fr_FR, getDisplayLanguage() will return "anglais".
- * If the name returned cannot be localized for the default locale,
+ * the default {@link Locale.Category#DISPLAY DISPLAY} locale is fr_FR,
+ * getDisplayLanguage() will return "anglais".
+ * If the name returned cannot be localized for the default
+ * {@link Locale.Category#DISPLAY DISPLAY} locale,
* (say, we don't have a Japanese name for Croatian),
* this function falls back on the English name, and uses the ISO code as a last-resort
* value. If the locale doesn't specify a language, this function returns the empty string.
@@ -1679,10 +1685,12 @@
/**
* Returns a name for the the locale's script that is appropriate for display to
- * the user. If possible, the name will be localized for the default locale. Returns
+ * the user. If possible, the name will be localized for the default
+ * {@link Locale.Category#DISPLAY DISPLAY} locale. Returns
* the empty string if this locale doesn't specify a script code.
*
- * @return the display name of the script code for the current default locale
+ * @return the display name of the script code for the current default
+ * {@link Locale.Category#DISPLAY DISPLAY} locale
* @since 1.7
*/
public String getDisplayScript() {
@@ -1695,7 +1703,8 @@
* localized for the given locale. Returns the empty string if
* this locale doesn't specify a script code.
*
- * @return the display name of the script code for the current default locale
+ * @return the display name of the script code for the current default
+ * {@link Locale.Category#DISPLAY DISPLAY} locale
* @throws NullPointerException if <code>inLocale</code> is <code>null</code>
* @since 1.7
*/
@@ -1706,11 +1715,15 @@
/**
* Returns a name for the locale's country that is appropriate for display to the
* user.
- * If possible, the name returned will be localized for the default locale.
- * For example, if the locale is fr_FR and the default locale
+ * If possible, the name returned will be localized for the default
+ * {@link Locale.Category#DISPLAY DISPLAY} locale.
+ * For example, if the locale is fr_FR and the default
+ * {@link Locale.Category#DISPLAY DISPLAY} locale
* is en_US, getDisplayCountry() will return "France"; if the locale is en_US and
- * the default locale is fr_FR, getDisplayCountry() will return "Etats-Unis".
- * If the name returned cannot be localized for the default locale,
+ * the default {@link Locale.Category#DISPLAY DISPLAY} locale is fr_FR,
+ * getDisplayCountry() will return "Etats-Unis".
+ * If the name returned cannot be localized for the default
+ * {@link Locale.Category#DISPLAY DISPLAY} locale,
* (say, we don't have a Japanese name for Croatia),
* this function falls back on the English name, and uses the ISO code as a last-resort
* value. If the locale doesn't specify a country, this function returns the empty string.
@@ -1762,7 +1775,8 @@
/**
* Returns a name for the locale's variant code that is appropriate for display to the
- * user. If possible, the name will be localized for the default locale. If the locale
+ * user. If possible, the name will be localized for the default
+ * {@link Locale.Category#DISPLAY DISPLAY} locale. If the locale
* doesn't specify a variant code, this function returns the empty string.
*/
public final String getDisplayVariant() {
--- a/jdk/src/share/classes/java/util/LocaleISOData.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/LocaleISOData.java Fri Mar 15 16:39:07 2013 -0700
@@ -473,7 +473,7 @@
+ "YE" + "YEM" // Yemen
+ "YT" + "MYT" // Mayotte
+ "ZA" + "ZAF" // South Africa, Republic of
- + "ZM" + "ZMW" // Zambia, Republic of
+ + "ZM" + "ZMB" // Zambia, Republic of
+ "ZW" + "ZWE" // Zimbabwe
;
--- a/jdk/src/share/classes/java/util/Scanner.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/Scanner.java Fri Mar 15 16:39:07 2013 -0700
@@ -151,7 +151,8 @@
* <p> An instance of this class is capable of scanning numbers in the standard
* formats as well as in the formats of the scanner's locale. A scanner's
* <a name="initial-locale">initial locale </a>is the value returned by the {@link
- * java.util.Locale#getDefault} method; it may be changed via the {@link
+ * java.util.Locale#getDefault(Locale.Category)
+ * Locale.getDefault(Locale.Category.FORMAT)} method; it may be changed via the {@link
* #useLocale} method. The {@link #reset} method will reset the value of the
* scanner's locale to the initial locale regardless of whether it was
* previously changed.
@@ -2641,7 +2642,7 @@
*
* <blockquote><pre>
* scanner.useDelimiter("\\p{javaWhitespace}+")
- * .useLocale(Locale.getDefault())
+ * .useLocale(Locale.getDefault(Locale.Category.FORMAT))
* .useRadix(10);
* </pre></blockquote>
*
--- a/jdk/src/share/classes/java/util/TimeZone.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/TimeZone.java Fri Mar 15 16:39:07 2013 -0700
@@ -534,7 +534,7 @@
/**
* Gets the {@code TimeZone} for the given {@code zoneId}.
*
- * @param zoneid a {@link ZoneId} from which the time zone ID is obtained
+ * @param zoneId a {@link ZoneId} from which the time zone ID is obtained
* @return the specified {@code TimeZone}, or the GMT zone if the given ID
* cannot be understood.
* @throws NullPointerException if {@code zoneId} is {@code null}
--- a/jdk/src/share/classes/java/util/concurrent/ForkJoinPool.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/concurrent/ForkJoinPool.java Fri Mar 15 16:39:07 2013 -0700
@@ -35,6 +35,7 @@
package java.util.concurrent;
+import java.lang.Thread.UncaughtExceptionHandler;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -104,38 +105,45 @@
* there is little difference among choice of methods.
*
* <table BORDER CELLPADDING=3 CELLSPACING=1>
+ * <caption>Summary of task execution methods</caption>
* <tr>
* <td></td>
* <td ALIGN=CENTER> <b>Call from non-fork/join clients</b></td>
* <td ALIGN=CENTER> <b>Call from within fork/join computations</b></td>
* </tr>
* <tr>
- * <td> <b>Arrange async execution</td>
+ * <td> <b>Arrange async execution</b></td>
* <td> {@link #execute(ForkJoinTask)}</td>
* <td> {@link ForkJoinTask#fork}</td>
* </tr>
* <tr>
- * <td> <b>Await and obtain result</td>
+ * <td> <b>Await and obtain result</b></td>
* <td> {@link #invoke(ForkJoinTask)}</td>
* <td> {@link ForkJoinTask#invoke}</td>
* </tr>
* <tr>
- * <td> <b>Arrange exec and obtain Future</td>
+ * <td> <b>Arrange exec and obtain Future</b></td>
* <td> {@link #submit(ForkJoinTask)}</td>
* <td> {@link ForkJoinTask#fork} (ForkJoinTasks <em>are</em> Futures)</td>
* </tr>
* </table>
*
* <p>The common pool is by default constructed with default
- * parameters, but these may be controlled by setting three {@link
- * System#getProperty system properties} with prefix {@code
- * java.util.concurrent.ForkJoinPool.common}: {@code parallelism} --
- * an integer greater than zero, {@code threadFactory} -- the class
- * name of a {@link ForkJoinWorkerThreadFactory}, and {@code
- * exceptionHandler} -- the class name of a {@link
- * java.lang.Thread.UncaughtExceptionHandler
- * Thread.UncaughtExceptionHandler}. Upon any error in establishing
- * these settings, default parameters are used.
+ * parameters, but these may be controlled by setting three
+ * {@linkplain System#getProperty system properties}:
+ * <ul>
+ * <li>{@code java.util.concurrent.ForkJoinPool.common.parallelism}
+ * - the parallelism level, a non-negative integer
+ * <li>{@code java.util.concurrent.ForkJoinPool.common.threadFactory}
+ * - the class name of a {@link ForkJoinWorkerThreadFactory}
+ * <li>{@code java.util.concurrent.ForkJoinPool.common.exceptionHandler}
+ * - the class name of a {@link UncaughtExceptionHandler}
+ * </ul>
+ * The system class loader is used to load these classes.
+ * Upon any error in establishing these settings, default parameters
+ * are used. It is possible to disable or limit the use of threads in
+ * the common pool by setting the parallelism property to zero, and/or
+ * using a factory that may return {@code null}.
*
* <p><b>Implementation notes</b>: This implementation restricts the
* maximum number of running threads to 32767. Attempts to create
@@ -225,18 +233,18 @@
* for work-stealing (this would contaminate lifo/fifo
* processing). Instead, we randomly associate submission queues
* with submitting threads, using a form of hashing. The
- * ThreadLocal Submitter class contains a value initially used as
- * a hash code for choosing existing queues, but may be randomly
- * repositioned upon contention with other submitters. In
- * essence, submitters act like workers except that they are
- * restricted to executing local tasks that they submitted (or in
- * the case of CountedCompleters, others with the same root task).
- * However, because most shared/external queue operations are more
- * expensive than internal, and because, at steady state, external
- * submitters will compete for CPU with workers, ForkJoinTask.join
- * and related methods disable them from repeatedly helping to
- * process tasks if all workers are active. Insertion of tasks in
- * shared mode requires a lock (mainly to protect in the case of
+ * ThreadLocalRandom probe value serves as a hash code for
+ * choosing existing queues, and may be randomly repositioned upon
+ * contention with other submitters. In essence, submitters act
+ * like workers except that they are restricted to executing local
+ * tasks that they submitted (or in the case of CountedCompleters,
+ * others with the same root task). However, because most
+ * shared/external queue operations are more expensive than
+ * internal, and because, at steady state, external submitters
+ * will compete for CPU with workers, ForkJoinTask.join and
+ * related methods disable them from repeatedly helping to process
+ * tasks if all workers are active. Insertion of tasks in shared
+ * mode requires a lock (mainly to protect in the case of
* resizing) but we use only a simple spinlock (using bits in
* field qlock), because submitters encountering a busy queue move
* on to try or create other queues -- they block only when
@@ -469,7 +477,7 @@
* Common Pool
* ===========
*
- * The static commonPool always exists after static
+ * The static common Pool always exists after static
* initialization. Since it (or any other created pool) need
* never be used, we minimize initial construction overhead and
* footprint to the setup of about a dozen fields, with no nested
@@ -548,6 +556,7 @@
*
* @param pool the pool this thread works in
* @throws NullPointerException if the pool is null
+ * @return the new worker thread
*/
public ForkJoinWorkerThread newThread(ForkJoinPool pool);
}
@@ -564,26 +573,6 @@
}
/**
- * Per-thread records for threads that submit to pools. Currently
- * holds only pseudo-random seed / index that is used to choose
- * submission queues in method externalPush. In the future, this may
- * also incorporate a means to implement different task rejection
- * and resubmission policies.
- *
- * Seeds for submitters and workers/workQueues work in basically
- * the same way but are initialized and updated using slightly
- * different mechanics. Both are initialized using the same
- * approach as in class ThreadLocal, where successive values are
- * unlikely to collide with previous values. Seeds are then
- * randomly modified upon collisions using xorshifts, which
- * requires a non-zero seed.
- */
- static final class Submitter {
- int seed;
- Submitter(int s) { seed = s; }
- }
-
- /**
* Class for artificial tasks that are used to replace the target
* of local joins if they are removed from an interior queue slot
* in WorkQueue.tryRemoveAndExec. We don't need the proxy to
@@ -737,7 +726,7 @@
* shared-queue version is embedded in method externalPush.)
*
* @param task the task. Caller must ensure non-null.
- * @throw RejectedExecutionException if array cannot be resized
+ * @throws RejectedExecutionException if array cannot be resized
*/
final void push(ForkJoinTask<?> task) {
ForkJoinTask<?>[] a; ForkJoinPool p;
@@ -936,7 +925,7 @@
* or any other cancelled task. Returns (true) on any CAS
* or consistency check failure so caller can retry.
*
- * @return false if no progress can be made, else true;
+ * @return false if no progress can be made, else true
*/
final boolean tryRemoveAndExec(ForkJoinTask<?> task) {
boolean stat = true, removed = false, empty = true;
@@ -981,7 +970,7 @@
/**
* Polls for and executes the given task or any other task in
- * its CountedCompleter computation
+ * its CountedCompleter computation.
*/
final boolean pollAndExecCC(ForkJoinTask<?> root) {
ForkJoinTask<?>[] a; int b; Object o;
@@ -1055,7 +1044,6 @@
private static final int ABASE;
private static final int ASHIFT;
static {
- int s;
try {
U = sun.misc.Unsafe.getUnsafe();
Class<?> k = WorkQueue.class;
@@ -1063,13 +1051,13 @@
QLOCK = U.objectFieldOffset
(k.getDeclaredField("qlock"));
ABASE = U.arrayBaseOffset(ak);
- s = U.arrayIndexScale(ak);
+ int scale = U.arrayIndexScale(ak);
+ if ((scale & (scale - 1)) != 0)
+ throw new Error("data type scale not a power of two");
+ ASHIFT = 31 - Integer.numberOfLeadingZeros(scale);
} catch (Exception e) {
throw new Error(e);
}
- if ((s & (s-1)) != 0)
- throw new Error("data type scale not a power of two");
- ASHIFT = 31 - Integer.numberOfLeadingZeros(s);
}
}
@@ -1083,15 +1071,6 @@
defaultForkJoinWorkerThreadFactory;
/**
- * Per-thread submission bookkeeping. Shared across all pools
- * to reduce ThreadLocal pollution and because random motion
- * to avoid contention in one pool is likely to hold for others.
- * Lazily initialized on first submission (but null-checked
- * in other contexts to avoid unnecessary initialization).
- */
- static final ThreadLocal<Submitter> submitters;
-
- /**
* Permission required for callers of methods that may start or
* kill threads.
*/
@@ -1103,12 +1082,15 @@
* to paranoically avoid potential initialization circularities
* as well as to simplify generated code.
*/
- static final ForkJoinPool commonPool;
+ static final ForkJoinPool common;
/**
- * Common pool parallelism. Must equal commonPool.parallelism.
+ * Common pool parallelism. To allow simpler use and management
+ * when common pool threads are disabled, we allow the underlying
+ * common.config field to be zero, but in that case still report
+ * parallelism as 1 to reflect resulting caller-runs mechanics.
*/
- static final int commonPoolParallelism;
+ static final int commonParallelism;
/**
* Sequence number for creating workerNamePrefix.
@@ -1116,8 +1098,8 @@
private static int poolNumberSequence;
/**
- * Return the next sequence number. We don't expect this to
- * ever contend so use simple builtin sync.
+ * Returns the next sequence number. We don't expect this to
+ * ever contend, so use simple builtin sync.
*/
private static final synchronized int nextPoolId() {
return ++poolNumberSequence;
@@ -1161,7 +1143,7 @@
*/
private static final int SEED_INCREMENT = 0x61c88647;
- /**
+ /*
* Bits and masks for control variables
*
* Field ctl is a long packed with:
@@ -1268,39 +1250,28 @@
final int config; // mode and parallelism level
WorkQueue[] workQueues; // main registry
final ForkJoinWorkerThreadFactory factory;
- final Thread.UncaughtExceptionHandler ueh; // per-worker UEH
+ final UncaughtExceptionHandler ueh; // per-worker UEH
final String workerNamePrefix; // to create worker name string
volatile Object pad10, pad11, pad12, pad13, pad14, pad15, pad16, pad17;
volatile Object pad18, pad19, pad1a, pad1b;
- /*
+ /**
* Acquires the plock lock to protect worker array and related
* updates. This method is called only if an initial CAS on plock
- * fails. This acts as a spinLock for normal cases, but falls back
+ * fails. This acts as a spinlock for normal cases, but falls back
* to builtin monitor to block when (rarely) needed. This would be
* a terrible idea for a highly contended lock, but works fine as
* a more conservative alternative to a pure spinlock.
*/
private int acquirePlock() {
- int spins = PL_SPINS, r = 0, ps, nps;
+ int spins = PL_SPINS, ps, nps;
for (;;) {
if (((ps = plock) & PL_LOCK) == 0 &&
U.compareAndSwapInt(this, PLOCK, ps, nps = ps + PL_LOCK))
return nps;
- else if (r == 0) { // randomize spins if possible
- Thread t = Thread.currentThread(); WorkQueue w; Submitter z;
- if ((t instanceof ForkJoinWorkerThread) &&
- (w = ((ForkJoinWorkerThread)t).workQueue) != null)
- r = w.seed;
- else if ((z = submitters.get()) != null)
- r = z.seed;
- else
- r = 1;
- }
else if (spins >= 0) {
- r ^= r << 1; r ^= r >>> 3; r ^= r << 10; // xorshift
- if (r >= 0)
+ if (ThreadLocalRandom.nextSecondarySeed() >= 0)
--spins;
}
else if (U.compareAndSwapInt(this, PLOCK, ps, ps | PL_SIGNAL)) {
@@ -1332,39 +1303,6 @@
}
/**
- * Performs secondary initialization, called when plock is zero.
- * Creates workQueue array and sets plock to a valid value. The
- * lock body must be exception-free (so no try/finally) so we
- * optimistically allocate new array outside the lock and throw
- * away if (very rarely) not needed. (A similar tactic is used in
- * fullExternalPush.) Because the plock seq value can eventually
- * wrap around zero, this method harmlessly fails to reinitialize
- * if workQueues exists, while still advancing plock.
- *
- * Additionally tries to create the first worker.
- */
- private void initWorkers() {
- WorkQueue[] ws, nws; int ps;
- int p = config & SMASK; // find power of two table size
- int n = (p > 1) ? p - 1 : 1; // ensure at least 2 slots
- n |= n >>> 1; n |= n >>> 2; n |= n >>> 4; n |= n >>> 8; n |= n >>> 16;
- n = (n + 1) << 1;
- if ((ws = workQueues) == null || ws.length == 0)
- nws = new WorkQueue[n];
- else
- nws = null;
- if (((ps = plock) & PL_LOCK) != 0 ||
- !U.compareAndSwapInt(this, PLOCK, ps, ps += PL_LOCK))
- ps = acquirePlock();
- if (((ws = workQueues) == null || ws.length == 0) && nws != null)
- workQueues = nws;
- int nps = (ps & SHUTDOWN) | ((ps + PL_LOCK) & ~SHUTDOWN);
- if (!U.compareAndSwapInt(this, PLOCK, ps, nps))
- releasePlock(nps);
- tryAddWorker();
- }
-
- /**
* Tries to create and start one worker if fewer than target
* parallelism level exist. Adjusts counts etc on failure.
*/
@@ -1406,7 +1344,7 @@
* @return the worker's queue
*/
final WorkQueue registerWorker(ForkJoinWorkerThread wt) {
- Thread.UncaughtExceptionHandler handler; WorkQueue[] ws; int s, ps;
+ UncaughtExceptionHandler handler; WorkQueue[] ws; int s, ps;
wt.setDaemon(true);
if ((handler = ueh) != null)
wt.setUncaughtExceptionHandler(handler);
@@ -1450,7 +1388,7 @@
* array, and adjusts counts. If pool is shutting down, tries to
* complete termination.
*
- * @param wt the worker thread or null if construction failed
+ * @param wt the worker thread, or null if construction failed
* @param ex the exception causing failure, or null if none
*/
final void deregisterWorker(ForkJoinWorkerThread wt, Throwable ex) {
@@ -1489,7 +1427,7 @@
if (e > 0) { // activate or create replacement
if ((ws = workQueues) == null ||
(i = e & SMASK) >= ws.length ||
- (v = ws[i]) != null)
+ (v = ws[i]) == null)
break;
long nc = (((long)(v.nextWait & E_MASK)) |
((long)(u + UAC_UNIT) << 32));
@@ -1526,10 +1464,10 @@
* @param task the task. Caller must ensure non-null.
*/
final void externalPush(ForkJoinTask<?> task) {
- WorkQueue[] ws; WorkQueue q; Submitter z; int m; ForkJoinTask<?>[] a;
- if ((z = submitters.get()) != null && plock > 0 &&
+ WorkQueue[] ws; WorkQueue q; int z, m; ForkJoinTask<?>[] a;
+ if ((z = ThreadLocalRandom.getProbe()) != 0 && plock > 0 &&
(ws = workQueues) != null && (m = (ws.length - 1)) >= 0 &&
- (q = ws[m & z.seed & SQMASK]) != null &&
+ (q = ws[m & z & SQMASK]) != null &&
U.compareAndSwapInt(q, QLOCK, 0, 1)) { // lock
int b = q.base, s = q.top, n, an;
if ((a = q.array) != null && (an = a.length) > (n = s + 1 - b)) {
@@ -1549,34 +1487,48 @@
/**
* Full version of externalPush. This method is called, among
* other times, upon the first submission of the first task to the
- * pool, so must perform secondary initialization (via
- * initWorkers). It also detects first submission by an external
- * thread by looking up its ThreadLocal, and creates a new shared
- * queue if the one at index if empty or contended. The plock lock
- * body must be exception-free (so no try/finally) so we
- * optimistically allocate new queues outside the lock and throw
- * them away if (very rarely) not needed.
+ * pool, so must perform secondary initialization. It also
+ * detects first submission by an external thread by looking up
+ * its ThreadLocal, and creates a new shared queue if the one at
+ * index if empty or contended. The plock lock body must be
+ * exception-free (so no try/finally) so we optimistically
+ * allocate new queues outside the lock and throw them away if
+ * (very rarely) not needed.
+ *
+ * Secondary initialization occurs when plock is zero, to create
+ * workQueue array and set plock to a valid value. This lock body
+ * must also be exception-free. Because the plock seq value can
+ * eventually wrap around zero, this method harmlessly fails to
+ * reinitialize if workQueues exists, while still advancing plock.
*/
private void fullExternalPush(ForkJoinTask<?> task) {
- int r = 0; // random index seed
- for (Submitter z = submitters.get();;) {
+ int r;
+ if ((r = ThreadLocalRandom.getProbe()) == 0) {
+ ThreadLocalRandom.localInit();
+ r = ThreadLocalRandom.getProbe();
+ }
+ for (;;) {
WorkQueue[] ws; WorkQueue q; int ps, m, k;
- if (z == null) {
- if (U.compareAndSwapInt(this, INDEXSEED, r = indexSeed,
- r += SEED_INCREMENT) && r != 0)
- submitters.set(z = new Submitter(r));
- }
- else if (r == 0) { // move to a different index
- r = z.seed;
- r ^= r << 13; // same xorshift as WorkQueues
- r ^= r >>> 17;
- z.seed = r ^ (r << 5);
- }
- else if ((ps = plock) < 0)
+ boolean move = false;
+ if ((ps = plock) < 0)
throw new RejectedExecutionException();
else if (ps == 0 || (ws = workQueues) == null ||
- (m = ws.length - 1) < 0)
- initWorkers();
+ (m = ws.length - 1) < 0) { // initialize workQueues
+ int p = config & SMASK; // find power of two table size
+ int n = (p > 1) ? p - 1 : 1; // ensure at least 2 slots
+ n |= n >>> 1; n |= n >>> 2; n |= n >>> 4;
+ n |= n >>> 8; n |= n >>> 16; n = (n + 1) << 1;
+ WorkQueue[] nws = ((ws = workQueues) == null || ws.length == 0 ?
+ new WorkQueue[n] : null);
+ if (((ps = plock) & PL_LOCK) != 0 ||
+ !U.compareAndSwapInt(this, PLOCK, ps, ps += PL_LOCK))
+ ps = acquirePlock();
+ if (((ws = workQueues) == null || ws.length == 0) && nws != null)
+ workQueues = nws;
+ int nps = (ps & SHUTDOWN) | ((ps + PL_LOCK) & ~SHUTDOWN);
+ if (!U.compareAndSwapInt(this, PLOCK, ps, nps))
+ releasePlock(nps);
+ }
else if ((q = ws[k = r & m & SQMASK]) != null) {
if (q.qlock == 0 && U.compareAndSwapInt(q, QLOCK, 0, 1)) {
ForkJoinTask<?>[] a = q.array;
@@ -1598,7 +1550,7 @@
return;
}
}
- r = 0; // move on failure
+ move = true; // move on failure
}
else if (((ps = plock) & PL_LOCK) == 0) { // create new queue
q = new WorkQueue(this, null, SHARED_QUEUE, r);
@@ -1612,7 +1564,9 @@
releasePlock(nps);
}
else
- r = 0; // try elsewhere while lock held
+ move = true; // move if busy
+ if (move)
+ r = ThreadLocalRandom.advanceProbe(r);
}
}
@@ -1703,7 +1657,7 @@
* park awaiting signal, else lingering to help scan and signal.
*
* * If a non-empty queue discovered or left as a hint,
- * help wake up other workers before return
+ * help wake up other workers before return.
*
* @param w the worker (via its WorkQueue)
* @return a task or null if none found
@@ -1758,14 +1712,13 @@
else if ((int)(c >> AC_SHIFT) == 1 - (config & SMASK))
idleAwaitWork(w, nc, c);
}
- else if (w.eventCount < 0 && !tryTerminate(false, false) &&
- ctl == c) { // block
+ else if (w.eventCount < 0 && ctl == c) {
Thread wt = Thread.currentThread();
Thread.interrupted(); // clear status
U.putObject(wt, PARKBLOCKER, this);
w.parker = wt; // emulate LockSupport.park
if (w.eventCount < 0) // recheck
- U.park(false, 0L);
+ U.park(false, 0L); // block
w.parker = null;
U.putObject(wt, PARKBLOCKER, null);
}
@@ -1774,7 +1727,7 @@
(ws = workQueues) != null && h < ws.length &&
(q = ws[h]) != null) { // signal others before retry
WorkQueue v; Thread p; int u, i, s;
- for (int n = (config & SMASK) >>> 1;;) {
+ for (int n = (config & SMASK) - 1;;) {
int idleCount = (w.eventCount < 0) ? 0 : -1;
if (((s = idleCount - q.base + q.top) <= n &&
(n = s) <= 0) ||
@@ -1814,7 +1767,8 @@
*/
private void idleAwaitWork(WorkQueue w, long currentCtl, long prevCtl) {
if (w != null && w.eventCount < 0 &&
- !tryTerminate(false, false) && (int)prevCtl != 0) {
+ !tryTerminate(false, false) && (int)prevCtl != 0 &&
+ ctl == currentCtl) {
int dc = -(short)(currentCtl >>> TC_SHIFT);
long parkTime = dc < 0 ? FAST_IDLE_TIMEOUT: (dc + 1) * IDLE_TIMEOUT;
long deadline = System.nanoTime() + parkTime - TIMEOUT_SLOP;
@@ -1832,6 +1786,7 @@
if (deadline - System.nanoTime() <= 0L &&
U.compareAndSwapLong(this, CTL, currentCtl, prevCtl)) {
w.eventCount = (w.eventCount + E_SEQ) | E_MASK;
+ w.hint = -1;
w.qlock = -1; // shrink
break;
}
@@ -1973,7 +1928,6 @@
* @param task the task to join
* @param mode if shared, exit upon completing any task
* if all workers are active
- *
*/
private int helpComplete(ForkJoinTask<?> task, int mode) {
WorkQueue[] ws; WorkQueue q; int m, n, s, u;
@@ -2125,29 +2079,22 @@
/**
* Returns a (probably) non-empty steal queue, if one is found
- * during a random, then cyclic scan, else null. This method must
- * be retried by caller if, by the time it tries to use the queue,
- * it is empty.
+ * during a scan, else null. This method must be retried by
+ * caller if, by the time it tries to use the queue, it is empty.
* @param r a (random) seed for scanning
*/
private WorkQueue findNonEmptyStealQueue(int r) {
- for (WorkQueue[] ws;;) {
- int ps = plock, m, n;
- if ((ws = workQueues) == null || (m = ws.length - 1) < 1)
- return null;
- for (int j = (m + 1) << 2; ;) {
- WorkQueue q = ws[(((r + j) << 1) | 1) & m];
- if (q != null && (n = q.base - q.top) < 0) {
- if (n < -1)
- signalWork(q);
- return q;
- }
- else if (--j < 0) {
- if (plock == ps)
- return null;
- break;
+ for (;;) {
+ int ps = plock, m; WorkQueue[] ws; WorkQueue q;
+ if ((ws = workQueues) != null && (m = ws.length - 1) >= 0) {
+ for (int j = (m + 1) << 2; j >= 0; --j) {
+ if ((q = ws[(((r + j) << 1) | 1) & m]) != null &&
+ q.base - q.top < 0)
+ return q;
}
}
+ if (plock == ps)
+ return null;
}
}
@@ -2159,37 +2106,34 @@
*/
final void helpQuiescePool(WorkQueue w) {
for (boolean active = true;;) {
- ForkJoinTask<?> localTask; // exhaust local queue
- while ((localTask = w.nextLocalTask()) != null)
- localTask.doExec();
- // Similar to loop in scan(), but ignoring submissions
- WorkQueue q = findNonEmptyStealQueue(w.nextSeed());
- if (q != null) {
- ForkJoinTask<?> t; int b;
+ long c; WorkQueue q; ForkJoinTask<?> t; int b;
+ while ((t = w.nextLocalTask()) != null) {
+ if (w.base - w.top < 0)
+ signalWork(w);
+ t.doExec();
+ }
+ if ((q = findNonEmptyStealQueue(w.nextSeed())) != null) {
if (!active) { // re-establish active count
- long c;
active = true;
do {} while (!U.compareAndSwapLong
(this, CTL, c = ctl, c + AC_UNIT));
}
- if ((b = q.base) - q.top < 0 && (t = q.pollAt(b)) != null)
+ if ((b = q.base) - q.top < 0 && (t = q.pollAt(b)) != null) {
+ if (q.base - q.top < 0)
+ signalWork(q);
w.runSubtask(t);
- }
- else {
- long c;
- if (active) { // decrement active count without queuing
- active = false;
- do {} while (!U.compareAndSwapLong
- (this, CTL, c = ctl, c -= AC_UNIT));
- }
- else
- c = ctl; // re-increment on exit
- if ((int)(c >> AC_SHIFT) + (config & SMASK) == 0) {
- do {} while (!U.compareAndSwapLong
- (this, CTL, c = ctl, c + AC_UNIT));
- break;
}
}
+ else if (active) { // decrement active count without queuing
+ long nc = (c = ctl) - AC_UNIT;
+ if ((int)(nc >> AC_SHIFT) + (config & SMASK) == 0)
+ return; // bypass decrement-then-increment
+ if (U.compareAndSwapLong(this, CTL, c, nc))
+ active = false;
+ }
+ else if ((int)((c = ctl) >> AC_SHIFT) + (config & SMASK) == 0 &&
+ U.compareAndSwapLong(this, CTL, c, c + AC_UNIT))
+ return;
}
}
@@ -2205,8 +2149,11 @@
return t;
if ((q = findNonEmptyStealQueue(w.nextSeed())) == null)
return null;
- if ((b = q.base) - q.top < 0 && (t = q.pollAt(b)) != null)
+ if ((b = q.base) - q.top < 0 && (t = q.pollAt(b)) != null) {
+ if (q.base - q.top < 0)
+ signalWork(q);
return t;
+ }
}
}
@@ -2235,7 +2182,7 @@
* producing extra tasks amortizes the uncertainty of progress and
* diffusion assumptions.
*
- * So, users will want to use values larger, but not much larger
+ * So, users will want to use values larger (but not much larger)
* than 1 to both smooth over transient shortages and hedge
* against uneven progress; as traded off against the cost of
* extra task overhead. We leave the user to pick a threshold
@@ -2288,45 +2235,49 @@
* @return true if now terminating or terminated
*/
private boolean tryTerminate(boolean now, boolean enable) {
- if (this == commonPool) // cannot shut down
+ int ps;
+ if (this == common) // cannot shut down
return false;
+ if ((ps = plock) >= 0) { // enable by setting plock
+ if (!enable)
+ return false;
+ if ((ps & PL_LOCK) != 0 ||
+ !U.compareAndSwapInt(this, PLOCK, ps, ps += PL_LOCK))
+ ps = acquirePlock();
+ int nps = ((ps + PL_LOCK) & ~SHUTDOWN) | SHUTDOWN;
+ if (!U.compareAndSwapInt(this, PLOCK, ps, nps))
+ releasePlock(nps);
+ }
for (long c;;) {
- if (((c = ctl) & STOP_BIT) != 0) { // already terminating
+ if (((c = ctl) & STOP_BIT) != 0) { // already terminating
if ((short)(c >>> TC_SHIFT) == -(config & SMASK)) {
synchronized (this) {
- notifyAll(); // signal when 0 workers
+ notifyAll(); // signal when 0 workers
}
}
return true;
}
- if (plock >= 0) { // not yet enabled
- int ps;
- if (!enable)
+ if (!now) { // check if idle & no tasks
+ WorkQueue[] ws; WorkQueue w;
+ if ((int)(c >> AC_SHIFT) != -(config & SMASK))
return false;
- if (((ps = plock) & PL_LOCK) != 0 ||
- !U.compareAndSwapInt(this, PLOCK, ps, ps += PL_LOCK))
- ps = acquirePlock();
- if (!U.compareAndSwapInt(this, PLOCK, ps, SHUTDOWN))
- releasePlock(SHUTDOWN);
- }
- if (!now) { // check if idle & no tasks
- if ((int)(c >> AC_SHIFT) != -(config & SMASK) ||
- hasQueuedSubmissions())
- return false;
- // Check for unqueued inactive workers. One pass suffices.
- WorkQueue[] ws = workQueues; WorkQueue w;
- if (ws != null) {
- for (int i = 1; i < ws.length; i += 2) {
- if ((w = ws[i]) != null && w.eventCount >= 0)
- return false;
+ if ((ws = workQueues) != null) {
+ for (int i = 0; i < ws.length; ++i) {
+ if ((w = ws[i]) != null) {
+ if (!w.isEmpty()) { // signal unprocessed tasks
+ signalWork(w);
+ return false;
+ }
+ if ((i & 1) != 0 && w.eventCount >= 0)
+ return false; // unqueued inactive worker
+ }
}
}
}
if (U.compareAndSwapLong(this, CTL, c, c | STOP_BIT)) {
for (int pass = 0; pass < 3; ++pass) {
- WorkQueue[] ws = workQueues;
- if (ws != null) {
- WorkQueue w; Thread wt;
+ WorkQueue[] ws; WorkQueue w; Thread wt;
+ if ((ws = workQueues) != null) {
int n = ws.length;
for (int i = 0; i < n; ++i) {
if ((w = ws[i]) != null) {
@@ -2337,7 +2288,7 @@
if (!wt.isInterrupted()) {
try {
wt.interrupt();
- } catch (SecurityException ignore) {
+ } catch (Throwable ignore) {
}
}
U.unpark(wt);
@@ -2348,7 +2299,7 @@
// Wake up workers parked on event queue
int i, e; long cc; Thread p;
while ((e = (int)(cc = ctl) & E_MASK) != 0 &&
- (i = e & SMASK) < n &&
+ (i = e & SMASK) < n && i >= 0 &&
(w = ws[i]) != null) {
long nc = ((long)(w.nextWait & E_MASK) |
((cc + AC_UNIT) & AC_MASK) |
@@ -2374,26 +2325,26 @@
* least one task.
*/
static WorkQueue commonSubmitterQueue() {
- ForkJoinPool p; WorkQueue[] ws; int m; Submitter z;
- return ((z = submitters.get()) != null &&
- (p = commonPool) != null &&
+ ForkJoinPool p; WorkQueue[] ws; int m, z;
+ return ((z = ThreadLocalRandom.getProbe()) != 0 &&
+ (p = common) != null &&
(ws = p.workQueues) != null &&
(m = ws.length - 1) >= 0) ?
- ws[m & z.seed & SQMASK] : null;
+ ws[m & z & SQMASK] : null;
}
/**
* Tries to pop the given task from submitter's queue in common pool.
*/
static boolean tryExternalUnpush(ForkJoinTask<?> t) {
- ForkJoinPool p; WorkQueue[] ws; WorkQueue q; Submitter z;
- ForkJoinTask<?>[] a; int m, s;
+ ForkJoinPool p; WorkQueue[] ws; WorkQueue q;
+ ForkJoinTask<?>[] a; int m, s, z;
if (t != null &&
- (z = submitters.get()) != null &&
- (p = commonPool) != null &&
+ (z = ThreadLocalRandom.getProbe()) != 0 &&
+ (p = common) != null &&
(ws = p.workQueues) != null &&
(m = ws.length - 1) >= 0 &&
- (q = ws[m & z.seed & SQMASK]) != null &&
+ (q = ws[m & z & SQMASK]) != null &&
(s = q.top) != q.base &&
(a = q.array) != null) {
long j = (((a.length - 1) & (s - 1)) << ASHIFT) + ABASE;
@@ -2445,9 +2396,10 @@
if (task != null)
task.doExec();
if (root.status < 0 ||
- (u = (int)(ctl >>> 32)) >= 0 || (u >> UAC_SHIFT) >= 0)
+ (config != 0 &&
+ ((u = (int)(ctl >>> 32)) >= 0 || (u >> UAC_SHIFT) >= 0)))
break;
- if (task == null) {
+ if (task == null) {
helpSignal(root, q.poolIndex);
if (root.status >= 0)
helpComplete(root, SHARED_QUEUE);
@@ -2463,14 +2415,14 @@
*/
static void externalHelpJoin(ForkJoinTask<?> t) {
// Some hard-to-avoid overlap with tryExternalUnpush
- ForkJoinPool p; WorkQueue[] ws; WorkQueue q, w; Submitter z;
- ForkJoinTask<?>[] a; int m, s, n;
+ ForkJoinPool p; WorkQueue[] ws; WorkQueue q, w;
+ ForkJoinTask<?>[] a; int m, s, n, z;
if (t != null &&
- (z = submitters.get()) != null &&
- (p = commonPool) != null &&
+ (z = ThreadLocalRandom.getProbe()) != 0 &&
+ (p = common) != null &&
(ws = p.workQueues) != null &&
(m = ws.length - 1) >= 0 &&
- (q = ws[m & z.seed & SQMASK]) != null &&
+ (q = ws[m & z & SQMASK]) != null &&
(a = q.array) != null) {
int am = a.length - 1;
if ((s = q.top) != q.base) {
@@ -2496,18 +2448,6 @@
}
}
- /**
- * Restricted version of helpQuiescePool for external callers
- */
- static void externalHelpQuiescePool() {
- ForkJoinPool p; ForkJoinTask<?> t; WorkQueue q; int b;
- if ((p = commonPool) != null &&
- (q = p.findNonEmptyStealQueue(1)) != null &&
- (b = q.base) - q.top < 0 &&
- (t = q.pollAt(b)) != null)
- t.doExec();
- }
-
// Exported methods
// Constructors
@@ -2524,7 +2464,7 @@
* java.lang.RuntimePermission}{@code ("modifyThread")}
*/
public ForkJoinPool() {
- this(Runtime.getRuntime().availableProcessors(),
+ this(Math.min(MAX_CAP, Runtime.getRuntime().availableProcessors()),
defaultForkJoinWorkerThreadFactory, null, false);
}
@@ -2572,50 +2512,63 @@
*/
public ForkJoinPool(int parallelism,
ForkJoinWorkerThreadFactory factory,
- Thread.UncaughtExceptionHandler handler,
+ UncaughtExceptionHandler handler,
boolean asyncMode) {
+ this(checkParallelism(parallelism),
+ checkFactory(factory),
+ handler,
+ asyncMode,
+ "ForkJoinPool-" + nextPoolId() + "-worker-");
checkPermission();
+ }
+
+ private static int checkParallelism(int parallelism) {
+ if (parallelism <= 0 || parallelism > MAX_CAP)
+ throw new IllegalArgumentException();
+ return parallelism;
+ }
+
+ private static ForkJoinWorkerThreadFactory checkFactory
+ (ForkJoinWorkerThreadFactory factory) {
if (factory == null)
throw new NullPointerException();
- if (parallelism <= 0 || parallelism > MAX_CAP)
- throw new IllegalArgumentException();
+ return factory;
+ }
+
+ /**
+ * Creates a {@code ForkJoinPool} with the given parameters, without
+ * any security checks or parameter validation. Invoked directly by
+ * makeCommonPool.
+ */
+ private ForkJoinPool(int parallelism,
+ ForkJoinWorkerThreadFactory factory,
+ UncaughtExceptionHandler handler,
+ boolean asyncMode,
+ String workerNamePrefix) {
+ this.workerNamePrefix = workerNamePrefix;
this.factory = factory;
this.ueh = handler;
this.config = parallelism | (asyncMode ? (FIFO_QUEUE << 16) : 0);
long np = (long)(-parallelism); // offset ctl counts
this.ctl = ((np << AC_SHIFT) & AC_MASK) | ((np << TC_SHIFT) & TC_MASK);
- int pn = nextPoolId();
- StringBuilder sb = new StringBuilder("ForkJoinPool-");
- sb.append(Integer.toString(pn));
- sb.append("-worker-");
- this.workerNamePrefix = sb.toString();
- }
-
- /**
- * Constructor for common pool, suitable only for static initialization.
- * Basically the same as above, but uses smallest possible initial footprint.
- */
- ForkJoinPool(int parallelism, long ctl,
- ForkJoinWorkerThreadFactory factory,
- Thread.UncaughtExceptionHandler handler) {
- this.config = parallelism;
- this.ctl = ctl;
- this.factory = factory;
- this.ueh = handler;
- this.workerNamePrefix = "ForkJoinPool.commonPool-worker-";
}
/**
* Returns the common pool instance. This pool is statically
- * constructed; its run state is unaffected by attempts to
- * {@link #shutdown} or {@link #shutdownNow}.
+ * constructed; its run state is unaffected by attempts to {@link
+ * #shutdown} or {@link #shutdownNow}. However this pool and any
+ * ongoing processing are automatically terminated upon program
+ * {@link System#exit}. Any program that relies on asynchronous
+ * task processing to complete before program termination should
+ * invoke {@code commonPool().}{@link #awaitQuiescence awaitQuiescence},
+ * before exit.
*
* @return the common pool instance
* @since 1.8
*/
public static ForkJoinPool commonPool() {
- // assert commonPool != null : "static init error";
- return commonPool;
+ // assert common != null : "static init error";
+ return common;
}
// Execution methods
@@ -2671,7 +2624,7 @@
if (task instanceof ForkJoinTask<?>) // avoid re-wrap
job = (ForkJoinTask<?>) task;
else
- job = new ForkJoinTask.AdaptedRunnableAction(task);
+ job = new ForkJoinTask.RunnableExecuteAction(task);
externalPush(job);
}
@@ -2738,27 +2691,23 @@
// In previous versions of this class, this method constructed
// a task to run ForkJoinTask.invokeAll, but now external
// invocation of multiple tasks is at least as efficient.
- List<ForkJoinTask<T>> fs = new ArrayList<ForkJoinTask<T>>(tasks.size());
- // Workaround needed because method wasn't declared with
- // wildcards in return type but should have been.
- @SuppressWarnings({"unchecked", "rawtypes"})
- List<Future<T>> futures = (List<Future<T>>) (List) fs;
+ ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
boolean done = false;
try {
for (Callable<T> t : tasks) {
ForkJoinTask<T> f = new ForkJoinTask.AdaptedCallable<T>(t);
+ futures.add(f);
externalPush(f);
- fs.add(f);
}
- for (ForkJoinTask<T> f : fs)
- f.quietlyJoin();
+ for (int i = 0, size = futures.size(); i < size; i++)
+ ((ForkJoinTask<?>)futures.get(i)).quietlyJoin();
done = true;
return futures;
} finally {
if (!done)
- for (ForkJoinTask<T> f : fs)
- f.cancel(false);
+ for (int i = 0, size = futures.size(); i < size; i++)
+ futures.get(i).cancel(false);
}
}
@@ -2777,7 +2726,7 @@
*
* @return the handler, or {@code null} if none
*/
- public Thread.UncaughtExceptionHandler getUncaughtExceptionHandler() {
+ public UncaughtExceptionHandler getUncaughtExceptionHandler() {
return ueh;
}
@@ -2787,7 +2736,8 @@
* @return the targeted parallelism level of this pool
*/
public int getParallelism() {
- return config & SMASK;
+ int par = (config & SMASK);
+ return (par > 0) ? par : 1;
}
/**
@@ -2797,7 +2747,7 @@
* @since 1.8
*/
public static int getCommonPoolParallelism() {
- return commonPoolParallelism;
+ return commonParallelism;
}
/**
@@ -3055,7 +3005,7 @@
* Possibly initiates an orderly shutdown in which previously
* submitted tasks are executed, but no new tasks will be
* accepted. Invocation has no effect on execution state if this
- * is the {@link #commonPool}, and no additional effect if
+ * is the {@link #commonPool()}, and no additional effect if
* already shut down. Tasks that are in the process of being
* submitted concurrently during the course of this method may or
* may not be rejected.
@@ -3073,7 +3023,7 @@
/**
* Possibly attempts to cancel and/or stop all tasks, and reject
* all subsequently submitted tasks. Invocation has no effect on
- * execution state if this is the {@link #commonPool}, and no
+ * execution state if this is the {@link #commonPool()}, and no
* additional effect if already shut down. Otherwise, tasks that
* are in the process of being submitted or executed concurrently
* during the course of this method may or may not be
@@ -3136,9 +3086,10 @@
/**
* Blocks until all tasks have completed execution after a
* shutdown request, or the timeout occurs, or the current thread
- * is interrupted, whichever happens first. Note that the {@link
- * #commonPool()} never terminates until program shutdown so
- * this method will always time out.
+ * is interrupted, whichever happens first. Because the {@link
+ * #commonPool()} never terminates until program shutdown, when
+ * applied to the common pool, this method is equivalent to {@link
+ * #awaitQuiescence(long, TimeUnit)} but always returns {@code false}.
*
* @param timeout the maximum time to wait
* @param unit the time unit of the timeout argument
@@ -3148,6 +3099,12 @@
*/
public boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException {
+ if (Thread.interrupted())
+ throw new InterruptedException();
+ if (this == common) {
+ awaitQuiescence(timeout, unit);
+ return false;
+ }
long nanos = unit.toNanos(timeout);
if (isTerminated())
return true;
@@ -3167,6 +3124,62 @@
}
/**
+ * If called by a ForkJoinTask operating in this pool, equivalent
+ * in effect to {@link ForkJoinTask#helpQuiesce}. Otherwise,
+ * waits and/or attempts to assist performing tasks until this
+ * pool {@link #isQuiescent} or the indicated timeout elapses.
+ *
+ * @param timeout the maximum time to wait
+ * @param unit the time unit of the timeout argument
+ * @return {@code true} if quiescent; {@code false} if the
+ * timeout elapsed.
+ */
+ public boolean awaitQuiescence(long timeout, TimeUnit unit) {
+ long nanos = unit.toNanos(timeout);
+ ForkJoinWorkerThread wt;
+ Thread thread = Thread.currentThread();
+ if ((thread instanceof ForkJoinWorkerThread) &&
+ (wt = (ForkJoinWorkerThread)thread).pool == this) {
+ helpQuiescePool(wt.workQueue);
+ return true;
+ }
+ long startTime = System.nanoTime();
+ WorkQueue[] ws;
+ int r = 0, m;
+ boolean found = true;
+ while (!isQuiescent() && (ws = workQueues) != null &&
+ (m = ws.length - 1) >= 0) {
+ if (!found) {
+ if ((System.nanoTime() - startTime) > nanos)
+ return false;
+ Thread.yield(); // cannot block
+ }
+ found = false;
+ for (int j = (m + 1) << 2; j >= 0; --j) {
+ ForkJoinTask<?> t; WorkQueue q; int b;
+ if ((q = ws[r++ & m]) != null && (b = q.base) - q.top < 0) {
+ found = true;
+ if ((t = q.pollAt(b)) != null) {
+ if (q.base - q.top < 0)
+ signalWork(q);
+ t.doExec();
+ }
+ break;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Waits and/or attempts to assist performing tasks indefinitely
+ * until the {@link #commonPool()} {@link #isQuiescent}.
+ */
+ static void quiesceCommonPool() {
+ common.awaitQuiescence(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
+ }
+
+ /**
* Interface for extending managed parallelism for tasks running
* in {@link ForkJoinPool}s.
*
@@ -3175,9 +3188,9 @@
* not necessary. Method {@code block} blocks the current thread
* if necessary (perhaps internally invoking {@code isReleasable}
* before actually blocking). These actions are performed by any
- * thread invoking {@link ForkJoinPool#managedBlock}. The
- * unusual methods in this API accommodate synchronizers that may,
- * but don't usually, block for long periods. Similarly, they
+ * thread invoking {@link ForkJoinPool#managedBlock(ManagedBlocker)}.
+ * The unusual methods in this API accommodate synchronizers that
+ * may, but don't usually, block for long periods. Similarly, they
* allow more efficient internal handling of cases in which
* additional workers may be, but usually are not, needed to
* ensure sufficient parallelism. Toward this end,
@@ -3235,6 +3248,7 @@
/**
* Returns {@code true} if blocking is unnecessary.
+ * @return {@code true} if blocking is unnecessary
*/
boolean isReleasable();
}
@@ -3319,7 +3333,7 @@
private static final long QLOCK;
static {
- int s; // initialize field offsets for CAS etc
+ // initialize field offsets for CAS etc
try {
U = sun.misc.Unsafe.getUnsafe();
Class<?> k = ForkJoinPool.class;
@@ -3339,54 +3353,58 @@
(wk.getDeclaredField("qlock"));
Class<?> ak = ForkJoinTask[].class;
ABASE = U.arrayBaseOffset(ak);
- s = U.arrayIndexScale(ak);
- ASHIFT = 31 - Integer.numberOfLeadingZeros(s);
+ int scale = U.arrayIndexScale(ak);
+ if ((scale & (scale - 1)) != 0)
+ throw new Error("data type scale not a power of two");
+ ASHIFT = 31 - Integer.numberOfLeadingZeros(scale);
} catch (Exception e) {
throw new Error(e);
}
- if ((s & (s-1)) != 0)
- throw new Error("data type scale not a power of two");
- submitters = new ThreadLocal<Submitter>();
- ForkJoinWorkerThreadFactory fac = defaultForkJoinWorkerThreadFactory =
+ defaultForkJoinWorkerThreadFactory =
new DefaultForkJoinWorkerThreadFactory();
modifyThreadPermission = new RuntimePermission("modifyThread");
- /*
- * Establish common pool parameters. For extra caution,
- * computations to set up common pool state are here; the
- * constructor just assigns these values to fields.
- */
+ common = java.security.AccessController.doPrivileged
+ (new java.security.PrivilegedAction<ForkJoinPool>() {
+ public ForkJoinPool run() { return makeCommonPool(); }});
+ int par = common.config; // report 1 even if threads disabled
+ commonParallelism = par > 0 ? par : 1;
+ }
- int par = 0;
- Thread.UncaughtExceptionHandler handler = null;
- try { // TBD: limit or report ignored exceptions?
+ /**
+ * Creates and returns the common pool, respecting user settings
+ * specified via system properties.
+ */
+ private static ForkJoinPool makeCommonPool() {
+ int parallelism = -1;
+ ForkJoinWorkerThreadFactory factory
+ = defaultForkJoinWorkerThreadFactory;
+ UncaughtExceptionHandler handler = null;
+ try { // ignore exceptions in accesing/parsing properties
String pp = System.getProperty
("java.util.concurrent.ForkJoinPool.common.parallelism");
- String hp = System.getProperty
- ("java.util.concurrent.ForkJoinPool.common.exceptionHandler");
String fp = System.getProperty
("java.util.concurrent.ForkJoinPool.common.threadFactory");
+ String hp = System.getProperty
+ ("java.util.concurrent.ForkJoinPool.common.exceptionHandler");
+ if (pp != null)
+ parallelism = Integer.parseInt(pp);
if (fp != null)
- fac = ((ForkJoinWorkerThreadFactory)ClassLoader.
- getSystemClassLoader().loadClass(fp).newInstance());
+ factory = ((ForkJoinWorkerThreadFactory)ClassLoader.
+ getSystemClassLoader().loadClass(fp).newInstance());
if (hp != null)
- handler = ((Thread.UncaughtExceptionHandler)ClassLoader.
+ handler = ((UncaughtExceptionHandler)ClassLoader.
getSystemClassLoader().loadClass(hp).newInstance());
- if (pp != null)
- par = Integer.parseInt(pp);
} catch (Exception ignore) {
}
- if (par <= 0)
- par = Runtime.getRuntime().availableProcessors();
- if (par > MAX_CAP)
- par = MAX_CAP;
- commonPoolParallelism = par;
- long np = (long)(-par); // precompute initial ctl value
- long ct = ((np << AC_SHIFT) & AC_MASK) | ((np << TC_SHIFT) & TC_MASK);
-
- commonPool = new ForkJoinPool(par, ct, fac, handler);
+ if (parallelism < 0)
+ parallelism = Runtime.getRuntime().availableProcessors();
+ if (parallelism > MAX_CAP)
+ parallelism = MAX_CAP;
+ return new ForkJoinPool(parallelism, factory, handler, false,
+ "ForkJoinPool.commonPool-worker-");
}
}
--- a/jdk/src/share/classes/java/util/concurrent/ForkJoinTask.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/concurrent/ForkJoinTask.java Fri Mar 15 16:39:07 2013 -0700
@@ -464,7 +464,7 @@
}
/**
- * Records exception and possibly propagates
+ * Records exception and possibly propagates.
*
* @return status on exit
*/
@@ -497,7 +497,7 @@
}
/**
- * Removes exception node and clears status
+ * Removes exception node and clears status.
*/
private void clearExceptionalCompletion() {
int h = System.identityHashCode(this);
@@ -635,7 +635,7 @@
throw (Error)ex;
if (ex instanceof RuntimeException)
throw (RuntimeException)ex;
- throw uncheckedThrowable(ex, RuntimeException.class);
+ ForkJoinTask.<RuntimeException>uncheckedThrow(ex);
}
}
@@ -645,8 +645,9 @@
* unchecked exceptions
*/
@SuppressWarnings("unchecked") static <T extends Throwable>
- T uncheckedThrowable(final Throwable t, final Class<T> c) {
- return (T)t; // rely on vacuous cast
+ void uncheckedThrow(Throwable t) throws T {
+ if (t != null)
+ throw (T)t; // rely on vacuous cast
}
/**
@@ -681,7 +682,7 @@
if ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread)
((ForkJoinWorkerThread)t).workQueue.push(this);
else
- ForkJoinPool.commonPool.externalPush(this);
+ ForkJoinPool.common.externalPush(this);
return this;
}
@@ -857,7 +858,7 @@
* <p>This method is designed to be invoked by <em>other</em>
* tasks. To terminate the current task, you can just return or
* throw an unchecked exception from its computation method, or
- * invoke {@link #completeExceptionally}.
+ * invoke {@link #completeExceptionally(Throwable)}.
*
* @param mayInterruptIfRunning this value has no effect in the
* default implementation because interrupts are not used to
@@ -1007,8 +1008,9 @@
if (Thread.interrupted())
throw new InterruptedException();
// Messy in part because we measure in nanosecs, but wait in millisecs
- int s; long ns, ms;
- if ((s = status) >= 0 && (ns = unit.toNanos(timeout)) > 0L) {
+ int s; long ms;
+ long ns = unit.toNanos(timeout);
+ if ((s = status) >= 0 && ns > 0L) {
long deadline = System.nanoTime() + ns;
ForkJoinPool p = null;
ForkJoinPool.WorkQueue w = null;
@@ -1104,7 +1106,7 @@
wt.pool.helpQuiescePool(wt.workQueue);
}
else
- ForkJoinPool.externalHelpQuiescePool();
+ ForkJoinPool.quiesceCommonPool();
}
/**
@@ -1391,6 +1393,24 @@
}
/**
+ * Adaptor for Runnables in which failure forces worker exception
+ */
+ static final class RunnableExecuteAction extends ForkJoinTask<Void> {
+ final Runnable runnable;
+ RunnableExecuteAction(Runnable runnable) {
+ if (runnable == null) throw new NullPointerException();
+ this.runnable = runnable;
+ }
+ public final Void getRawResult() { return null; }
+ public final void setRawResult(Void v) { }
+ public final boolean exec() { runnable.run(); return true; }
+ void internalPropagateException(Throwable ex) {
+ rethrow(ex); // rethrow outside exec() catches.
+ }
+ private static final long serialVersionUID = 5232453952276885070L;
+ }
+
+ /**
* Adaptor for Callables
*/
static final class AdaptedCallable<T> extends ForkJoinTask<T>
--- a/jdk/src/share/classes/java/util/concurrent/ThreadLocalRandom.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/concurrent/ThreadLocalRandom.java Fri Mar 15 16:39:07 2013 -0700
@@ -83,22 +83,20 @@
* programs.
*
* Because this class is in a different package than class Thread,
- * field access methods must use Unsafe to bypass access control
- * rules. The base functionality of Random methods is
- * conveniently isolated in method next(bits), that just reads and
- * writes the Thread field rather than its own field. However, to
- * conform to the requirements of the Random constructor, during
- * construction, the common static ThreadLocalRandom must maintain
- * initialization and value fields, mainly for the sake of
- * disabling user calls to setSeed while still allowing a call
- * from constructor. For serialization compatibility, these
- * fields are left with the same declarations as used in the
- * previous ThreadLocal-based version of this class, that used
- * them differently. Note that serialization is completely
- * unnecessary because there is only a static singleton. But these
- * mechanics still ensure compatibility across versions.
+ * field access methods use Unsafe to bypass access control rules.
+ * The base functionality of Random methods is conveniently
+ * isolated in method next(bits), that just reads and writes the
+ * Thread field rather than its own field. However, to conform to
+ * the requirements of the Random superclass constructor, the
+ * common static ThreadLocalRandom maintains an "initialized"
+ * field for the sake of rejecting user calls to setSeed while
+ * still allowing a call from constructor. Note that
+ * serialization is completely unnecessary because there is only a
+ * static singleton. But we generate a serial form containing
+ * "rnd" and "initialized" fields to ensure compatibility across
+ * versions.
*
- * Per-instance initialization is similar to that in the no-arg
+ * Per-thread initialization is similar to that in the no-arg
* Random constructor, but we avoid correlation among not only
* initial seeds of those created in different threads, but also
* those created using class Random itself; while at the same time
@@ -132,10 +130,11 @@
private static final ThreadLocal<Double> nextLocalGaussian =
new ThreadLocal<Double>();
- /*
- * Field used only during singleton initialization
+ /**
+ * Field used only during singleton initialization.
+ * True when constructor completes.
*/
- boolean initialized; // true when constructor completes
+ boolean initialized;
/** Constructor used only for static singleton */
private ThreadLocalRandom() {
@@ -184,7 +183,8 @@
* @throws UnsupportedOperationException always
*/
public void setSeed(long seed) {
- if (initialized) // allow call from super() constructor
+ // only allow call from super() constructor
+ if (initialized)
throw new UnsupportedOperationException();
}
@@ -357,39 +357,29 @@
r ^= r >>> 17;
r ^= r << 5;
}
- else if ((r = (int)UNSAFE.getLong(t, SEED)) == 0)
- r = 1; // avoid zero
+ else {
+ localInit();
+ if ((r = (int)UNSAFE.getLong(t, SEED)) == 0)
+ r = 1; // avoid zero
+ }
UNSAFE.putInt(t, SECONDARY, r);
return r;
}
- // Serialization support, maintains original persistent form.
+ // Serialization support
private static final long serialVersionUID = -5851777807851030925L;
/**
* @serialField rnd long
+ * seed for random computations
* @serialField initialized boolean
- * @serialField pad0 long
- * @serialField pad1 long
- * @serialField pad2 long
- * @serialField pad3 long
- * @serialField pad4 long
- * @serialField pad5 long
- * @serialField pad6 long
- * @serialField pad7 long
+ * always true
*/
private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("rnd", long.class),
- new ObjectStreamField("initialized", boolean.class),
- new ObjectStreamField("pad0", long.class),
- new ObjectStreamField("pad1", long.class),
- new ObjectStreamField("pad2", long.class),
- new ObjectStreamField("pad3", long.class),
- new ObjectStreamField("pad4", long.class),
- new ObjectStreamField("pad5", long.class),
- new ObjectStreamField("pad6", long.class),
- new ObjectStreamField("pad7", long.class) };
+ new ObjectStreamField("initialized", boolean.class)
+ };
/**
* Saves the {@code ThreadLocalRandom} to a stream (that is, serializes it).
@@ -398,16 +388,8 @@
throws java.io.IOException {
java.io.ObjectOutputStream.PutField fields = out.putFields();
- fields.put("rnd", 0L);
+ fields.put("rnd", UNSAFE.getLong(Thread.currentThread(), SEED));
fields.put("initialized", true);
- fields.put("pad0", 0L);
- fields.put("pad1", 0L);
- fields.put("pad2", 0L);
- fields.put("pad3", 0L);
- fields.put("pad4", 0L);
- fields.put("pad5", 0L);
- fields.put("pad6", 0L);
- fields.put("pad7", 0L);
out.writeFields();
}
--- a/jdk/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java Fri Mar 15 16:39:07 2013 -0700
@@ -34,8 +34,10 @@
*/
package java.util.concurrent;
-import java.util.concurrent.locks.*;
-import java.util.concurrent.atomic.*;
+import java.util.concurrent.locks.AbstractQueuedSynchronizer;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.*;
/**
@@ -491,10 +493,15 @@
* policy limiting the number of threads. Even though it is not
* treated as an error, failure to create threads may result in
* new tasks being rejected or existing ones remaining stuck in
- * the queue. On the other hand, no special precautions exist to
- * handle OutOfMemoryErrors that might be thrown while trying to
- * create threads, since there is generally no recourse from
- * within this class.
+ * the queue.
+ *
+ * We go further and preserve pool invariants even in the face of
+ * errors such as OutOfMemoryError, that might be thrown while
+ * trying to create threads. Such errors are rather common due to
+ * the need to allocate a native stack in Thread#start, and users
+ * will want to perform clean pool shutdown to clean up. There
+ * will likely be enough memory available for the cleanup code to
+ * complete without encountering yet another OutOfMemoryError.
*/
private volatile ThreadFactory threadFactory;
@@ -568,9 +575,13 @@
* task execution. This protects against interrupts that are
* intended to wake up a worker thread waiting for a task from
* instead interrupting a task being run. We implement a simple
- * non-reentrant mutual exclusion lock rather than use ReentrantLock
- * because we do not want worker tasks to be able to reacquire the
- * lock when they invoke pool control methods like setCorePoolSize.
+ * non-reentrant mutual exclusion lock rather than use
+ * ReentrantLock because we do not want worker tasks to be able to
+ * reacquire the lock when they invoke pool control methods like
+ * setCorePoolSize. Additionally, to suppress interrupts until
+ * the thread actually starts running tasks, we initialize lock
+ * state to a negative value, and clear it upon start (in
+ * runWorker).
*/
private final class Worker
extends AbstractQueuedSynchronizer
@@ -594,6 +605,7 @@
* @param firstTask the first task (null if none)
*/
Worker(Runnable firstTask) {
+ setState(-1); // inhibit interrupts until runWorker
this.firstTask = firstTask;
this.thread = getThreadFactory().newThread(this);
}
@@ -609,7 +621,7 @@
// The value 1 represents the locked state.
protected boolean isHeldExclusively() {
- return getState() == 1;
+ return getState() != 0;
}
protected boolean tryAcquire(int unused) {
@@ -630,6 +642,16 @@
public boolean tryLock() { return tryAcquire(1); }
public void unlock() { release(1); }
public boolean isLocked() { return isHeldExclusively(); }
+
+ void interruptIfStarted() {
+ Thread t;
+ if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
+ try {
+ t.interrupt();
+ } catch (SecurityException ignore) {
+ }
+ }
+ }
}
/*
@@ -728,12 +750,8 @@
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
- for (Worker w : workers) {
- try {
- w.thread.interrupt();
- } catch (SecurityException ignore) {
- }
- }
+ for (Worker w : workers)
+ w.interruptIfStarted();
} finally {
mainLock.unlock();
}
@@ -790,19 +808,6 @@
private static final boolean ONLY_ONE = true;
- /**
- * Ensures that unless the pool is stopping, the current thread
- * does not have its interrupt set. This requires a double-check
- * of state in case the interrupt was cleared concurrently with a
- * shutdownNow -- if so, the interrupt is re-enabled.
- */
- private void clearInterruptsForTaskRun() {
- if (runStateLessThan(ctl.get(), STOP) &&
- Thread.interrupted() &&
- runStateAtLeast(ctl.get(), STOP))
- Thread.currentThread().interrupt();
- }
-
/*
* Misc utilities, most of which are also exported to
* ScheduledThreadPoolExecutor
@@ -862,12 +867,13 @@
* Checks if a new worker can be added with respect to current
* pool state and the given bound (either core or maximum). If so,
* the worker count is adjusted accordingly, and, if possible, a
- * new worker is created and started running firstTask as its
+ * new worker is created and started, running firstTask as its
* first task. This method returns false if the pool is stopped or
* eligible to shut down. It also returns false if the thread
- * factory fails to create a thread when asked, which requires a
- * backout of workerCount, and a recheck for termination, in case
- * the existence of this worker was holding up termination.
+ * factory fails to create a thread when asked. If the thread
+ * creation fails, either due to the thread factory returning
+ * null, or due to an exception (typically OutOfMemoryError in
+ * Thread#start), we roll back cleanly.
*
* @param firstTask the task the new thread should run first (or
* null if none). Workers are created with an initial first task
@@ -910,46 +916,65 @@
}
}
- Worker w = new Worker(firstTask);
- Thread t = w.thread;
+ boolean workerStarted = false;
+ boolean workerAdded = false;
+ Worker w = null;
+ try {
+ final ReentrantLock mainLock = this.mainLock;
+ w = new Worker(firstTask);
+ final Thread t = w.thread;
+ if (t != null) {
+ mainLock.lock();
+ try {
+ // Recheck while holding lock.
+ // Back out on ThreadFactory failure or if
+ // shut down before lock acquired.
+ int c = ctl.get();
+ int rs = runStateOf(c);
+ if (rs < SHUTDOWN ||
+ (rs == SHUTDOWN && firstTask == null)) {
+ if (t.isAlive()) // precheck that t is startable
+ throw new IllegalThreadStateException();
+ workers.add(w);
+ int s = workers.size();
+ if (s > largestPoolSize)
+ largestPoolSize = s;
+ workerAdded = true;
+ }
+ } finally {
+ mainLock.unlock();
+ }
+ if (workerAdded) {
+ t.start();
+ workerStarted = true;
+ }
+ }
+ } finally {
+ if (! workerStarted)
+ addWorkerFailed(w);
+ }
+ return workerStarted;
+ }
+
+ /**
+ * Rolls back the worker thread creation.
+ * - removes worker from workers, if present
+ * - decrements worker count
+ * - rechecks for termination, in case the existence of this
+ * worker was holding up termination
+ */
+ private void addWorkerFailed(Worker w) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
- // Recheck while holding lock.
- // Back out on ThreadFactory failure or if
- // shut down before lock acquired.
- int c = ctl.get();
- int rs = runStateOf(c);
-
- if (t == null ||
- (rs >= SHUTDOWN &&
- ! (rs == SHUTDOWN &&
- firstTask == null))) {
- decrementWorkerCount();
- tryTerminate();
- return false;
- }
-
- workers.add(w);
-
- int s = workers.size();
- if (s > largestPoolSize)
- largestPoolSize = s;
+ if (w != null)
+ workers.remove(w);
+ decrementWorkerCount();
+ tryTerminate();
} finally {
mainLock.unlock();
}
-
- t.start();
- // It is possible (but unlikely) for a thread to have been
- // added to workers, but not yet started, during transition to
- // STOP, which could result in a rare missed interrupt,
- // because Thread.interrupt is not guaranteed to have any effect
- // on a non-yet-started Thread (see Thread#interrupt).
- if (runStateOf(ctl.get()) == STOP && ! t.isInterrupted())
- t.interrupt();
-
- return true;
}
/**
@@ -1096,15 +1121,25 @@
* @param w the worker
*/
final void runWorker(Worker w) {
+ Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
+ w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
while (task != null || (task = getTask()) != null) {
w.lock();
- clearInterruptsForTaskRun();
+ // If pool is stopping, ensure thread is interrupted;
+ // if not, ensure thread is not interrupted. This
+ // requires a recheck in second case to deal with
+ // shutdownNow race while clearing interrupt
+ if ((runStateAtLeast(ctl.get(), STOP) ||
+ (Thread.interrupted() &&
+ runStateAtLeast(ctl.get(), STOP))) &&
+ !wt.isInterrupted())
+ wt.interrupt();
try {
- beforeExecute(w.thread, task);
+ beforeExecute(wt, task);
Throwable thrown = null;
try {
task.run();
@@ -2064,3 +2099,4 @@
}
}
}
+
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicInteger.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicInteger.java Fri Mar 15 16:39:07 2013 -0700
@@ -219,7 +219,7 @@
int prev, next;
do {
prev = get();
- next = updateFunction.operateAsInt(prev);
+ next = updateFunction.applyAsInt(prev);
} while (!compareAndSet(prev, next));
return prev;
}
@@ -238,7 +238,7 @@
int prev, next;
do {
prev = get();
- next = updateFunction.operateAsInt(prev);
+ next = updateFunction.applyAsInt(prev);
} while (!compareAndSet(prev, next));
return next;
}
@@ -262,7 +262,7 @@
int prev, next;
do {
prev = get();
- next = accumulatorFunction.operateAsInt(prev, x);
+ next = accumulatorFunction.applyAsInt(prev, x);
} while (!compareAndSet(prev, next));
return prev;
}
@@ -286,7 +286,7 @@
int prev, next;
do {
prev = get();
- next = accumulatorFunction.operateAsInt(prev, x);
+ next = accumulatorFunction.applyAsInt(prev, x);
} while (!compareAndSet(prev, next));
return next;
}
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java Fri Mar 15 16:39:07 2013 -0700
@@ -263,7 +263,7 @@
int prev, next;
do {
prev = getRaw(offset);
- next = updateFunction.operateAsInt(prev);
+ next = updateFunction.applyAsInt(prev);
} while (!compareAndSetRaw(offset, prev, next));
return prev;
}
@@ -284,7 +284,7 @@
int prev, next;
do {
prev = getRaw(offset);
- next = updateFunction.operateAsInt(prev);
+ next = updateFunction.applyAsInt(prev);
} while (!compareAndSetRaw(offset, prev, next));
return next;
}
@@ -310,7 +310,7 @@
int prev, next;
do {
prev = getRaw(offset);
- next = accumulatorFunction.operateAsInt(prev, x);
+ next = accumulatorFunction.applyAsInt(prev, x);
} while (!compareAndSetRaw(offset, prev, next));
return prev;
}
@@ -336,7 +336,7 @@
int prev, next;
do {
prev = getRaw(offset);
- next = accumulatorFunction.operateAsInt(prev, x);
+ next = accumulatorFunction.applyAsInt(prev, x);
} while (!compareAndSetRaw(offset, prev, next));
return next;
}
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java Fri Mar 15 16:39:07 2013 -0700
@@ -281,7 +281,7 @@
int prev, next;
do {
prev = get(obj);
- next = updateFunction.operateAsInt(prev);
+ next = updateFunction.applyAsInt(prev);
} while (!compareAndSet(obj, prev, next));
return prev;
}
@@ -301,7 +301,7 @@
int prev, next;
do {
prev = get(obj);
- next = updateFunction.operateAsInt(prev);
+ next = updateFunction.applyAsInt(prev);
} while (!compareAndSet(obj, prev, next));
return next;
}
@@ -326,7 +326,7 @@
int prev, next;
do {
prev = get(obj);
- next = accumulatorFunction.operateAsInt(prev, x);
+ next = accumulatorFunction.applyAsInt(prev, x);
} while (!compareAndSet(obj, prev, next));
return prev;
}
@@ -351,7 +351,7 @@
int prev, next;
do {
prev = get(obj);
- next = accumulatorFunction.operateAsInt(prev, x);
+ next = accumulatorFunction.applyAsInt(prev, x);
} while (!compareAndSet(obj, prev, next));
return next;
}
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLong.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLong.java Fri Mar 15 16:39:07 2013 -0700
@@ -233,7 +233,7 @@
long prev, next;
do {
prev = get();
- next = updateFunction.operateAsLong(prev);
+ next = updateFunction.applyAsLong(prev);
} while (!compareAndSet(prev, next));
return prev;
}
@@ -252,7 +252,7 @@
long prev, next;
do {
prev = get();
- next = updateFunction.operateAsLong(prev);
+ next = updateFunction.applyAsLong(prev);
} while (!compareAndSet(prev, next));
return next;
}
@@ -276,7 +276,7 @@
long prev, next;
do {
prev = get();
- next = accumulatorFunction.operateAsLong(prev, x);
+ next = accumulatorFunction.applyAsLong(prev, x);
} while (!compareAndSet(prev, next));
return prev;
}
@@ -300,7 +300,7 @@
long prev, next;
do {
prev = get();
- next = accumulatorFunction.operateAsLong(prev, x);
+ next = accumulatorFunction.applyAsLong(prev, x);
} while (!compareAndSet(prev, next));
return next;
}
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLongArray.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLongArray.java Fri Mar 15 16:39:07 2013 -0700
@@ -262,7 +262,7 @@
long prev, next;
do {
prev = getRaw(offset);
- next = updateFunction.operateAsLong(prev);
+ next = updateFunction.applyAsLong(prev);
} while (!compareAndSetRaw(offset, prev, next));
return prev;
}
@@ -283,7 +283,7 @@
long prev, next;
do {
prev = getRaw(offset);
- next = updateFunction.operateAsLong(prev);
+ next = updateFunction.applyAsLong(prev);
} while (!compareAndSetRaw(offset, prev, next));
return next;
}
@@ -309,7 +309,7 @@
long prev, next;
do {
prev = getRaw(offset);
- next = accumulatorFunction.operateAsLong(prev, x);
+ next = accumulatorFunction.applyAsLong(prev, x);
} while (!compareAndSetRaw(offset, prev, next));
return prev;
}
@@ -335,7 +335,7 @@
long prev, next;
do {
prev = getRaw(offset);
- next = accumulatorFunction.operateAsLong(prev, x);
+ next = accumulatorFunction.applyAsLong(prev, x);
} while (!compareAndSetRaw(offset, prev, next));
return next;
}
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java Fri Mar 15 16:39:07 2013 -0700
@@ -284,7 +284,7 @@
long prev, next;
do {
prev = get(obj);
- next = updateFunction.operateAsLong(prev);
+ next = updateFunction.applyAsLong(prev);
} while (!compareAndSet(obj, prev, next));
return prev;
}
@@ -304,7 +304,7 @@
long prev, next;
do {
prev = get(obj);
- next = updateFunction.operateAsLong(prev);
+ next = updateFunction.applyAsLong(prev);
} while (!compareAndSet(obj, prev, next));
return next;
}
@@ -329,7 +329,7 @@
long prev, next;
do {
prev = get(obj);
- next = accumulatorFunction.operateAsLong(prev, x);
+ next = accumulatorFunction.applyAsLong(prev, x);
} while (!compareAndSet(obj, prev, next));
return prev;
}
@@ -354,7 +354,7 @@
long prev, next;
do {
prev = get(obj);
- next = accumulatorFunction.operateAsLong(prev, x);
+ next = accumulatorFunction.applyAsLong(prev, x);
} while (!compareAndSet(obj, prev, next));
return next;
}
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicReference.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicReference.java Fri Mar 15 16:39:07 2013 -0700
@@ -157,7 +157,7 @@
V prev, next;
do {
prev = get();
- next = updateFunction.operate(prev);
+ next = updateFunction.apply(prev);
} while (!compareAndSet(prev, next));
return prev;
}
@@ -176,7 +176,7 @@
V prev, next;
do {
prev = get();
- next = updateFunction.operate(prev);
+ next = updateFunction.apply(prev);
} while (!compareAndSet(prev, next));
return next;
}
@@ -200,7 +200,7 @@
V prev, next;
do {
prev = get();
- next = accumulatorFunction.operate(prev, x);
+ next = accumulatorFunction.apply(prev, x);
} while (!compareAndSet(prev, next));
return prev;
}
@@ -224,7 +224,7 @@
V prev, next;
do {
prev = get();
- next = accumulatorFunction.operate(prev, x);
+ next = accumulatorFunction.apply(prev, x);
} while (!compareAndSet(prev, next));
return next;
}
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java Fri Mar 15 16:39:07 2013 -0700
@@ -217,7 +217,7 @@
E prev, next;
do {
prev = getRaw(offset);
- next = updateFunction.operate(prev);
+ next = updateFunction.apply(prev);
} while (!compareAndSetRaw(offset, prev, next));
return prev;
}
@@ -238,7 +238,7 @@
E prev, next;
do {
prev = getRaw(offset);
- next = updateFunction.operate(prev);
+ next = updateFunction.apply(prev);
} while (!compareAndSetRaw(offset, prev, next));
return next;
}
@@ -264,7 +264,7 @@
E prev, next;
do {
prev = getRaw(offset);
- next = accumulatorFunction.operate(prev, x);
+ next = accumulatorFunction.apply(prev, x);
} while (!compareAndSetRaw(offset, prev, next));
return prev;
}
@@ -290,7 +290,7 @@
E prev, next;
do {
prev = getRaw(offset);
- next = accumulatorFunction.operate(prev, x);
+ next = accumulatorFunction.apply(prev, x);
} while (!compareAndSetRaw(offset, prev, next));
return next;
}
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java Fri Mar 15 16:39:07 2013 -0700
@@ -200,7 +200,7 @@
V prev, next;
do {
prev = get(obj);
- next = updateFunction.operate(prev);
+ next = updateFunction.apply(prev);
} while (!compareAndSet(obj, prev, next));
return prev;
}
@@ -220,7 +220,7 @@
V prev, next;
do {
prev = get(obj);
- next = updateFunction.operate(prev);
+ next = updateFunction.apply(prev);
} while (!compareAndSet(obj, prev, next));
return next;
}
@@ -245,7 +245,7 @@
V prev, next;
do {
prev = get(obj);
- next = accumulatorFunction.operate(prev, x);
+ next = accumulatorFunction.apply(prev, x);
} while (!compareAndSet(obj, prev, next));
return prev;
}
@@ -270,7 +270,7 @@
V prev, next;
do {
prev = get(obj);
- next = accumulatorFunction.operate(prev, x);
+ next = accumulatorFunction.apply(prev, x);
} while (!compareAndSet(obj, prev, next));
return next;
}
--- a/jdk/src/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java Fri Mar 15 16:39:07 2013 -0700
@@ -100,14 +100,14 @@
Cell[] as; long b, v, r; int m; Cell a;
if ((as = cells) != null ||
(r = Double.doubleToRawLongBits
- (function.operateAsDouble
+ (function.applyAsDouble
(Double.longBitsToDouble(b = base), x))) != b && !casBase(b, r)) {
boolean uncontended = true;
if (as == null || (m = as.length - 1) < 0 ||
(a = as[getProbe() & m]) == null ||
!(uncontended =
(r = Double.doubleToRawLongBits
- (function.operateAsDouble
+ (function.applyAsDouble
(Double.longBitsToDouble(v = a.value), x))) == v ||
a.cas(v, r)))
doubleAccumulate(x, function, uncontended);
@@ -129,7 +129,7 @@
if (as != null) {
for (int i = 0; i < as.length; ++i) {
if ((a = as[i]) != null)
- result = function.operateAsDouble
+ result = function.applyAsDouble
(result, Double.longBitsToDouble(a.value));
}
}
@@ -174,7 +174,7 @@
if ((a = as[i]) != null) {
double v = Double.longBitsToDouble(a.value);
a.value = identity;
- result = function.operateAsDouble(result, v);
+ result = function.applyAsDouble(result, v);
}
}
}
--- a/jdk/src/share/classes/java/util/concurrent/atomic/LongAccumulator.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/LongAccumulator.java Fri Mar 15 16:39:07 2013 -0700
@@ -101,12 +101,12 @@
public void accumulate(long x) {
Cell[] as; long b, v, r; int m; Cell a;
if ((as = cells) != null ||
- (r = function.operateAsLong(b = base, x)) != b && !casBase(b, r)) {
+ (r = function.applyAsLong(b = base, x)) != b && !casBase(b, r)) {
boolean uncontended = true;
if (as == null || (m = as.length - 1) < 0 ||
(a = as[getProbe() & m]) == null ||
!(uncontended =
- (r = function.operateAsLong(v = a.value, x)) == v ||
+ (r = function.applyAsLong(v = a.value, x)) == v ||
a.cas(v, r)))
longAccumulate(x, function, uncontended);
}
@@ -127,7 +127,7 @@
if (as != null) {
for (int i = 0; i < as.length; ++i) {
if ((a = as[i]) != null)
- result = function.operateAsLong(result, a.value);
+ result = function.applyAsLong(result, a.value);
}
}
return result;
@@ -171,7 +171,7 @@
if ((a = as[i]) != null) {
long v = a.value;
a.value = identity;
- result = function.operateAsLong(result, v);
+ result = function.applyAsLong(result, v);
}
}
}
--- a/jdk/src/share/classes/java/util/concurrent/atomic/Striped64.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/Striped64.java Fri Mar 15 16:39:07 2013 -0700
@@ -253,7 +253,7 @@
else if (!wasUncontended) // CAS already known to fail
wasUncontended = true; // Continue after rehash
else if (a.cas(v = a.value, ((fn == null) ? v + x :
- fn.operateAsLong(v, x))))
+ fn.applyAsLong(v, x))))
break;
else if (n >= NCPU || cells != as)
collide = false; // At max size or stale
@@ -291,7 +291,7 @@
break;
}
else if (casBase(v = base, ((fn == null) ? v + x :
- fn.operateAsLong(v, x))))
+ fn.applyAsLong(v, x))))
break; // Fall back on using base
}
}
@@ -344,7 +344,7 @@
Double.doubleToRawLongBits
(Double.longBitsToDouble(v) + x) :
Double.doubleToRawLongBits
- (fn.operateAsDouble
+ (fn.applyAsDouble
(Double.longBitsToDouble(v), x)))))
break;
else if (n >= NCPU || cells != as)
@@ -387,7 +387,7 @@
Double.doubleToRawLongBits
(Double.longBitsToDouble(v) + x) :
Double.doubleToRawLongBits
- (fn.operateAsDouble
+ (fn.applyAsDouble
(Double.longBitsToDouble(v), x)))))
break; // Fall back on using base
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/util/function/BiConsumer.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.function;
+
+/**
+ * An operation which accepts two input arguments and returns no result. This is
+ * the two-arity specialization of {@link Consumer}. Unlike most other
+ * functional interfaces, {@code BiConsumer} is expected to operate via
+ * side-effects.
+ *
+ * @param <T> the type of the first argument to the {@code accept} operation.
+ * @param <U> the type of the second argument to the {@code accept} operation.
+ *
+ * @see Consumer
+ * @since 1.8
+ */
+@FunctionalInterface
+public interface BiConsumer<T, U> {
+
+ /**
+ * Performs operations upon the provided objects which may modify those
+ * objects and/or external state.
+ *
+ * @param t an input object
+ * @param u an input object
+ */
+ void accept(T t, U u);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/util/function/BiFunction.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.function;
+
+/**
+ * Apply a function to the input arguments, yielding an appropriate result. This
+ * is the two-arity specialization of {@link Function}. A function may
+ * variously provide a mapping between types, object instances or keys and
+ * values or any other form of transformation upon the input.
+ *
+ * @param <T> the type of the first argument to the {@code apply} operation.
+ * @param <U> the type of the second argument to the {@code apply} operation.
+ * @param <R> the type of results returned by the {@code apply} operation.
+ *
+ * @see Function
+ * @since 1.8
+ */
+@FunctionalInterface
+public interface BiFunction<T, U, R> {
+
+ /**
+ * Compute the result of applying the function to the input arguments
+ *
+ * @param t an input object
+ * @param u an input object
+ * @return the function result
+ */
+ R apply(T t, U u);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/util/function/BiPredicate.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.function;
+
+import java.util.Objects;
+
+/**
+ * Determines if the input objects match some criteria. This is the two-arity
+ * specialization of {@link Predicate}.
+ *
+ * @param <T> the type of the first argument to {@code test}.
+ * @param <U> the type of the second argument to {@code test}.
+ *
+ * @see Predicate
+ * @since 1.8
+ */
+@FunctionalInterface
+public interface BiPredicate<T, U> {
+
+ /**
+ * Return {@code true} if the inputs match some criteria.
+ *
+ * @param t an input object.
+ * @param u an input object.
+ * @return {@code true} if the inputs match some criteria.
+ */
+ boolean test(T t, U u);
+
+ /**
+ * Returns a predicate which evaluates to {@code true} only if this
+ * predicate and the provided predicate both evaluate to {@code true}. If
+ * this predicate returns {@code false} then the remaining predicate is not
+ * evaluated.
+ *
+ * @param p a predicate which will be logically-ANDed with this predicate.
+ * @return a new predicate which returns {@code true} only if both
+ * predicates return {@code true}.
+ */
+ public default BiPredicate<T, U> and(BiPredicate<? super T, ? super U> p) {
+ Objects.requireNonNull(p);
+ return (T t, U u) -> test(t, u) && p.test(t, u);
+ }
+
+ /**
+ * Returns a predicate which negates the result of this predicate.
+ *
+ * @return a new predicate who's result is always the opposite of this
+ * predicate.
+ */
+ public default BiPredicate<T, U> negate() {
+ return (T t, U u) -> !test(t, u);
+ }
+
+ /**
+ * Returns a predicate which evaluates to {@code true} if either this
+ * predicate or the provided predicate evaluates to {@code true}. If this
+ * predicate returns {@code true} then the remaining predicate is not
+ * evaluated.
+ *
+ * @param p a predicate which will be logically-ORed with this predicate.
+ * @return a new predicate which returns {@code true} if either predicate
+ * returns {@code true}.
+ */
+ public default BiPredicate<T, U> or(BiPredicate<? super T, ? super U> p) {
+ Objects.requireNonNull(p);
+ return (T t, U u) -> test(t, u) || p.test(t, u);
+ }
+
+ /**
+ * Returns a predicate that evaluates to {@code true} if both or neither of
+ * the component predicates evaluate to {@code true}.
+ *
+ * @param p a predicate which will be logically-XORed with this predicate.
+ * @return a predicate that evaluates to {@code true} if both or neither of
+ * the component predicates evaluate to {@code true}.
+ */
+ public default BiPredicate<T, U> xor(BiPredicate<? super T, ? super U> p) {
+ Objects.requireNonNull(p);
+ return (T t, U u) -> test(t, u) ^ p.test(t, u);
+ }
+}
--- a/jdk/src/share/classes/java/util/function/BinaryOperator.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/function/BinaryOperator.java Fri Mar 15 16:39:07 2013 -0700
@@ -25,24 +25,14 @@
package java.util.function;
/**
- * An operation upon two operands yielding a result. The operands and the result
- * are all of the same type.
+ * An operation upon two operands yielding a result. This is a specialization of
+ * {@code BiFunction} where the operands and the result are all of the same type.
*
- * @param <T> the type of operands to {@code operate} and of the result
+ * @param <T> the type of operands to {@code apply} and of the result
*
+ * @see BiFunction
* @since 1.8
*/
@FunctionalInterface
-public interface BinaryOperator<T> {
-
- /**
- * Returns the result of the operation upon the operands.
- * The operands are named {@code left} and {@code right} for operations
- * where the order of operands matters.
- *
- * @param left the left operand
- * @param right the right operand
- * @return the result of the operation
- */
- public T operate(T left, T right);
+public interface BinaryOperator<T> extends BiFunction<T,T,T> {
}
--- a/jdk/src/share/classes/java/util/function/Block.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package java.util.function;
-
-/**
- * An operation upon an input object. The operation may modify that object or
- * external state (other objects).
- *
- * @param <T> The type of input objects to {@code accept}
- *
- * @since 1.8
- */
-@FunctionalInterface
-public interface Block<T> {
-
- /**
- * Use the input object in operations which may modify that object or
- * external state (other objects).
- *
- * @param t the input object
- */
- public void accept(T t);
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/util/function/BooleanSupplier.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.function;
+
+
+/**
+ * A supplier of {@code boolean} values. This is the {@code boolean}-providing
+ * primitive specialization of {@link Supplier}.
+ *
+ * @see Supplier
+ * @since 1.8
+ */
+@FunctionalInterface
+public interface BooleanSupplier {
+
+ /**
+ * Returns a {@code boolean} value.
+ *
+ * @return a {@code boolean} value
+ */
+ public boolean getAsBoolean();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/util/function/Consumer.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.function;
+
+/**
+ * An operation which accepts a single input argument and returns no result.
+ * Unlike most other functional interfaces, {@code Consumer} is expected to
+ * operate via side-effects.
+ *
+ * @param <T> The type of input objects to {@code accept}
+ *
+ * @since 1.8
+ */
+@FunctionalInterface
+public interface Consumer<T> {
+
+ /**
+ * Accept an input value.
+ *
+ * @param t the input object
+ */
+ public void accept(T t);
+}
--- a/jdk/src/share/classes/java/util/function/DoubleBinaryOperator.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/function/DoubleBinaryOperator.java Fri Mar 15 16:39:07 2013 -0700
@@ -26,23 +26,22 @@
/**
* An operation on two {@code double} operands yielding a {@code double} result.
+ * This is the primitive type specialization of {@link BinaryOperator} for
+ * {@code double}.
*
+ * @see BinaryOperator
* @since 1.8
*/
@FunctionalInterface
-public interface DoubleBinaryOperator /* extends BinaryOperator<Double> */ {
-//
-// @Override
-// public default Double operate(Double left, Double right) { return operateAsDouble((double) left, (double) right); }
-
+public interface DoubleBinaryOperator {
/**
* Returns the {@code double} result of the operation upon the
* {@code double} operands. The parameters are named {@code left} and
* {@code right} for operations where the order of parameters matters.
*
* @param left the left operand value
- * @param right the right operand value
+ * @param right the right operand value
* @return the result of the operation
*/
- public double operateAsDouble(double left, double right);
+ public double applyAsDouble(double left, double right);
}
--- a/jdk/src/share/classes/java/util/function/DoubleBlock.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package java.util.function;
-
-/**
- * An operation upon a {@code double} input value. The operation may modify
- * external state.
- *
- * <p/>This is the primitive type specialization of {@link Block} for
- * {@code double} and also may be used as a {@code Block<Double>}.
- *
- * @since 1.8
- */
-@FunctionalInterface
-public interface DoubleBlock {
-
- /**
- * Use the {@code double} input value in an operation which may modify
- * external state.
- *
- * @param t the input value
- */
- public void accept(double t);
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/util/function/DoubleConsumer.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.function;
+
+/**
+ * An operation which accepts a single double argument and returns no result.
+ * This is the primitive type specialization of {@link Consumer} for
+ * {@code double}. Unlike most other functional interfaces,
+ * {@code DoubleConsumer} is expected to operate via side-effects.
+ *
+ * @see Consumer
+ * @since 1.8
+ */
+@FunctionalInterface
+public interface DoubleConsumer {
+
+ /**
+ * Accept an input value.
+ *
+ * @param value the input value
+ */
+ public void accept(double value);
+}
--- a/jdk/src/share/classes/java/util/function/DoubleFunction.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/function/DoubleFunction.java Fri Mar 15 16:39:07 2013 -0700
@@ -25,22 +25,23 @@
package java.util.function;
/**
- * Apply a function to the input object yielding an appropriate {@code double}
- * value; this is the {@code double}-bearing specialization for {@link Function}.
+ * Apply a function to the double-valued input argument, yielding an appropriate
+ * result. This is the {@code double}-consuming primitive specialization for
+ * {@link Function}.
*
- * @param <T> the type of input objects to the function
+ * @param <R> the type of output objects from the function
*
+ * @see Function
* @since 1.8
*/
@FunctionalInterface
-public interface DoubleFunction<T> {
+public interface DoubleFunction<R> {
/**
- * Apply a function to the input object yielding an appropriate
- * {@code double} value.
+ * Compute the result of applying the function to the input argument
*
- * @param t the input object
- * @return the function result value
+ * @param value the input value
+ * @return the function result
*/
- public double applyAsDouble(T t);
+ public R apply(double value);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/util/function/DoublePredicate.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2010, 2013 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.function;
+
+import java.util.Objects;
+
+/**
+ * Determines if the {@code double} input value matches some criteria. This is
+ * the {@code double}-consuming primitive type specialization of
+ * {@link Predicate}.
+ *
+ * @see Predicate
+ * @since 1.8
+ */
+@FunctionalInterface
+public interface DoublePredicate {
+
+ /**
+ * Returns {@code true} if the input value matches some criteria.
+ *
+ * @param value the value to be tested.
+ * @return {@code true} if the input value matches some criteria, otherwise
+ * {@code false}.
+ */
+ public boolean test(double value);
+
+ /**
+ * Returns a predicate which evaluates to {@code true} only if this
+ * predicate and the provided predicate both evaluate to {@code true}. If
+ * this predicate returns {@code false} then the remaining predicate is not
+ * evaluated.
+ *
+ * @param p a predicate which will be logically-ANDed with this predicate.
+ * @return a new predicate which returns {@code true} only if both
+ * predicates return {@code true}.
+ */
+ public default DoublePredicate and(DoublePredicate p) {
+ Objects.requireNonNull(p);
+ return (value) -> test(value) && p.test(value);
+ }
+
+ /**
+ * Returns a predicate which negates the result of this predicate.
+ *
+ * @return a new predicate who's result is always the opposite of this
+ * predicate.
+ */
+ public default DoublePredicate negate() {
+ return (value) -> !test(value);
+ }
+
+ /**
+ * Returns a predicate which evaluates to {@code true} if either this
+ * predicate or the provided predicate evaluates to {@code true}. If this
+ * predicate returns {@code true} then the remaining predicate is not
+ * evaluated.
+ *
+ * @param p a predicate which will be logically-ANDed with this predicate.
+ * @return a new predicate which returns {@code true} if either predicate
+ * returns {@code true}.
+ */
+ public default DoublePredicate or(DoublePredicate p) {
+ Objects.requireNonNull(p);
+ return (value) -> test(value) || p.test(value);
+ }
+
+ /**
+ * Returns a predicate that evaluates to {@code true} if both or neither of
+ * the component predicates evaluate to {@code true}.
+ *
+ * @param p a predicate which will be logically-XORed with this predicate.
+ * @return a predicate that evaluates to {@code true} if all or none of the
+ * component predicates evaluate to {@code true}.
+ */
+ public default DoublePredicate xor(DoublePredicate p) {
+ Objects.requireNonNull(p);
+ return (value) -> test(value) ^ p.test(value);
+ }
+}
--- a/jdk/src/share/classes/java/util/function/DoubleSupplier.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/function/DoubleSupplier.java Fri Mar 15 16:39:07 2013 -0700
@@ -25,11 +25,10 @@
package java.util.function;
/**
- * A supplier of {@code double} values.
+ * A supplier of {@code double} values. This is the {@code double}-providing
+ * primitive specialization of {@link Supplier}.
*
- * <p/>This is the primitive type specialization of {@link Supplier} for
- * {@code double} and also may be used as a {@code Supplier<Double>}.
- *
+ * @see Supplier
* @since 1.8
*/
@FunctionalInterface
--- a/jdk/src/share/classes/java/util/function/DoubleUnaryOperator.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/function/DoubleUnaryOperator.java Fri Mar 15 16:39:07 2013 -0700
@@ -25,9 +25,11 @@
package java.util.function;
/**
- * An operation on a single {@code double} operand yielding a {@code double}
- * result.
+ * An operation on a {@code double} operand yielding a {@code double}
+ * result. This is the primitive type specialization of {@link UnaryOperator}
+ * for {@code double}.
*
+ * @see UnaryOperator
* @since 1.8
*/
@FunctionalInterface
@@ -40,5 +42,5 @@
* @param operand the operand value
* @return the operation result value
*/
- public double operateAsDouble(double operand);
+ public double applyAsDouble(double operand);
}
--- a/jdk/src/share/classes/java/util/function/Function.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/function/Function.java Fri Mar 15 16:39:07 2013 -0700
@@ -24,14 +24,14 @@
*/
package java.util.function;
+
/**
- * Apply a function to the input object yielding an appropriate result object. A
+ * Apply a function to the input argument, yielding an appropriate result. A
* function may variously provide a mapping between types, object instances or
* keys and values or any other form of transformation upon the input.
*
- * @param <T> the type of input objects to the {@code apply} operation
- * @param <R> the type of result objects from the {@code apply} operation. May
- * be the same type as {@code <T>}.
+ * @param <T> the type of the input to the {@code apply} operation.
+ * @param <R> the type of the result of the {@code apply} operation.
*
* @since 1.8
*/
@@ -39,7 +39,7 @@
public interface Function<T, R> {
/**
- * Yield an appropriate result object for the input object.
+ * Compute the result of applying the function to the input argument
*
* @param t the input object
* @return the function result
--- a/jdk/src/share/classes/java/util/function/IntBinaryOperator.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/function/IntBinaryOperator.java Fri Mar 15 16:39:07 2013 -0700
@@ -26,7 +26,10 @@
/**
* An operation on two {@code int} operands yielding an {@code int} result.
+ * This is the primitive type specialization of {@link BinaryOperator} for
+ * {@code int}.
*
+ * @see BinaryOperator
* @since 1.8
*/
@FunctionalInterface
@@ -41,5 +44,5 @@
* @param right the right operand value
* @return the result of the operation
*/
- public int operateAsInt(int left, int right);
+ public int applyAsInt(int left, int right);
}
--- a/jdk/src/share/classes/java/util/function/IntBlock.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package java.util.function;
-
-/**
- * An operation upon an {@code int} input value. The operation may modify
- * external state.
- *
- * <p/>This is the primitive type specialization of {@link Block} for
- * {@code int} and also may be used as a {@code Block<Integer>}.
- *
- * @since 1.8
- */
-@FunctionalInterface
-public interface IntBlock {
-
- /**
- * Use the {@code int} input value in an operation which may modify external
- * state.
- *
- * @param t the input value
- */
- public void accept(int t);
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/util/function/IntConsumer.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.function;
+
+/**
+ * An operation which accepts a single integer argument and returns no result.
+ * This is the primitive type specialization of {@link Consumer} for {@code int}.
+ * Unlike most other functional interfaces, {@code IntConsumer} is expected to
+ * operate via side-effects.
+ *
+ * @see Consumer
+ * @since 1.8
+ */
+@FunctionalInterface
+public interface IntConsumer {
+
+ /**
+ * Accept an input value.
+ *
+ * @param value the input value
+ */
+ public void accept(int value);
+}
--- a/jdk/src/share/classes/java/util/function/IntFunction.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/function/IntFunction.java Fri Mar 15 16:39:07 2013 -0700
@@ -25,22 +25,23 @@
package java.util.function;
/**
- * Apply a function to the input object yielding an appropriate {@code int}
- * value; this is the {@code int}-bearing specialization for {@link Function}.
+ * Apply a function to the integer-valued input argument, yielding an
+ * appropriate result. This is the {@code int}-consuming primitive
+ * specialization for {@link Function}.
*
- * @param <T> the type of input objects to the function
+ * @param <R> the type of output objects from the function
*
+ * @see Function
* @since 1.8
*/
@FunctionalInterface
-public interface IntFunction<T> {
+public interface IntFunction<R> {
/**
- * Apply a function to the input object yielding an appropriate {@code int}
- * value.
+ * Compute the result of applying the function to the input argument
*
- * @param t the input object
- * @return the function result value
+ * @param value the input value
+ * @return the function result
*/
- public int applyAsInt(T t);
+ public R apply(int value);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/util/function/IntPredicate.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2010, 2013 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.function;
+
+import java.util.Objects;
+
+/**
+ * Determines if the {@code int} input value matches some criteria. This is the
+ * {@code int}-consuming primitive type specialization of {@link Predicate}.
+ *
+ * @see Predicate
+ * @since 1.8
+ */
+@FunctionalInterface
+public interface IntPredicate {
+
+ /**
+ * Returns {@code true} if the input value matches some criteria.
+ *
+ * @param value the value to be tested.
+ * @return {@code true} if the input value matches some criteria, otherwise
+ * {@code false}
+ */
+ public boolean test(int value);
+
+ /**
+ * Returns a predicate which evaluates to {@code true} only if this
+ * predicate and the provided predicate both evaluate to {@code true}. If
+ * this predicate returns {@code false} then the remaining predicate is not
+ * evaluated.
+ *
+ * @param p a predicate which will be logically-ANDed with this predicate.
+ * @return a new predicate which returns {@code true} only if both
+ * predicates return {@code true}.
+ */
+ public default IntPredicate and(IntPredicate p) {
+ Objects.requireNonNull(p);
+ return (value) -> test(value) && p.test(value);
+ }
+
+ /**
+ * Returns a predicate which negates the result of this predicate.
+ *
+ * @return a new predicate who's result is always the opposite of this
+ * predicate.
+ */
+ public default IntPredicate negate() {
+ return (value) -> !test(value);
+ }
+
+ /**
+ * Returns a predicate which evaluates to {@code true} if either this
+ * predicate or the provided predicate evaluates to {@code true}. If this
+ * predicate returns {@code true} then the remaining predicate is not
+ * evaluated.
+ *
+ * @param p a predicate which will be logically-ORed with this predicate.
+ * @return a new predicate which returns {@code true} if either predicate
+ * returns {@code true}.
+ */
+ public default IntPredicate or(IntPredicate p) {
+ Objects.requireNonNull(p);
+ return (value) -> test(value) || p.test(value);
+ }
+
+ /**
+ * Returns a predicate that evaluates to {@code true} if both or neither of
+ * the component predicates evaluate to {@code true}.
+ *
+ * @param p a predicate which will be logically-XORed with this predicate.
+ * @return a predicate that evaluates to {@code true} if both or neither of
+ * the component predicates evaluate to {@code true}
+ */
+ public default IntPredicate xor(IntPredicate p) {
+ Objects.requireNonNull(p);
+ return (value) -> test(value) ^ p.test(value);
+ }
+}
--- a/jdk/src/share/classes/java/util/function/IntSupplier.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/function/IntSupplier.java Fri Mar 15 16:39:07 2013 -0700
@@ -25,11 +25,10 @@
package java.util.function;
/**
- * A supplier of {@code int} values.
+ * A supplier of {@code int} values. This is the {@code int}-providing
+ * primitive specialization of {@link Supplier}.
*
- * <p/>This is the primitive type specialization of {@link Supplier} for
- * {@code int} and also may be used as a {@code Supplier<Integer>}.
- *
+ * @see Supplier
* @since 1.8
*/
@FunctionalInterface
--- a/jdk/src/share/classes/java/util/function/IntUnaryOperator.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/function/IntUnaryOperator.java Fri Mar 15 16:39:07 2013 -0700
@@ -26,18 +26,21 @@
/**
* An operation on a single {@code int} operand yielding an {@code int} result.
+ * This is the primitive type specialization of {@link UnaryOperator} for
+ * {@code int}.
*
+ * @see UnaryOperator
* @since 1.8
*/
@FunctionalInterface
public interface IntUnaryOperator {
/**
- * Returns the {@code int} result of the operation upon the {@code int}
- * operand.
+ * Returns the {@code int} value result of the operation upon the
+ * {@code int} operand.
*
* @param operand the operand value
* @return the operation result value
*/
- public int operateAsInt(int operand);
+ public int applyAsInt(int operand);
}
--- a/jdk/src/share/classes/java/util/function/LongBinaryOperator.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/function/LongBinaryOperator.java Fri Mar 15 16:39:07 2013 -0700
@@ -26,7 +26,10 @@
/**
* An operation on two {@code long} operands yielding a {@code long} result.
+ * This is the primitive type specialization of {@link BinaryOperator} for
+ * {@code long}.
*
+ * @see BinaryOperator
* @since 1.8
*/
@FunctionalInterface
@@ -41,5 +44,5 @@
* @param right the right operand value
* @return the result of the operation
*/
- public long operateAsLong(long left, long right);
+ public long applyAsLong(long left, long right);
}
--- a/jdk/src/share/classes/java/util/function/LongBlock.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package java.util.function;
-
-/**
- * An operation upon a {@code long} input value. The operation may modify
- * external state.
- *
- * <p/>This is the primitive type specialization of {@link Block} for
- * {@code long} and also may be used as a {@code Block<Long>}.
- *
- * @since 1.8
- */
-@FunctionalInterface
-public interface LongBlock {
-
- /**
- * Use the {@code long} input value in an operation which may modify
- * external state.
- *
- * @param t the input value
- */
- public void accept(long t);
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/util/function/LongConsumer.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.function;
+
+/**
+ * An operation which accepts a single long argument and returns no result.
+ * This is the {@code long}-consuming primitive type specialization of
+ * {@link Consumer}. Unlike most other functional interfaces, {@code LongConsumer}
+ * is expected to operate via side-effects.
+ *
+ * @see Consumer
+ * @since 1.8
+ */
+@FunctionalInterface
+public interface LongConsumer {
+
+ /**
+ * Accept an input value.
+ *
+ * @param value the input value
+ */
+ public void accept(long value);
+}
--- a/jdk/src/share/classes/java/util/function/LongFunction.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/function/LongFunction.java Fri Mar 15 16:39:07 2013 -0700
@@ -25,22 +25,23 @@
package java.util.function;
/**
- * Apply a function to the input object yielding an appropriate {@code long}
- * value; this is the {@code long}-bearing specialization for {@link Function}.
+ * Apply a function to the long-valued input argument, yielding an appropriate
+ * result. This is the {@code long}-consuming primitive specialization for
+ * {@link Function}.
*
- * @param <T> the type of input objects to the function
+ * @param <R> the type of output objects from the function
*
+ * @see Function
* @since 1.8
*/
@FunctionalInterface
-public interface LongFunction<T> {
+public interface LongFunction<R> {
/**
- * Apply a function to the input object yielding an appropriate {@code long}
- * value.
+ * Compute the result of applying the function to the input argument
*
- * @param t the input object
- * @return the function result value
+ * @param value the input value
+ * @return the function result
*/
- public long applyAsLong(T t);
+ public R apply(long value);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/util/function/LongPredicate.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2010, 2013 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.function;
+
+import java.util.Objects;
+
+/**
+ * Determines if the {@code long} input value matches some criteria. This is the
+ * {@code long}-consuming primitive type specialization of {@link Predicate}.
+ *
+ * @see Predicate
+ * @since 1.8
+ */
+@FunctionalInterface
+public interface LongPredicate {
+
+ /**
+ * Returns {@code true} if the input value matches some criteria.
+ *
+ * @param value the value to be tested.
+ * @return {@code true} if the input value matches some criteria, otherwise
+ * {@code false}.
+ */
+ public boolean test(long value);
+
+ /**
+ * Returns a predicate which evaluates to {@code true} only if this
+ * predicate and the provided predicate both evaluate to {@code true}. If
+ * this predicate returns {@code false} then the remaining predicate is not
+ * evaluated.
+ *
+ * @param p a predicate which will be logically-ANDed with this predicate.
+ * @return a new predicate which returns {@code true} only if both
+ * predicates return {@code true}.
+ */
+ public default LongPredicate and(LongPredicate p) {
+ Objects.requireNonNull(p);
+ return (value) -> test(value) && p.test(value);
+ }
+
+ /**
+ * Returns a predicate which negates the result of this predicate.
+ *
+ * @return a new predicate who's result is always the opposite of this
+ * predicate.
+ */
+ public default LongPredicate negate() {
+ return (value) -> !test(value);
+ }
+
+ /**
+ * Returns a predicate which evaluates to {@code true} if either this
+ * predicate or the provided predicate evaluates to {@code true}. If this
+ * predicate returns {@code true} then the remaining predicate is not
+ * evaluated.
+ *
+ * @param p a predicate which will be logically-ORed with this predicate.
+ * @return a new predicate which returns {@code true} if either predicate
+ * returns {@code true}.
+ */
+ public default LongPredicate or(LongPredicate p) {
+ Objects.requireNonNull(p);
+ return (value) -> test(value) || p.test(value);
+ }
+
+ /**
+ * Returns a predicate that evaluates to {@code true} if both or neither of
+ * the component predicates evaluate to {@code true}.
+ *
+ * @param p a predicate which will be logically-XORed with this predicate.
+ * @return a predicate that evaluates to {@code true} if both or neither of
+ * the component predicates evaluate to {@code true}.
+ */
+ public default LongPredicate xor(LongPredicate p) {
+ Objects.requireNonNull(p);
+ return (value) -> test(value) ^ p.test(value);
+ }
+}
--- a/jdk/src/share/classes/java/util/function/LongSupplier.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/function/LongSupplier.java Fri Mar 15 16:39:07 2013 -0700
@@ -25,11 +25,10 @@
package java.util.function;
/**
- * A supplier of {@code long} values.
+ * A supplier of {@code long} values. This is the {@code long}-providing
+ * primitive specialization of {@link Supplier}.
*
- * <p/>This is the primitive type specialization of {@link Supplier} for
- * {@code long} and also may be used as a {@code Supplier<Long>}.
- *
+ * @see Supplier
* @since 1.8
*/
@FunctionalInterface
@@ -38,7 +37,7 @@
/**
* Returns a {@code long} value.
*
- * @return a {@code long} value.
+ * @return a {@code long} value
*/
public long getAsLong();
}
--- a/jdk/src/share/classes/java/util/function/LongUnaryOperator.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/function/LongUnaryOperator.java Fri Mar 15 16:39:07 2013 -0700
@@ -26,7 +26,10 @@
/**
* An operation on a single {@code long} operand yielding a {@code long} result.
+ * This is the primitive type specialization of {@link UnaryOperator} for
+ * {@code long}.
*
+ * @see UnaryOperator
* @since 1.8
*/
@FunctionalInterface
@@ -39,5 +42,5 @@
* @param operand the operand value
* @return the operation result value
*/
- public long operateAsLong(long operand);
+ public long applyAsLong(long operand);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/util/function/ObjDoubleConsumer.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.function;
+
+/**
+ * An operation which accepts an object reference and a double, and returns no
+ * result. This is the {@code (reference, double)} specialization of
+ * {@link BiConsumer}. Unlike most other functional interfaces,
+ * {@code ObjDoubleConsumer} is expected to operate via side-effects.
+ *
+ * @param <T> Type of reference argument to {@code accept()}.
+ *
+ * @see BiConsumer
+ * @since 1.8
+ */
+@FunctionalInterface
+public interface ObjDoubleConsumer<T> {
+
+ /**
+ * Accept a set of input values.
+ *
+ * @param t an input object
+ * @param value an input value
+ */
+ public void accept(T t, double value);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/util/function/ObjIntConsumer.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.function;
+
+/**
+ * An operation which accepts an object reference and an int, and returns no
+ * result. This is the {@code (reference, int)} specialization of
+ * {@link BiConsumer}. Unlike most other functional interfaces,
+ * {@code ObjIntConsumer} is expected to operate via side-effects.
+ *
+ * @param <T> Type of reference argument to {@code accept()}.
+ *
+ * @see BiConsumer
+ * @since 1.8
+ */
+@FunctionalInterface
+public interface ObjIntConsumer<T> {
+
+ /**
+ * Accept a set of input values.
+ *
+ * @param t an input object
+ * @param value an input value
+ */
+ public void accept(T t, int value);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/util/function/ObjLongConsumer.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.function;
+
+/**
+ * An operation which accepts an object reference and a long, and returns no
+ * result. This is the {@code (reference, long)} specialization of
+ * {@link BiConsumer}. Unlike most other functional interfaces,
+ * {@code ObjLongConsumer} is expected to operate via side-effects.
+ *
+ * @param <T> Type of reference argument to {@code accept()}.
+ *
+ * @see BiConsumer
+ * @since 1.8
+ */
+@FunctionalInterface
+public interface ObjLongConsumer<T> {
+
+ /**
+ * Accept a set of input values.
+ *
+ * @param t an input object
+ * @param value an input value
+ */
+ public void accept(T t, long value);
+}
--- a/jdk/src/share/classes/java/util/function/Predicate.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/function/Predicate.java Fri Mar 15 16:39:07 2013 -0700
@@ -24,10 +24,12 @@
*/
package java.util.function;
+import java.util.Objects;
+
/**
* Determines if the input object matches some criteria.
*
- * @param <T> the type of input objects to {@code test}
+ * @param <T> the type of argument to {@code test}
*
* @since 1.8
*/
@@ -42,4 +44,57 @@
* {@code false}
*/
public boolean test(T t);
+
+ /**
+ * Returns a predicate which evaluates to {@code true} only if this
+ * predicate and the provided predicate both evaluate to {@code true}. If
+ * this predicate returns {@code false} then the remaining predicate is not
+ * evaluated.
+ *
+ * @param p a predicate which will be logically-ANDed with this predicate.
+ * @return a new predicate which returns {@code true} only if both
+ * predicates return {@code true}.
+ */
+ public default Predicate<T> and(Predicate<? super T> p) {
+ Objects.requireNonNull(p);
+ return (t) -> test(t) && p.test(t);
+ }
+
+ /**
+ * Returns a predicate which negates the result of this predicate.
+ *
+ * @return a new predicate who's result is always the opposite of this
+ * predicate.
+ */
+ public default Predicate<T> negate() {
+ return (t) -> !test(t);
+ }
+
+ /**
+ * Returns a predicate which evaluates to {@code true} if either this
+ * predicate or the provided predicate evaluates to {@code true}. If this
+ * predicate returns {@code true} then the remaining predicate is not
+ * evaluated.
+ *
+ * @param p a predicate which will be logically-ORed with this predicate.
+ * @return a new predicate which returns {@code true} if either predicate
+ * returns {@code true}.
+ */
+ public default Predicate<T> or(Predicate<? super T> p) {
+ Objects.requireNonNull(p);
+ return (t) -> test(t) || p.test(t);
+ }
+
+ /**
+ * Returns a predicate that evaluates to {@code true} if both or neither of
+ * the component predicates evaluate to {@code true}.
+ *
+ * @param p a predicate which will be logically-XORed with this predicte.
+ * @return a predicate that evaluates to {@code true} if both or neither of
+ * the component predicates evaluate to {@code true}.
+ */
+ public default Predicate<T> xor(Predicate<? super T> p) {
+ Objects.requireNonNull(p);
+ return (t) -> test(t) ^ p.test(t);
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/util/function/ToDoubleBiFunction.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.function;
+
+/**
+ * Apply a function to the input arguments, yielding an appropriate result.
+ * This is the {@code double}-bearing specialization for {@link BiFunction}.
+ *
+ * @param <T> the type of the first argument to the {@code applyAsDouble}
+ * operation.
+ * @param <U> the type of the second argument to the {@code applyAsDouble}
+ * operation.
+ *
+ * @see BiFunction
+ * @since 1.8
+ */
+@FunctionalInterface
+public interface ToDoubleBiFunction<T, U> {
+
+ /**
+ * Compute the result of applying the function to the input arguments
+ *
+ * @param t an input object
+ * @param u an input object
+ * @return the function result value
+ */
+ public double applyAsDouble(T t, U u);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/util/function/ToDoubleFunction.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.function;
+
+/**
+ * Apply a function to the input argument, yielding an appropriate result.
+ * This is the {@code double}-bearing specialization for {@link Function}.
+ *
+ * @param <T> the type of input objects to the function
+ *
+ * @see Function
+ * @since 1.8
+ */
+@FunctionalInterface
+public interface ToDoubleFunction<T> {
+
+ /**
+ * Compute the result of applying the function to the input argument
+ *
+ * @param t the input object
+ * @return the function result value
+ */
+ public double applyAsDouble(T t);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/util/function/ToIntBiFunction.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.function;
+
+/**
+ * Apply a function to the input arguments, yielding an appropriate result.
+ * This is the {@code int}-bearing specialization for {@link BiFunction}.
+ *
+ * @param <T> the type of the first argument to the {@code applyAsLong}
+ * operation.
+ * @param <U> the type of the second argument to the {@code applyAsLong}
+ * operation.
+ *
+ * @see BiFunction
+ * @since 1.8
+ */
+@FunctionalInterface
+public interface ToIntBiFunction<T, U> {
+
+ /**
+ * Compute the result of applying the function to the input arguments
+ *
+ * @param t an input object
+ * @param u an input object
+ * @return the function result value
+ */
+ public int applyAsInt(T t, U u);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/util/function/ToIntFunction.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.function;
+
+/**
+ * Apply a function to the input argument, yielding an appropriate result.
+ * This is the {@code int}-bearing specialization for {@link Function}.
+ *
+ * @param <T> the type of input objects to the function
+ *
+ * @see Function
+ * @since 1.8
+ */
+@FunctionalInterface
+public interface ToIntFunction<T> {
+
+ /**
+ * Compute the result of applying the function to the input arguments
+ *
+ * @param t the input object
+ * @return the function result value
+ */
+ public int applyAsInt(T t);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/util/function/ToLongBiFunction.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.function;
+
+/**
+ * Apply a function to the input arguments, yielding an appropriate result.
+ * This is the {@code long}-bearing specialization for {@link BiFunction}.
+ *
+ * @param <T> the type of the first argument to the {@code applyAsLong}
+ * operation.
+ * @param <U> the type of the second argument to the {@code applyAsLong}
+ * operation.
+ *
+ * @see BiFunction
+ * @since 1.8
+ */
+@FunctionalInterface
+public interface ToLongBiFunction<T, U> {
+
+ /**
+ * Compute the result of applying the function to the input arguments.
+ *
+ * @param t an input object
+ * @param u an input object
+ * @return the function result value
+ */
+ public long applyAsLong(T t, U u);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/util/function/ToLongFunction.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.function;
+
+/**
+ * Apply a function to the input argument, yielding an appropriate result.
+ * This is the {@code long}-bearing specialization for {@link Function}.
+ *
+ * @param <T> the type of input objects to the function
+ *
+ * @see Function
+ * @since 1.8
+ */
+@FunctionalInterface
+public interface ToLongFunction<T> {
+
+ /**
+ * Compute the result of applying the function to the input arguments.
+ *
+ * @param t the input object
+ * @return the function result value
+ */
+ public long applyAsLong(T t);
+}
--- a/jdk/src/share/classes/java/util/function/UnaryOperator.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/function/UnaryOperator.java Fri Mar 15 16:39:07 2013 -0700
@@ -26,20 +26,14 @@
/**
* An operation upon a single operand yielding a result. The operand and the
- * result are of the same type.
+ * result are of the same type. This is a specialization of {@code Function} for
+ * the case where the operand and result are of the same type.
*
- * @param <T> the type of operand to {@code operate} and of the result
+ * @param <T> the type of operand to {@code apply} and of the result
*
+ * @see Function
* @since 1.8
*/
@FunctionalInterface
-public interface UnaryOperator<T> {
-
- /**
- * Returns the result of the operation upon the operand.
- *
- * @param operand the operand
- * @return the operation result
- */
- public T operate(T operand);
+public interface UnaryOperator<T> extends Function<T, T> {
}
--- a/jdk/src/share/classes/java/util/function/package-info.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/function/package-info.java Fri Mar 15 16:39:07 2013 -0700
@@ -22,27 +22,62 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
+
/**
- * <em>Functional interfaces</em> provide typing for lambda expressions. Each
- * functional interface provides a single abstract method to which the lambda
- * expression's parameter and return types are matched.
+ * <em>Functional interfaces</em> provide target types for lambda expressions
+ * and method references. Each functional interface has a single abstract method
+ * to which the lambda expression's parameter and return types are matched or
+ * adapted. Functional interfaces can provide a target type in multiple contexts,
+ * such as assignment context, method invocation, or cast context:
+ *
+ * <pre>
+ * Predicate<String> p = String::isEmpty;
+ *
+ * stream.filter(e -> e.getSize() > 10)...
*
- * <p>The interfaces in this package are all functional interfaces used with the
- * collections and streams frameworks. The operation identified by each
- * interface is generally applied to a collection or stream of objects.
+ * stream.map((ToIntFunction) e -> e.getSize())...
+ * </pre>
+ *
+ * <p>The interfaces in this package are functional interfaces used by the JDK,
+ * and are available to be used by user code as well. While they do not identify
+ * a complete set of function shapes to which lambda expressions might be adapted,
+ * they provide enough to cover common requirements.
*
- * <p>All functional interface implementations are expected to ensure that:
+ * <p>The interfaces in this package are annotated with @{link FunctionalInterface}.
+ * This annotation is not a requirement for the compiler to recognize an interface
+ * as a functional interface, but merely an aid to capture design intent and enlist the
+ * help of the compiler in identifying accidental violations of design intent.
+ *
+ * <p>The functional interfaces in this package follow an extensible naming convention,
+ * as follows:
+ *
* <ul>
- * <li>When used for aggregate operations upon many elements it should not be
- * assumed that the operation will be called upon elements in any specific order.
- * </li>
- * <li>{@code null} values are accepted and returned by these functional
- * interfaces according to the constraints of the specification in which the
- * functional interfaces are used. The functional interfaces themselves do not
- * constrain or mandate use of {@code null} values. Most usages of the
- * functional interfaces will define the role, if any, of {@code null} for that
- * context.
- * </li>
+ * <li>There are several basic function shapes, including {@link java.util.function.Function} ({@code T -> R}),
+ * {@link java.util.function.Consumer} ({@code T -> void}),
+ * {@link java.util.function.Predicate} ({@code T -> boolean}),
+ * and {@link java.util.function.Supplier} ({@code () -> T}).
+ * </li>
+ * <li>Function shapes have a natural arity based on how they are most commonly used.
+ * The basic shapes can be modified by an arity prefix to indicate a different arity,
+ * such as {@link java.util.function.BiFunction} ({@code (T, U) -> R}).
+ * </li>
+ * <li>There are additional derived function shapes which extend the basic function
+ * shapes, including {@link java.util.function.UnaryOperator} (extends {@code Function}) and
+ * {@link java.util.function.BinaryOperator} (extends {@code BiFunction}).
+ * </li>
+ * <li>Type parameters of functional interfaces can be specialized to primitives with
+ * additional type prefixes. To specialize the return type for a type that has both
+ * generic return type and generic arguments, we prefix {@code ToXxx}, as in
+ * {@link java.util.function.ToIntFunction}. Otherwise, type arguments are specialized left-to-right,
+ * as in {@link java.util.function.DoubleConsumer} or {@link java.util.function.ObjIntConsumer}.
+ * (The type prefix {@code Obj} is used to indicate that we don't want to specialize this parameter,
+ * but want to move on to the next parameter.) These schemes can be combined as in {@code IntToDoubleFunction}.
+ * </li>
+ * <li>If there are specialization prefixes for all arguments, the arity prefix may be left
+ * out (as in {@link java.util.function.ObjIntConsumer}).
+ * </li>
* </ul>
+ *
+ * @see java.lang.FunctionalInterface
*/
package java.util.function;
--- a/jdk/src/share/classes/java/util/jar/JarFile.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/jar/JarFile.java Fri Mar 15 16:39:07 2013 -0700
@@ -34,6 +34,7 @@
import java.security.cert.Certificate;
import java.security.AccessController;
import java.security.CodeSource;
+import sun.misc.IOUtils;
import sun.security.action.GetPropertyAction;
import sun.security.util.ManifestEntryVerifier;
import sun.misc.SharedSecrets;
@@ -63,8 +64,13 @@
private JarVerifier jv;
private boolean jvInitialized;
private boolean verify;
- private boolean computedHasClassPathAttribute;
+
+ // indicates if Class-Path attribute present (only valid if hasCheckedSpecialAttributes true)
private boolean hasClassPathAttribute;
+ // indicates if Profile attribute present (only valid if hasCheckedSpecialAttributes true)
+ private boolean hasProfileAttribute;
+ // true if manifest checked for special attributes
+ private volatile boolean hasCheckedSpecialAttributes;
// Set up JavaUtilJarAccess in SharedSecrets
static {
@@ -329,6 +335,9 @@
if (names != null) {
for (int i = 0; i < names.length; i++) {
JarEntry e = getJarEntry(names[i]);
+ if (e == null) {
+ throw new JarException("corrupted jar file");
+ }
if (!e.isDirectory()) {
if (mev == null) {
mev = new ManifestEntryVerifier
@@ -348,6 +357,10 @@
// treat the jar file as being unsigned
jv = null;
verify = false;
+ if (JarVerifier.debug != null) {
+ JarVerifier.debug.println("jarfile parsing error!");
+ ex.printStackTrace();
+ }
}
// if after initializing the verifier we have nothing
@@ -375,11 +388,9 @@
* META-INF files.
*/
private byte[] getBytes(ZipEntry ze) throws IOException {
- byte[] b = new byte[(int)ze.getSize()];
- try (DataInputStream is = new DataInputStream(super.getInputStream(ze))) {
- is.readFully(b, 0, b.length);
+ try (InputStream is = super.getInputStream(ze)) {
+ return IOUtils.readFully(is, (int)ze.getSize(), true);
}
- return b;
}
/**
@@ -421,27 +432,45 @@
jv);
}
- // Statics for hand-coded Boyer-Moore search in hasClassPathAttribute()
+ // Statics for hand-coded Boyer-Moore search
+ private static final char[] CLASSPATH_CHARS = {'c','l','a','s','s','-','p','a','t','h'};
+ private static final char[] PROFILE_CHARS = { 'p', 'r', 'o', 'f', 'i', 'l', 'e' };
// The bad character shift for "class-path"
- private static int[] lastOcc;
+ private static final int[] CLASSPATH_LASTOCC;
// The good suffix shift for "class-path"
- private static int[] optoSft;
- // Initialize the shift arrays to search for "class-path"
- private static char[] src = {'c','l','a','s','s','-','p','a','t','h'};
+ private static final int[] CLASSPATH_OPTOSFT;
+ // The bad character shift for "profile"
+ private static final int[] PROFILE_LASTOCC;
+ // The good suffix shift for "profile"
+ private static final int[] PROFILE_OPTOSFT;
+
static {
- lastOcc = new int[128];
- optoSft = new int[10];
- lastOcc[(int)'c']=1;
- lastOcc[(int)'l']=2;
- lastOcc[(int)'s']=5;
- lastOcc[(int)'-']=6;
- lastOcc[(int)'p']=7;
- lastOcc[(int)'a']=8;
- lastOcc[(int)'t']=9;
- lastOcc[(int)'h']=10;
+ CLASSPATH_LASTOCC = new int[128];
+ CLASSPATH_OPTOSFT = new int[10];
+ CLASSPATH_LASTOCC[(int)'c'] = 1;
+ CLASSPATH_LASTOCC[(int)'l'] = 2;
+ CLASSPATH_LASTOCC[(int)'s'] = 5;
+ CLASSPATH_LASTOCC[(int)'-'] = 6;
+ CLASSPATH_LASTOCC[(int)'p'] = 7;
+ CLASSPATH_LASTOCC[(int)'a'] = 8;
+ CLASSPATH_LASTOCC[(int)'t'] = 9;
+ CLASSPATH_LASTOCC[(int)'h'] = 10;
for (int i=0; i<9; i++)
- optoSft[i]=10;
- optoSft[9]=1;
+ CLASSPATH_OPTOSFT[i] = 10;
+ CLASSPATH_OPTOSFT[9]=1;
+
+ PROFILE_LASTOCC = new int[128];
+ PROFILE_OPTOSFT = new int[7];
+ PROFILE_LASTOCC[(int)'p'] = 1;
+ PROFILE_LASTOCC[(int)'r'] = 2;
+ PROFILE_LASTOCC[(int)'o'] = 3;
+ PROFILE_LASTOCC[(int)'f'] = 4;
+ PROFILE_LASTOCC[(int)'i'] = 5;
+ PROFILE_LASTOCC[(int)'l'] = 6;
+ PROFILE_LASTOCC[(int)'e'] = 7;
+ for (int i=0; i<6; i++)
+ PROFILE_OPTOSFT[i] = 7;
+ PROFILE_OPTOSFT[6] = 1;
}
private JarEntry getManEntry() {
@@ -466,49 +495,70 @@
return manEntry;
}
- // Returns true iff this jar file has a manifest with a class path
- // attribute. Returns false if there is no manifest or the manifest
- // does not contain a "Class-Path" attribute. Currently exported to
- // core libraries via sun.misc.SharedSecrets.
+ /**
+ * Returns {@code true} iff this JAR file has a manifest with the
+ * Class-Path attribute
+ */
boolean hasClassPathAttribute() throws IOException {
- if (computedHasClassPathAttribute) {
- return hasClassPathAttribute;
- }
-
- hasClassPathAttribute = false;
- if (!isKnownToNotHaveClassPathAttribute()) {
- JarEntry manEntry = getManEntry();
- if (manEntry != null) {
- byte[] b = new byte[(int)manEntry.getSize()];
- try (DataInputStream dis = new DataInputStream(
- super.getInputStream(manEntry))) {
- dis.readFully(b, 0, b.length);
- }
-
- int last = b.length - src.length;
- int i = 0;
- next:
- while (i<=last) {
- for (int j=9; j>=0; j--) {
- char c = (char) b[i+j];
- c = (((c-'A')|('Z'-c)) >= 0) ? (char)(c + 32) : c;
- if (c != src[j]) {
- i += Math.max(j + 1 - lastOcc[c&0x7F], optoSft[j]);
- continue next;
- }
- }
- hasClassPathAttribute = true;
- break;
- }
- }
- }
- computedHasClassPathAttribute = true;
+ checkForSpecialAttributes();
return hasClassPathAttribute;
}
+ /**
+ * Returns {@code true} iff this JAR file has a manifest with the
+ * Profile attribute
+ */
+ boolean hasProfileAttribute() throws IOException {
+ checkForSpecialAttributes();
+ return hasProfileAttribute;
+ }
+
+ /**
+ * Returns true if the pattern {@code src} is found in {@code b}.
+ * The {@code lastOcc} and {@code optoSft} arrays are the precomputed
+ * bad character and good suffix shifts.
+ */
+ private boolean match(char[] src, byte[] b, int[] lastOcc, int[] optoSft) {
+ int len = src.length;
+ int last = b.length - len;
+ int i = 0;
+ next:
+ while (i<=last) {
+ for (int j=(len-1); j>=0; j--) {
+ char c = (char) b[i+j];
+ c = (((c-'A')|('Z'-c)) >= 0) ? (char)(c + 32) : c;
+ if (c != src[j]) {
+ i += Math.max(j + 1 - lastOcc[c&0x7F], optoSft[j]);
+ continue next;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * On first invocation, check if the JAR file has the Class-Path
+ * and/or Profile attributes. A no-op on subsequent calls.
+ */
+ private void checkForSpecialAttributes() throws IOException {
+ if (hasCheckedSpecialAttributes) return;
+ if (!isKnownNotToHaveSpecialAttributes()) {
+ JarEntry manEntry = getManEntry();
+ if (manEntry != null) {
+ byte[] b = getBytes(manEntry);
+ if (match(CLASSPATH_CHARS, b, CLASSPATH_LASTOCC, CLASSPATH_OPTOSFT))
+ hasClassPathAttribute = true;
+ if (match(PROFILE_CHARS, b, PROFILE_LASTOCC, PROFILE_OPTOSFT))
+ hasProfileAttribute = true;
+ }
+ }
+ hasCheckedSpecialAttributes = true;
+ }
+
private static String javaHome;
- private static String[] jarNames;
- private boolean isKnownToNotHaveClassPathAttribute() {
+ private static volatile String[] jarNames;
+ private boolean isKnownNotToHaveSpecialAttributes() {
// Optimize away even scanning of manifest for jar files we
// deliver which don't have a class-path attribute. If one of
// these jars is changed to include such an attribute this code
@@ -518,19 +568,20 @@
new GetPropertyAction("java.home"));
}
if (jarNames == null) {
- String[] names = new String[10];
+ String[] names = new String[11];
String fileSep = File.separator;
int i = 0;
names[i++] = fileSep + "rt.jar";
- names[i++] = fileSep + "sunrsasign.jar";
names[i++] = fileSep + "jsse.jar";
names[i++] = fileSep + "jce.jar";
names[i++] = fileSep + "charsets.jar";
names[i++] = fileSep + "dnsns.jar";
- names[i++] = fileSep + "ldapsec.jar";
+ names[i++] = fileSep + "zipfs.jar";
names[i++] = fileSep + "localedata.jar";
+ names[i++] = fileSep = "cldrdata.jar";
names[i++] = fileSep + "sunjce_provider.jar";
names[i++] = fileSep + "sunpkcs11.jar";
+ names[i++] = fileSep + "sunec.jar";
jarNames = names;
}
--- a/jdk/src/share/classes/java/util/jar/JavaUtilJarAccessImpl.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/jar/JavaUtilJarAccessImpl.java Fri Mar 15 16:39:07 2013 -0700
@@ -37,6 +37,10 @@
return jar.hasClassPathAttribute();
}
+ public boolean jarFileHasProfileAttribute(JarFile jar) throws IOException {
+ return jar.hasProfileAttribute();
+ }
+
public CodeSource[] getCodeSources(JarFile jar, URL url) {
return jar.getCodeSources(url);
}
--- a/jdk/src/share/classes/java/util/logging/Level.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/logging/Level.java Fri Mar 15 16:39:07 2013 -0700
@@ -24,6 +24,10 @@
*/
package java.util.logging;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import java.util.ResourceBundle;
/**
@@ -59,7 +63,6 @@
*/
public class Level implements java.io.Serializable {
- private static java.util.ArrayList<Level> known = new java.util.ArrayList<>();
private static String defaultBundle = "sun.util.logging.resources.logging";
/**
@@ -77,6 +80,9 @@
*/
private final String resourceBundleName;
+ // localized level name
+ private String localizedLevelName;
+
/**
* OFF is a special level that can be used to turn off logging.
* This level is initialized to <CODE>Integer.MAX_VALUE</CODE>.
@@ -202,9 +208,8 @@
this.name = name;
this.value = value;
this.resourceBundleName = resourceBundleName;
- synchronized (Level.class) {
- known.add(this);
- }
+ this.localizedLevelName = resourceBundleName == null ? name : null;
+ KnownLevel.add(this);
}
/**
@@ -236,12 +241,76 @@
* @return localized name
*/
public String getLocalizedName() {
+ return getLocalizedLevelName();
+ }
+
+ // package-private getLevelName() is used by the implementation
+ // instead of getName() to avoid calling the subclass's version
+ final String getLevelName() {
+ return this.name;
+ }
+
+ final synchronized String getLocalizedLevelName() {
+ if (localizedLevelName != null) {
+ return localizedLevelName;
+ }
+
try {
ResourceBundle rb = ResourceBundle.getBundle(resourceBundleName);
- return rb.getString(name);
+ localizedLevelName = rb.getString(name);
} catch (Exception ex) {
- return name;
+ localizedLevelName = name;
+ }
+ return localizedLevelName;
+ }
+
+ // Returns a mirrored Level object that matches the given name as
+ // specified in the Level.parse method. Returns null if not found.
+ //
+ // It returns the same Level object as the one returned by Level.parse
+ // method if the given name is a non-localized name or integer.
+ //
+ // If the name is a localized name, findLevel and parse method may
+ // return a different level value if there is a custom Level subclass
+ // that overrides Level.getLocalizedName() to return a different string
+ // than what's returned by the default implementation.
+ //
+ static Level findLevel(String name) {
+ if (name == null) {
+ throw new NullPointerException();
}
+
+ KnownLevel level;
+
+ // Look for a known Level with the given non-localized name.
+ level = KnownLevel.findByName(name);
+ if (level != null) {
+ return level.mirroredLevel;
+ }
+
+ // Now, check if the given name is an integer. If so,
+ // first look for a Level with the given value and then
+ // if necessary create one.
+ try {
+ int x = Integer.parseInt(name);
+ level = KnownLevel.findByValue(x);
+ if (level == null) {
+ // add new Level
+ Level levelObject = new Level(name, x);
+ level = KnownLevel.findByValue(x);
+ }
+ return level.mirroredLevel;
+ } catch (NumberFormatException ex) {
+ // Not an integer.
+ // Drop through.
+ }
+
+ level = KnownLevel.findByLocalizedLevelName(name);
+ if (level != null) {
+ return level.mirroredLevel;
+ }
+
+ return null;
}
/**
@@ -268,21 +337,15 @@
// Serialization magic to prevent "doppelgangers".
// This is a performance optimization.
private Object readResolve() {
- synchronized (Level.class) {
- for (int i = 0; i < known.size(); i++) {
- Level other = known.get(i);
- if (this.name.equals(other.name) && this.value == other.value
- && (this.resourceBundleName == other.resourceBundleName ||
- (this.resourceBundleName != null &&
- this.resourceBundleName.equals(other.resourceBundleName)))) {
- return other;
- }
- }
- // Woops. Whoever sent us this object knows
- // about a new log level. Add it to our list.
- known.add(this);
- return this;
+ KnownLevel o = KnownLevel.matches(this);
+ if (o != null) {
+ return o.levelObject;
}
+
+ // Woops. Whoever sent us this object knows
+ // about a new log level. Add it to our list.
+ Level level = new Level(this.name, this.value, this.resourceBundleName);
+ return level;
}
/**
@@ -296,6 +359,7 @@
* <li> "SEVERE"
* <li> "1000"
* </ul>
+ *
* @param name string to be parsed
* @throws NullPointerException if the name is null
* @throws IllegalArgumentException if the value is not valid.
@@ -315,12 +379,12 @@
// Check that name is not null.
name.length();
+ KnownLevel level;
+
// Look for a known Level with the given non-localized name.
- for (int i = 0; i < known.size(); i++) {
- Level l = known.get(i);
- if (name.equals(l.name)) {
- return l;
- }
+ level = KnownLevel.findByName(name);
+ if (level != null) {
+ return level.levelObject;
}
// Now, check if the given name is an integer. If so,
@@ -328,14 +392,13 @@
// if necessary create one.
try {
int x = Integer.parseInt(name);
- for (int i = 0; i < known.size(); i++) {
- Level l = known.get(i);
- if (l.value == x) {
- return l;
- }
+ level = KnownLevel.findByValue(x);
+ if (level == null) {
+ // add new Level
+ Level levelObject = new Level(name, x);
+ level = KnownLevel.findByValue(x);
}
- // Create a new Level.
- return new Level(name, x);
+ return level.levelObject;
} catch (NumberFormatException ex) {
// Not an integer.
// Drop through.
@@ -344,11 +407,9 @@
// Finally, look for a known level with the given localized name,
// in the current default locale.
// This is relatively expensive, but not excessively so.
- for (int i = 0; i < known.size(); i++) {
- Level l = known.get(i);
- if (name.equals(l.getLocalizedName())) {
- return l;
- }
+ level = KnownLevel.findByLocalizedName(name);
+ if (level != null) {
+ return level.levelObject;
}
// OK, we've tried everything and failed
@@ -375,4 +436,124 @@
public int hashCode() {
return this.value;
}
+
+ // KnownLevel class maintains the global list of all known levels.
+ // The API allows multiple custom Level instances of the same name/value
+ // be created. This class provides convenient methods to find a level
+ // by a given name, by a given value, or by a given localized name.
+ //
+ // KnownLevel wraps the following Level objects:
+ // 1. levelObject: standard Level object or custom Level object
+ // 2. mirroredLevel: Level object representing the level specified in the
+ // logging configuration.
+ //
+ // Level.getName, Level.getLocalizedName, Level.getResourceBundleName methods
+ // are non-final but the name and resource bundle name are parameters to
+ // the Level constructor. Use the mirroredLevel object instead of the
+ // levelObject to prevent the logging framework to execute foreign code
+ // implemented by untrusted Level subclass.
+ //
+ // Implementation Notes:
+ // If Level.getName, Level.getLocalizedName, Level.getResourceBundleName methods
+ // were final, the following KnownLevel implementation can be removed.
+ // Future API change should take this into consideration.
+ static final class KnownLevel {
+ private static Map<String, List<KnownLevel>> nameToLevels = new HashMap<>();
+ private static Map<Integer, List<KnownLevel>> intToLevels = new HashMap<>();
+ final Level levelObject; // instance of Level class or Level subclass
+ final Level mirroredLevel; // instance of Level class
+ KnownLevel(Level l) {
+ this.levelObject = l;
+ if (l.getClass() == Level.class) {
+ this.mirroredLevel = l;
+ } else {
+ this.mirroredLevel = new Level(l.name, l.value, l.resourceBundleName);
+ }
+ }
+
+ static synchronized void add(Level l) {
+ // the mirroredLevel object is always added to the list
+ // before the custom Level instance
+ KnownLevel o = new KnownLevel(l);
+ List<KnownLevel> list = nameToLevels.get(l.name);
+ if (list == null) {
+ list = new ArrayList<>();
+ nameToLevels.put(l.name, list);
+ }
+ list.add(o);
+
+ list = intToLevels.get(l.value);
+ if (list == null) {
+ list = new ArrayList<>();
+ intToLevels.put(l.value, list);
+ }
+ list.add(o);
+ }
+
+ // Returns a KnownLevel with the given non-localized name.
+ static synchronized KnownLevel findByName(String name) {
+ List<KnownLevel> list = nameToLevels.get(name);
+ if (list != null) {
+ return list.get(0);
+ }
+ return null;
+ }
+
+ // Returns a KnownLevel with the given value.
+ static synchronized KnownLevel findByValue(int value) {
+ List<KnownLevel> list = intToLevels.get(value);
+ if (list != null) {
+ return list.get(0);
+ }
+ return null;
+ }
+
+ // Returns a KnownLevel with the given localized name matching
+ // by calling the Level.getLocalizedLevelName() method (i.e. found
+ // from the resourceBundle associated with the Level object).
+ // This method does not call Level.getLocalizedName() that may
+ // be overridden in a subclass implementation
+ static synchronized KnownLevel findByLocalizedLevelName(String name) {
+ for (List<KnownLevel> levels : nameToLevels.values()) {
+ for (KnownLevel l : levels) {
+ String lname = l.levelObject.getLocalizedLevelName();
+ if (name.equals(lname)) {
+ return l;
+ }
+ }
+ }
+ return null;
+ }
+
+ // Returns a KnownLevel with the given localized name matching
+ // by calling the Level.getLocalizedName() method
+ static synchronized KnownLevel findByLocalizedName(String name) {
+ for (List<KnownLevel> levels : nameToLevels.values()) {
+ for (KnownLevel l : levels) {
+ String lname = l.levelObject.getLocalizedName();
+ if (name.equals(lname)) {
+ return l;
+ }
+ }
+ }
+ return null;
+ }
+
+ static synchronized KnownLevel matches(Level l) {
+ List<KnownLevel> list = nameToLevels.get(l.name);
+ if (list != null) {
+ for (KnownLevel level : list) {
+ Level other = level.mirroredLevel;
+ if (l.value == other.value &&
+ (l.resourceBundleName == other.resourceBundleName ||
+ (l.resourceBundleName != null &&
+ l.resourceBundleName.equals(other.resourceBundleName)))) {
+ return level;
+ }
+ }
+ }
+ return null;
+ }
+ }
+
}
--- a/jdk/src/share/classes/java/util/logging/LogManager.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/logging/LogManager.java Fri Mar 15 16:39:07 2013 -0700
@@ -35,6 +35,10 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.beans.PropertyChangeListener;
+import java.net.URL;
+import sun.misc.JavaAWTAccess;
+import sun.misc.SharedSecrets;
+import sun.security.action.GetPropertyAction;
/**
* There is a single global LogManager object that is used to
@@ -152,10 +156,9 @@
// count to allow for cases where the same listener is registered many times.
private final Map<Object,Integer> listenerMap = new HashMap<>();
- // Table of named Loggers that maps names to Loggers.
- private Hashtable<String,LoggerWeakRef> namedLoggers = new Hashtable<>();
- // Tree of named Loggers
- private LogNode root = new LogNode(null);
+ // LoggerContext for system loggers and user loggers
+ private final LoggerContext systemContext = new SystemLoggerContext();
+ private final LoggerContext userContext = new LoggerContext();
private Logger rootLogger;
// Have we done the primordial reading of the configuration file?
@@ -194,11 +197,12 @@
// Create and retain Logger for the root of the namespace.
manager.rootLogger = manager.new RootLogger();
manager.addLogger(manager.rootLogger);
+ manager.systemContext.addLocalLogger(manager.rootLogger);
// Adding the global Logger. Doing so in the Logger.<clinit>
// would deadlock with the LogManager.<clinit>.
- Logger.getGlobal().setLogManager(manager);
- manager.addLogger(Logger.getGlobal());
+ Logger.global.setLogManager(manager);
+ manager.addLogger(Logger.global);
// We don't call readConfiguration() here, as we may be running
// very early in the JVM startup sequence. Instead readConfiguration
@@ -276,14 +280,14 @@
return;
}
readPrimordialConfiguration = true;
+
try {
- AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
- public Object run() throws Exception {
+ AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
+ public Void run() throws Exception {
readConfiguration();
// Platform loggers begin to delegate to java.util.logging.Logger
sun.util.logging.PlatformLogger.redirectPlatformLoggers();
-
return null;
}
});
@@ -375,20 +379,68 @@
}
}
- // Package-level method.
+ // Returns the LoggerContext for the user code (i.e. application or AppContext).
+ // Loggers are isolated from each AppContext.
+ private LoggerContext getUserContext() {
+ LoggerContext context = null;
+
+ SecurityManager sm = System.getSecurityManager();
+ JavaAWTAccess javaAwtAccess = SharedSecrets.getJavaAWTAccess();
+ if (sm != null && javaAwtAccess != null) {
+ synchronized (javaAwtAccess) {
+ // AppContext.getAppContext() returns the system AppContext if called
+ // from a system thread but Logger.getLogger might be called from
+ // an applet code. Instead, find the AppContext of the applet code
+ // from the execution stack.
+ Object ecx = javaAwtAccess.getExecutionContext();
+ if (ecx == null) {
+ // fall back to AppContext.getAppContext()
+ ecx = javaAwtAccess.getContext();
+ }
+ context = (LoggerContext)javaAwtAccess.get(ecx, LoggerContext.class);
+ if (context == null) {
+ if (javaAwtAccess.isMainAppContext()) {
+ context = userContext;
+ } else {
+ context = new LoggerContext();
+ // during initialization, rootLogger is null when
+ // instantiating itself RootLogger
+ if (manager.rootLogger != null)
+ context.addLocalLogger(manager.rootLogger);
+ }
+ javaAwtAccess.put(ecx, LoggerContext.class, context);
+ }
+ }
+ } else {
+ context = userContext;
+ }
+ return context;
+ }
+
+ private List<LoggerContext> contexts() {
+ List<LoggerContext> cxs = new ArrayList<>();
+ cxs.add(systemContext);
+ cxs.add(getUserContext());
+ return cxs;
+ }
+
// Find or create a specified logger instance. If a logger has
// already been created with the given name it is returned.
// Otherwise a new logger instance is created and registered
// in the LogManager global namespace.
-
// This method will always return a non-null Logger object.
// Synchronization is not required here. All synchronization for
// adding a new Logger object is handled by addLogger().
- Logger demandLogger(String name) {
+ //
+ // This method must delegate to the LogManager implementation to
+ // add a new Logger or return the one that has been added previously
+ // as a LogManager subclass may override the addLogger, getLogger,
+ // readConfiguration, and other methods.
+ Logger demandLogger(String name, String resourceBundleName) {
Logger result = getLogger(name);
if (result == null) {
// only allocate the new logger once
- Logger newLogger = new Logger(name, null);
+ Logger newLogger = new Logger(name, resourceBundleName);
do {
if (addLogger(newLogger)) {
// We successfully added the new Logger that we
@@ -413,24 +465,249 @@
return result;
}
- // If logger.getUseParentHandlers() returns 'true' and any of the logger's
- // parents have levels or handlers defined, make sure they are instantiated.
- private void processParentHandlers(Logger logger, String name) {
- int ix = 1;
- for (;;) {
- int ix2 = name.indexOf(".", ix);
- if (ix2 < 0) {
- break;
+ Logger demandSystemLogger(String name, String resourceBundleName) {
+ // Add a system logger in the system context's namespace
+ final Logger sysLogger = systemContext.demandLogger(name, resourceBundleName);
+
+ // Add the system logger to the LogManager's namespace if not exist
+ // so that there is only one single logger of the given name.
+ // System loggers are visible to applications unless a logger of
+ // the same name has been added.
+ Logger logger;
+ do {
+ // First attempt to call addLogger instead of getLogger
+ // This would avoid potential bug in custom LogManager.getLogger
+ // implementation that adds a logger if does not exist
+ if (addLogger(sysLogger)) {
+ // successfully added the new system logger
+ logger = sysLogger;
+ } else {
+ logger = getLogger(name);
+ }
+ } while (logger == null);
+
+ // LogManager will set the sysLogger's handlers via LogManager.addLogger method.
+ if (logger != sysLogger && sysLogger.getHandlers().length == 0) {
+ // if logger already exists but handlers not set
+ final Logger l = logger;
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ public Void run() {
+ for (Handler hdl : l.getHandlers()) {
+ sysLogger.addHandler(hdl);
+ }
+ return null;
+ }
+ });
+ }
+ return sysLogger;
+ }
+
+ // LoggerContext maintains the logger namespace per context.
+ // The default LogManager implementation has one system context and user
+ // context. The system context is used to maintain the namespace for
+ // all system loggers and is queried by the system code. If a system logger
+ // doesn't exist in the user context, it'll also be added to the user context.
+ // The user context is queried by the user code and all other loggers are
+ // added in the user context.
+ static class LoggerContext {
+ // Table of named Loggers that maps names to Loggers.
+ private final Hashtable<String,LoggerWeakRef> namedLoggers = new Hashtable<>();
+ // Tree of named Loggers
+ private final LogNode root;
+
+ private LoggerContext() {
+ this.root = new LogNode(null, this);
+ }
+
+ Logger demandLogger(String name, String resourceBundleName) {
+ // a LogManager subclass may have its own implementation to add and
+ // get a Logger. So delegate to the LogManager to do the work.
+ return manager.demandLogger(name, resourceBundleName);
+ }
+
+ synchronized Logger findLogger(String name) {
+ LoggerWeakRef ref = namedLoggers.get(name);
+ if (ref == null) {
+ return null;
+ }
+ Logger logger = ref.get();
+ if (logger == null) {
+ // Hashtable holds stale weak reference
+ // to a logger which has been GC-ed.
+ removeLogger(name);
+ }
+ return logger;
+ }
+
+ // Add a logger to this context. This method will only set its level
+ // and process parent loggers. It doesn't set its handlers.
+ synchronized boolean addLocalLogger(Logger logger) {
+ final String name = logger.getName();
+ if (name == null) {
+ throw new NullPointerException();
+ }
+
+ // cleanup some Loggers that have been GC'ed
+ manager.drainLoggerRefQueueBounded();
+
+ LoggerWeakRef ref = namedLoggers.get(name);
+ if (ref != null) {
+ if (ref.get() == null) {
+ // It's possible that the Logger was GC'ed after the
+ // drainLoggerRefQueueBounded() call above so allow
+ // a new one to be registered.
+ removeLogger(name);
+ } else {
+ // We already have a registered logger with the given name.
+ return false;
+ }
+ }
+
+ // We're adding a new logger.
+ // Note that we are creating a weak reference here.
+ ref = manager.new LoggerWeakRef(logger);
+ namedLoggers.put(name, ref);
+
+ // Apply any initial level defined for the new logger.
+ Level level = manager.getLevelProperty(name + ".level", null);
+ if (level != null) {
+ doSetLevel(logger, level);
}
- String pname = name.substring(0,ix2);
+
+ // instantiation of the handler is done in the LogManager.addLogger
+ // implementation as a handler class may be only visible to LogManager
+ // subclass for the custom log manager case
+ processParentHandlers(logger, name);
+
+ // Find the new node and its parent.
+ LogNode node = getNode(name);
+ node.loggerRef = ref;
+ Logger parent = null;
+ LogNode nodep = node.parent;
+ while (nodep != null) {
+ LoggerWeakRef nodeRef = nodep.loggerRef;
+ if (nodeRef != null) {
+ parent = nodeRef.get();
+ if (parent != null) {
+ break;
+ }
+ }
+ nodep = nodep.parent;
+ }
+
+ if (parent != null) {
+ doSetParent(logger, parent);
+ }
+ // Walk over the children and tell them we are their new parent.
+ node.walkAndSetParent(logger);
+ // new LogNode is ready so tell the LoggerWeakRef about it
+ ref.setNode(node);
+ return true;
+ }
+
+ void removeLogger(String name) {
+ namedLoggers.remove(name);
+ }
+
+ synchronized Enumeration<String> getLoggerNames() {
+ return namedLoggers.keys();
+ }
+
+ // If logger.getUseParentHandlers() returns 'true' and any of the logger's
+ // parents have levels or handlers defined, make sure they are instantiated.
+ private void processParentHandlers(final Logger logger, final String name) {
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ public Void run() {
+ if (logger != manager.rootLogger) {
+ boolean useParent = manager.getBooleanProperty(name + ".useParentHandlers", true);
+ if (!useParent) {
+ logger.setUseParentHandlers(false);
+ }
+ }
+ return null;
+ }
+ });
- if (getProperty(pname+".level") != null ||
- getProperty(pname+".handlers") != null) {
- // This pname has a level/handlers definition.
- // Make sure it exists.
- demandLogger(pname);
+ int ix = 1;
+ for (;;) {
+ int ix2 = name.indexOf(".", ix);
+ if (ix2 < 0) {
+ break;
+ }
+ String pname = name.substring(0, ix2);
+ if (manager.getProperty(pname + ".level") != null ||
+ manager.getProperty(pname + ".handlers") != null) {
+ // This pname has a level/handlers definition.
+ // Make sure it exists.
+ demandLogger(pname, null);
+ }
+ ix = ix2+1;
+ }
+ }
+
+ // Gets a node in our tree of logger nodes.
+ // If necessary, create it.
+ LogNode getNode(String name) {
+ if (name == null || name.equals("")) {
+ return root;
}
- ix = ix2+1;
+ LogNode node = root;
+ while (name.length() > 0) {
+ int ix = name.indexOf(".");
+ String head;
+ if (ix > 0) {
+ head = name.substring(0, ix);
+ name = name.substring(ix + 1);
+ } else {
+ head = name;
+ name = "";
+ }
+ if (node.children == null) {
+ node.children = new HashMap<>();
+ }
+ LogNode child = node.children.get(head);
+ if (child == null) {
+ child = new LogNode(node, this);
+ node.children.put(head, child);
+ }
+ node = child;
+ }
+ return node;
+ }
+ }
+
+ static class SystemLoggerContext extends LoggerContext {
+ // Add a system logger in the system context's namespace as well as
+ // in the LogManager's namespace if not exist so that there is only
+ // one single logger of the given name. System loggers are visible
+ // to applications unless a logger of the same name has been added.
+ Logger demandLogger(String name, String resourceBundleName) {
+ Logger result = findLogger(name);
+ if (result == null) {
+ // only allocate the new system logger once
+ Logger newLogger = new Logger(name, resourceBundleName);
+ do {
+ if (addLocalLogger(newLogger)) {
+ // We successfully added the new Logger that we
+ // created above so return it without refetching.
+ result = newLogger;
+ } else {
+ // We didn't add the new Logger that we created above
+ // because another thread added a Logger with the same
+ // name after our null check above and before our call
+ // to addLogger(). We have to refetch the Logger because
+ // addLogger() returns a boolean instead of the Logger
+ // reference itself. However, if the thread that created
+ // the other Logger is not holding a strong reference to
+ // the other Logger, then it is possible for the other
+ // Logger to be GC'ed after we saw it in addLogger() and
+ // before we can refetch it. If it has been GC'ed then
+ // we'll just loop around and try again.
+ result = findLogger(name);
+ }
+ } while (result == null);
+ }
+ return result;
}
}
@@ -439,32 +716,27 @@
// be made based on the logging configuration, which can
// only be modified by trusted code.
private void loadLoggerHandlers(final Logger logger, final String name,
- final String handlersPropertyName) {
+ final String handlersPropertyName)
+ {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
- if (logger != rootLogger) {
- boolean useParent = getBooleanProperty(name + ".useParentHandlers", true);
- if (!useParent) {
- logger.setUseParentHandlers(false);
- }
- }
-
String names[] = parseClassNames(handlersPropertyName);
for (int i = 0; i < names.length; i++) {
String word = names[i];
try {
Class<?> clz = ClassLoader.getSystemClassLoader().loadClass(word);
- Handler hdl = (Handler) clz.newInstance();
- try {
- // Check if there is a property defining the
- // this handler's level.
- String levs = getProperty(word + ".level");
- if (levs != null) {
- hdl.setLevel(Level.parse(levs));
+ Handler hdl = (Handler) clz.newInstance();
+ // Check if there is a property defining the
+ // this handler's level.
+ String levs = getProperty(word + ".level");
+ if (levs != null) {
+ Level l = Level.findLevel(levs);
+ if (l != null) {
+ hdl.setLevel(l);
+ } else {
+ // Probably a bad level. Drop through.
+ System.err.println("Can't set level for " + word);
}
- } catch (Exception ex) {
- System.err.println("Can't set level for " + word);
- // Probably a bad level. Drop through.
}
// Add this Handler to the logger
logger.addHandler(hdl);
@@ -475,7 +747,8 @@
}
}
return null;
- }});
+ }
+ });
}
@@ -520,7 +793,7 @@
if (node != null) {
// if we have a LogNode, then we were a named Logger
// so clear namedLoggers weak ref to us
- manager.namedLoggers.remove(name);
+ node.context.removeLogger(name);
name = null; // clear our ref to the Logger's name
node.loggerRef = null; // clear LogNode's weak ref to us
@@ -609,73 +882,22 @@
* false if a logger of that name already exists.
* @exception NullPointerException if the logger name is null.
*/
- public synchronized boolean addLogger(Logger logger) {
+ public boolean addLogger(Logger logger) {
final String name = logger.getName();
if (name == null) {
throw new NullPointerException();
}
-
- // cleanup some Loggers that have been GC'ed
- drainLoggerRefQueueBounded();
-
- LoggerWeakRef ref = namedLoggers.get(name);
- if (ref != null) {
- if (ref.get() == null) {
- // It's possible that the Logger was GC'ed after the
- // drainLoggerRefQueueBounded() call above so allow
- // a new one to be registered.
- namedLoggers.remove(name);
- } else {
- // We already have a registered logger with the given name.
- return false;
- }
- }
-
- // We're adding a new logger.
- // Note that we are creating a weak reference here.
- ref = new LoggerWeakRef(logger);
- namedLoggers.put(name, ref);
-
- // Apply any initial level defined for the new logger.
- Level level = getLevelProperty(name+".level", null);
- if (level != null) {
- doSetLevel(logger, level);
+ LoggerContext cx = getUserContext();
+ if (cx.addLocalLogger(logger)) {
+ // Do we have a per logger handler too?
+ // Note: this will add a 200ms penalty
+ loadLoggerHandlers(logger, name, name + ".handlers");
+ return true;
+ } else {
+ return false;
}
-
- // Do we have a per logger handler too?
- // Note: this will add a 200ms penalty
- loadLoggerHandlers(logger, name, name+".handlers");
- processParentHandlers(logger, name);
-
- // Find the new node and its parent.
- LogNode node = findNode(name);
- node.loggerRef = ref;
- Logger parent = null;
- LogNode nodep = node.parent;
- while (nodep != null) {
- LoggerWeakRef nodeRef = nodep.loggerRef;
- if (nodeRef != null) {
- parent = nodeRef.get();
- if (parent != null) {
- break;
- }
- }
- nodep = nodep.parent;
- }
-
- if (parent != null) {
- doSetParent(logger, parent);
- }
- // Walk over the children and tell them we are their new parent.
- node.walkAndSetParent(logger);
-
- // new LogNode is ready so tell the LoggerWeakRef about it
- ref.setNode(node);
-
- return true;
}
-
// Private method to set a level on a logger.
// If necessary, we raise privilege before doing the call.
private static void doSetLevel(final Logger logger, final Level level) {
@@ -694,8 +916,6 @@
}});
}
-
-
// Private method to set a parent on a logger.
// If necessary, we raise privilege before doing the setParent call.
private static void doSetParent(final Logger logger, final Logger parent) {
@@ -714,36 +934,6 @@
}});
}
- // Find a node in our tree of logger nodes.
- // If necessary, create it.
- private LogNode findNode(String name) {
- if (name == null || name.equals("")) {
- return root;
- }
- LogNode node = root;
- while (name.length() > 0) {
- int ix = name.indexOf(".");
- String head;
- if (ix > 0) {
- head = name.substring(0,ix);
- name = name.substring(ix+1);
- } else {
- head = name;
- name = "";
- }
- if (node.children == null) {
- node.children = new HashMap<>();
- }
- LogNode child = node.children.get(head);
- if (child == null) {
- child = new LogNode(node);
- node.children.put(head, child);
- }
- node = child;
- }
- return node;
- }
-
/**
* Method to find a named logger.
* <p>
@@ -759,18 +949,8 @@
* @param name name of the logger
* @return matching logger or null if none is found
*/
- public synchronized Logger getLogger(String name) {
- LoggerWeakRef ref = namedLoggers.get(name);
- if (ref == null) {
- return null;
- }
- Logger logger = ref.get();
- if (logger == null) {
- // Hashtable holds stale weak reference
- // to a logger which has been GC-ed.
- namedLoggers.remove(name);
- }
- return logger;
+ public Logger getLogger(String name) {
+ return getUserContext().findLogger(name);
}
/**
@@ -789,8 +969,8 @@
* <p>
* @return enumeration of logger name strings
*/
- public synchronized Enumeration<String> getLoggerNames() {
- return namedLoggers.keys();
+ public Enumeration<String> getLoggerNames() {
+ return getUserContext().getLoggerNames();
}
/**
@@ -875,20 +1055,20 @@
// the global handlers, if they haven't been initialized yet.
initializedGlobalHandlers = true;
}
- Enumeration<String> enum_ = getLoggerNames();
- while (enum_.hasMoreElements()) {
- String name = enum_.nextElement();
- resetLogger(name);
+ for (LoggerContext cx : contexts()) {
+ Enumeration<String> enum_ = cx.getLoggerNames();
+ while (enum_.hasMoreElements()) {
+ String name = enum_.nextElement();
+ Logger logger = cx.findLogger(name);
+ if (logger != null) {
+ resetLogger(logger);
+ }
+ }
}
}
-
// Private method to reset an individual target logger.
- private void resetLogger(String name) {
- Logger logger = getLogger(name);
- if (logger == null) {
- return;
- }
+ private void resetLogger(Logger logger) {
// Close all the Logger's handlers.
Handler[] targets = logger.getHandlers();
for (int i = 0; i < targets.length; i++) {
@@ -900,6 +1080,7 @@
// Problems closing a handler? Keep going...
}
}
+ String name = logger.getName();
if (name != null && name.equals("")) {
// This is the root logger.
logger.setLevel(defaultLevel);
@@ -1065,11 +1246,8 @@
if (val == null) {
return defaultValue;
}
- try {
- return Level.parse(val.trim());
- } catch (Exception ex) {
- return defaultValue;
- }
+ Level l = Level.findLevel(val.trim());
+ return l != null ? l : defaultValue;
}
// Package private method to get a filter property.
@@ -1159,9 +1337,11 @@
HashMap<String,LogNode> children;
LoggerWeakRef loggerRef;
LogNode parent;
+ final LoggerContext context;
- LogNode(LogNode parent) {
+ LogNode(LogNode parent, LoggerContext context) {
this.parent = parent;
+ this.context = context;
}
// Recursive method to walk the tree below a node and set
@@ -1188,7 +1368,6 @@
// that we only instantiate the global handlers when they
// are first needed.
private class RootLogger extends Logger {
-
private RootLogger() {
super("", null);
setLevel(defaultLevel);
@@ -1234,11 +1413,13 @@
System.err.println("Bad level value for property: " + key);
continue;
}
- Logger l = getLogger(name);
- if (l == null) {
- continue;
+ for (LoggerContext cx : contexts()) {
+ Logger l = cx.findLogger(name);
+ if (l == null) {
+ continue;
+ }
+ l.setLevel(level);
}
- l.setLevel(level);
}
}
--- a/jdk/src/share/classes/java/util/logging/Logger.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/logging/Logger.java Fri Mar 15 16:39:07 2013 -0700
@@ -314,6 +314,40 @@
}
}
+ // Until all JDK code converted to call sun.util.logging.PlatformLogger
+ // (see 7054233), we need to determine if Logger.getLogger is to add
+ // a system logger or user logger.
+ //
+ // As an interim solution, if the immediate caller whose caller loader is
+ // null, we assume it's a system logger and add it to the system context.
+ // These system loggers only set the resource bundle to the given
+ // resource bundle name (rather than the default system resource bundle).
+ private static class SystemLoggerHelper {
+ static boolean disableCallerCheck = getBooleanProperty("sun.util.logging.disableCallerCheck");
+ private static boolean getBooleanProperty(final String key) {
+ String s = AccessController.doPrivileged(new PrivilegedAction<String>() {
+ public String run() {
+ return System.getProperty(key);
+ }
+ });
+ return Boolean.valueOf(s);
+ }
+ }
+
+ private static Logger demandLogger(String name, String resourceBundleName) {
+ LogManager manager = LogManager.getLogManager();
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null && !SystemLoggerHelper.disableCallerCheck) {
+ // 0: Reflection 1: Logger.demandLogger 2: Logger.getLogger 3: caller
+ final int SKIP_FRAMES = 3;
+ Class<?> caller = sun.reflect.Reflection.getCallerClass(SKIP_FRAMES);
+ if (caller.getClassLoader() == null) {
+ return manager.demandSystemLogger(name, resourceBundleName);
+ }
+ }
+ return manager.demandLogger(name, resourceBundleName);
+ }
+
/**
* Find or create a logger for a named subsystem. If a logger has
* already been created with the given name it is returned. Otherwise
@@ -355,8 +389,7 @@
// would throw an IllegalArgumentException in the second call
// because the wrapper would result in an attempt to replace
// the existing "resourceBundleForFoo" with null.
- LogManager manager = LogManager.getLogManager();
- return manager.demandLogger(name);
+ return demandLogger(name, null);
}
/**
@@ -403,8 +436,7 @@
// Synchronization is not required here. All synchronization for
// adding a new Logger object is handled by LogManager.addLogger().
public static Logger getLogger(String name, String resourceBundleName) {
- LogManager manager = LogManager.getLogManager();
- Logger result = manager.demandLogger(name);
+ Logger result = demandLogger(name, resourceBundleName);
// MissingResourceException or IllegalArgumentException can be
// thrown by setupResourceInfo().
@@ -412,6 +444,17 @@
return result;
}
+ // package-private
+ // Add a platform logger to the system context.
+ // i.e. caller of sun.util.logging.PlatformLogger.getLogger
+ static Logger getPlatformLogger(String name) {
+ LogManager manager = LogManager.getLogManager();
+
+ // all loggers in the system context will default to
+ // the system logger's resource bundle
+ Logger result = manager.demandSystemLogger(name, SYSTEM_LOGGER_RB_NAME);
+ return result;
+ }
/**
* Create an anonymous Logger. The newly created Logger is not
@@ -564,7 +607,7 @@
private void doLog(LogRecord lr) {
lr.setLoggerName(name);
String ebname = getEffectiveResourceBundleName();
- if (ebname != null) {
+ if (ebname != null && !ebname.equals(SYSTEM_LOGGER_RB_NAME)) {
lr.setResourceBundleName(ebname);
lr.setResourceBundle(findResourceBundle(ebname));
}
@@ -1547,6 +1590,23 @@
// May also return null if we can't find the resource bundle and
// there is no suitable previous cached value.
+ static final String SYSTEM_LOGGER_RB_NAME = "sun.util.logging.resources.logging";
+
+ private static ResourceBundle findSystemResourceBundle(final Locale locale) {
+ // the resource bundle is in a restricted package
+ return AccessController.doPrivileged(new PrivilegedAction<ResourceBundle>() {
+ public ResourceBundle run() {
+ try {
+ return ResourceBundle.getBundle(SYSTEM_LOGGER_RB_NAME,
+ locale,
+ ClassLoader.getSystemClassLoader());
+ } catch (MissingResourceException e) {
+ throw new InternalError(e.toString());
+ }
+ }
+ });
+ }
+
private synchronized ResourceBundle findResourceBundle(String name) {
// Return a null bundle for a null name.
if (name == null) {
@@ -1561,6 +1621,13 @@
return catalog;
}
+ if (name.equals(SYSTEM_LOGGER_RB_NAME)) {
+ catalog = findSystemResourceBundle(currentLocale);
+ catalogName = name;
+ catalogLocale = currentLocale;
+ return catalog;
+ }
+
// Use the thread's context ClassLoader. If there isn't one,
// use the SystemClassloader.
ClassLoader cl = Thread.currentThread().getContextClassLoader();
@@ -1577,7 +1644,6 @@
// ClassLoader. Drop through.
}
-
// Fall back to searching up the call stack and trying each
// calling ClassLoader.
for (int ix = 0; ; ix++) {
--- a/jdk/src/share/classes/java/util/logging/Logging.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/logging/Logging.java Fri Mar 15 16:39:07 2013 -0700
@@ -34,7 +34,7 @@
*
* The <tt>LoggingMXBean</tt> interface provides a standard
* method for management access to the individual
- * java.util.Logger objects available at runtime.
+ * {@code Logger} objects available at runtime.
*
* @author Ron Mann
* @author Mandy Chung
@@ -75,7 +75,7 @@
if (level == null) {
return EMPTY_STRING;
} else {
- return level.getName();
+ return level.getLevelName();
}
}
@@ -85,7 +85,6 @@
}
Logger logger = logManager.getLogger(loggerName);
-
if (logger == null) {
throw new IllegalArgumentException("Logger " + loggerName +
"does not exist");
@@ -94,7 +93,10 @@
Level level = null;
if (levelName != null) {
// parse will throw IAE if logLevel is invalid
- level = Level.parse(levelName);
+ level = Level.findLevel(levelName);
+ if (level == null) {
+ throw new IllegalArgumentException("Unknown level \"" + levelName + "\"");
+ }
}
logger.setLevel(level);
--- a/jdk/src/share/classes/java/util/logging/LoggingProxyImpl.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/logging/LoggingProxyImpl.java Fri Mar 15 16:39:07 2013 -0700
@@ -37,7 +37,8 @@
@Override
public Object getLogger(String name) {
- return Logger.getLogger(name);
+ // always create a platform logger with the resource bundle name
+ return Logger.getPlatformLogger(name);
}
@Override
@@ -92,12 +93,16 @@
@Override
public Object parseLevel(String levelName) {
- return Level.parse(levelName);
+ Level level = Level.findLevel(levelName);
+ if (level == null) {
+ throw new IllegalArgumentException("Unknown level \"" + levelName + "\"");
+ }
+ return level;
}
@Override
public String getLevelName(Object level) {
- return ((Level) level).getName();
+ return ((Level) level).getLevelName();
}
@Override
--- a/jdk/src/share/classes/java/util/logging/SimpleFormatter.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/java/util/logging/SimpleFormatter.java Fri Mar 15 16:39:07 2013 -0700
@@ -162,7 +162,7 @@
dat,
source,
record.getLoggerName(),
- record.getLevel().getLocalizedName(),
+ record.getLevel().getLocalizedLevelName(),
message,
throwable);
}
--- a/jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -39,11 +39,13 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.logging.Level;
import java.util.Map;
import java.util.Set;
@@ -78,6 +80,8 @@
import javax.management.RuntimeOperationsException;
import javax.management.ServiceNotFoundException;
import javax.management.loading.ClassLoaderRepository;
+import sun.misc.JavaSecurityAccess;
+import sun.misc.SharedSecrets;
import sun.reflect.misc.MethodUtil;
import sun.reflect.misc.ReflectUtil;
@@ -138,6 +142,9 @@
private boolean registered = false;
private transient MBeanServer server = null;
+ private final static JavaSecurityAccess javaSecurityAccess = SharedSecrets.getJavaSecurityAccess();
+ final private AccessControlContext acc = AccessController.getContext();
+
/*************************************/
/* constructors */
/*************************************/
@@ -1025,10 +1032,31 @@
if (opClassName != null) {
try {
- final ClassLoader targetClassLoader =
- targetObject.getClass().getClassLoader();
- targetClass = Class.forName(opClassName, false,
- targetClassLoader);
+ AccessControlContext stack = AccessController.getContext();
+ final Object obj = targetObject;
+ final String className = opClassName;
+ final ClassNotFoundException[] caughtException = new ClassNotFoundException[1];
+
+ targetClass = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Class<?>>() {
+
+ @Override
+ public Class<?> run() {
+ try {
+ ReflectUtil.checkPackageAccess(className);
+ final ClassLoader targetClassLoader =
+ obj.getClass().getClassLoader();
+ return Class.forName(className, false,
+ targetClassLoader);
+ } catch (ClassNotFoundException e) {
+ caughtException[0] = e;
+ }
+ return null;
+ }
+ }, stack, acc);
+
+ if (caughtException[0] != null) {
+ throw caughtException[0];
+ }
} catch (ClassNotFoundException e) {
final String msg =
"class for invoke " + opName + " not found";
@@ -1061,9 +1089,9 @@
return result;
}
- private static Method resolveMethod(Class<?> targetClass,
+ private Method resolveMethod(Class<?> targetClass,
String opMethodName,
- String[] sig)
+ final String[] sig)
throws ReflectionException {
final boolean tracing = MODELMBEAN_LOGGER.isLoggable(Level.FINER);
@@ -1078,30 +1106,45 @@
if (sig == null)
argClasses = null;
else {
+ final AccessControlContext stack = AccessController.getContext();
+ final ReflectionException[] caughtException = new ReflectionException[1];
final ClassLoader targetClassLoader = targetClass.getClassLoader();
argClasses = new Class<?>[sig.length];
- for (int i = 0; i < sig.length; i++) {
- if (tracing) {
- MODELMBEAN_LOGGER.logp(Level.FINER,
- RequiredModelMBean.class.getName(),"resolveMethod",
- "resolve type " + sig[i]);
- }
- argClasses[i] = (Class<?>) primitiveClassMap.get(sig[i]);
- if (argClasses[i] == null) {
- try {
- argClasses[i] =
- Class.forName(sig[i], false, targetClassLoader);
- } catch (ClassNotFoundException e) {
+
+ javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Void>() {
+
+ @Override
+ public Void run() {
+ for (int i = 0; i < sig.length; i++) {
if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER,
- RequiredModelMBean.class.getName(),
- "resolveMethod",
- "class not found");
+ RequiredModelMBean.class.getName(),"resolveMethod",
+ "resolve type " + sig[i]);
}
- final String msg = "Parameter class not found";
- throw new ReflectionException(e, msg);
+ argClasses[i] = (Class<?>) primitiveClassMap.get(sig[i]);
+ if (argClasses[i] == null) {
+ try {
+ ReflectUtil.checkPackageAccess(sig[i]);
+ argClasses[i] =
+ Class.forName(sig[i], false, targetClassLoader);
+ } catch (ClassNotFoundException e) {
+ if (tracing) {
+ MODELMBEAN_LOGGER.logp(Level.FINER,
+ RequiredModelMBean.class.getName(),
+ "resolveMethod",
+ "class not found");
+ }
+ final String msg = "Parameter class not found";
+ caughtException[0] = new ReflectionException(e, msg);
+ }
+ }
}
+ return null;
}
+ }, stack, acc);
+
+ if (caughtException[0] != null) {
+ throw caughtException[0];
}
}
@@ -1133,7 +1176,7 @@
/* Find a method in RequiredModelMBean as determined by the given
parameters. Return null if there is none, or if the parameters
exclude using it. Called from invoke. */
- private static Method findRMMBMethod(String opMethodName,
+ private Method findRMMBMethod(String opMethodName,
Object targetObjectField,
String opClassName,
String[] sig) {
@@ -1155,19 +1198,29 @@
if (opClassName == null)
targetClass = rmmbClass;
else {
- try {
- final ClassLoader targetClassLoader =
- rmmbClass.getClassLoader();
- targetClass = Class.forName(opClassName, false,
- targetClassLoader);
- if (!rmmbClass.isAssignableFrom(targetClass))
- return null;
- } catch (ClassNotFoundException e) {
- return null;
- }
+ AccessControlContext stack = AccessController.getContext();
+ final String className = opClassName;
+ targetClass = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Class<?>>() {
+
+ @Override
+ public Class<?> run() {
+ try {
+ ReflectUtil.checkPackageAccess(className);
+ final ClassLoader targetClassLoader =
+ rmmbClass.getClassLoader();
+ Class clz = Class.forName(className, false,
+ targetClassLoader);
+ if (!rmmbClass.isAssignableFrom(clz))
+ return null;
+ return clz;
+ } catch (ClassNotFoundException e) {
+ return null;
+ }
+ }
+ }, stack, acc);
}
try {
- return resolveMethod(targetClass, opMethodName, sig);
+ return targetClass != null ? resolveMethod(targetClass, opMethodName, sig) : null;
} catch (ReflectionException e) {
return null;
}
@@ -1177,12 +1230,35 @@
* Invoke the given method, and throw the somewhat unpredictable
* appropriate exception if the method itself gets an exception.
*/
- private Object invokeMethod(String opName, Method method,
- Object targetObject, Object[] opArgs)
+ private Object invokeMethod(String opName, final Method method,
+ final Object targetObject, final Object[] opArgs)
throws MBeanException, ReflectionException {
try {
- ReflectUtil.checkPackageAccess(method.getDeclaringClass());
- return MethodUtil.invoke(method, targetObject, opArgs);
+ final Throwable[] caughtException = new Throwable[1];
+ AccessControlContext stack = AccessController.getContext();
+ Object rslt = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Object>() {
+
+ @Override
+ public Object run() {
+ try {
+ ReflectUtil.checkPackageAccess(method.getDeclaringClass());
+ return MethodUtil.invoke(method, targetObject, opArgs);
+ } catch (InvocationTargetException e) {
+ caughtException[0] = e;
+ } catch (IllegalAccessException e) {
+ caughtException[0] = e;
+ }
+ return null;
+ }
+ }, stack, acc);
+ if (caughtException[0] != null) {
+ if (caughtException[0] instanceof Exception) {
+ throw (Exception)caughtException[0];
+ } else if(caughtException[0] instanceof Error) {
+ throw (Error)caughtException[0];
+ }
+ }
+ return rslt;
} catch (RuntimeErrorException ree) {
throw new RuntimeOperationsException(ree,
"RuntimeException occurred in RequiredModelMBean "+
@@ -1567,7 +1643,7 @@
}
// make sure response class matches type field
- String respType = attrInfo.getType();
+ final String respType = attrInfo.getType();
if (response != null) {
String responseClass = response.getClass().getName();
if (!respType.equals(responseClass)) {
@@ -1590,9 +1666,31 @@
// inequality may come from type subclassing
boolean subtype;
try {
- ClassLoader cl =
- response.getClass().getClassLoader();
- Class<?> c = Class.forName(respType, true, cl);
+ final Class respClass = response.getClass();
+ final Exception[] caughException = new Exception[1];
+
+ AccessControlContext stack = AccessController.getContext();
+
+ Class c = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Class<?>>() {
+
+ @Override
+ public Class<?> run() {
+ try {
+ ReflectUtil.checkPackageAccess(respType);
+ ClassLoader cl =
+ respClass.getClassLoader();
+ return Class.forName(respType, true, cl);
+ } catch (Exception e) {
+ caughException[0] = e;
+ }
+ return null;
+ }
+ }, stack, acc);
+
+ if (caughException[0] != null) {
+ throw caughException[0];
+ }
+
subtype = c.isInstance(response);
} catch (Exception e) {
subtype = false;
@@ -2745,16 +2843,37 @@
return MBeanServerFactory.getClassLoaderRepository(server);
}
- private Class<?> loadClass(String className)
+ private Class<?> loadClass(final String className)
throws ClassNotFoundException {
- try {
- return Class.forName(className);
- } catch (ClassNotFoundException e) {
- final ClassLoaderRepository clr =
- getClassLoaderRepository();
- if (clr == null) throw new ClassNotFoundException(className);
- return clr.loadClass(className);
+ AccessControlContext stack = AccessController.getContext();
+ final ClassNotFoundException[] caughtException = new ClassNotFoundException[1];
+
+ Class c = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Class<?>>() {
+
+ @Override
+ public Class<?> run() {
+ try {
+ ReflectUtil.checkPackageAccess(className);
+ return Class.forName(className);
+ } catch (ClassNotFoundException e) {
+ final ClassLoaderRepository clr =
+ getClassLoaderRepository();
+ try {
+ if (clr == null) throw new ClassNotFoundException(className);
+ return clr.loadClass(className);
+ } catch (ClassNotFoundException ex) {
+ caughtException[0] = ex;
+ }
+ }
+ return null;
+ }
+ }, stack, acc);
+
+ if (caughtException[0] != null) {
+ throw caughtException[0];
}
+
+ return c;
}
--- a/jdk/src/share/classes/javax/swing/JTable.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/javax/swing/JTable.java Fri Mar 15 16:39:07 2013 -0700
@@ -781,15 +781,11 @@
scrollPane.getCorner(JScrollPane.UPPER_TRAILING_CORNER);
if (corner == null || corner instanceof UIResource){
corner = null;
- Object componentClass = UIManager.get(
- "Table.scrollPaneCornerComponent");
- if (componentClass instanceof Class){
- try {
- corner = (Component)
- ((Class)componentClass).newInstance();
- } catch (Exception e) {
- // just ignore and don't set corner
- }
+ try {
+ corner = (Component) UIManager.get(
+ "Table.scrollPaneCornerComponent");
+ } catch (Exception e) {
+ // just ignore and don't set corner
}
scrollPane.setCorner(JScrollPane.UPPER_TRAILING_CORNER,
corner);
--- a/jdk/src/share/classes/javax/swing/RepaintManager.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/javax/swing/RepaintManager.java Fri Mar 15 16:39:07 2013 -0700
@@ -27,11 +27,12 @@
import java.awt.*;
import java.awt.event.*;
-import java.awt.peer.ComponentPeer;
-import java.awt.peer.ContainerPeer;
import java.awt.image.VolatileImage;
+import java.security.AccessControlContext;
import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
import java.applet.*;
import sun.awt.AWTAccessor;
@@ -39,6 +40,8 @@
import sun.awt.DisplayChangedListener;
import sun.awt.SunToolkit;
import sun.java2d.SunGraphicsEnvironment;
+import sun.misc.JavaSecurityAccess;
+import sun.misc.SharedSecrets;
import sun.security.action.GetPropertyAction;
import com.sun.java.swing.SwingUtilities3;
@@ -176,6 +179,9 @@
*/
private final ProcessingRunnable processingRunnable;
+ private final static JavaSecurityAccess javaSecurityAccess =
+ SharedSecrets.getJavaSecurityAccess();
+
static {
volatileImageBufferEnabled = "true".equals(AccessController.
@@ -548,13 +554,26 @@
// This is called from the toolkit thread when awt needs to run a
// Runnable before we paint.
//
- void nativeQueueSurfaceDataRunnable(AppContext appContext, Component c,
- Runnable r) {
+ void nativeQueueSurfaceDataRunnable(AppContext appContext,
+ final Component c, final Runnable r)
+ {
synchronized(this) {
if (runnableList == null) {
runnableList = new LinkedList<Runnable>();
}
- runnableList.add(r);
+ runnableList.add(new Runnable() {
+ public void run() {
+ AccessControlContext stack = AccessController.getContext();
+ AccessControlContext acc =
+ AWTAccessor.getComponentAccessor().getAccessControlContext(c);
+ javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Void>() {
+ public Void run() {
+ r.run();
+ return null;
+ }
+ }, stack, acc);
+ }
+ });
}
scheduleProcessingRunnable(appContext);
}
@@ -652,9 +671,9 @@
* @see #addInvalidComponent
*/
public void validateInvalidComponents() {
- java.util.List<Component> ic;
+ final java.util.List<Component> ic;
synchronized(this) {
- if(invalidComponents == null) {
+ if (invalidComponents == null) {
return;
}
ic = invalidComponents;
@@ -662,7 +681,17 @@
}
int n = ic.size();
for(int i = 0; i < n; i++) {
- ic.get(i).validate();
+ final Component c = ic.get(i);
+ AccessControlContext stack = AccessController.getContext();
+ AccessControlContext acc =
+ AWTAccessor.getComponentAccessor().getAccessControlContext(c);
+ javaSecurityAccess.doIntersectionPrivilege(
+ new PrivilegedAction<Void>() {
+ public Void run() {
+ c.validate();
+ return null;
+ }
+ }, stack, acc);
}
}
@@ -740,78 +769,78 @@
paintDirtyRegions(tmpDirtyComponents);
}
- private void paintDirtyRegions(Map<Component,Rectangle>
- tmpDirtyComponents){
- int i, count;
- java.util.List<Component> roots;
- Component dirtyComponent;
-
- count = tmpDirtyComponents.size();
- if (count == 0) {
+ private void paintDirtyRegions(
+ final Map<Component,Rectangle> tmpDirtyComponents)
+ {
+ if (tmpDirtyComponents.isEmpty()) {
return;
}
- Rectangle rect;
- int localBoundsX = 0;
- int localBoundsY = 0;
- int localBoundsH;
- int localBoundsW;
-
- roots = new ArrayList<Component>(count);
-
+ final java.util.List<Component> roots =
+ new ArrayList<Component>(tmpDirtyComponents.size());
for (Component dirty : tmpDirtyComponents.keySet()) {
collectDirtyComponents(tmpDirtyComponents, dirty, roots);
}
- count = roots.size();
+ final AtomicInteger count = new AtomicInteger(roots.size());
painting = true;
try {
- for(i=0 ; i < count ; i++) {
- dirtyComponent = roots.get(i);
- rect = tmpDirtyComponents.get(dirtyComponent);
- // Sometimes when RepaintManager is changed during the painting
- // we may get null here, see #6995769 for details
- if (rect == null) {
- continue;
- }
- localBoundsH = dirtyComponent.getHeight();
- localBoundsW = dirtyComponent.getWidth();
+ for (int j=0 ; j < count.get(); j++) {
+ final int i = j;
+ final Component dirtyComponent = roots.get(j);
+ AccessControlContext stack = AccessController.getContext();
+ AccessControlContext acc =
+ AWTAccessor.getComponentAccessor().getAccessControlContext(dirtyComponent);
+ javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Void>() {
+ public Void run() {
+ Rectangle rect = tmpDirtyComponents.get(dirtyComponent);
+ // Sometimes when RepaintManager is changed during the painting
+ // we may get null here, see #6995769 for details
+ if (rect == null) {
+ return null;
+ }
- SwingUtilities.computeIntersection(localBoundsX,
- localBoundsY,
- localBoundsW,
- localBoundsH,
- rect);
- if (dirtyComponent instanceof JComponent) {
- ((JComponent)dirtyComponent).paintImmediately(
- rect.x,rect.y,rect.width, rect.height);
- }
- else if (dirtyComponent.isShowing()) {
- Graphics g = JComponent.safelyGetGraphics(
- dirtyComponent, dirtyComponent);
- // If the Graphics goes away, it means someone disposed of
- // the window, don't do anything.
- if (g != null) {
- g.setClip(rect.x, rect.y, rect.width, rect.height);
- try {
- dirtyComponent.paint(g);
- } finally {
- g.dispose();
+ int localBoundsH = dirtyComponent.getHeight();
+ int localBoundsW = dirtyComponent.getWidth();
+ SwingUtilities.computeIntersection(0,
+ 0,
+ localBoundsW,
+ localBoundsH,
+ rect);
+ if (dirtyComponent instanceof JComponent) {
+ ((JComponent)dirtyComponent).paintImmediately(
+ rect.x,rect.y,rect.width, rect.height);
}
+ else if (dirtyComponent.isShowing()) {
+ Graphics g = JComponent.safelyGetGraphics(
+ dirtyComponent, dirtyComponent);
+ // If the Graphics goes away, it means someone disposed of
+ // the window, don't do anything.
+ if (g != null) {
+ g.setClip(rect.x, rect.y, rect.width, rect.height);
+ try {
+ dirtyComponent.paint(g);
+ } finally {
+ g.dispose();
+ }
+ }
+ }
+ // If the repaintRoot has been set, service it now and
+ // remove any components that are children of repaintRoot.
+ if (repaintRoot != null) {
+ adjustRoots(repaintRoot, roots, i + 1);
+ count.set(roots.size());
+ paintManager.isRepaintingRoot = true;
+ repaintRoot.paintImmediately(0, 0, repaintRoot.getWidth(),
+ repaintRoot.getHeight());
+ paintManager.isRepaintingRoot = false;
+ // Only service repaintRoot once.
+ repaintRoot = null;
+ }
+
+ return null;
}
- }
- // If the repaintRoot has been set, service it now and
- // remove any components that are children of repaintRoot.
- if (repaintRoot != null) {
- adjustRoots(repaintRoot, roots, i + 1);
- count = roots.size();
- paintManager.isRepaintingRoot = true;
- repaintRoot.paintImmediately(0, 0, repaintRoot.getWidth(),
- repaintRoot.getHeight());
- paintManager.isRepaintingRoot = false;
- // Only service repaintRoot once.
- repaintRoot = null;
- }
+ }, stack, acc);
}
} finally {
painting = false;
--- a/jdk/src/share/classes/javax/swing/UIDefaults.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/javax/swing/UIDefaults.java Fri Mar 15 16:39:07 2013 -0700
@@ -677,6 +677,8 @@
try {
String className = (String)get(uiClassID);
if (className != null) {
+ ReflectUtil.checkPackageAccess(className);
+
Class cls = (Class)get(className);
if (cls == null) {
if (uiClassLoader == null) {
--- a/jdk/src/share/classes/javax/swing/plaf/nimbus/NimbusLookAndFeel.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/javax/swing/plaf/nimbus/NimbusLookAndFeel.java Fri Mar 15 16:39:07 2013 -0700
@@ -159,7 +159,12 @@
// Store Table ScrollPane Corner Component
uiDefaults.put("Table.scrollPaneCornerComponent",
- TableScrollPaneCorner.class);
+ new UIDefaults.ActiveValue() {
+ @Override
+ public Object createValue(UIDefaults table) {
+ return new TableScrollPaneCorner();
+ }
+ });
// Setup the settings for ToolBarSeparator which is custom
// installed for Nimbus
--- a/jdk/src/share/classes/sun/applet/AppletPanel.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/applet/AppletPanel.java Fri Mar 15 16:39:07 2013 -0700
@@ -45,6 +45,7 @@
import java.util.Collections;
import java.util.Locale;
import java.util.WeakHashMap;
+import sun.awt.AWTAccessor;
import sun.awt.AppContext;
import sun.awt.EmbeddedFrame;
import sun.awt.SunToolkit;
@@ -448,12 +449,12 @@
// to avoid deadlock.
try {
final AppletPanel p = this;
-
- EventQueue.invokeAndWait(new Runnable() {
- public void run() {
- p.validate();
- }
- });
+ Runnable r = new Runnable() {
+ public void run() {
+ p.validate();
+ }
+ };
+ AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r);
}
catch(InterruptedException ie) {
}
@@ -478,18 +479,19 @@
try {
final AppletPanel p = this;
final Applet a = applet;
-
- EventQueue.invokeAndWait(new Runnable() {
- public void run() {
- p.validate();
- a.setVisible(true);
+ Runnable r = new Runnable() {
+ public void run() {
+ p.validate();
+ a.setVisible(true);
- // Fix for BugTraq ID 4041703.
- // Set the default focus for an applet.
- if (hasInitialFocus())
- setDefaultFocus();
+ // Fix for BugTraq ID 4041703.
+ // Set the default focus for an applet.
+ if (hasInitialFocus()) {
+ setDefaultFocus();
}
- });
+ }
+ };
+ AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r);
}
catch(InterruptedException ie) {
}
@@ -512,13 +514,12 @@
// to avoid deadlock.
try {
final Applet a = applet;
-
- EventQueue.invokeAndWait(new Runnable() {
- public void run()
- {
- a.setVisible(false);
- }
- });
+ Runnable r = new Runnable() {
+ public void run() {
+ a.setVisible(false);
+ }
+ };
+ AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r);
}
catch(InterruptedException ie) {
}
@@ -570,17 +571,14 @@
}
status = APPLET_DISPOSE;
- try
- {
+ try {
final Applet a = applet;
-
- EventQueue.invokeAndWait(new Runnable()
- {
- public void run()
- {
+ Runnable r = new Runnable() {
+ public void run() {
remove(a);
}
- });
+ };
+ AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r);
}
catch(InterruptedException ie)
{
--- a/jdk/src/share/classes/sun/awt/AWTAccessor.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/awt/AWTAccessor.java Fri Mar 15 16:39:07 2013 -0700
@@ -34,6 +34,8 @@
import java.awt.event.KeyEvent;
import java.awt.geom.Point2D;
import java.awt.peer.ComponentPeer;
+
+import java.lang.reflect.InvocationTargetException;
import java.security.AccessControlContext;
import java.io.File;
@@ -476,6 +478,12 @@
* appeared.
*/
void wakeup(EventQueue eventQueue, boolean isShutdown);
+
+ /**
+ * Static in EventQueue
+ */
+ void invokeAndWait(Object source, Runnable r)
+ throws InterruptedException, InvocationTargetException;
}
/*
--- a/jdk/src/share/classes/sun/awt/AppContext.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/awt/AppContext.java Fri Mar 15 16:39:07 2013 -0700
@@ -327,21 +327,27 @@
// Before we return the main "system" AppContext, check to
// see if there's an AWTSecurityManager installed. If so,
// allow it to choose the AppContext to return.
- SecurityManager securityManager = System.getSecurityManager();
- if ((securityManager != null) &&
- (securityManager instanceof AWTSecurityManager))
- {
- AWTSecurityManager awtSecMgr = (AWTSecurityManager)securityManager;
- AppContext secAppContext = awtSecMgr.getAppContext();
- if (secAppContext != null) {
- appContext = secAppContext; // Return what we're told
- }
+ AppContext secAppContext = getExecutionAppContext();
+ if (secAppContext != null) {
+ appContext = secAppContext; // Return what we're told
}
}
return appContext;
}
+ private final static AppContext getExecutionAppContext() {
+ SecurityManager securityManager = System.getSecurityManager();
+ if ((securityManager != null) &&
+ (securityManager instanceof AWTSecurityManager))
+ {
+ AWTSecurityManager awtSecMgr = (AWTSecurityManager) securityManager;
+ AppContext secAppContext = awtSecMgr.getAppContext();
+ return secAppContext; // Return what we're told
+ }
+ return null;
+ }
+
/**
* Returns the main ("system") AppContext.
*
@@ -806,6 +812,21 @@
public boolean isMainAppContext() {
return (numAppContexts.get() == 1);
}
+ public Object getContext() {
+ return getAppContext();
+ }
+ public Object getExecutionContext() {
+ return getExecutionAppContext();
+ }
+ public Object get(Object context, Object key) {
+ return ((AppContext)context).get(key);
+ }
+ public void put(Object context, Object key, Object value) {
+ ((AppContext)context).put(key, value);
+ }
+ public void remove(Object context, Object key) {
+ ((AppContext)context).remove(key);
+ }
});
}
}
--- a/jdk/src/share/classes/sun/awt/image/ByteComponentRaster.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/awt/image/ByteComponentRaster.java Fri Mar 15 16:39:07 2013 -0700
@@ -198,7 +198,7 @@
}
this.bandOffset = this.dataOffsets[0];
- verify(false);
+ verify();
}
/**
@@ -857,38 +857,68 @@
}
/**
- * Verify that the layout parameters are consistent with
- * the data. If strictCheck
- * is false, this method will check for ArrayIndexOutOfBounds conditions. If
- * strictCheck is true, this method will check for additional error
- * conditions such as line wraparound (width of a line greater than
- * the scanline stride).
- * @return String Error string, if the layout is incompatible with
- * the data. Otherwise returns null.
+ * Verify that the layout parameters are consistent with the data.
+ *
+ * The method verifies whether scanline stride and pixel stride do not
+ * cause an integer overflow during calculation of a position of the pixel
+ * in data buffer. It also verifies whether the data buffer has enough data
+ * to correspond the raster layout attributes.
+ *
+ * @throws RasterFormatException if an integer overflow is detected,
+ * or if data buffer has not enough capacity.
*/
- private void verify (boolean strictCheck) {
- // Make sure data for Raster is in a legal range
- for (int i=0; i < dataOffsets.length; i++) {
+ protected final void verify() {
+ for (int i = 0; i < dataOffsets.length; i++) {
if (dataOffsets[i] < 0) {
- throw new RasterFormatException("Data offsets for band "+i+
- "("+dataOffsets[i]+
- ") must be >= 0");
+ throw new RasterFormatException("Data offsets for band " + i
+ + "(" + dataOffsets[i]
+ + ") must be >= 0");
}
}
int maxSize = 0;
int size;
- for (int i=0; i < numDataElements; i++) {
- size = (height-1)*scanlineStride + (width-1)*pixelStride +
- dataOffsets[i];
+ // we can be sure that width and height are greater than 0
+ if (scanlineStride < 0 ||
+ scanlineStride > (Integer.MAX_VALUE / height))
+ {
+ // integer overflow
+ throw new RasterFormatException("Incorrect scanline stride: "
+ + scanlineStride);
+ }
+ int lastScanOffset = (height - 1) * scanlineStride;
+
+ if (pixelStride < 0 ||
+ pixelStride > (Integer.MAX_VALUE / width))
+ {
+ // integer overflow
+ throw new RasterFormatException("Incorrect pixel stride: "
+ + pixelStride);
+ }
+ int lastPixelOffset = (width - 1) * pixelStride;
+
+ if (lastPixelOffset > (Integer.MAX_VALUE - lastScanOffset)) {
+ // integer overflow
+ throw new RasterFormatException("Incorrect raster attributes");
+ }
+ lastPixelOffset += lastScanOffset;
+
+ for (int i = 0; i < numDataElements; i++) {
+ size = lastPixelOffset + dataOffsets[i];
+ if (dataOffsets[i] > (Integer.MAX_VALUE - lastPixelOffset)) {
+ throw new RasterFormatException("Incorrect band offset: "
+ + dataOffsets[i]);
+
+ }
+
if (size > maxSize) {
maxSize = size;
}
}
if (data.length < maxSize) {
- throw new RasterFormatException("Data array too small (should be "+
- maxSize+" )");
+ throw new RasterFormatException("Data array too small (should be "
+ + maxSize + " )");
}
}
--- a/jdk/src/share/classes/sun/awt/image/ByteInterleavedRaster.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/awt/image/ByteInterleavedRaster.java Fri Mar 15 16:39:07 2013 -0700
@@ -250,7 +250,7 @@
}
}
- verify(false);
+ verify();
}
/**
@@ -1292,33 +1292,6 @@
return createCompatibleWritableRaster(width,height);
}
- /**
- * Verify that the layout parameters are consistent with
- * the data. If strictCheck
- * is false, this method will check for ArrayIndexOutOfBounds conditions. If
- * strictCheck is true, this method will check for additional error
- * conditions such as line wraparound (width of a line greater than
- * the scanline stride).
- * @return String Error string, if the layout is incompatible with
- * the data. Otherwise returns null.
- */
- private void verify (boolean strictCheck) {
- int maxSize = 0;
- int size;
-
- for (int i=0; i < numDataElements; i++) {
- size = (height-1)*scanlineStride + (width-1)*pixelStride +
- dataOffsets[i];
- if (size > maxSize) {
- maxSize = size;
- }
- }
- if (data.length < maxSize) {
- throw new RasterFormatException("Data array too small (should be "+
- maxSize+" )");
- }
- }
-
public String toString() {
return new String ("ByteInterleavedRaster: width = "+width+" height = "
+ height
--- a/jdk/src/share/classes/sun/awt/image/ShortComponentRaster.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/awt/image/ShortComponentRaster.java Fri Mar 15 16:39:07 2013 -0700
@@ -198,7 +198,7 @@
}
this.bandOffset = this.dataOffsets[0];
- verify(false);
+ verify();
}
/**
@@ -791,38 +791,67 @@
}
/**
- * Verify that the layout parameters are consistent with
- * the data. If strictCheck
- * is false, this method will check for ArrayIndexOutOfBounds conditions. If
- * strictCheck is true, this method will check for additional error
- * conditions such as line wraparound (width of a line greater than
- * the scanline stride).
- * @return String Error string, if the layout is incompatible with
- * the data. Otherwise returns null.
+ * Verify that the layout parameters are consistent with the data.
+ *
+ * The method verifies whether scanline stride and pixel stride do not
+ * cause an integer overflow during calculation of a position of the pixel
+ * in data buffer. It also verifies whether the data buffer has enough data
+ * to correspond the raster layout attributes.
+ *
+ * @throws RasterFormatException if an integer overflow is detected,
+ * or if data buffer has not enough capacity.
*/
- private void verify (boolean strictCheck) {
- // Make sure data for Raster is in a legal range
- for (int i=0; i < dataOffsets.length; i++) {
+ protected final void verify() {
+ for (int i = 0; i < dataOffsets.length; i++) {
if (dataOffsets[i] < 0) {
- throw new RasterFormatException("Data offsets for band "+i+
- "("+dataOffsets[i]+
- ") must be >= 0");
+ throw new RasterFormatException("Data offsets for band " + i
+ + "(" + dataOffsets[i]
+ + ") must be >= 0");
}
}
int maxSize = 0;
int size;
- for (int i=0; i < numDataElements; i++) {
- size = (height-1)*scanlineStride + (width-1)*pixelStride +
- dataOffsets[i];
+ // we can be sure that width and height are greater than 0
+ if (scanlineStride < 0 ||
+ scanlineStride > (Integer.MAX_VALUE / height))
+ {
+ // integer overflow
+ throw new RasterFormatException("Incorrect scanline stride: "
+ + scanlineStride);
+ }
+ int lastScanOffset = (height - 1) * scanlineStride;
+
+ if (pixelStride < 0 ||
+ pixelStride > (Integer.MAX_VALUE / width))
+ {
+ // integer overflow
+ throw new RasterFormatException("Incorrect pixel stride: "
+ + pixelStride);
+ }
+ int lastPixelOffset = (width - 1) * pixelStride;
+
+ if (lastPixelOffset > (Integer.MAX_VALUE - lastScanOffset)) {
+ // integer overflow
+ throw new RasterFormatException("Incorrect raster attributes");
+ }
+ lastPixelOffset += lastScanOffset;
+
+ for (int i = 0; i < numDataElements; i++) {
+ size = lastPixelOffset + dataOffsets[i];
+ if (dataOffsets[i] > (Integer.MAX_VALUE - lastPixelOffset)) {
+ throw new RasterFormatException("Incorrect band offset: "
+ + dataOffsets[i]);
+ }
+
if (size > maxSize) {
maxSize = size;
}
}
if (data.length < maxSize) {
- throw new RasterFormatException("Data array too small (should be "+
- maxSize+" )");
+ throw new RasterFormatException("Data array too small (should be "
+ + maxSize + " )");
}
}
--- a/jdk/src/share/classes/sun/awt/image/ShortInterleavedRaster.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/awt/image/ShortInterleavedRaster.java Fri Mar 15 16:39:07 2013 -0700
@@ -171,7 +171,7 @@
sampleModel);
}
this.bandOffset = this.dataOffsets[0];
- verify(false);
+ verify();
}
/**
@@ -762,33 +762,6 @@
return createCompatibleWritableRaster(width,height);
}
- /**
- * Verify that the layout parameters are consistent with
- * the data. If strictCheck
- * is false, this method will check for ArrayIndexOutOfBounds conditions. If
- * strictCheck is true, this method will check for additional error
- * conditions such as line wraparound (width of a line greater than
- * the scanline stride).
- * @return String Error string, if the layout is incompatible with
- * the data. Otherwise returns null.
- */
- private void verify (boolean strictCheck) {
- int maxSize = 0;
- int size;
-
- for (int i=0; i < numDataElements; i++) {
- size = (height-1)*scanlineStride + (width-1)*pixelStride +
- dataOffsets[i];
- if (size > maxSize) {
- maxSize = size;
- }
- }
- if (data.length < maxSize) {
- throw new RasterFormatException("Data array too small (should be "+
- maxSize+" )");
- }
- }
-
public String toString() {
return new String ("ShortInterleavedRaster: width = "+width
+" height = " + height
--- a/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMS.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMS.java Fri Mar 15 16:39:07 2013 -0700
@@ -25,29 +25,91 @@
package sun.java2d.cmm.lcms;
-import java.awt.color.ColorSpace;
import java.awt.color.ICC_Profile;
-import java.awt.color.CMMException;
+import java.util.Arrays;
+import java.util.HashMap;
import sun.java2d.cmm.ColorTransform;
import sun.java2d.cmm.PCMM;
-import sun.java2d.cmm.lcms.LCMS;
-import sun.java2d.cmm.lcms.LCMSTransform;
public class LCMS implements PCMM {
/* methods invoked from ICC_Profile */
- public native long loadProfile(byte[] data);
+ @Override
+ public long loadProfile(byte[] data) {
+ long id = loadProfileNative(data);
+
+ if (id != 0L) {
+ if (profiles == null) {
+ profiles = new HashMap<>();
+ }
+ profiles.put(id, new TagCache(id));
+ }
+ return id;
+ }
- public native void freeProfile(long profileID);
+ private native long loadProfileNative(byte[] data);
+
+ @Override
+ public void freeProfile(long profileID) {
+ TagCache c = profiles.remove(profileID);
+ if (c != null) {
+ c.clear();
+ }
+ if (profiles.isEmpty()) {
+ profiles = null;
+ }
+ freeProfileNative(profileID);
+ }
+
+ private native void freeProfileNative(long profileID);
public native synchronized int getProfileSize(long profileID);
public native synchronized void getProfileData(long profileID, byte[] data);
- public native synchronized int getTagSize(long profileID, int tagSignature);
- public native synchronized void getTagData(long profileID, int tagSignature,
- byte[] data);
- public native synchronized void setTagData(long profileID, int tagSignature,
+ @Override
+ public synchronized int getTagSize(long profileID, int tagSignature) {
+ TagCache cache = profiles.get(profileID);
+
+ if (cache == null) {
+ cache = new TagCache(profileID);
+ profiles.put(profileID, cache);
+ }
+
+ TagData t = cache.getTag(tagSignature);
+ return t == null ? 0 : t.getSize();
+ }
+
+ private static native byte[] getTagNative(long profileID, int signature);
+
+ @Override
+ public synchronized void getTagData(long profileID, int tagSignature,
+ byte[] data)
+ {
+ TagCache cache = profiles.get(profileID);
+
+ if (cache == null) {
+ cache = new TagCache(profileID);
+ profiles.put(profileID, cache);
+ }
+
+ TagData t = cache.getTag(tagSignature);
+ if (t != null) {
+ t.copyDataTo(data);
+ }
+ }
+
+ @Override
+ public synchronized void setTagData(long profileID, int tagSignature, byte[] data) {
+ TagCache cache = profiles.get(profileID);
+
+ if (cache != null) {
+ cache.clear();
+ }
+ setTagDataNative(profileID, tagSignature, data);
+ }
+
+ private native synchronized void setTagDataNative(long profileID, int tagSignature,
byte[] data);
public static native long getProfileID(ICC_Profile profile);
@@ -103,4 +165,59 @@
initLCMS(LCMSTransform.class, LCMSImageLayout.class, ICC_Profile.class);
}
+
+ private static class TagData {
+ private int signature;
+ private byte[] data;
+
+ TagData(int sig, byte[] data) {
+ this.signature = sig;
+ this.data = data;
+ }
+
+ int getSize() {
+ return data.length;
+ }
+
+ byte[] getData() {
+ return Arrays.copyOf(data, data.length);
+ }
+
+ void copyDataTo(byte[] dst) {
+ System.arraycopy(data, 0, dst, 0, data.length);
+ }
+
+ int getSignature() {
+ return signature;
+ }
+ }
+
+ private static class TagCache {
+ private long profileID;
+ private HashMap<Integer, TagData> tags;
+
+ TagCache(long id) {
+ profileID = id;
+
+ tags = new HashMap<>();
+ }
+
+ TagData getTag(int sig) {
+ TagData t = tags.get(sig);
+ if (t == null) {
+ byte[] tagData = getTagNative(profileID, sig);
+ if (tagData != null) {
+ t = new TagData(sig, tagData);
+ tags.put(sig, t);
+ }
+ }
+ return t;
+ }
+
+ void clear() {
+ tags.clear();
+ }
+ }
+
+ private static HashMap<Long, TagCache> profiles;
}
--- a/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java Fri Mar 15 16:39:07 2013 -0700
@@ -22,26 +22,19 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
-
package sun.java2d.cmm.lcms;
-import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.ComponentColorModel;
-import java.awt.image.Raster;
-import java.awt.image.WritableRaster;
-import java.awt.image.SinglePixelPackedSampleModel;
import java.awt.image.ComponentSampleModel;
import java.awt.image.DataBuffer;
-import java.awt.image.DataBufferByte;
-import java.awt.image.DataBufferUShort;
-import java.awt.image.DataBufferInt;
import java.awt.image.ColorModel;
+import java.awt.image.Raster;
+import java.awt.image.SampleModel;
import sun.awt.image.ByteComponentRaster;
import sun.awt.image.ShortComponentRaster;
import sun.awt.image.IntegerComponentRaster;
-
class LCMSImageLayout {
public static int BYTES_SH(int x) {
@@ -49,47 +42,34 @@
}
public static int EXTRA_SH(int x) {
- return x<<7;
+ return x << 7;
}
public static int CHANNELS_SH(int x) {
- return x<<3;
+ return x << 3;
}
-
- public static final int SWAPFIRST = 1<<14;
-
- public static final int DOSWAP = 1<<10;
-
+ public static final int SWAPFIRST = 1 << 14;
+ public static final int DOSWAP = 1 << 10;
public static final int PT_RGB_8 =
- CHANNELS_SH(3) | BYTES_SH(1);
-
+ CHANNELS_SH(3) | BYTES_SH(1);
public static final int PT_GRAY_8 =
- CHANNELS_SH(1) | BYTES_SH(1);
-
+ CHANNELS_SH(1) | BYTES_SH(1);
public static final int PT_GRAY_16 =
- CHANNELS_SH(1) | BYTES_SH(2);
-
+ CHANNELS_SH(1) | BYTES_SH(2);
public static final int PT_RGBA_8 =
- EXTRA_SH(1) | CHANNELS_SH(3) | BYTES_SH(1);
-
+ EXTRA_SH(1) | CHANNELS_SH(3) | BYTES_SH(1);
public static final int PT_ARGB_8 =
- EXTRA_SH(1) | CHANNELS_SH(3) | BYTES_SH(1) | SWAPFIRST;
-
+ EXTRA_SH(1) | CHANNELS_SH(3) | BYTES_SH(1) | SWAPFIRST;
public static final int PT_BGR_8 =
- DOSWAP | CHANNELS_SH(3) | BYTES_SH(1);
-
+ DOSWAP | CHANNELS_SH(3) | BYTES_SH(1);
public static final int PT_ABGR_8 =
- DOSWAP | EXTRA_SH(1) | CHANNELS_SH(3) | BYTES_SH(1);
-
- public static final int PT_BGRA_8 = EXTRA_SH(1) | CHANNELS_SH(3) |
- BYTES_SH(1) | DOSWAP | SWAPFIRST;
-
- public static final int DT_BYTE = 0;
- public static final int DT_SHORT = 1;
- public static final int DT_INT = 2;
- public static final int DT_DOUBLE = 3;
-
-
+ DOSWAP | EXTRA_SH(1) | CHANNELS_SH(3) | BYTES_SH(1);
+ public static final int PT_BGRA_8 = EXTRA_SH(1) | CHANNELS_SH(3)
+ | BYTES_SH(1) | DOSWAP | SWAPFIRST;
+ public static final int DT_BYTE = 0;
+ public static final int DT_SHORT = 1;
+ public static final int DT_INT = 2;
+ public static final int DT_DOUBLE = 3;
boolean isIntPacked = false;
int pixelType;
int dataType;
@@ -98,25 +78,30 @@
int nextRowOffset;
int offset;
+ /* This flag indicates whether the image can be processed
+ * at once by doTransfrom() native call. Otherwise, the
+ * image is processed scan by scan.
+ */
+ private boolean imageAtOnce = false;
Object dataArray;
+
private LCMSImageLayout(int np, int pixelType, int pixelSize) {
this.pixelType = pixelType;
width = np;
height = 1;
- nextRowOffset = np*pixelSize;
+ nextRowOffset = np * pixelSize;
offset = 0;
}
private LCMSImageLayout(int width, int height, int pixelType,
- int pixelSize) {
+ int pixelSize) {
this.pixelType = pixelType;
this.width = width;
this.height = height;
- nextRowOffset = width*pixelSize;
+ nextRowOffset = width * pixelSize;
offset = 0;
}
-
public LCMSImageLayout(byte[] data, int np, int pixelType, int pixelSize) {
this(np, pixelType, pixelSize);
dataType = DT_BYTE;
@@ -135,102 +120,218 @@
dataArray = data;
}
- public LCMSImageLayout(double[] data, int np, int pixelType, int pixelSize)
- {
+ public LCMSImageLayout(double[] data, int np, int pixelType, int pixelSize) {
this(np, pixelType, pixelSize);
dataType = DT_DOUBLE;
dataArray = data;
}
- public LCMSImageLayout(BufferedImage image) {
- ShortComponentRaster shortRaster;
- IntegerComponentRaster intRaster;
- ByteComponentRaster byteRaster;
+ private LCMSImageLayout() {
+ }
+
+ /* This method creates a layout object for given image.
+ * Returns null if the image is not supported by current implementation.
+ */
+ public static LCMSImageLayout createImageLayout(BufferedImage image) {
+ LCMSImageLayout l = new LCMSImageLayout();
+
switch (image.getType()) {
case BufferedImage.TYPE_INT_RGB:
- pixelType = PT_ARGB_8;
- isIntPacked = true;
+ l.pixelType = PT_ARGB_8;
+ l.isIntPacked = true;
break;
case BufferedImage.TYPE_INT_ARGB:
- pixelType = PT_ARGB_8;
- isIntPacked = true;
+ l.pixelType = PT_ARGB_8;
+ l.isIntPacked = true;
break;
case BufferedImage.TYPE_INT_BGR:
- pixelType = PT_ABGR_8;
- isIntPacked = true;
+ l.pixelType = PT_ABGR_8;
+ l.isIntPacked = true;
break;
case BufferedImage.TYPE_3BYTE_BGR:
- pixelType = PT_BGR_8;
+ l.pixelType = PT_BGR_8;
break;
case BufferedImage.TYPE_4BYTE_ABGR:
- pixelType = PT_ABGR_8;
+ l.pixelType = PT_ABGR_8;
break;
case BufferedImage.TYPE_BYTE_GRAY:
- pixelType = PT_GRAY_8;
+ l.pixelType = PT_GRAY_8;
break;
case BufferedImage.TYPE_USHORT_GRAY:
- pixelType = PT_GRAY_16;
+ l.pixelType = PT_GRAY_16;
break;
default:
- // TODO: Add support for some images having
- // SinglePixelPackedModel and ComponentSampleModel
- throw new IllegalArgumentException(
- "CMMImageLayout - bad image type passed to constructor");
+ /* ColorConvertOp creates component images as
+ * default destination, so this kind of images
+ * has to be supported.
+ */
+ ColorModel cm = image.getColorModel();
+ if (cm instanceof ComponentColorModel) {
+ ComponentColorModel ccm = (ComponentColorModel) cm;
+
+ // verify whether the component size is fine
+ int[] cs = ccm.getComponentSize();
+ for (int s : cs) {
+ if (s != 8) {
+ return null;
+ }
+ }
+
+ return createImageLayout(image.getRaster());
+
+ }
+ return null;
}
- width = image.getWidth();
- height = image.getHeight();
+ l.width = image.getWidth();
+ l.height = image.getHeight();
switch (image.getType()) {
case BufferedImage.TYPE_INT_RGB:
case BufferedImage.TYPE_INT_ARGB:
case BufferedImage.TYPE_INT_BGR:
- intRaster = (IntegerComponentRaster)image.getRaster();
- nextRowOffset = intRaster.getScanlineStride()*4;
- offset = intRaster.getDataOffset(0)*4;
- dataArray = intRaster.getDataStorage();
- dataType = DT_INT;
+ do {
+ IntegerComponentRaster intRaster = (IntegerComponentRaster)
+ image.getRaster();
+ l.nextRowOffset = intRaster.getScanlineStride() * 4;
+ l.offset = intRaster.getDataOffset(0) * 4;
+ l.dataArray = intRaster.getDataStorage();
+ l.dataType = DT_INT;
+
+ if (l.nextRowOffset == l.width * 4 * intRaster.getPixelStride()) {
+ l.imageAtOnce = true;
+ }
+ } while (false);
break;
case BufferedImage.TYPE_3BYTE_BGR:
case BufferedImage.TYPE_4BYTE_ABGR:
- byteRaster = (ByteComponentRaster)image.getRaster();
- nextRowOffset = byteRaster.getScanlineStride();
- int firstBand = image.getSampleModel().getNumBands() - 1;
- offset = byteRaster.getDataOffset(firstBand);
- dataArray = byteRaster.getDataStorage();
- dataType = DT_BYTE;
+ do {
+ ByteComponentRaster byteRaster = (ByteComponentRaster)
+ image.getRaster();
+ l.nextRowOffset = byteRaster.getScanlineStride();
+ int firstBand = image.getSampleModel().getNumBands() - 1;
+ l.offset = byteRaster.getDataOffset(firstBand);
+ l.dataArray = byteRaster.getDataStorage();
+ l.dataType = DT_BYTE;
+ if (l.nextRowOffset == l.width * byteRaster.getPixelStride()) {
+ l.imageAtOnce = true;
+ }
+ } while (false);
break;
case BufferedImage.TYPE_BYTE_GRAY:
- byteRaster = (ByteComponentRaster)image.getRaster();
- nextRowOffset = byteRaster.getScanlineStride();
- offset = byteRaster.getDataOffset(0);
- dataArray = byteRaster.getDataStorage();
- dataType = DT_BYTE;
+ do {
+ ByteComponentRaster byteRaster = (ByteComponentRaster)
+ image.getRaster();
+ l.nextRowOffset = byteRaster.getScanlineStride();
+ l.offset = byteRaster.getDataOffset(0);
+ l.dataArray = byteRaster.getDataStorage();
+ l.dataType = DT_BYTE;
+
+ if (l.nextRowOffset == l.width * byteRaster.getPixelStride()) {
+ l.imageAtOnce = true;
+ }
+ } while (false);
break;
case BufferedImage.TYPE_USHORT_GRAY:
- shortRaster = (ShortComponentRaster)image.getRaster();
- nextRowOffset = shortRaster.getScanlineStride()*2;
- offset = shortRaster.getDataOffset(0) * 2;
- dataArray = shortRaster.getDataStorage();
- dataType = DT_SHORT;
+ do {
+ ShortComponentRaster shortRaster = (ShortComponentRaster)
+ image.getRaster();
+ l.nextRowOffset = shortRaster.getScanlineStride() * 2;
+ l.offset = shortRaster.getDataOffset(0) * 2;
+ l.dataArray = shortRaster.getDataStorage();
+ l.dataType = DT_SHORT;
+
+ if (l.nextRowOffset == l.width * 2 * shortRaster.getPixelStride()) {
+ l.imageAtOnce = true;
+ }
+ } while (false);
break;
+ default:
+ return null;
+ }
+ return l;
+ }
+
+ private static enum BandOrder {
+ DIRECT,
+ INVERTED,
+ ARBITRARY,
+ UNKNOWN;
+
+ public static BandOrder getBandOrder(int[] bandOffsets) {
+ BandOrder order = UNKNOWN;
+
+ int numBands = bandOffsets.length;
+
+ for (int i = 0; (order != ARBITRARY) && (i < bandOffsets.length); i++) {
+ switch (order) {
+ case UNKNOWN:
+ if (bandOffsets[i] == i) {
+ order = DIRECT;
+ } else if (bandOffsets[i] == (numBands - 1 - i)) {
+ order = INVERTED;
+ } else {
+ order = ARBITRARY;
+ }
+ break;
+ case DIRECT:
+ if (bandOffsets[i] != i) {
+ order = ARBITRARY;
+ }
+ break;
+ case INVERTED:
+ if (bandOffsets[i] != (numBands - 1 - i)) {
+ order = ARBITRARY;
+ }
+ break;
+ }
+ }
+ return order;
}
}
- public static boolean isSupported(BufferedImage image) {
- switch (image.getType()) {
- case BufferedImage.TYPE_INT_RGB:
- case BufferedImage.TYPE_INT_ARGB:
- case BufferedImage.TYPE_INT_BGR:
- case BufferedImage.TYPE_3BYTE_BGR:
- case BufferedImage.TYPE_4BYTE_ABGR:
- case BufferedImage.TYPE_BYTE_GRAY:
- case BufferedImage.TYPE_USHORT_GRAY:
- return true;
+ public static LCMSImageLayout createImageLayout(Raster r) {
+ LCMSImageLayout l = new LCMSImageLayout();
+ if (r instanceof ByteComponentRaster) {
+ ByteComponentRaster br = (ByteComponentRaster)r;
+
+ ComponentSampleModel csm = (ComponentSampleModel)r.getSampleModel();
+
+ l.pixelType = CHANNELS_SH(br.getNumBands()) | BYTES_SH(1);
+
+ int[] bandOffsets = csm.getBandOffsets();
+ BandOrder order = BandOrder.getBandOrder(bandOffsets);
+
+ int firstBand = 0;
+ switch (order) {
+ case INVERTED:
+ l.pixelType |= DOSWAP;
+ firstBand = csm.getNumBands() - 1;
+ break;
+ case DIRECT:
+ // do nothing
+ break;
+ default:
+ // unable to create the image layout;
+ return null;
+ }
+
+ l.nextRowOffset = br.getScanlineStride();
+ l.offset = br.getDataOffset(firstBand);
+ l.dataArray = br.getDataStorage();
+ l.dataType = DT_BYTE;
+
+ l.width = br.getWidth();
+ l.height = br.getHeight();
+
+ if (l.nextRowOffset == l.width * br.getPixelStride()) {
+ l.imageAtOnce = true;
+ }
+ return l;
}
- return false;
+ return null;
}
}
--- a/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java Fri Mar 15 16:39:07 2013 -0700
@@ -161,13 +161,18 @@
}
public void colorConvert(BufferedImage src, BufferedImage dst) {
- if (LCMSImageLayout.isSupported(src) &&
- LCMSImageLayout.isSupported(dst))
- {
- doTransform(new LCMSImageLayout(src), new LCMSImageLayout(dst));
- return;
+ LCMSImageLayout srcIL, dstIL;
+
+ dstIL = LCMSImageLayout.createImageLayout(dst);
+
+ if (dstIL != null) {
+ srcIL = LCMSImageLayout.createImageLayout(src);
+ if (srcIL != null) {
+ doTransform(srcIL, dstIL);
+ return;
+ }
}
- LCMSImageLayout srcIL, dstIL;
+
Raster srcRas = src.getRaster();
WritableRaster dstRas = dst.getRaster();
ColorModel srcCM = src.getColorModel();
@@ -439,6 +444,14 @@
public void colorConvert(Raster src, WritableRaster dst) {
LCMSImageLayout srcIL, dstIL;
+ dstIL = LCMSImageLayout.createImageLayout(dst);
+ if (dstIL != null) {
+ srcIL = LCMSImageLayout.createImageLayout(src);
+ if (srcIL != null) {
+ doTransform(srcIL, dstIL);
+ return;
+ }
+ }
// Can't pass src and dst directly to CMM, so process per scanline
SampleModel srcSM = src.getSampleModel();
SampleModel dstSM = dst.getSampleModel();
--- a/jdk/src/share/classes/sun/misc/ClassFileTransformer.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/misc/ClassFileTransformer.java Fri Mar 15 16:39:07 2013 -0700
@@ -25,43 +25,31 @@
package sun.misc;
import java.util.ArrayList;
+import java.util.List;
/**
- * This is an abstract base class which is called by java.lang.ClassLoader
- * when ClassFormatError is thrown inside defineClass().
- *
- * The purpose of this class is to allow applications (e.g. Java Plug-in)
- * to have a chance to transform the byte code from one form to another
- * if necessary.
- *
- * One application of this class is used by Java Plug-in to transform
- * malformed JDK 1.1 class file into a well-formed Java 2 class file
- * on-the-fly, so JDK 1.1 applets with malformed class file in the
- * Internet may run in Java 2 after transformation.
+ * This is an abstract base class originally intended to be called by
+ * {@code java.lang.ClassLoader} when {@code ClassFormatError} is
+ * thrown inside {@code defineClass()}. It is no longer hooked into
+ * {@code ClassLoader} and will be removed in a future release.
*
* @author Stanley Man-Kit Ho
*/
-public abstract class ClassFileTransformer
-{
- // Singleton of ClassFileTransformer
- //
- private static ArrayList<ClassFileTransformer> transformerList
+@Deprecated
+public abstract class ClassFileTransformer {
+
+ private static final List<ClassFileTransformer> transformers
= new ArrayList<ClassFileTransformer>();
- private static ClassFileTransformer[] transformers
- = new ClassFileTransformer[0];
/**
* Add the class file transformer object.
*
* @param t Class file transformer instance
*/
- public static void add(ClassFileTransformer t)
- {
- synchronized(transformerList)
- {
- transformerList.add(t);
- transformers = transformerList.toArray(new ClassFileTransformer[0]);
+ public static void add(ClassFileTransformer t) {
+ synchronized (transformers) {
+ transformers.add(t);
}
}
@@ -70,13 +58,11 @@
*
* @return ClassFileTransformer object array
*/
- public static ClassFileTransformer[] getTransformers()
- {
- // transformers is not intended to be changed frequently,
- // so it is okay to not put synchronized block here
- // to speed up performance.
- //
- return transformers;
+ public static ClassFileTransformer[] getTransformers() {
+ synchronized (transformers) {
+ ClassFileTransformer[] result = new ClassFileTransformer[transformers.size()];
+ return transformers.toArray(result);
+ }
}
@@ -89,5 +75,5 @@
* @return Transformed byte array
*/
public abstract byte[] transform(byte[] b, int off, int len)
- throws ClassFormatError;
+ throws ClassFormatError;
}
--- a/jdk/src/share/classes/sun/misc/JavaAWTAccess.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/misc/JavaAWTAccess.java Fri Mar 15 16:39:07 2013 -0700
@@ -26,6 +26,14 @@
package sun.misc;
public interface JavaAWTAccess {
+ public Object getContext();
+ public Object getExecutionContext();
+
+ public Object get(Object context, Object key);
+ public void put(Object context, Object key, Object value);
+ public void remove(Object context, Object key);
+
+ // convenience methods whose context is the object returned by getContext()
public Object get(Object key);
public void put(Object key, Object value);
public void remove(Object key);
--- a/jdk/src/share/classes/sun/misc/JavaUtilJarAccess.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/misc/JavaUtilJarAccess.java Fri Mar 15 16:39:07 2013 -0700
@@ -35,6 +35,7 @@
public interface JavaUtilJarAccess {
public boolean jarFileHasClassPathAttribute(JarFile jar) throws IOException;
+ public boolean jarFileHasProfileAttribute(JarFile jar) throws IOException;
public CodeSource[] getCodeSources(JarFile jar, URL url);
public CodeSource getCodeSource(JarFile jar, URL url, String name);
public Enumeration<String> entryNames(JarFile jar, CodeSource[] cs);
--- a/jdk/src/share/classes/sun/misc/URLClassPath.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/misc/URLClassPath.java Fri Mar 15 16:39:07 2013 -0700
@@ -808,9 +808,6 @@
/**
* If the Profile attribute is present then this method checks that the runtime
* supports that profile.
- *
- * ## Add a fast path like Class-Path to avoid reading the manifest when the attribute
- * is not present.
*/
void checkProfileAttribute() throws IOException {
Manifest man = jar.getManifest();
@@ -998,7 +995,8 @@
parseExtensionsDependencies();
// check Profile attribute if present
- if (!profileCheckSuppressedByLauncher) {
+ if (!profileCheckSuppressedByLauncher &&
+ SharedSecrets.javaUtilJarAccess().jarFileHasProfileAttribute(jar)) {
checkProfileAttribute();
}
--- a/jdk/src/share/classes/sun/net/httpserver/ChunkedInputStream.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/net/httpserver/ChunkedInputStream.java Fri Mar 15 16:39:07 2013 -0700
@@ -41,8 +41,12 @@
private boolean needToReadHeader = true;
- static char CR = '\r';
- static char LF = '\n';
+ final static char CR = '\r';
+ final static char LF = '\n';
+ /*
+ * Maximum chunk header size of 2KB + 2 bytes for CRLF
+ */
+ private final static int MAX_CHUNK_HEADER_SIZE = 2050;
private int numeric (char[] arr, int nchars) throws IOException {
assert arr.length >= nchars;
@@ -73,10 +77,14 @@
char[] len_arr = new char [16];
int len_size = 0;
boolean end_of_len = false;
+ int read = 0;
while ((c=in.read())!= -1) {
char ch = (char) c;
- if (len_size == len_arr.length -1) {
+ read++;
+ if ((len_size == len_arr.length -1) ||
+ (read > MAX_CHUNK_HEADER_SIZE))
+ {
throw new IOException ("invalid chunk header");
}
if (gotCR) {
--- a/jdk/src/share/classes/sun/net/www/http/ChunkedInputStream.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/net/www/http/ChunkedInputStream.java Fri Mar 15 16:39:07 2013 -0700
@@ -125,6 +125,11 @@
*/
private boolean closed;
+ /*
+ * Maximum chunk header size of 2KB + 2 bytes for CRLF
+ */
+ private final static int MAX_CHUNK_HEADER_SIZE = 2050;
+
/**
* State to indicate that next field should be :-
* chunk-size [ chunk-extension ] CRLF
@@ -290,6 +295,10 @@
break;
}
pos++;
+ if ((pos - rawPos) >= MAX_CHUNK_HEADER_SIZE) {
+ error = true;
+ throw new IOException("Chunk header too long");
+ }
}
if (pos >= rawCount) {
return;
--- a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -2637,7 +2637,7 @@
multipleCookies = true;
}
- return retValue.length() == 0 ? null : retValue.toString();
+ return retValue.length() == 0 ? "" : retValue.toString();
}
return value;
--- a/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java Fri Mar 15 16:39:07 2013 -0700
@@ -421,7 +421,7 @@
synchronized (writeLock) {
ensureOpen();
- InetSocketAddress isa = (InetSocketAddress)target;
+ InetSocketAddress isa = Net.checkAddress(target);
InetAddress ia = isa.getAddress();
if (ia == null)
throw new IOException("Target address not resolved");
@@ -432,9 +432,9 @@
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
if (ia.isMulticastAddress()) {
- sm.checkMulticast(isa.getAddress());
+ sm.checkMulticast(ia);
} else {
- sm.checkConnect(isa.getAddress().getHostAddress(),
+ sm.checkConnect(ia.getHostAddress(),
isa.getPort());
}
}
@@ -454,7 +454,7 @@
return 0;
writerThread = NativeThread.current();
do {
- n = send(fd, src, target);
+ n = send(fd, src, isa);
} while ((n == IOStatus.INTERRUPTED) && isOpen());
synchronized (stateLock) {
@@ -471,7 +471,7 @@
}
}
- private int send(FileDescriptor fd, ByteBuffer src, SocketAddress target)
+ private int send(FileDescriptor fd, ByteBuffer src, InetSocketAddress target)
throws IOException
{
if (src instanceof DirectBuffer)
@@ -502,7 +502,7 @@
}
private int sendFromNativeBuffer(FileDescriptor fd, ByteBuffer bb,
- SocketAddress target)
+ InetSocketAddress target)
throws IOException
{
int pos = bb.position();
@@ -514,7 +514,7 @@
int written;
try {
written = send0(preferIPv6, fd, ((DirectBuffer)bb).address() + pos,
- rem, target);
+ rem, target.getAddress(), target.getPort());
} catch (PortUnreachableException pue) {
if (isConnected())
throw pue;
@@ -1116,8 +1116,8 @@
boolean connected)
throws IOException;
- private native int send0(boolean preferIPv6, FileDescriptor fd, long address, int len,
- SocketAddress sa)
+ private native int send0(boolean preferIPv6, FileDescriptor fd, long address,
+ int len, InetAddress addr, int port)
throws IOException;
static {
--- a/jdk/src/share/classes/sun/print/RasterPrinterJob.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/print/RasterPrinterJob.java Fri Mar 15 16:39:07 2013 -0700
@@ -527,9 +527,92 @@
}
}
+ private PageFormat attributeToPageFormat(PrintService service,
+ PrintRequestAttributeSet attSet) {
+ PageFormat page = defaultPage();
+
+ if (service == null) {
+ return page;
+ }
+
+ OrientationRequested orient = (OrientationRequested)
+ attSet.get(OrientationRequested.class);
+ if (orient == null) {
+ orient = (OrientationRequested)
+ service.getDefaultAttributeValue(OrientationRequested.class);
+ }
+ if (orient == OrientationRequested.REVERSE_LANDSCAPE) {
+ page.setOrientation(PageFormat.REVERSE_LANDSCAPE);
+ } else if (orient == OrientationRequested.LANDSCAPE) {
+ page.setOrientation(PageFormat.LANDSCAPE);
+ } else {
+ page.setOrientation(PageFormat.PORTRAIT);
+ }
+
+ Media media = (Media)attSet.get(Media.class);
+ if (media == null) {
+ media =
+ (Media)service.getDefaultAttributeValue(Media.class);
+ }
+ if (!(media instanceof MediaSizeName)) {
+ media = MediaSizeName.NA_LETTER;
+ }
+ MediaSize size =
+ MediaSize.getMediaSizeForName((MediaSizeName)media);
+ if (size == null) {
+ size = MediaSize.NA.LETTER;
+ }
+ Paper paper = new Paper();
+ float dim[] = size.getSize(1); //units == 1 to avoid FP error
+ double w = Math.rint((dim[0]*72.0)/Size2DSyntax.INCH);
+ double h = Math.rint((dim[1]*72.0)/Size2DSyntax.INCH);
+ paper.setSize(w, h);
+ MediaPrintableArea area =
+ (MediaPrintableArea)
+ attSet.get(MediaPrintableArea.class);
+ double ix, iw, iy, ih;
+
+ if (area != null) {
+ // Should pass in same unit as updatePageAttributes
+ // to avoid rounding off errors.
+ ix = Math.rint(
+ area.getX(MediaPrintableArea.INCH) * DPI);
+ iy = Math.rint(
+ area.getY(MediaPrintableArea.INCH) * DPI);
+ iw = Math.rint(
+ area.getWidth(MediaPrintableArea.INCH) * DPI);
+ ih = Math.rint(
+ area.getHeight(MediaPrintableArea.INCH) * DPI);
+ }
+ else {
+ if (w >= 72.0 * 6.0) {
+ ix = 72.0;
+ iw = w - 2 * 72.0;
+ } else {
+ ix = w / 6.0;
+ iw = w * 0.75;
+ }
+ if (h >= 72.0 * 6.0) {
+ iy = 72.0;
+ ih = h - 2 * 72.0;
+ } else {
+ iy = h / 6.0;
+ ih = h * 0.75;
+ }
+ }
+ paper.setImageableArea(ix, iy, iw, ih);
+ page.setPaper(paper);
+ return page;
+ }
protected void updatePageAttributes(PrintService service,
PageFormat page) {
+ updateAttributesWithPageFormat(service, page, this.attributes);
+ }
+
+ protected void updateAttributesWithPageFormat(PrintService service,
+ PageFormat page,
+ PrintRequestAttributeSet attributes) {
if (service == null || page == null) {
return;
}
@@ -659,6 +742,18 @@
throw new HeadlessException();
}
+ DialogTypeSelection dlg =
+ (DialogTypeSelection)attributes.get(DialogTypeSelection.class);
+
+ // Check for native, note that default dialog is COMMON.
+ if (dlg == DialogTypeSelection.NATIVE) {
+ PrintService pservice = getPrintService();
+ PageFormat page = pageDialog(attributeToPageFormat(pservice,
+ attributes));
+ updateAttributesWithPageFormat(pservice, page, attributes);
+ return page;
+ }
+
final GraphicsConfiguration gc =
GraphicsEnvironment.getLocalGraphicsEnvironment().
getDefaultScreenDevice().getDefaultConfiguration();
@@ -698,77 +793,7 @@
attributes.remove(amCategory);
}
attributes.addAll(newas);
-
- PageFormat page = defaultPage();
-
- OrientationRequested orient =
- (OrientationRequested)
- attributes.get(OrientationRequested.class);
- int pfOrient = PageFormat.PORTRAIT;
- if (orient != null) {
- if (orient == OrientationRequested.REVERSE_LANDSCAPE) {
- pfOrient = PageFormat.REVERSE_LANDSCAPE;
- } else if (orient == OrientationRequested.LANDSCAPE) {
- pfOrient = PageFormat.LANDSCAPE;
- }
- }
- page.setOrientation(pfOrient);
-
- Media media = (Media)attributes.get(Media.class);
- if (media == null) {
- media =
- (Media)service.getDefaultAttributeValue(Media.class);
- }
- if (!(media instanceof MediaSizeName)) {
- media = MediaSizeName.NA_LETTER;
- }
- MediaSize size =
- MediaSize.getMediaSizeForName((MediaSizeName)media);
- if (size == null) {
- size = MediaSize.NA.LETTER;
- }
- Paper paper = new Paper();
- float dim[] = size.getSize(1); //units == 1 to avoid FP error
- double w = Math.rint((dim[0]*72.0)/Size2DSyntax.INCH);
- double h = Math.rint((dim[1]*72.0)/Size2DSyntax.INCH);
- paper.setSize(w, h);
- MediaPrintableArea area =
- (MediaPrintableArea)
- attributes.get(MediaPrintableArea.class);
- double ix, iw, iy, ih;
-
- if (area != null) {
- // Should pass in same unit as updatePageAttributes
- // to avoid rounding off errors.
- ix = Math.rint(
- area.getX(MediaPrintableArea.INCH) * DPI);
- iy = Math.rint(
- area.getY(MediaPrintableArea.INCH) * DPI);
- iw = Math.rint(
- area.getWidth(MediaPrintableArea.INCH) * DPI);
- ih = Math.rint(
- area.getHeight(MediaPrintableArea.INCH) * DPI);
- }
- else {
- if (w >= 72.0 * 6.0) {
- ix = 72.0;
- iw = w - 2 * 72.0;
- } else {
- ix = w / 6.0;
- iw = w * 0.75;
- }
- if (h >= 72.0 * 6.0) {
- iy = 72.0;
- ih = h - 2 * 72.0;
- } else {
- iy = h / 6.0;
- ih = h * 0.75;
- }
- }
- paper.setImageableArea(ix, iy, iw, ih);
- page.setPaper(paper);
-
- return page;
+ return attributeToPageFormat(service, attributes);
} else {
return null;
}
@@ -795,7 +820,6 @@
throw new HeadlessException();
}
-
DialogTypeSelection dlg =
(DialogTypeSelection)attributes.get(DialogTypeSelection.class);
@@ -816,7 +840,6 @@
}
-
/* A security check has already been performed in the
* java.awt.print.printerJob.getPrinterJob method.
* So by the time we get here, it is OK for the current thread
--- a/jdk/src/share/classes/sun/reflect/annotation/AnnotationSupport.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/reflect/annotation/AnnotationSupport.java Fri Mar 15 16:39:07 2013 -0700
@@ -86,11 +86,11 @@
Class<? extends Annotation> containerClass = containerInstance.annotationType();
AnnotationType annoType = AnnotationType.getInstance(containerClass);
if (annoType == null)
- throw new InvalidContainerAnnotationError(containerInstance + " is an invalid container for repeating annotations");
+ throw new AnnotationFormatError(containerInstance + " is an invalid container for repeating annotations");
Method m = annoType.members().get("value");
if (m == null)
- throw new InvalidContainerAnnotationError(containerInstance +
+ throw new AnnotationFormatError(containerInstance +
" is an invalid container for repeating annotations");
m.setAccessible(true);
@@ -103,11 +103,9 @@
IllegalArgumentException | // parameters doesn't match
InvocationTargetException | // the value method threw an exception
ClassCastException e) { // well, a cast failed ...
- throw new InvalidContainerAnnotationError(
+ throw new AnnotationFormatError(
containerInstance + " is an invalid container for repeating annotations",
- e,
- containerInstance,
- null);
+ e);
}
}
@@ -129,12 +127,10 @@
return l;
} catch (ClassCastException |
NullPointerException e) {
- throw new InvalidContainerAnnotationError(
+ throw new AnnotationFormatError(
String.format("%s is an invalid container for repeating annotations of type: %s",
containerInstance, annotationClass),
- e,
- containerInstance,
- annotationClass);
+ e);
}
}
}
--- a/jdk/src/share/classes/sun/reflect/misc/MethodUtil.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/reflect/misc/MethodUtil.java Fri Mar 15 16:39:07 2013 -0700
@@ -252,6 +252,12 @@
public static Object invoke(Method m, Object obj, Object[] params)
throws InvocationTargetException, IllegalAccessException {
if (m.getDeclaringClass().equals(AccessController.class) ||
+ (m.getDeclaringClass().equals(java.lang.invoke.MethodHandles.class)
+ && m.getName().equals("lookup")) ||
+ (m.getDeclaringClass().equals(java.lang.invoke.MethodHandles.Lookup.class)
+ && (m.getName().startsWith("find") ||
+ m.getName().startsWith("bind") ||
+ m.getName().startsWith("unreflect"))) ||
m.getDeclaringClass().equals(Method.class))
throw new InvocationTargetException(
new UnsupportedOperationException("invocation not supported"));
--- a/jdk/src/share/classes/sun/reflect/misc/ReflectUtil.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/reflect/misc/ReflectUtil.java Fri Mar 15 16:39:07 2013 -0700
@@ -178,4 +178,31 @@
return !isAncestor(from, to);
}
+
+ /**
+ * Access check on the interfaces that a proxy class implements and throw
+ * {@code SecurityException} if it accesses a restricted package.
+ *
+ * @param ccl the caller's class loader
+ * @param interfaces the list of interfaces that a proxy class implements
+ *
+ * @see Proxy#checkProxyAccess
+ */
+ public static void checkProxyPackageAccess(ClassLoader ccl,
+ Class<?>... interfaces)
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ for (Class<?> intf : interfaces) {
+ ClassLoader cl = intf.getClassLoader();
+ if (needsPackageAccessCheck(ccl, cl)) {
+ checkPackageAccess(intf);
+ }
+ }
+ }
+ }
+
+ // Note that bytecode instrumentation tools may exclude 'sun.*'
+ // classes but not generated proxy classes and so keep it in com.sun.*
+ public static final String PROXY_PACKAGE = "com.sun.proxy";
}
--- a/jdk/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java Fri Mar 15 16:39:07 2013 -0700
@@ -153,7 +153,7 @@
returnServerError(e.getMessage());
}
else
- returnClientError("invalid command: " + command);
+ returnClientError("invalid command.");
} catch (Exception e) {
returnServerError("internal error: " + e.getMessage());
}
@@ -225,7 +225,7 @@
try {
port = Integer.parseInt(param);
} catch (NumberFormatException e) {
- throw new CGIClientException("invalid port number: " + param);
+ throw new CGIClientException("invalid port number.");
}
if (port <= 0 || port > 0xFFFF)
throw new CGIClientException("invalid port: " + port);
@@ -293,11 +293,14 @@
"unexpected EOF reading server response");
if (line.toLowerCase().startsWith(key)) {
- // if contentLengthFound is true
- // we should probably do something here
- responseContentLength =
- Integer.parseInt(line.substring(key.length()).trim());
- contentLengthFound = true;
+ if (contentLengthFound) {
+ throw new CGIServerException(
+ "Multiple Content-length entries found.");
+ } else {
+ responseContentLength =
+ Integer.parseInt(line.substring(key.length()).trim());
+ contentLengthFound = true;
+ }
}
} while ((line.length() != 0) &&
(line.charAt(0) != '\r') && (line.charAt(0) != '\n'));
--- a/jdk/src/share/classes/sun/rmi/transport/proxy/HttpInputStream.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/rmi/transport/proxy/HttpInputStream.java Fri Mar 15 16:39:07 2013 -0700
@@ -70,11 +70,14 @@
throw new EOFException();
if (line.toLowerCase().startsWith(key)) {
- // if contentLengthFound is true
- // we should probably do something here
- bytesLeft =
- Integer.parseInt(line.substring(key.length()).trim());
- contentLengthFound = true;
+ if (contentLengthFound) {
+ throw new IOException(
+ "Multiple Content-length entries found.");
+ } else {
+ bytesLeft =
+ Integer.parseInt(line.substring(key.length()).trim());
+ contentLengthFound = true;
+ }
}
// The idea here is to go past the first blank line.
--- a/jdk/src/share/classes/sun/security/jgss/GSSCredentialImpl.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/security/jgss/GSSCredentialImpl.java Fri Mar 15 16:39:07 2013 -0700
@@ -29,6 +29,7 @@
import sun.security.jgss.spi.*;
import java.util.*;
import com.sun.security.jgss.*;
+import sun.security.jgss.spnego.SpNegoCredElement;
public class GSSCredentialImpl implements ExtendedGSSCredential {
@@ -87,6 +88,7 @@
throw new GSSException(GSSException.NO_CRED);
}
+ // Wrap a mech cred into a GSS cred
public GSSCredentialImpl(GSSManagerImpl gssManager,
GSSCredentialSpi mechElement) throws GSSException {
@@ -103,6 +105,11 @@
usage);
tempCred = mechElement;
hashtable.put(key, tempCred);
+ // More mechs that can use this cred, say, SPNEGO
+ if (!GSSUtil.isSpNegoMech(mechElement.getMechanism())) {
+ key = new SearchKey(GSSUtil.GSS_SPNEGO_MECH_OID, usage);
+ hashtable.put(key, new SpNegoCredElement(mechElement));
+ }
}
void init(GSSManagerImpl gssManager) {
--- a/jdk/src/share/classes/sun/security/jgss/spnego/SpNegoCredElement.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/security/jgss/spnego/SpNegoCredElement.java Fri Mar 15 16:39:07 2013 -0700
@@ -44,7 +44,7 @@
private GSSCredentialSpi cred = null;
- SpNegoCredElement(GSSCredentialSpi cred) throws GSSException {
+ public SpNegoCredElement(GSSCredentialSpi cred) throws GSSException {
this.cred = cred;
}
--- a/jdk/src/share/classes/sun/security/pkcs10/PKCS10.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/security/pkcs10/PKCS10.java Fri Mar 15 16:39:07 2013 -0700
@@ -37,7 +37,7 @@
import java.security.SignatureException;
import java.security.PublicKey;
-import sun.misc.BASE64Encoder;
+import java.util.Base64;
import sun.security.util.*;
import sun.security.x509.AlgorithmId;
@@ -289,10 +289,9 @@
if (encoded == null)
throw new SignatureException("Cert request was not signed");
- BASE64Encoder encoder = new BASE64Encoder();
out.println("-----BEGIN NEW CERTIFICATE REQUEST-----");
- encoder.encodeBuffer(encoded, out);
+ out.println(Base64.getMimeEncoder().encodeToString(encoded));
out.println("-----END NEW CERTIFICATE REQUEST-----");
}
--- a/jdk/src/share/classes/sun/security/pkcs11/P11KeyAgreement.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/security/pkcs11/P11KeyAgreement.java Fri Mar 15 16:39:07 2013 -0700
@@ -37,6 +37,7 @@
import static sun.security.pkcs11.TemplateManager.*;
import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+import sun.security.util.KeyUtil;
/**
* KeyAgreement implementation class. This class currently supports
@@ -134,6 +135,10 @@
BigInteger p, g, y;
if (key instanceof DHPublicKey) {
DHPublicKey dhKey = (DHPublicKey)key;
+
+ // validate the Diffie-Hellman public key
+ KeyUtil.validate(dhKey);
+
y = dhKey.getY();
DHParameterSpec params = dhKey.getParams();
p = params.getP();
@@ -145,6 +150,10 @@
try {
DHPublicKeySpec spec = kf.engineGetKeySpec(
key, DHPublicKeySpec.class);
+
+ // validate the Diffie-Hellman public key
+ KeyUtil.validate(spec);
+
y = spec.getY();
p = spec.getP();
g = spec.getG();
--- a/jdk/src/share/classes/sun/security/provider/PolicyFile.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/security/provider/PolicyFile.java Fri Mar 15 16:39:07 2013 -0700
@@ -1336,10 +1336,9 @@
if (pppe.isWildcardName()) {
// a wildcard name matches any principal with the same class
- for (Principal p : principals) {
- if (pppe.principalClass.equals(p.getClass().getName())) {
- continue;
- }
+ if (wildcardPrincipalNameImplies(pppe.principalClass,
+ principals)) {
+ continue;
}
if (debug != null) {
debug.println("evaluation (principal name wildcard) failed");
@@ -1414,6 +1413,21 @@
addPerms(perms, principals, entry);
}
+ /**
+ * Returns true if the array of principals contains at least one
+ * principal of the specified class.
+ */
+ private static boolean wildcardPrincipalNameImplies(String principalClass,
+ Principal[] principals)
+ {
+ for (Principal p : principals) {
+ if (principalClass.equals(p.getClass().getName())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private void addPerms(Permissions perms,
Principal[] accPs,
PolicyEntry entry) {
--- a/jdk/src/share/classes/sun/security/provider/X509Factory.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/security/provider/X509Factory.java Fri Mar 15 16:39:07 2013 -0700
@@ -35,7 +35,7 @@
import sun.security.provider.certpath.X509CertificatePair;
import sun.security.util.DerValue;
import sun.security.util.Cache;
-import sun.misc.BASE64Decoder;
+import java.util.Base64;
import sun.security.pkcs.ParsingException;
/**
@@ -512,7 +512,7 @@
hyphen = 0;
last = next;
}
- if (hyphen == 5 && (last==-1 || last=='\r' || last=='\n')) {
+ if (hyphen == 5 && (last == -1 || last == '\r' || last == '\n')) {
break;
}
}
@@ -575,8 +575,7 @@
checkHeaderFooter(header.toString(), footer.toString());
- BASE64Decoder decoder = new BASE64Decoder();
- return decoder.decodeBuffer(new String(data, 0, pos));
+ return Base64.getMimeDecoder().decode(new String(data, 0, pos));
}
}
--- a/jdk/src/share/classes/sun/security/provider/certpath/OCSP.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/security/provider/certpath/OCSP.java Fri Mar 15 16:39:07 2013 -0700
@@ -89,7 +89,7 @@
new GetIntegerAction("com.sun.security.ocsp.timeout",
DEFAULT_CONNECT_TIMEOUT));
if (tmp < 0) {
- tmp = DEFAULT_CONNECT_TIMEOUT;
+ return DEFAULT_CONNECT_TIMEOUT;
}
// Convert to milliseconds, as the system property will be
// specified in seconds
--- a/jdk/src/share/classes/sun/security/ssl/CipherBox.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/security/ssl/CipherBox.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -392,7 +392,8 @@
* uniformly use the bad_record_mac alert to hide the specific type of
* the error.
*/
- int decrypt(byte[] buf, int offset, int len) throws BadPaddingException {
+ int decrypt(byte[] buf, int offset, int len,
+ int tagLen) throws BadPaddingException {
if (cipher == null) {
return len;
}
@@ -416,9 +417,10 @@
System.out);
} catch (IOException e) { }
}
+
if (blockSize != 0) {
- newLen = removePadding(buf, offset, newLen,
- blockSize, protocolVersion);
+ newLen = removePadding(
+ buf, offset, newLen, tagLen, blockSize, protocolVersion);
if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
if (newLen < blockSize) {
@@ -448,7 +450,7 @@
*
* @see decrypt(byte[], int, int)
*/
- int decrypt(ByteBuffer bb) throws BadPaddingException {
+ int decrypt(ByteBuffer bb, int tagLen) throws BadPaddingException {
int len = bb.remaining();
@@ -471,7 +473,6 @@
}
if (debug != null && Debug.isOn("plaintext")) {
- bb.position(pos);
try {
HexDumpEncoder hd = new HexDumpEncoder();
@@ -479,7 +480,8 @@
"Padded plaintext after DECRYPTION: len = "
+ newLen);
- hd.encodeBuffer(bb, System.out);
+ hd.encodeBuffer(
+ (ByteBuffer)bb.duplicate().position(pos), System.out);
} catch (IOException e) { }
}
@@ -488,7 +490,8 @@
*/
if (blockSize != 0) {
bb.position(pos);
- newLen = removePadding(bb, blockSize, protocolVersion);
+ newLen = removePadding(
+ bb, tagLen, blockSize, protocolVersion);
if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
if (newLen < blockSize) {
@@ -590,6 +593,65 @@
return newlen;
}
+ /*
+ * A constant-time check of the padding.
+ *
+ * NOTE that we are checking both the padding and the padLen bytes here.
+ *
+ * The caller MUST ensure that the len parameter is a positive number.
+ */
+ private static int[] checkPadding(
+ byte[] buf, int offset, int len, byte pad) {
+
+ if (len <= 0) {
+ throw new RuntimeException("padding len must be positive");
+ }
+
+ // An array of hits is used to prevent Hotspot optimization for
+ // the purpose of a constant-time check.
+ int[] results = {0, 0}; // {missed #, matched #}
+ for (int i = 0; i <= 256;) {
+ for (int j = 0; j < len && i <= 256; j++, i++) { // j <= i
+ if (buf[offset + j] != pad) {
+ results[0]++; // mismatched padding data
+ } else {
+ results[1]++; // matched padding data
+ }
+ }
+ }
+
+ return results;
+ }
+
+ /*
+ * A constant-time check of the padding.
+ *
+ * NOTE that we are checking both the padding and the padLen bytes here.
+ *
+ * The caller MUST ensure that the bb parameter has remaining.
+ */
+ private static int[] checkPadding(ByteBuffer bb, byte pad) {
+
+ if (!bb.hasRemaining()) {
+ throw new RuntimeException("hasRemaining() must be positive");
+ }
+
+ // An array of hits is used to prevent Hotspot optimization for
+ // the purpose of a constant-time check.
+ int[] results = {0, 0}; // {missed #, matched #}
+ bb.mark();
+ for (int i = 0; i <= 256; bb.reset()) {
+ for (; bb.hasRemaining() && i <= 256; i++) {
+ if (bb.get() != pad) {
+ results[0]++; // mismatched padding data
+ } else {
+ results[1]++; // matched padding data
+ }
+ }
+ }
+
+ return results;
+ }
/*
* Typical TLS padding format for a 64 bit block cipher is as follows:
@@ -602,86 +664,95 @@
* as it makes the data a multiple of the block size
*/
private static int removePadding(byte[] buf, int offset, int len,
- int blockSize, ProtocolVersion protocolVersion)
- throws BadPaddingException {
+ int tagLen, int blockSize,
+ ProtocolVersion protocolVersion) throws BadPaddingException {
+
// last byte is length byte (i.e. actual padding length - 1)
int padOffset = offset + len - 1;
- int pad = buf[padOffset] & 0x0ff;
+ int padLen = buf[padOffset] & 0xFF;
- int newlen = len - (pad + 1);
- if (newlen < 0) {
- throw new BadPaddingException("Padding length invalid: " + pad);
+ int newLen = len - (padLen + 1);
+ if ((newLen - tagLen) < 0) {
+ // If the buffer is not long enough to contain the padding plus
+ // a MAC tag, do a dummy constant-time padding check.
+ //
+ // Note that it is a dummy check, so we won't care about what is
+ // the actual padding data.
+ checkPadding(buf, offset, len, (byte)(padLen & 0xFF));
+
+ throw new BadPaddingException("Invalid Padding length: " + padLen);
}
+ // The padding data should be filled with the padding length value.
+ int[] results = checkPadding(buf, offset + newLen,
+ padLen + 1, (byte)(padLen & 0xFF));
if (protocolVersion.v >= ProtocolVersion.TLS10.v) {
- for (int i = 1; i <= pad; i++) {
- int val = buf[padOffset - i] & 0xff;
- if (val != pad) {
- throw new BadPaddingException
- ("Invalid TLS padding: " + val);
- }
+ if (results[0] != 0) { // padding data has invalid bytes
+ throw new BadPaddingException("Invalid TLS padding data");
}
} else { // SSLv3
// SSLv3 requires 0 <= length byte < block size
// some implementations do 1 <= length byte <= block size,
// so accept that as well
// v3 does not require any particular value for the other bytes
- if (pad > blockSize) {
- throw new BadPaddingException("Invalid SSLv3 padding: " + pad);
+ if (padLen > blockSize) {
+ throw new BadPaddingException("Invalid SSLv3 padding");
}
}
- return newlen;
+ return newLen;
}
/*
* Position/limit is equal the removed padding.
*/
private static int removePadding(ByteBuffer bb,
- int blockSize, ProtocolVersion protocolVersion)
- throws BadPaddingException {
+ int tagLen, int blockSize,
+ ProtocolVersion protocolVersion) throws BadPaddingException {
int len = bb.remaining();
int offset = bb.position();
// last byte is length byte (i.e. actual padding length - 1)
int padOffset = offset + len - 1;
- int pad = bb.get(padOffset) & 0x0ff;
+ int padLen = bb.get(padOffset) & 0xFF;
- int newlen = len - (pad + 1);
- if (newlen < 0) {
- throw new BadPaddingException("Padding length invalid: " + pad);
+ int newLen = len - (padLen + 1);
+ if ((newLen - tagLen) < 0) {
+ // If the buffer is not long enough to contain the padding plus
+ // a MAC tag, do a dummy constant-time padding check.
+ //
+ // Note that it is a dummy check, so we won't care about what is
+ // the actual padding data.
+ checkPadding(bb.duplicate(), (byte)(padLen & 0xFF));
+
+ throw new BadPaddingException("Invalid Padding length: " + padLen);
}
- /*
- * We could zero the padding area, but not much useful
- * information there.
- */
+ // The padding data should be filled with the padding length value.
+ int[] results = checkPadding(
+ (ByteBuffer)bb.duplicate().position(offset + newLen),
+ (byte)(padLen & 0xFF));
if (protocolVersion.v >= ProtocolVersion.TLS10.v) {
- bb.put(padOffset, (byte)0); // zero the padding.
- for (int i = 1; i <= pad; i++) {
- int val = bb.get(padOffset - i) & 0xff;
- if (val != pad) {
- throw new BadPaddingException
- ("Invalid TLS padding: " + val);
- }
+ if (results[0] != 0) { // padding data has invalid bytes
+ throw new BadPaddingException("Invalid TLS padding data");
}
} else { // SSLv3
// SSLv3 requires 0 <= length byte < block size
// some implementations do 1 <= length byte <= block size,
// so accept that as well
// v3 does not require any particular value for the other bytes
- if (pad > blockSize) {
- throw new BadPaddingException("Invalid SSLv3 padding: " + pad);
+ if (padLen > blockSize) {
+ throw new BadPaddingException("Invalid SSLv3 padding");
}
}
/*
* Reset buffer limit to remove padding.
*/
- bb.position(offset + newlen);
- bb.limit(offset + newlen);
+ bb.position(offset + newLen);
+ bb.limit(offset + newLen);
- return newlen;
+ return newLen;
}
/*
@@ -708,4 +779,45 @@
boolean isCBCMode() {
return isCBCMode;
}
+
+ /**
+ * Is the cipher null?
+ *
+ * @return true if the cipher is null, false otherwise.
+ */
+ boolean isNullCipher() {
+ return cipher == null;
+ }
+
+ /**
+ * Sanity check the length of a fragment before decryption.
+ *
+ * In CBC mode, check that the fragment length is one or multiple times
+ * of the block size of the cipher suite, and is at least one (one is the
+ * smallest size of padding in CBC mode) bigger than the tag size of the
+ * MAC algorithm except the explicit IV size for TLS 1.1 or later.
+ *
+ * In non-CBC mode, check that the fragment length is not less than the
+ * tag size of the MAC algorithm.
+ *
+ * @return true if the length of a fragment matches above requirements
+ */
+ boolean sanityCheck(int tagLen, int fragmentLen) {
+ if (!isCBCMode) {
+ return fragmentLen >= tagLen;
+ }
+
+ if ((fragmentLen % blockSize) == 0) {
+ int minimal = tagLen + 1;
+ minimal = (minimal >= blockSize) ? minimal : blockSize;
+ if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
+ minimal += blockSize; // plus the size of the explicit IV
+ }
+
+ return (fragmentLen >= minimal);
+ }
+
+ return false;
+ }
+
}
--- a/jdk/src/share/classes/sun/security/ssl/CipherSuite.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/security/ssl/CipherSuite.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -549,9 +549,18 @@
// size of the MAC value (and MAC key) in bytes
final int size;
- MacAlg(String name, int size) {
+ // block size of the underlying hash algorithm
+ final int hashBlockSize;
+
+ // minimal padding size of the underlying hash algorithm
+ final int minimalPaddingSize;
+
+ MacAlg(String name, int size,
+ int hashBlockSize, int minimalPaddingSize) {
this.name = name;
this.size = size;
+ this.hashBlockSize = hashBlockSize;
+ this.minimalPaddingSize = minimalPaddingSize;
}
/**
@@ -596,11 +605,11 @@
new BulkCipher(CIPHER_AES, 32, 16, true);
// MACs
- final static MacAlg M_NULL = new MacAlg("NULL", 0);
- final static MacAlg M_MD5 = new MacAlg("MD5", 16);
- final static MacAlg M_SHA = new MacAlg("SHA", 20);
- final static MacAlg M_SHA256 = new MacAlg("SHA256", 32);
- final static MacAlg M_SHA384 = new MacAlg("SHA384", 48);
+ final static MacAlg M_NULL = new MacAlg("NULL", 0, 0, 0);
+ final static MacAlg M_MD5 = new MacAlg("MD5", 16, 64, 9);
+ final static MacAlg M_SHA = new MacAlg("SHA", 20, 64, 9);
+ final static MacAlg M_SHA256 = new MacAlg("SHA256", 32, 64, 9);
+ final static MacAlg M_SHA384 = new MacAlg("SHA384", 48, 128, 17);
/**
* PRFs (PseudoRandom Function) from TLS specifications.
--- a/jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java Fri Mar 15 16:39:07 2013 -0700
@@ -129,9 +129,8 @@
*/
@Override
void processMessage(byte type, int messageLen) throws IOException {
- if (state > type
- && (type != HandshakeMessage.ht_hello_request
- && state != HandshakeMessage.ht_client_hello)) {
+ if (state >= type
+ && (type != HandshakeMessage.ht_hello_request)) {
throw new SSLProtocolException(
"Handshake message sequence violation, " + type);
}
@@ -194,8 +193,12 @@
}
break;
case K_DH_ANON:
- this.serverKeyExchange(new DH_ServerKeyExchange(
+ try {
+ this.serverKeyExchange(new DH_ServerKeyExchange(
input, protocolVersion));
+ } catch (GeneralSecurityException e) {
+ throwSSLException("Server key", e);
+ }
break;
case K_DHE_DSS:
case K_DHE_RSA:
@@ -921,7 +924,7 @@
case K_DHE_RSA:
case K_DHE_DSS:
case K_DH_ANON:
- preMasterSecret = dh.getAgreedSecret(serverDH);
+ preMasterSecret = dh.getAgreedSecret(serverDH, true);
break;
case K_ECDHE_RSA:
case K_ECDHE_ECDSA:
--- a/jdk/src/share/classes/sun/security/ssl/DHClientKeyExchange.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/security/ssl/DHClientKeyExchange.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,7 @@
import java.io.IOException;
import java.io.PrintStream;
import java.math.BigInteger;
-
+import javax.net.ssl.SSLHandshakeException;
/*
* Message used by clients to send their Diffie-Hellman public
@@ -51,7 +51,7 @@
private byte dh_Yc[]; // 1 to 2^16 -1 bytes
BigInteger getClientPublicKey() {
- return new BigInteger(1, dh_Yc);
+ return dh_Yc == null ? null : new BigInteger(1, dh_Yc);
}
/*
@@ -73,7 +73,14 @@
* but that's what the protocol spec requires.)
*/
DHClientKeyExchange(HandshakeInStream input) throws IOException {
- dh_Yc = input.getBytes16();
+ if (input.available() >= 2) {
+ dh_Yc = input.getBytes16();
+ } else {
+ // currently, we don't support cipher suites that requires
+ // implicit public key of client.
+ throw new SSLHandshakeException(
+ "Unsupported implicit client DiffieHellman public key");
+ }
}
@Override
@@ -87,7 +94,9 @@
@Override
void send(HandshakeOutStream s) throws IOException {
- s.putBytes16(dh_Yc);
+ if (dh_Yc != null && dh_Yc.length != 0) {
+ s.putBytes16(dh_Yc);
+ }
}
@Override
--- a/jdk/src/share/classes/sun/security/ssl/DHCrypt.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/security/ssl/DHCrypt.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,12 +28,15 @@
import java.math.BigInteger;
import java.security.*;
-
+import java.io.IOException;
+import javax.net.ssl.SSLHandshakeException;
import javax.crypto.SecretKey;
import javax.crypto.KeyAgreement;
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.*;
+import sun.security.util.KeyUtil;
+
/**
* This class implements the Diffie-Hellman key exchange algorithm.
* D-H means combining your private key with your partners public key to
@@ -54,7 +57,8 @@
* . if we are server, call DHCrypt(keyLength,random). This generates
* an ephemeral keypair of the request length.
* . if we are client, call DHCrypt(modulus, base, random). This
- * generates an ephemeral keypair using the parameters specified by the server.
+ * generates an ephemeral keypair using the parameters specified by
+ * the server.
* . send parameters and public value to remote peer
* . receive peers ephemeral public key
* . call getAgreedSecret() to calculate the shared secret
@@ -83,6 +87,9 @@
// public component of our key, X = (g ^ x) mod p
private BigInteger publicValue; // X (aka y)
+ // the times to recove from failure if public key validation
+ private static int MAX_FAILOVER_TIMES = 2;
+
/**
* Generate a Diffie-Hellman keypair of the specified size.
*/
@@ -90,9 +97,12 @@
try {
KeyPairGenerator kpg = JsseJce.getKeyPairGenerator("DiffieHellman");
kpg.initialize(keyLength, random);
- KeyPair kp = kpg.generateKeyPair();
- privateKey = kp.getPrivate();
- DHPublicKeySpec spec = getDHPublicKeySpec(kp.getPublic());
+
+ DHPublicKeySpec spec = generateDHPublicKeySpec(kpg);
+ if (spec == null) {
+ throw new RuntimeException("Could not generate DH keypair");
+ }
+
publicValue = spec.getY();
modulus = spec.getP();
base = spec.getG();
@@ -115,20 +125,25 @@
KeyPairGenerator kpg = JsseJce.getKeyPairGenerator("DiffieHellman");
DHParameterSpec params = new DHParameterSpec(modulus, base);
kpg.initialize(params, random);
- KeyPair kp = kpg.generateKeyPair();
- privateKey = kp.getPrivate();
- DHPublicKeySpec spec = getDHPublicKeySpec(kp.getPublic());
+
+ DHPublicKeySpec spec = generateDHPublicKeySpec(kpg);
+ if (spec == null) {
+ throw new RuntimeException("Could not generate DH keypair");
+ }
+
publicValue = spec.getY();
} catch (GeneralSecurityException e) {
throw new RuntimeException("Could not generate DH keypair", e);
}
}
+
static DHPublicKeySpec getDHPublicKeySpec(PublicKey key) {
if (key instanceof DHPublicKey) {
DHPublicKey dhKey = (DHPublicKey)key;
DHParameterSpec params = dhKey.getParams();
- return new DHPublicKeySpec(dhKey.getY(), params.getP(), params.getG());
+ return new DHPublicKeySpec(dhKey.getY(),
+ params.getP(), params.getG());
}
try {
KeyFactory factory = JsseJce.getKeyFactory("DH");
@@ -166,17 +181,32 @@
* <P>It is illegal to call this member function if the private key
* has not been set (or generated).
*
- * @param peerPublicKey the peer's public key.
- * @returns the secret, which is an unsigned big-endian integer
- * the same size as the Diffie-Hellman modulus.
+ * @param peerPublicKey the peer's public key.
+ * @param keyIsValidated whether the {@code peerPublicKey} has beed
+ * validated
+ * @return the secret, which is an unsigned big-endian integer
+ * the same size as the Diffie-Hellman modulus.
*/
- SecretKey getAgreedSecret(BigInteger peerPublicValue) {
+ SecretKey getAgreedSecret(BigInteger peerPublicValue,
+ boolean keyIsValidated) throws IOException {
try {
KeyFactory kf = JsseJce.getKeyFactory("DiffieHellman");
DHPublicKeySpec spec =
new DHPublicKeySpec(peerPublicValue, modulus, base);
PublicKey publicKey = kf.generatePublic(spec);
KeyAgreement ka = JsseJce.getKeyAgreement("DiffieHellman");
+
+ // validate the Diffie-Hellman public key
+ if (!keyIsValidated &&
+ !KeyUtil.isOracleJCEProvider(ka.getProvider().getName())) {
+ try {
+ KeyUtil.validate(spec);
+ } catch (InvalidKeyException ike) {
+ // prefer handshake_failure alert to internal_error alert
+ throw new SSLHandshakeException(ike.getMessage());
+ }
+ }
+
ka.init(privateKey);
ka.doPhase(publicKey, true);
return ka.generateSecret("TlsPremasterSecret");
@@ -185,4 +215,33 @@
}
}
+ // Generate and validate DHPublicKeySpec
+ private DHPublicKeySpec generateDHPublicKeySpec(KeyPairGenerator kpg)
+ throws GeneralSecurityException {
+
+ boolean doExtraValiadtion =
+ (!KeyUtil.isOracleJCEProvider(kpg.getProvider().getName()));
+ for (int i = 0; i <= MAX_FAILOVER_TIMES; i++) {
+ KeyPair kp = kpg.generateKeyPair();
+ privateKey = kp.getPrivate();
+ DHPublicKeySpec spec = getDHPublicKeySpec(kp.getPublic());
+
+ // validate the Diffie-Hellman public key
+ if (doExtraValiadtion) {
+ try {
+ KeyUtil.validate(spec);
+ } catch (InvalidKeyException ivke) {
+ if (i == MAX_FAILOVER_TIMES) {
+ throw ivke;
+ }
+ // otherwise, ignore the exception and try the next one
+ continue;
+ }
+ }
+
+ return spec;
+ }
+
+ return null;
+ }
}
--- a/jdk/src/share/classes/sun/security/ssl/EngineInputRecord.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/security/ssl/EngineInputRecord.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -178,71 +178,6 @@
}
/*
- * Verifies and removes the MAC value. Returns true if
- * the MAC checks out OK.
- *
- * On entry:
- * position = beginning of app/MAC data
- * limit = end of MAC data.
- *
- * On return:
- * position = beginning of app data
- * limit = end of app data
- */
- boolean checkMAC(MAC signer, ByteBuffer bb) {
- if (internalData) {
- return checkMAC(signer);
- }
-
- int len = signer.MAClen();
- if (len == 0) { // no mac
- return true;
- }
-
- /*
- * Grab the original limit
- */
- int lim = bb.limit();
-
- /*
- * Delineate the area to apply a MAC on.
- */
- int macData = lim - len;
- bb.limit(macData);
-
- byte[] mac = signer.compute(contentType(), bb);
-
- if (len != mac.length) {
- throw new RuntimeException("Internal MAC error");
- }
-
- /*
- * Delineate the MAC values, position was already set
- * by doing the compute above.
- *
- * We could zero the MAC area, but not much useful information
- * there anyway.
- */
- bb.position(macData);
- bb.limit(lim);
-
- try {
- for (int i = 0; i < len; i++) {
- if (bb.get() != mac[i]) { // No BB.equals(byte []); !
- return false;
- }
- }
- return true;
- } finally {
- /*
- * Position to the data.
- */
- bb.rewind();
- bb.limit(macData);
- }
- }
-
- /*
* Pass the data down if it's internally cached, otherwise
* do it here.
*
@@ -251,21 +186,164 @@
* If external data(app), return a new ByteBuffer with data to
* process.
*/
- ByteBuffer decrypt(CipherBox box, ByteBuffer bb)
- throws BadPaddingException {
+ ByteBuffer decrypt(MAC signer,
+ CipherBox box, ByteBuffer bb) throws BadPaddingException {
if (internalData) {
- decrypt(box);
+ decrypt(signer, box); // MAC is checked during decryption
return tmpBB;
}
- box.decrypt(bb);
- bb.rewind();
+ BadPaddingException reservedBPE = null;
+ int tagLen = signer.MAClen();
+ int cipheredLength = bb.remaining();
+
+ if (!box.isNullCipher()) {
+ // sanity check length of the ciphertext
+ if (!box.sanityCheck(tagLen, cipheredLength)) {
+ throw new BadPaddingException(
+ "ciphertext sanity check failed");
+ }
+
+ try {
+ // Note that the CipherBox.decrypt() does not change
+ // the capacity of the buffer.
+ box.decrypt(bb, tagLen);
+ } catch (BadPaddingException bpe) {
+ // RFC 2246 states that decryption_failed should be used
+ // for this purpose. However, that allows certain attacks,
+ // so we just send bad record MAC. We also need to make
+ // sure to always check the MAC to avoid a timing attack
+ // for the same issue. See paper by Vaudenay et al and the
+ // update in RFC 4346/5246.
+ //
+ // Failover to message authentication code checking.
+ reservedBPE = bpe;
+ } finally {
+ bb.rewind();
+ }
+ }
+
+ if (tagLen != 0) {
+ int macOffset = bb.limit() - tagLen;
+
+ // Note that although it is not necessary, we run the same MAC
+ // computation and comparison on the payload for both stream
+ // cipher and CBC block cipher.
+ if (bb.remaining() < tagLen) {
+ // negative data length, something is wrong
+ if (reservedBPE == null) {
+ reservedBPE = new BadPaddingException("bad record");
+ }
+
+ // set offset of the dummy MAC
+ macOffset = cipheredLength - tagLen;
+ bb.limit(cipheredLength);
+ }
+
+ // Run MAC computation and comparison on the payload.
+ if (checkMacTags(contentType(), bb, signer, false)) {
+ if (reservedBPE == null) {
+ reservedBPE = new BadPaddingException("bad record MAC");
+ }
+ }
+
+ // Run MAC computation and comparison on the remainder.
+ //
+ // It is only necessary for CBC block cipher. It is used to get a
+ // constant time of MAC computation and comparison on each record.
+ if (box.isCBCMode()) {
+ int remainingLen = calculateRemainingLen(
+ signer, cipheredLength, macOffset);
+
+ // NOTE: here we use the InputRecord.buf because I did not find
+ // an effective way to work on ByteBuffer when its capacity is
+ // less than remainingLen.
+
+ // NOTE: remainingLen may be bigger (less than 1 block of the
+ // hash algorithm of the MAC) than the cipheredLength. However,
+ // We won't need to worry about it because we always use a
+ // maximum buffer for every record. We need a change here if
+ // we use small buffer size in the future.
+ if (remainingLen > buf.length) {
+ // unlikely to happen, just a placehold
+ throw new RuntimeException(
+ "Internal buffer capacity error");
+ }
+
+ // Won't need to worry about the result on the remainder. And
+ // then we won't need to worry about what's actual data to
+ // check MAC tag on. We start the check from the header of the
+ // buffer so that we don't need to construct a new byte buffer.
+ checkMacTags(contentType(), buf, 0, remainingLen, signer, true);
+ }
+
+ bb.limit(macOffset);
+ }
+
+ // Is it a failover?
+ if (reservedBPE != null) {
+ throw reservedBPE;
+ }
return bb.slice();
}
/*
+ * Run MAC computation and comparison
+ *
+ * Please DON'T change the content of the ByteBuffer parameter!
+ */
+ private static boolean checkMacTags(byte contentType, ByteBuffer bb,
+ MAC signer, boolean isSimulated) {
+
+ int tagLen = signer.MAClen();
+ int lim = bb.limit();
+ int macData = lim - tagLen;
+
+ bb.limit(macData);
+ byte[] hash = signer.compute(contentType, bb, isSimulated);
+ if (hash == null || tagLen != hash.length) {
+ // Something is wrong with MAC implementation.
+ throw new RuntimeException("Internal MAC error");
+ }
+
+ bb.position(macData);
+ bb.limit(lim);
+ try {
+ int[] results = compareMacTags(bb, hash);
+ return (results[0] != 0);
+ } finally {
+ bb.rewind();
+ bb.limit(macData);
+ }
+ }
+
+ /*
+ * A constant-time comparison of the MAC tags.
+ *
+ * Please DON'T change the content of the ByteBuffer parameter!
+ */
+ private static int[] compareMacTags(ByteBuffer bb, byte[] tag) {
+
+ // An array of hits is used to prevent Hotspot optimization for
+ // the purpose of a constant-time check.
+ int[] results = {0, 0}; // {missed #, matched #}
+
+ // The caller ensures there are enough bytes available in the buffer.
+ // So we won't need to check the remaining of the buffer.
+ for (int i = 0; i < tag.length; i++) {
+ if (bb.get() != tag[i]) {
+ results[0]++; // mismatched bytes
+ } else {
+ results[1]++; // matched bytes
+ }
+ }
+
+ return results;
+ }
+
+ /*
* Override the actual write below. We do things this way to be
* consistent with InputRecord. InputRecord may try to write out
* data to the peer, and *then* throw an Exception. This forces
--- a/jdk/src/share/classes/sun/security/ssl/EngineOutputRecord.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/security/ssl/EngineOutputRecord.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -118,7 +118,7 @@
throws IOException {
if (signer.MAClen() != 0) {
- byte[] hash = signer.compute(contentType(), bb);
+ byte[] hash = signer.compute(contentType(), bb, false);
/*
* position was advanced to limit in compute above.
--- a/jdk/src/share/classes/sun/security/ssl/HandshakeMessage.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/security/ssl/HandshakeMessage.java Fri Mar 15 16:39:07 2013 -0700
@@ -41,12 +41,14 @@
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
+import javax.crypto.spec.DHPublicKeySpec;
import javax.net.ssl.*;
import sun.security.internal.spec.TlsPrfParameterSpec;
import sun.security.ssl.CipherSuite.*;
import static sun.security.ssl.CipherSuite.PRF.*;
+import sun.security.util.KeyUtil;
/**
* Many data structures are involved in the handshake messages. These
@@ -712,6 +714,7 @@
this.protocolVersion = protocolVersion;
this.preferableSignatureAlgorithm = null;
+ // The DH key has been validated in the constructor of DHCrypt.
setValues(obj);
signature = null;
}
@@ -728,6 +731,7 @@
this.protocolVersion = protocolVersion;
+ // The DH key has been validated in the constructor of DHCrypt.
setValues(obj);
Signature sig;
@@ -754,7 +758,8 @@
* DH_anon key exchange
*/
DH_ServerKeyExchange(HandshakeInStream input,
- ProtocolVersion protocolVersion) throws IOException {
+ ProtocolVersion protocolVersion)
+ throws IOException, GeneralSecurityException {
this.protocolVersion = protocolVersion;
this.preferableSignatureAlgorithm = null;
@@ -762,6 +767,10 @@
dh_p = input.getBytes16();
dh_g = input.getBytes16();
dh_Ys = input.getBytes16();
+ KeyUtil.validate(new DHPublicKeySpec(new BigInteger(1, dh_Ys),
+ new BigInteger(1, dh_p),
+ new BigInteger(1, dh_g)));
+
signature = null;
}
@@ -782,6 +791,9 @@
dh_p = input.getBytes16();
dh_g = input.getBytes16();
dh_Ys = input.getBytes16();
+ KeyUtil.validate(new DHPublicKeySpec(new BigInteger(1, dh_Ys),
+ new BigInteger(1, dh_p),
+ new BigInteger(1, dh_g)));
// read the signature and hash algorithm
if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
--- a/jdk/src/share/classes/sun/security/ssl/InputRecord.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/security/ssl/InputRecord.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -133,44 +133,174 @@
return handshakeHash;
}
- /*
- * Verify and remove the MAC ... used for all records.
- */
- boolean checkMAC(MAC signer) {
- int len = signer.MAClen();
- if (len == 0) { // no mac
- return true;
+ void decrypt(MAC signer, CipherBox box) throws BadPaddingException {
+
+ BadPaddingException reservedBPE = null;
+ int tagLen = signer.MAClen();
+ int cipheredLength = count - headerSize;
+
+ if (!box.isNullCipher()) {
+ // sanity check length of the ciphertext
+ if (!box.sanityCheck(tagLen, cipheredLength)) {
+ throw new BadPaddingException(
+ "ciphertext sanity check failed");
+ }
+
+ try {
+ // Note that the CipherBox.decrypt() does not change
+ // the capacity of the buffer.
+ count = headerSize +
+ box.decrypt(buf, headerSize, cipheredLength, tagLen);
+ } catch (BadPaddingException bpe) {
+ // RFC 2246 states that decryption_failed should be used
+ // for this purpose. However, that allows certain attacks,
+ // so we just send bad record MAC. We also need to make
+ // sure to always check the MAC to avoid a timing attack
+ // for the same issue. See paper by Vaudenay et al and the
+ // update in RFC 4346/5246.
+ //
+ // Failover to message authentication code checking.
+ reservedBPE = bpe;
+ }
}
- int offset = count - len;
+ if (tagLen != 0) {
+ int macOffset = count - tagLen;
+ int contentLen = macOffset - headerSize;
+
+ // Note that although it is not necessary, we run the same MAC
+ // computation and comparison on the payload for both stream
+ // cipher and CBC block cipher.
+ if (contentLen < 0) {
+ // negative data length, something is wrong
+ if (reservedBPE == null) {
+ reservedBPE = new BadPaddingException("bad record");
+ }
+
+ // set offset of the dummy MAC
+ macOffset = headerSize + cipheredLength - tagLen;
+ contentLen = macOffset - headerSize;
+ }
+
+ count -= tagLen; // Set the count before any MAC checking
+ // exception occurs, so that the following
+ // process can read the actual decrypted
+ // content (minus the MAC) in the fragment
+ // if necessary.
- if (offset < headerSize) {
- // data length would be negative, something is wrong
- return false;
+ // Run MAC computation and comparison on the payload.
+ if (checkMacTags(contentType(),
+ buf, headerSize, contentLen, signer, false)) {
+ if (reservedBPE == null) {
+ reservedBPE = new BadPaddingException("bad record MAC");
+ }
+ }
+
+ // Run MAC computation and comparison on the remainder.
+ //
+ // It is only necessary for CBC block cipher. It is used to get a
+ // constant time of MAC computation and comparison on each record.
+ if (box.isCBCMode()) {
+ int remainingLen = calculateRemainingLen(
+ signer, cipheredLength, contentLen);
+
+ // NOTE: remainingLen may be bigger (less than 1 block of the
+ // hash algorithm of the MAC) than the cipheredLength. However,
+ // We won't need to worry about it because we always use a
+ // maximum buffer for every record. We need a change here if
+ // we use small buffer size in the future.
+ if (remainingLen > buf.length) {
+ // unlikely to happen, just a placehold
+ throw new RuntimeException(
+ "Internal buffer capacity error");
+ }
+
+ // Won't need to worry about the result on the remainder. And
+ // then we won't need to worry about what's actual data to
+ // check MAC tag on. We start the check from the header of the
+ // buffer so that we don't need to construct a new byte buffer.
+ checkMacTags(contentType(), buf, 0, remainingLen, signer, true);
+ }
}
- byte[] mac = signer.compute(contentType(), buf,
- headerSize, offset - headerSize);
+ // Is it a failover?
+ if (reservedBPE != null) {
+ throw reservedBPE;
+ }
+ }
- if (len != mac.length) {
+ /*
+ * Run MAC computation and comparison
+ *
+ * Please DON'T change the content of the byte buffer parameter!
+ */
+ static boolean checkMacTags(byte contentType, byte[] buffer,
+ int offset, int contentLen, MAC signer, boolean isSimulated) {
+
+ int tagLen = signer.MAClen();
+ byte[] hash = signer.compute(
+ contentType, buffer, offset, contentLen, isSimulated);
+ if (hash == null || tagLen != hash.length) {
+ // Something is wrong with MAC implementation.
throw new RuntimeException("Internal MAC error");
}
- for (int i = 0; i < len; i++) {
- if (buf[offset + i] != mac[i]) {
- return false;
+ int[] results = compareMacTags(buffer, offset + contentLen, hash);
+ return (results[0] != 0);
+ }
+
+ /*
+ * A constant-time comparison of the MAC tags.
+ *
+ * Please DON'T change the content of the byte buffer parameter!
+ */
+ private static int[] compareMacTags(
+ byte[] buffer, int offset, byte[] tag) {
+
+ // An array of hits is used to prevent Hotspot optimization for
+ // the purpose of a constant-time check.
+ int[] results = {0, 0}; // {missed #, matched #}
+
+ // The caller ensures there are enough bytes available in the buffer.
+ // So we won't need to check the length of the buffer.
+ for (int i = 0; i < tag.length; i++) {
+ if (buffer[offset + i] != tag[i]) {
+ results[0]++; // mismatched bytes
+ } else {
+ results[1]++; // matched bytes
}
}
- count -= len;
- return true;
+
+ return results;
}
- void decrypt(CipherBox box) throws BadPaddingException {
- int len = count - headerSize;
- count = headerSize + box.decrypt(buf, headerSize, len);
+ /*
+ * Calculate the length of a dummy buffer to run MAC computation
+ * and comparison on the remainder.
+ *
+ * The caller MUST ensure that the fullLen is not less than usedLen.
+ */
+ static int calculateRemainingLen(
+ MAC signer, int fullLen, int usedLen) {
+
+ int blockLen = signer.hashBlockLen();
+ int minimalPaddingLen = signer.minimalPaddingLen();
+
+ // (blockLen - minimalPaddingLen) is the maximum message size of
+ // the last block of hash function operation. See FIPS 180-4, or
+ // MD5 specification.
+ fullLen += 13 - (blockLen - minimalPaddingLen);
+ usedLen += 13 - (blockLen - minimalPaddingLen);
+
+ // Note: fullLen is always not less than usedLen, and blockLen
+ // is always bigger than minimalPaddingLen, so we don't worry
+ // about negative values. 0x01 is added to the result to ensure
+ // that the return value is positive. The extra one byte does
+ // not impact the overall MAC compression function evaluations.
+ return 0x01 + (int)(Math.ceil(fullLen/(1.0d * blockLen)) -
+ Math.ceil(usedLen/(1.0d * blockLen))) * signer.hashBlockLen();
}
-
/*
* Well ... hello_request messages are _never_ hashed since we can't
* know when they'd appear in the sequence.
--- a/jdk/src/share/classes/sun/security/ssl/MAC.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/security/ssl/MAC.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -43,8 +43,8 @@
* provide integrity protection for SSL messages. The MAC is actually
* one of several keyed hashes, as associated with the cipher suite and
* protocol version. (SSL v3.0 uses one construct, TLS uses another.)
- *
- * <P>NOTE: MAC computation is the only place in the SSL protocol that the
+ * <P>
+ * NOTE: MAC computation is the only place in the SSL protocol that the
* sequence number is used. It's also reset to zero with each change of
* a cipher spec, so this is the only place this state is needed.
*
@@ -58,6 +58,9 @@
// Value of the null MAC is fixed
private static final byte nullMAC[] = new byte[0];
+ // internal identifier for the MAC algorithm
+ private final MacAlg macAlg;
+
// stuff defined by the kind of MAC algorithm
private final int macSize;
@@ -82,6 +85,7 @@
private MAC() {
macSize = 0;
+ macAlg = M_NULL;
mac = null;
block = null;
}
@@ -91,6 +95,7 @@
*/
MAC(MacAlg macAlg, ProtocolVersion protocolVersion, SecretKey key)
throws NoSuchAlgorithmException, InvalidKeyException {
+ this.macAlg = macAlg;
this.macSize = macAlg.size;
String algorithm;
@@ -128,15 +133,31 @@
}
/**
+ * Returns the hash function block length of the MAC alorithm.
+ */
+ int hashBlockLen() {
+ return macAlg.hashBlockSize;
+ }
+
+ /**
+ * Returns the hash function minimal padding length of the MAC alorithm.
+ */
+ int minimalPaddingLen() {
+ return macAlg.minimalPaddingSize;
+ }
+
+ /**
* Computes and returns the MAC for the data in this byte array.
*
* @param type record type
* @param buf compressed record on which the MAC is computed
* @param offset start of compressed record data
* @param len the size of the compressed record
+ * @param isSimulated if true, simulate the the MAC computation
*/
- final byte[] compute(byte type, byte buf[], int offset, int len) {
- return compute(type, null, buf, offset, len);
+ final byte[] compute(byte type, byte buf[],
+ int offset, int len, boolean isSimulated) {
+ return compute(type, null, buf, offset, len, isSimulated);
}
/**
@@ -149,9 +170,10 @@
* @param type record type
* @param bb a ByteBuffer in which the position and limit
* demarcate the data to be MAC'd.
+ * @param isSimulated if true, simulate the the MAC computation
*/
- final byte[] compute(byte type, ByteBuffer bb) {
- return compute(type, bb, null, 0, bb.remaining());
+ final byte[] compute(byte type, ByteBuffer bb, boolean isSimulated) {
+ return compute(type, bb, null, 0, bb.remaining(), isSimulated);
}
/**
@@ -204,18 +226,21 @@
* or buf/offset/len.
*/
private byte[] compute(byte type, ByteBuffer bb, byte[] buf,
- int offset, int len) {
+ int offset, int len, boolean isSimulated) {
if (macSize == 0) {
return nullMAC;
}
- block[BLOCK_OFFSET_TYPE] = type;
- block[block.length - 2] = (byte)(len >> 8);
- block[block.length - 1] = (byte)(len );
+ // MUST NOT increase the sequence number for a simulated computation.
+ if (!isSimulated) {
+ block[BLOCK_OFFSET_TYPE] = type;
+ block[block.length - 2] = (byte)(len >> 8);
+ block[block.length - 1] = (byte)(len );
- mac.update(block);
- incrementSequenceNumber();
+ mac.update(block);
+ incrementSequenceNumber();
+ }
// content
if (bb != null) {
--- a/jdk/src/share/classes/sun/security/ssl/OutputRecord.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/security/ssl/OutputRecord.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -205,7 +205,7 @@
}
if (signer.MAClen() != 0) {
byte[] hash = signer.compute(contentType, buf,
- headerSize, count - headerSize);
+ headerSize, count - headerSize, false);
write(hash);
}
}
--- a/jdk/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java Fri Mar 15 16:39:07 2013 -0700
@@ -34,7 +34,7 @@
import javax.net.ssl.*;
import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec;
-import sun.security.util.KeyLength;
+import sun.security.util.KeyUtil;
/**
* This is the client key exchange message (CLIENT --> SERVER) used with
@@ -191,7 +191,7 @@
"unable to get the plaintext of the premaster secret");
}
- int keySize = KeyLength.getKeySize(secretKey);
+ int keySize = KeyUtil.getKeySize(secretKey);
if (keySize > 0 && keySize != 384) { // 384 = 48 * 8
if (debug != null && Debug.isOn("handshake")) {
System.out.println(
--- a/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -958,35 +958,15 @@
* throw a fatal alert if the integrity check fails.
*/
try {
- decryptedBB = inputRecord.decrypt(readCipher, readBB);
+ decryptedBB = inputRecord.decrypt(readMAC, readCipher, readBB);
} catch (BadPaddingException e) {
- // RFC 2246 states that decryption_failed should be used
- // for this purpose. However, that allows certain attacks,
- // so we just send bad record MAC. We also need to make
- // sure to always check the MAC to avoid a timing attack
- // for the same issue. See paper by Vaudenay et al.
- //
- // rewind the BB if necessary.
- readBB.rewind();
-
- inputRecord.checkMAC(readMAC, readBB);
-
- // use the same alert types as for MAC failure below
byte alertType = (inputRecord.contentType() ==
Record.ct_handshake) ?
Alerts.alert_handshake_failure :
Alerts.alert_bad_record_mac;
- fatal(alertType, "Invalid padding", e);
+ fatal(alertType, e.getMessage(), e);
}
- if (!inputRecord.checkMAC(readMAC, decryptedBB)) {
- if (inputRecord.contentType() == Record.ct_handshake) {
- fatal(Alerts.alert_handshake_failure,
- "bad handshake record MAC");
- } else {
- fatal(Alerts.alert_bad_record_mac, "bad record MAC");
- }
- }
// if (!inputRecord.decompress(c))
// fatal(Alerts.alert_decompression_failure,
--- a/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -986,29 +986,13 @@
* throw a fatal alert if the integrity check fails.
*/
try {
- r.decrypt(readCipher);
+ r.decrypt(readMAC, readCipher);
} catch (BadPaddingException e) {
- // RFC 2246 states that decryption_failed should be used
- // for this purpose. However, that allows certain attacks,
- // so we just send bad record MAC. We also need to make
- // sure to always check the MAC to avoid a timing attack
- // for the same issue. See paper by Vaudenay et al.
- r.checkMAC(readMAC);
- // use the same alert types as for MAC failure below
byte alertType = (r.contentType() == Record.ct_handshake)
? Alerts.alert_handshake_failure
: Alerts.alert_bad_record_mac;
- fatal(alertType, "Invalid padding", e);
+ fatal(alertType, e.getMessage(), e);
}
- if (!r.checkMAC(readMAC)) {
- if (r.contentType() == Record.ct_handshake) {
- fatal(Alerts.alert_handshake_failure,
- "bad handshake record MAC");
- } else {
- fatal(Alerts.alert_bad_record_mac, "bad record MAC");
- }
- }
-
// if (!r.decompress(c))
// fatal(Alerts.alert_decompression_failure,
--- a/jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java Fri Mar 15 16:39:07 2013 -0700
@@ -150,7 +150,7 @@
// In SSLv3 and TLS, messages follow strictly increasing
// numerical order _except_ for one annoying special case.
//
- if ((state > type)
+ if ((state >= type)
&& (state != HandshakeMessage.ht_client_key_exchange
&& type != HandshakeMessage.ht_certificate_verify)) {
throw new SSLProtocolException(
@@ -250,13 +250,15 @@
}
//
- // Move the state machine forward except for that annoying
- // special case. This means that clients could send extra
- // cert verify messages; not a problem so long as all of
- // them actually check out.
+ // Move state machine forward if the message handling
+ // code didn't already do so
//
- if (state < type && type != HandshakeMessage.ht_certificate_verify) {
- state = type;
+ if (state < type) {
+ if(type == HandshakeMessage.ht_certificate_verify) {
+ state = type + 2; // an annoying special case
+ } else {
+ state = type;
+ }
}
}
@@ -1406,7 +1408,7 @@
if (debug != null && Debug.isOn("handshake")) {
mesg.print(System.out);
}
- return dh.getAgreedSecret(mesg.getClientPublicKey());
+ return dh.getAgreedSecret(mesg.getClientPublicKey(), false);
}
private SecretKey clientKeyExchange(ECDHClientKeyExchange mesg)
--- a/jdk/src/share/classes/sun/security/ssl/SignatureAndHashAlgorithm.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/security/ssl/SignatureAndHashAlgorithm.java Fri Mar 15 16:39:07 2013 -0700
@@ -38,7 +38,7 @@
import java.util.Collections;
import java.util.ArrayList;
-import sun.security.util.KeyLength;
+import sun.security.util.KeyUtil;
/**
* Signature and hash algorithm.
@@ -274,7 +274,7 @@
* If key size is less than 512, the digest length should be
* less than or equal to 20 bytes.
*/
- int keySize = KeyLength.getKeySize(signingKey);
+ int keySize = KeyUtil.getKeySize(signingKey);
if (keySize >= 768) {
maxDigestLength = HashAlgorithm.SHA512.length;
} else if ((keySize >= 512) && (keySize < 768)) {
--- a/jdk/src/share/classes/sun/security/tools/jarsigner/Main.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/security/tools/jarsigner/Main.java Fri Mar 15 16:39:07 2013 -0700
@@ -57,7 +57,7 @@
import sun.security.tools.PathList;
import sun.security.x509.*;
import sun.security.util.*;
-import sun.misc.BASE64Encoder;
+import java.util.Base64;
/**
@@ -1120,7 +1120,6 @@
* different, replace the hash in the manifest with the newly
* generated one. (This may invalidate existing signatures!)
*/
- BASE64Encoder encoder = new JarBASE64Encoder();
Vector<ZipEntry> mfFiles = new Vector<>();
boolean wasSigned = false;
@@ -1148,15 +1147,14 @@
if (manifest.getAttributes(ze.getName()) != null) {
// jar entry is contained in manifest, check and
// possibly update its digest attributes
- if (updateDigests(ze, zipFile, digests, encoder,
+ if (updateDigests(ze, zipFile, digests,
manifest) == true) {
mfModified = true;
}
} else if (!ze.isDirectory()) {
// Add entry to manifest
Attributes attrs = getDigestAttributes(ze, zipFile,
- digests,
- encoder);
+ digests);
mfEntries.put(ze.getName(), attrs);
mfModified = true;
}
@@ -1955,8 +1953,7 @@
* of base64-encoded strings.
*/
private synchronized String[] getDigests(ZipEntry ze, ZipFile zf,
- MessageDigest[] digests,
- BASE64Encoder encoder)
+ MessageDigest[] digests)
throws IOException {
int n, i;
@@ -1980,7 +1977,7 @@
// complete the digests
String[] base64Digests = new String[digests.length];
for (i=0; i<digests.length; i++) {
- base64Digests[i] = encoder.encode(digests[i].digest());
+ base64Digests[i] = Base64.getEncoder().encodeToString(digests[i].digest());
}
return base64Digests;
}
@@ -1990,11 +1987,10 @@
* attributes
*/
private Attributes getDigestAttributes(ZipEntry ze, ZipFile zf,
- MessageDigest[] digests,
- BASE64Encoder encoder)
+ MessageDigest[] digests)
throws IOException {
- String[] base64Digests = getDigests(ze, zf, digests, encoder);
+ String[] base64Digests = getDigests(ze, zf, digests);
Attributes attrs = new Attributes();
for (int i=0; i<digests.length; i++) {
@@ -2016,12 +2012,11 @@
*/
private boolean updateDigests(ZipEntry ze, ZipFile zf,
MessageDigest[] digests,
- BASE64Encoder encoder,
Manifest mf) throws IOException {
boolean update = false;
Attributes attrs = mf.getAttributes(ze.getName());
- String[] base64Digests = getDigests(ze, zf, digests, encoder);
+ String[] base64Digests = getDigests(ze, zf, digests);
for (int i=0; i<digests.length; i++) {
// The entry name to be written into attrs
@@ -2094,19 +2089,6 @@
}
}
-/**
- * This is a BASE64Encoder that does not insert a default newline at the end of
- * every output line. This is necessary because java.util.jar does its own
- * line management (see Manifest.make72Safe()). Inserting additional new lines
- * can cause line-wrapping problems (see CR 6219522).
- */
-class JarBASE64Encoder extends BASE64Encoder {
- /**
- * Encode the suffix that ends every output line.
- */
- protected void encodeLineSuffix(OutputStream aStream) throws IOException { }
-}
-
class SignatureFile {
/** SignatureFile */
@@ -2129,7 +2111,6 @@
sf = new Manifest();
Attributes mattr = sf.getMainAttributes();
- BASE64Encoder encoder = new JarBASE64Encoder();
mattr.putValue(Attributes.Name.SIGNATURE_VERSION.toString(), "1.0");
mattr.putValue("Created-By", version + " (" + javaVendor + ")");
@@ -2138,7 +2119,7 @@
// sign the whole manifest
for (int i=0; i < digests.length; i++) {
mattr.putValue(digests[i].getAlgorithm()+"-Digest-Manifest",
- encoder.encode(md.manifestDigest(digests[i])));
+ Base64.getEncoder().encodeToString(md.manifestDigest(digests[i])));
}
}
@@ -2149,7 +2130,7 @@
for (int i=0; i < digests.length; i++) {
mattr.putValue(digests[i].getAlgorithm() +
"-Digest-" + ManifestDigester.MF_MAIN_ATTRS,
- encoder.encode(mde.digest(digests[i])));
+ Base64.getEncoder().encodeToString(mde.digest(digests[i])));
}
} else {
throw new IllegalStateException
@@ -2170,7 +2151,7 @@
Attributes attr = new Attributes();
for (int i=0; i < digests.length; i++) {
attr.putValue(digests[i].getAlgorithm()+"-Digest",
- encoder.encode(mde.digest(digests[i])));
+ Base64.getEncoder().encodeToString(mde.digest(digests[i])));
}
entries.put(name, attr);
}
--- a/jdk/src/share/classes/sun/security/tools/keytool/Main.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/security/tools/keytool/Main.java Fri Mar 15 16:39:07 2013 -0700
@@ -63,7 +63,7 @@
import java.security.cert.X509CRLEntry;
import java.security.cert.X509CRLSelector;
import javax.security.auth.x500.X500Principal;
-import sun.misc.BASE64Encoder;
+import java.util.Base64;
import sun.security.util.ObjectIdentifier;
import sun.security.pkcs10.PKCS10;
import sun.security.pkcs10.PKCS10Attribute;
@@ -73,7 +73,6 @@
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
-import sun.misc.BASE64Decoder;
import sun.security.pkcs.PKCS9Attribute;
import sun.security.tools.KeyStoreUtil;
import sun.security.tools.PathList;
@@ -555,11 +554,11 @@
return cmd != PRINTCERT && cmd != PRINTCERTREQ;
}
+
/**
* Execute the commands.
*/
void doCommands(PrintStream out) throws Exception {
-
if (storetype == null) {
storetype = KeyStore.getDefaultType();
}
@@ -1189,7 +1188,7 @@
sb.append(s);
}
}
- byte[] rawReq = new BASE64Decoder().decodeBuffer(new String(sb));
+ byte[] rawReq = Base64.getMimeDecoder().decode(new String(sb));
PKCS10 req = new PKCS10(rawReq);
info.set(X509CertInfo.KEY, new CertificateX509Key(req.getSubjectPublicKeyInfo()));
@@ -1266,7 +1265,7 @@
crl.sign(privateKey, sigAlgName);
if (rfc) {
out.println("-----BEGIN X509 CRL-----");
- new BASE64Encoder().encodeBuffer(crl.getEncodedInternal(), out);
+ out.println(Base64.getMimeEncoder().encodeToString(crl.getEncodedInternal()));
out.println("-----END X509 CRL-----");
} else {
out.write(crl.getEncodedInternal());
@@ -2148,7 +2147,7 @@
if (rfc) {
X509CRL xcrl = (X509CRL)crl;
out.println("-----BEGIN X509 CRL-----");
- new BASE64Encoder().encodeBuffer(xcrl.getEncoded(), out);
+ out.println(Base64.getMimeEncoder().encodeToString(xcrl.getEncoded()));
out.println("-----END X509 CRL-----");
} else {
out.println(crl.toString());
@@ -2175,7 +2174,7 @@
sb.append(s);
}
}
- PKCS10 req = new PKCS10(new BASE64Decoder().decodeBuffer(new String(sb)));
+ PKCS10 req = new PKCS10(Base64.getMimeDecoder().decode(new String(sb)));
PublicKey pkey = req.getSubjectPublicKeyInfo();
out.printf(rb.getString("PKCS.10.Certificate.Request.Version.1.0.Subject.s.Public.Key.s.format.s.key."),
@@ -2227,8 +2226,10 @@
Object[] source = {new Integer(i + 1)};
out.println(form.format(source));
}
- if (rfc) dumpCert(x509Cert, out);
- else printX509Cert(x509Cert, out);
+ if (rfc)
+ dumpCert(x509Cert, out);
+ else
+ printX509Cert(x509Cert, out);
if (i < (certs.length-1)) {
out.println();
}
@@ -2946,9 +2947,8 @@
throws IOException, CertificateException
{
if (rfc) {
- BASE64Encoder encoder = new BASE64Encoder();
out.println(X509Factory.BEGIN_CERT);
- encoder.encodeBuffer(cert.getEncoded(), out);
+ out.println(Base64.getMimeEncoder().encodeToString(cert.getEncoded()));
out.println(X509Factory.END_CERT);
} else {
out.write(cert.getEncoded()); // binary
--- a/jdk/src/share/classes/sun/security/util/DerIndefLenConverter.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/security/util/DerIndefLenConverter.java Fri Mar 15 16:39:07 2013 -0700
@@ -325,6 +325,10 @@
}
}
+ if (unresolved != 0) {
+ throw new IOException("not all indef len BER resolved");
+ }
+
newData = new byte[dataSize + numOfTotalLenBytes + unused];
dataPos=0; newDataPos=0; index=0;
--- a/jdk/src/share/classes/sun/security/util/DisabledAlgorithmConstraints.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/security/util/DisabledAlgorithmConstraints.java Fri Mar 15 16:39:07 2013 -0700
@@ -440,7 +440,7 @@
// Does this key constraint disable the specified key?
public boolean disables(Key key) {
- int size = KeyLength.getKeySize(key);
+ int size = KeyUtil.getKeySize(key);
if (size == 0) {
return true; // we don't allow any key of size 0.
--- a/jdk/src/share/classes/sun/security/util/KeyLength.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.util;
-
-import java.security.Key;
-import java.security.PrivilegedAction;
-import java.security.AccessController;
-import java.security.interfaces.ECKey;
-import java.security.interfaces.RSAKey;
-import java.security.interfaces.DSAKey;
-import javax.crypto.SecretKey;
-import javax.crypto.interfaces.DHKey;
-
-/**
- * A utility class to get key length
- */
-public final class KeyLength {
-
- /**
- * Returns the key size of the given key object in bits.
- *
- * @param key the key object, cannot be null
- * @return the key size of the given key object in bits, or -1 if the
- * key size is not accessible
- */
- final public static int getKeySize(Key key) {
- int size = -1;
-
- if (key instanceof Length) {
- try {
- Length ruler = (Length)key;
- size = ruler.length();
- } catch (UnsupportedOperationException usoe) {
- // ignore the exception
- }
-
- if (size >= 0) {
- return size;
- }
- }
-
- // try to parse the length from key specification
- if (key instanceof SecretKey) {
- SecretKey sk = (SecretKey)key;
- String format = sk.getFormat();
- if ("RAW".equals(format) && sk.getEncoded() != null) {
- size = (sk.getEncoded().length * 8);
- } // Otherwise, it may be a unextractable key of PKCS#11, or
- // a key we are not able to handle.
- } else if (key instanceof RSAKey) {
- RSAKey pubk = (RSAKey)key;
- size = pubk.getModulus().bitLength();
- } else if (key instanceof ECKey) {
- ECKey pubk = (ECKey)key;
- size = pubk.getParams().getOrder().bitLength();
- } else if (key instanceof DSAKey) {
- DSAKey pubk = (DSAKey)key;
- size = pubk.getParams().getP().bitLength();
- } else if (key instanceof DHKey) {
- DHKey pubk = (DHKey)key;
- size = pubk.getParams().getP().bitLength();
- } // Otherwise, it may be a unextractable key of PKCS#11, or
- // a key we are not able to handle.
-
- return size;
- }
-}
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/security/util/KeyUtil.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.util;
+
+import java.security.Key;
+import java.security.PrivilegedAction;
+import java.security.AccessController;
+import java.security.InvalidKeyException;
+import java.security.interfaces.ECKey;
+import java.security.interfaces.RSAKey;
+import java.security.interfaces.DSAKey;
+import java.security.spec.KeySpec;
+import javax.crypto.SecretKey;
+import javax.crypto.interfaces.DHKey;
+import javax.crypto.interfaces.DHPublicKey;
+import javax.crypto.spec.DHParameterSpec;
+import javax.crypto.spec.DHPublicKeySpec;
+import java.math.BigInteger;
+
+/**
+ * A utility class to get key length, valiate keys, etc.
+ */
+public final class KeyUtil {
+
+ /**
+ * Returns the key size of the given key object in bits.
+ *
+ * @param key the key object, cannot be null
+ * @return the key size of the given key object in bits, or -1 if the
+ * key size is not accessible
+ */
+ public static final int getKeySize(Key key) {
+ int size = -1;
+
+ if (key instanceof Length) {
+ try {
+ Length ruler = (Length)key;
+ size = ruler.length();
+ } catch (UnsupportedOperationException usoe) {
+ // ignore the exception
+ }
+
+ if (size >= 0) {
+ return size;
+ }
+ }
+
+ // try to parse the length from key specification
+ if (key instanceof SecretKey) {
+ SecretKey sk = (SecretKey)key;
+ String format = sk.getFormat();
+ if ("RAW".equals(format) && sk.getEncoded() != null) {
+ size = (sk.getEncoded().length * 8);
+ } // Otherwise, it may be a unextractable key of PKCS#11, or
+ // a key we are not able to handle.
+ } else if (key instanceof RSAKey) {
+ RSAKey pubk = (RSAKey)key;
+ size = pubk.getModulus().bitLength();
+ } else if (key instanceof ECKey) {
+ ECKey pubk = (ECKey)key;
+ size = pubk.getParams().getOrder().bitLength();
+ } else if (key instanceof DSAKey) {
+ DSAKey pubk = (DSAKey)key;
+ size = pubk.getParams().getP().bitLength();
+ } else if (key instanceof DHKey) {
+ DHKey pubk = (DHKey)key;
+ size = pubk.getParams().getP().bitLength();
+ } // Otherwise, it may be a unextractable key of PKCS#11, or
+ // a key we are not able to handle.
+
+ return size;
+ }
+
+ /**
+ * Returns whether the key is valid or not.
+ * <P>
+ * Note that this method is only apply to DHPublicKey at present.
+ *
+ * @param publicKey
+ * the key object, cannot be null
+ *
+ * @throws NullPointerException if {@code publicKey} is null
+ * @throws InvalidKeyException if {@code publicKey} is invalid
+ */
+ public static final void validate(Key key)
+ throws InvalidKeyException {
+ if (key == null) {
+ throw new NullPointerException(
+ "The key to be validated cannot be null");
+ }
+
+ if (key instanceof DHPublicKey) {
+ validateDHPublicKey((DHPublicKey)key);
+ }
+ }
+
+
+ /**
+ * Returns whether the key spec is valid or not.
+ * <P>
+ * Note that this method is only apply to DHPublicKeySpec at present.
+ *
+ * @param keySpec
+ * the key spec object, cannot be null
+ *
+ * @throws NullPointerException if {@code keySpec} is null
+ * @throws InvalidKeyException if {@code keySpec} is invalid
+ */
+ public static final void validate(KeySpec keySpec)
+ throws InvalidKeyException {
+ if (keySpec == null) {
+ throw new NullPointerException(
+ "The key spec to be validated cannot be null");
+ }
+
+ if (keySpec instanceof DHPublicKeySpec) {
+ validateDHPublicKey((DHPublicKeySpec)keySpec);
+ }
+ }
+
+ /**
+ * Returns whether the specified provider is Oracle provider or not.
+ * <P>
+ * Note that this method is only apply to SunJCE and SunPKCS11 at present.
+ *
+ * @param providerName
+ * the provider name
+ * @return true if, and only if, the provider of the specified
+ * {@code providerName} is Oracle provider
+ */
+ public static final boolean isOracleJCEProvider(String providerName) {
+ return providerName != null && (providerName.equals("SunJCE") ||
+ providerName.startsWith("SunPKCS11"));
+ }
+
+ /**
+ * Returns whether the Diffie-Hellman public key is valid or not.
+ *
+ * Per RFC 2631 and NIST SP800-56A, the following algorithm is used to
+ * validate Diffie-Hellman public keys:
+ * 1. Verify that y lies within the interval [2,p-1]. If it does not,
+ * the key is invalid.
+ * 2. Compute y^q mod p. If the result == 1, the key is valid.
+ * Otherwise the key is invalid.
+ */
+ private static void validateDHPublicKey(DHPublicKey publicKey)
+ throws InvalidKeyException {
+ DHParameterSpec paramSpec = publicKey.getParams();
+
+ BigInteger p = paramSpec.getP();
+ BigInteger g = paramSpec.getG();
+ BigInteger y = publicKey.getY();
+
+ validateDHPublicKey(p, g, y);
+ }
+
+ private static void validateDHPublicKey(DHPublicKeySpec publicKeySpec)
+ throws InvalidKeyException {
+ validateDHPublicKey(publicKeySpec.getP(),
+ publicKeySpec.getG(), publicKeySpec.getY());
+ }
+
+ private static void validateDHPublicKey(BigInteger p,
+ BigInteger g, BigInteger y) throws InvalidKeyException {
+
+ // For better interoperability, the interval is limited to [2, p-2].
+ BigInteger leftOpen = BigInteger.ONE;
+ BigInteger rightOpen = p.subtract(BigInteger.ONE);
+ if (y.compareTo(leftOpen) <= 0) {
+ throw new InvalidKeyException(
+ "Diffie-Hellman public key is too small");
+ }
+ if (y.compareTo(rightOpen) >= 0) {
+ throw new InvalidKeyException(
+ "Diffie-Hellman public key is too large");
+ }
+
+ // Don't bother to check against the y^q mod p if safe primes are used.
+ }
+}
+
--- a/jdk/src/share/classes/sun/security/util/ManifestEntryVerifier.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/security/util/ManifestEntryVerifier.java Fri Mar 15 16:39:07 2013 -0700
@@ -31,7 +31,7 @@
import java.util.*;
import java.util.jar.*;
-import sun.misc.BASE64Decoder;
+import java.util.Base64;
import sun.security.jca.Providers;
@@ -63,7 +63,6 @@
/** the manifest hashes for the digests in use */
ArrayList<byte[]> manifestHashes;
- private BASE64Decoder decoder = null;
private String name = null;
private Manifest man;
@@ -81,7 +80,6 @@
createdDigests = new HashMap<String, MessageDigest>(11);
digests = new ArrayList<MessageDigest>();
manifestHashes = new ArrayList<byte[]>();
- decoder = new BASE64Decoder();
this.man = man;
}
@@ -147,7 +145,7 @@
digest.reset();
digests.add(digest);
manifestHashes.add(
- decoder.decodeBuffer((String)se.getValue()));
+ Base64.getMimeDecoder().decode((String)se.getValue()));
}
}
}
--- a/jdk/src/share/classes/sun/security/util/SecurityConstants.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/security/util/SecurityConstants.java Fri Mar 15 16:39:07 2013 -0700
@@ -71,31 +71,6 @@
public static final AllPermission ALL_PERMISSION = new AllPermission();
/**
- * Permission type used when AWT is not present.
- */
- private static class FakeAWTPermission extends BasicPermission {
- private static final long serialVersionUID = -1L;
- public FakeAWTPermission(String name) {
- super(name);
- }
- public String toString() {
- return "(\"java.awt.AWTPermission\" \"" + getName() + "\")";
- }
- }
-
- /**
- * Permission factory used when AWT is not present.
- */
- private static class FakeAWTPermissionFactory
- implements PermissionFactory<FakeAWTPermission>
- {
- @Override
- public FakeAWTPermission newPermission(String name) {
- return new FakeAWTPermission(name);
- }
- }
-
- /**
* AWT Permissions used in the JDK.
*/
public static class AWT {
@@ -107,37 +82,29 @@
private static final String AWTFactory = "sun.awt.AWTPermissionFactory";
/**
- * The PermissionFactory to create AWT permissions (or fake permissions
- * if AWT is not present).
+ * The PermissionFactory to create AWT permissions (or null if AWT is
+ * not present)
*/
private static final PermissionFactory<?> factory = permissionFactory();
private static PermissionFactory<?> permissionFactory() {
- Class<?> c = AccessController
- .doPrivileged(new PrivilegedAction<Class<?>>() {
- public Class<?> run() {
- try {
- return Class.forName(AWTFactory, true, null);
- } catch (ClassNotFoundException e) {
- // not available
- return null;
- }
- }});
- if (c != null) {
- // AWT present
- try {
- return (PermissionFactory<?>)c.newInstance();
- } catch (ReflectiveOperationException x) {
- throw new InternalError(x.getMessage(), x);
- }
- } else {
- // AWT not present
- return new FakeAWTPermissionFactory();
+ Class<?> c;
+ try {
+ c = Class.forName(AWTFactory, false, AWT.class.getClassLoader());
+ } catch (ClassNotFoundException e) {
+ // not available
+ return null;
+ }
+ // AWT present
+ try {
+ return (PermissionFactory<?>)c.newInstance();
+ } catch (ReflectiveOperationException x) {
+ throw new InternalError(x);
}
}
private static Permission newAWTPermission(String name) {
- return factory.newPermission(name);
+ return (factory == null) ? null : factory.newPermission(name);
}
// java.lang.SecurityManager
--- a/jdk/src/share/classes/sun/security/util/SignatureFileVerifier.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/security/util/SignatureFileVerifier.java Fri Mar 15 16:39:07 2013 -0700
@@ -35,7 +35,7 @@
import java.util.jar.*;
import sun.security.pkcs.*;
-import sun.misc.BASE64Decoder;
+import java.util.Base64;
import sun.security.jca.Providers;
@@ -220,7 +220,6 @@
name);
}
- BASE64Decoder decoder = new BASE64Decoder();
CodeSigner[] newSigners = getSigners(infos, block);
@@ -232,10 +231,10 @@
sf.getEntries().entrySet().iterator();
// see if we can verify the whole manifest first
- boolean manifestSigned = verifyManifestHash(sf, md, decoder, manifestDigests);
+ boolean manifestSigned = verifyManifestHash(sf, md, manifestDigests);
// verify manifest main attributes
- if (!manifestSigned && !verifyManifestMainAttrs(sf, md, decoder)) {
+ if (!manifestSigned && !verifyManifestMainAttrs(sf, md)) {
throw new SecurityException
("Invalid signature file digest for Manifest main attributes");
}
@@ -247,7 +246,7 @@
String name = e.getKey();
if (manifestSigned ||
- (verifySection(e.getValue(), name, md, decoder))) {
+ (verifySection(e.getValue(), name, md))) {
if (name.startsWith("./"))
name = name.substring(2);
@@ -275,7 +274,6 @@
*/
private boolean verifyManifestHash(Manifest sf,
ManifestDigester md,
- BASE64Decoder decoder,
List<Object> manifestDigests)
throws IOException
{
@@ -297,7 +295,7 @@
if (digest != null) {
byte[] computedHash = md.manifestDigest(digest);
byte[] expectedHash =
- decoder.decodeBuffer((String)se.getValue());
+ Base64.getMimeDecoder().decode((String)se.getValue());
if (debug != null) {
debug.println("Signature File: Manifest digest " +
@@ -320,8 +318,7 @@
}
private boolean verifyManifestMainAttrs(Manifest sf,
- ManifestDigester md,
- BASE64Decoder decoder)
+ ManifestDigester md)
throws IOException
{
Attributes mattr = sf.getMainAttributes();
@@ -342,7 +339,7 @@
md.get(ManifestDigester.MF_MAIN_ATTRS, false);
byte[] computedHash = mde.digest(digest);
byte[] expectedHash =
- decoder.decodeBuffer((String)se.getValue());
+ Base64.getMimeDecoder().decode((String)se.getValue());
if (debug != null) {
debug.println("Signature File: " +
@@ -387,8 +384,7 @@
private boolean verifySection(Attributes sfAttr,
String name,
- ManifestDigester md,
- BASE64Decoder decoder)
+ ManifestDigester md)
throws IOException
{
boolean oneDigestVerified = false;
@@ -418,7 +414,7 @@
boolean ok = false;
byte[] expected =
- decoder.decodeBuffer((String)se.getValue());
+ Base64.getMimeDecoder().decode((String)se.getValue());
byte[] computed;
if (workaround) {
computed = mde.digestWorkaround(digest);
--- a/jdk/src/share/classes/sun/security/util/UntrustedCertificates.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/security/util/UntrustedCertificates.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -737,5 +737,111 @@
"B8WfedLHjFW/TMcnXlEWKz4=\n" +
"-----END CERTIFICATE-----");
+ //
+ // Revoked DigiCert code signing certificates used to sign malware
+ //
+
+ // Subject: CN=Buster Paper Comercial Ltda,
+ // O=Buster Paper Comercial Ltda,
+ // L=S?o Jos? Dos Campos,
+ // ST=S?o Paulo,
+ // C=BR
+ // Issuer: CN=DigiCert Assured ID Code Signing CA-1,
+ // OU=www.digicert.com,
+ // O=DigiCert Inc,
+ // C=US
+ // Serial: 07:b4:4c:db:ff:fb:78:de:05:f4:26:16:72:a6:73:12
+ add("buster-paper-comercial-ltda-72A67312",
+ "-----BEGIN CERTIFICATE-----\n" +
+ "MIIGwzCCBaugAwIBAgIQB7RM2//7eN4F9CYWcqZzEjANBgkqhkiG9w0BAQUFADBv\n" +
+ "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n" +
+ "d3cuZGlnaWNlcnQuY29tMS4wLAYDVQQDEyVEaWdpQ2VydCBBc3N1cmVkIElEIENv\n" +
+ "ZGUgU2lnbmluZyBDQS0xMB4XDTEzMDExNzAwMDAwMFoXDTE0MDEyMjEyMDAwMFow\n" +
+ "gY4xCzAJBgNVBAYTAkJSMRMwEQYDVQQIDApTw6NvIFBhdWxvMR4wHAYDVQQHDBVT\n" +
+ "w6NvIEpvc8OpIERvcyBDYW1wb3MxJDAiBgNVBAoTG0J1c3RlciBQYXBlciBDb21l\n" +
+ "cmNpYWwgTHRkYTEkMCIGA1UEAxMbQnVzdGVyIFBhcGVyIENvbWVyY2lhbCBMdGRh\n" +
+ "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzO0l6jWIpEfO2oUpVHpL\n" +
+ "HETj5lzivNb0S9jKHgGJax917czh81PnGTxwxFXd6gLJuy/XFHvmiSi8g8jzlymn\n" +
+ "2Ji5zQ3CPaz7nomJokSUDlMVJ2qYWtctw4jrdjuI4qtn+koXXUFkWjkf8h8251I4\n" +
+ "tUs7S49HE2Go5owCYP3byajj7fsFAYR/Xb7TdVtndkZsUB/YgOjHovyACjouaNCi\n" +
+ "mDiRyQ6zLLjZGiyeD65Yiseuhp5b8/BL5h1p7w76QYMYMVQNAdtDKut2R8MBpuWf\n" +
+ "Ny7Eoi0x/gm1p9X5Rcl5aN7K0G4UtTAJKbkuUfXddsyFoM0Nx8uo8SgNQ8Y/X5Jx\n" +
+ "BwIDAQABo4IDOTCCAzUwHwYDVR0jBBgwFoAUe2jOKarAF75JeuHlP9an90WPNTIw\n" +
+ "HQYDVR0OBBYEFFLZ3n5nt/Eer7n1bvtOqMb1qKO5MA4GA1UdDwEB/wQEAwIHgDAT\n" +
+ "BgNVHSUEDDAKBggrBgEFBQcDAzBzBgNVHR8EbDBqMDOgMaAvhi1odHRwOi8vY3Js\n" +
+ "My5kaWdpY2VydC5jb20vYXNzdXJlZC1jcy0yMDExYS5jcmwwM6AxoC+GLWh0dHA6\n" +
+ "Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9hc3N1cmVkLWNzLTIwMTFhLmNybDCCAcQGA1Ud\n" +
+ "IASCAbswggG3MIIBswYJYIZIAYb9bAMBMIIBpDA6BggrBgEFBQcCARYuaHR0cDov\n" +
+ "L3d3dy5kaWdpY2VydC5jb20vc3NsLWNwcy1yZXBvc2l0b3J5Lmh0bTCCAWQGCCsG\n" +
+ "AQUFBwICMIIBVh6CAVIAQQBuAHkAIAB1AHMAZQAgAG8AZgAgAHQAaABpAHMAIABD\n" +
+ "AGUAcgB0AGkAZgBpAGMAYQB0AGUAIABjAG8AbgBzAHQAaQB0AHUAdABlAHMAIABh\n" +
+ "AGMAYwBlAHAAdABhAG4AYwBlACAAbwBmACAAdABoAGUAIABEAGkAZwBpAEMAZQBy\n" +
+ "AHQAIABDAFAALwBDAFAAUwAgAGEAbgBkACAAdABoAGUAIABSAGUAbAB5AGkAbgBn\n" +
+ "ACAAUABhAHIAdAB5ACAAQQBnAHIAZQBlAG0AZQBuAHQAIAB3AGgAaQBjAGgAIABs\n" +
+ "AGkAbQBpAHQAIABsAGkAYQBiAGkAbABpAHQAeQAgAGEAbgBkACAAYQByAGUAIABp\n" +
+ "AG4AYwBvAHIAcABvAHIAYQB0AGUAZAAgAGgAZQByAGUAaQBuACAAYgB5ACAAcgBl\n" +
+ "AGYAZQByAGUAbgBjAGUALjCBggYIKwYBBQUHAQEEdjB0MCQGCCsGAQUFBzABhhho\n" +
+ "dHRwOi8vb2NzcC5kaWdpY2VydC5jb20wTAYIKwYBBQUHMAKGQGh0dHA6Ly9jYWNl\n" +
+ "cnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENvZGVTaWduaW5nQ0Et\n" +
+ "MS5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQUFAAOCAQEAPTTQvpOIikXI\n" +
+ "hTLnNbajaFRR5GhQpTzUNgBfF9VYSlNw/wMjpGsrh5RxaJCip52jbehmTgjMRhft\n" +
+ "jRYyml44PAVsCcR9uEoDpCZYpI1fHI1R+F8jd1C9rqprbSwwOG4xlg4SmvTHYs6e\n" +
+ "gBItQ/1p9XY+Sf4Wv1qOuOFL1qvV/5VyR2zdlOQCmKCeMgxt6a/tHLBDiAA67D44\n" +
+ "/vfdoNJl0CU2It0PO60jdCPFNWIRcxL+OSDqAoePeUC7xQ+JsTEIxuUE8+d6w6fc\n" +
+ "BV2mYb1flh22t46GLjh4gyo7xw3aL6L0L0jzlTT6IcEw6NIbaPbIKj/npQnHobYj\n" +
+ "XMuKLxbh7g==\n" +
+ "-----END CERTIFICATE-----");
+
+ // Subject: CN=BUSTER ASSISTENCIA TECNICA ELETRONICA LTDA - ME,
+ // O=BUSTER ASSISTENCIA TECNICA ELETRONICA LTDA - ME,
+ // L=S?o Paulo,
+ // ST=S?o Paulo,
+ // C=BR
+ // Issuer: CN=DigiCert Assured ID Code Signing CA-1,
+ // OU=www.digicert.com,
+ // O=DigiCert Inc,
+ // C=US
+ // Serial: 0a:38:9b:95:ee:73:6d:d1:3b:c0:ed:74:3f:d7:4d:2f
+ add("buster-assistencia-tecnica-electronica-ltda-3FD74D2F",
+ "-----BEGIN CERTIFICATE-----\n" +
+ "MIIG4DCCBcigAwIBAgIQCjible5zbdE7wO10P9dNLzANBgkqhkiG9w0BAQUFADBv\n" +
+ "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n" +
+ "d3cuZGlnaWNlcnQuY29tMS4wLAYDVQQDEyVEaWdpQ2VydCBBc3N1cmVkIElEIENv\n" +
+ "ZGUgU2lnbmluZyBDQS0xMB4XDTEyMTEwOTAwMDAwMFoXDTEzMTExNDEyMDAwMFow\n" +
+ "gasxCzAJBgNVBAYTAkJSMRMwEQYDVQQIDApTw6NvIFBhdWxvMRMwEQYDVQQHDApT\n" +
+ "w6NvIFBhdWxvMTgwNgYDVQQKEy9CVVNURVIgQVNTSVNURU5DSUEgVEVDTklDQSBF\n" +
+ "TEVUUk9OSUNBIExUREEgLSBNRTE4MDYGA1UEAxMvQlVTVEVSIEFTU0lTVEVOQ0lB\n" +
+ "IFRFQ05JQ0EgRUxFVFJPTklDQSBMVERBIC0gTUUwggEiMA0GCSqGSIb3DQEBAQUA\n" +
+ "A4IBDwAwggEKAoIBAQDAqNeEs5/B2CTXGjTOkUIdu6jV6qulOZwdw4sefHWYj1UR\n" +
+ "4z6zPk9kjpUgbnb402RFq88QtfInwddZ/wXn9OxMtDd/3TnC7HrhNS7ga79ZFL2V\n" +
+ "JnmzKHum2Yvh0q82QEJ9tHBR2X9VdKpUIH08Zs3k6cWWM1H0YX0cxA/HohhesQJW\n" +
+ "kwJ3urOIJiH/HeByDk8a1NS8safcCxk5vxvW4WvCg43iT09LeHY5Aa8abKw8lqVb\n" +
+ "0tD5ZSIjdmdj3TT1U37iAHLLRM2DXbxfdbhouUX1c5U1ZHAMA67HwjKiseOiDaHj\n" +
+ "NUGbC37C+cgbc9VVM/cURD8WvS0Kj6fQv7F2QtJDAgMBAAGjggM5MIIDNTAfBgNV\n" +
+ "HSMEGDAWgBR7aM4pqsAXvkl64eU/1qf3RY81MjAdBgNVHQ4EFgQU88EXKAyDsh30\n" +
+ "o9+Gu9a4xUy+FSMwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMD\n" +
+ "MHMGA1UdHwRsMGowM6AxoC+GLWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9hc3N1\n" +
+ "cmVkLWNzLTIwMTFhLmNybDAzoDGgL4YtaHR0cDovL2NybDQuZGlnaWNlcnQuY29t\n" +
+ "L2Fzc3VyZWQtY3MtMjAxMWEuY3JsMIIBxAYDVR0gBIIBuzCCAbcwggGzBglghkgB\n" +
+ "hv1sAwEwggGkMDoGCCsGAQUFBwIBFi5odHRwOi8vd3d3LmRpZ2ljZXJ0LmNvbS9z\n" +
+ "c2wtY3BzLXJlcG9zaXRvcnkuaHRtMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4A\n" +
+ "eQAgAHUAcwBlACAAbwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQA\n" +
+ "ZQAgAGMAbwBuAHMAdABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUA\n" +
+ "IABvAGYAIAB0AGgAZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAA\n" +
+ "YQBuAGQAIAB0AGgAZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcA\n" +
+ "cgBlAGUAbQBlAG4AdAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIA\n" +
+ "aQBsAGkAdAB5ACAAYQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQA\n" +
+ "ZQBkACAAaABlAHIAZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMIGC\n" +
+ "BggrBgEFBQcBAQR2MHQwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0\n" +
+ "LmNvbTBMBggrBgEFBQcwAoZAaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0Rp\n" +
+ "Z2lDZXJ0QXNzdXJlZElEQ29kZVNpZ25pbmdDQS0xLmNydDAMBgNVHRMBAf8EAjAA\n" +
+ "MA0GCSqGSIb3DQEBBQUAA4IBAQAei1QmiXepje8OIfo/WonD4MIXgpPr2dfRaquQ\n" +
+ "A8q63OpTRSveyqdQDCSPpDRF/nvO1Y30yksZvIH1tNBsW5LBdxAKN3lFdBlqBwtE\n" +
+ "Q3jHc0KVVYRJ0FBaGE/PJHmRajscdAhYIcMPhTga0u0tDK+wOHEq3993dfl6yHjA\n" +
+ "XHU2iW5pnk75ZoE39zALD5eKXT8ZXrET5c3XUFJKWA+XuGmdmyzqo0Au49PanBv9\n" +
+ "UlZnabYfqoMArqMS0tGSX4cGgi9/2E+pHG9BX4sFW+ZDumroOA2pxyMWEKjxePEL\n" +
+ "zCOfhbsRWdMLYepauaNZOIMZXmFwcrIl0TGMkTAtATz+XmZc\n" +
+ "-----END CERTIFICATE-----");
+
}
}
--- a/jdk/src/share/classes/sun/security/x509/X509CertImpl.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/security/x509/X509CertImpl.java Fri Mar 15 16:39:07 2013 -0700
@@ -41,7 +41,7 @@
import javax.security.auth.x500.X500Principal;
import sun.misc.HexDumpEncoder;
-import sun.misc.BASE64Decoder;
+import java.util.Base64;
import sun.security.util.*;
import sun.security.provider.X509Factory;
@@ -263,7 +263,6 @@
}
if (line.equals(X509Factory.BEGIN_CERT)) {
/* stream appears to be hex-encoded bytes */
- BASE64Decoder decoder = new BASE64Decoder();
ByteArrayOutputStream decstream = new ByteArrayOutputStream();
try {
while ((line = certBufferedReader.readLine()) != null) {
@@ -271,7 +270,7 @@
der = new DerValue(decstream.toByteArray());
break;
} else {
- decstream.write(decoder.decodeBuffer(line));
+ decstream.write(Base64.getMimeDecoder().decode(line));
}
}
} catch (IOException ioe2) {
--- a/jdk/src/share/classes/sun/tools/jar/Manifest.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/tools/jar/Manifest.java Fri Mar 15 16:39:07 2013 -0700
@@ -30,8 +30,7 @@
import java.security.*;
import sun.net.www.MessageHeader;
-import sun.misc.BASE64Encoder;
-import sun.misc.BASE64Decoder;
+import java.util.Base64;
/**
* This is OBSOLETE. DO NOT USE THIS. Use java.util.jar.Manifest
@@ -178,7 +177,6 @@
return;
}
- BASE64Encoder enc = new BASE64Encoder();
/* compute hashes, write over any other "Hash-Algorithms" (?) */
for (int j = 0; j < hashes.length; ++j) {
@@ -190,7 +188,7 @@
while ((len = is.read(tmpbuf, 0, tmpbuf.length)) != -1) {
dig.update(tmpbuf, 0, len);
}
- mh.set(hashes[j] + "-Digest", enc.encode(dig.digest()));
+ mh.set(hashes[j] + "-Digest", Base64.getMimeEncoder().encodeToString(dig.digest()));
} catch (NoSuchAlgorithmException e) {
throw new JarException("Digest algorithm " + hashes[j] +
" not available.");
--- a/jdk/src/share/classes/sun/tools/jar/SignatureFile.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/tools/jar/SignatureFile.java Fri Mar 15 16:39:07 2013 -0700
@@ -30,8 +30,8 @@
import java.security.*;
import sun.net.www.MessageHeader;
-import sun.misc.BASE64Encoder;
-import sun.misc.BASE64Decoder;
+import java.util.Base64;
+
import sun.security.pkcs.*;
import sun.security.x509.AlgorithmId;
@@ -305,7 +305,6 @@
}
smh.set("Name", name);
- BASE64Encoder encoder = new BASE64Encoder();
try {
for (int i = 0; i < hashes.length; ++i) {
MessageDigest dig = getDigest(hashes[i]);
@@ -314,7 +313,7 @@
mh.print(ps);
byte[] headerBytes = baos.toByteArray();
byte[] digest = dig.digest(headerBytes);
- smh.set(hashes[i] + "-Digest", encoder.encode(digest));
+ smh.set(hashes[i] + "-Digest", Base64.getMimeEncoder().encodeToString(digest));
}
return smh;
} catch (NoSuchAlgorithmException e) {
--- a/jdk/src/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java Fri Mar 15 16:39:07 2013 -0700
@@ -33,6 +33,7 @@
import java.text.spi.DecimalFormatSymbolsProvider;
import java.text.spi.NumberFormatProvider;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;
@@ -89,10 +90,7 @@
* LocaleProviderAdapter preference list. The default list is intended
* to behave the same manner in JDK7.
*/
- private static Type[] adapterPreference = {
- Type.JRE,
- Type.SPI,
- };
+ private static final List<Type> adapterPreference;
/**
* JRE Locale Data Adapter instance
@@ -129,10 +127,11 @@
static {
String order = AccessController.doPrivileged(
new sun.security.action.GetPropertyAction("java.locale.providers"));
- // Override adapterPreference with the properties one
+ List<Type> typeList = new ArrayList<>();
+
+ // Check user specified adapter preference
if (order != null && order.length() != 0) {
String[] types = order.split(",");
- List<Type> typeList = new ArrayList<>();
for (String type : types) {
try {
Type aType = Type.valueOf(type.trim().toUpperCase(Locale.ROOT));
@@ -153,19 +152,23 @@
LocaleServiceProviderPool.config(LocaleProviderAdapter.class, e.toString());
}
}
+ }
- if (!typeList.isEmpty()) {
- if (!typeList.contains(Type.JRE)) {
- // Append FALLBACK as the last resort.
- fallbackLocaleProviderAdapter = new FallbackLocaleProviderAdapter();
- typeList.add(Type.FALLBACK);
- }
- adapterPreference = typeList.toArray(new Type[0]);
+ if (!typeList.isEmpty()) {
+ if (!typeList.contains(Type.JRE)) {
+ // Append FALLBACK as the last resort.
+ fallbackLocaleProviderAdapter = new FallbackLocaleProviderAdapter();
+ typeList.add(Type.FALLBACK);
}
+ } else {
+ // Default preference list
+ typeList.add(Type.JRE);
+ typeList.add(Type.SPI);
}
+
+ adapterPreference = Collections.unmodifiableList(typeList);
}
-
/**
* Returns the singleton instance for each adapter type
*/
@@ -202,7 +205,7 @@
/**
* Returns the preference order of LocaleProviderAdapter.Type
*/
- public static Type[] getAdapterPreference() {
+ public static List<Type> getAdapterPreference() {
return adapterPreference;
}
--- a/jdk/src/share/demo/java2d/J2DBench/build.xml Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/demo/java2d/J2DBench/build.xml Fri Mar 15 16:39:07 2013 -0700
@@ -52,7 +52,7 @@
<javac debug="flase" source="1.5" target="1.5" srcdir="${src}" destdir="${build}"/>
</target>
- <target name="run" depends="dist"
+ <target name="run" depends="dist"
description="run J2DBench" >
<java jar="${dist}/J2DBench.jar"
fork="true"
@@ -60,7 +60,7 @@
</java>
</target>
- <target name="analyze" depends="dist"
+ <target name="analyze" depends="dist"
description="run J2DAnalyzer" >
<java jar="${dist}/J2DAnalyzer.jar"
fork="true"
@@ -80,6 +80,10 @@
<copy todir="${build}/j2dbench/tests/iio/images">
<fileset dir="${resources}/images" />
</copy>
+ <mkdir dir="${build}/j2dbench/tests/cmm/images"/>
+ <copy todir="${build}/j2dbench/tests/cmm/images">
+ <fileset dir="${resources}/cmm_images" />
+ </copy>
</target>
<target name="dist" depends="compile, resources"
@@ -88,14 +92,14 @@
<mkdir dir="${dist}"/>
<!-- Put everything in ${build} into the J2DBench.jar file -->
- <jar jarfile="${dist}/J2DBench.jar" basedir="${build}"
+ <jar jarfile="${dist}/J2DBench.jar" basedir="${build}"
excludes="j2dbench/report/**" >
<manifest>
<attribute name="Built-By" value="${user.name}"/>
<attribute name="Main-Class" value="j2dbench.J2DBench"/>
</manifest>
</jar>
- <jar jarfile="${dist}/J2DAnalyzer.jar" basedir="${build}"
+ <jar jarfile="${dist}/J2DAnalyzer.jar" basedir="${build}"
includes="j2dbench/report/**" >
<manifest>
<attribute name="Built-By" value="${user.name}"/>
Binary file jdk/src/share/demo/java2d/J2DBench/resources/cmm_images/img_icc_large.jpg has changed
Binary file jdk/src/share/demo/java2d/J2DBench/resources/cmm_images/img_icc_medium.jpg has changed
Binary file jdk/src/share/demo/java2d/J2DBench/resources/cmm_images/img_icc_small.jpg has changed
--- a/jdk/src/share/demo/java2d/J2DBench/src/j2dbench/tests/cmm/ColorConversionTests.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/demo/java2d/J2DBench/src/j2dbench/tests/cmm/ColorConversionTests.java Fri Mar 15 16:39:07 2013 -0700
@@ -51,6 +51,7 @@
DataConversionTests.init();
ColorConvertOpTests.init();
+ EmbeddedProfileTests.init();
}
protected ColorConversionTests(Group parent, String nodeName, String description) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/demo/java2d/J2DBench/src/j2dbench/tests/cmm/EmbeddedProfileTests.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This source code is provided to illustrate the usage of a given feature
+ * or technique and has been deliberately simplified. Additional steps
+ * required for a production-quality application, such as security checks,
+ * input validation and proper error handling, might not be present in
+ * this sample code.
+ */
+
+package j2dbench.tests.cmm;
+
+import j2dbench.Group;
+import j2dbench.Option;
+import j2dbench.Result;
+import j2dbench.TestEnvironment;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.net.URL;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.stream.ImageInputStream;
+
+/* This benchmark verifies how changes in cmm library affects image decoding */
+public class EmbeddedProfileTests extends ColorConversionTests {
+
+ protected static Group grpRoot;
+ protected static Group grpOptionsRoot;
+
+ protected static Option inputImages;
+
+ public static void init() {
+ grpRoot = new Group(colorConvRoot, "embed", "Embedded Profile Tests");
+
+ grpOptionsRoot = new Group(grpRoot, "embedOptions", "Options");
+
+ inputImages = createImageList();
+
+ new ReadImageTest();
+ }
+
+ private static enum IccImageResource {
+ SMALL("images/img_icc_small.jpg", "512x512", "Small: 512x512"),
+ MEDIUM("images/img_icc_medium.jpg", "2048x2048", "Medium: 2048x2048"),
+ LARGE("images/img_icc_large.jpg", "4096x4096", "Large: 4096x4096");
+
+ private IccImageResource(String file, String name, String description) {
+ this.url = CMMTests.class.getResource(file);
+ this.abbrev = name;
+ this.description = description;
+ }
+
+ public final URL url;
+ public final String abbrev;
+ public final String description;
+ }
+
+ private static Option createImageList() {
+ IccImageResource[] images = IccImageResource.values();
+
+ int num = images.length;
+
+ String[] names = new String[num];
+ String[] abbrev = new String[num];
+ String[] descr = new String[num];
+
+ for (int i = 0; i < num; i++) {
+ names[i] = images[i].toString();
+ abbrev[i] = images[i].abbrev;
+ descr[i] = images[i].description;
+ }
+
+ Option list = new Option.ObjectList(grpOptionsRoot,
+ "Images", "Input Images",
+ names, images, abbrev, descr, 1);
+
+ return list;
+ }
+
+ public EmbeddedProfileTests(Group parent, String nodeName, String description) {
+ super(parent, nodeName, description);
+ addDependencies(grpOptionsRoot, true);
+ }
+
+ private static class Context {
+ URL input;
+
+ public Context(TestEnvironment env, Result res) {
+
+ IccImageResource icc_input = (IccImageResource)
+ env.getModifier(inputImages);
+
+ input = icc_input.url;
+ }
+ }
+
+ public Object initTest(TestEnvironment env, Result res) {
+ return new Context(env, res);
+ }
+
+ public void cleanupTest(TestEnvironment env, Object o) {
+ Context ctx = (Context)o;
+ ctx.input = null;
+ }
+
+ private static class ReadImageTest extends EmbeddedProfileTests {
+ public ReadImageTest() {
+ super(grpRoot, "embd_img_read", "ImageReader.read()");
+ }
+
+ public void runTest(Object octx, int numReps) {
+ final Context ctx = (Context)octx;
+ final URL url = ctx.input;
+ ImageInputStream iis = null;
+ ImageReader reader = null;
+
+ try {
+ iis = ImageIO.createImageInputStream(url.openStream());
+ reader = ImageIO.getImageReaders(iis).next();
+ } catch (IOException e) {
+ throw new RuntimeException("Unable to run the becnhmark", e);
+ }
+
+ do {
+ try {
+ reader.setInput(iis);
+ BufferedImage img = reader.read(0);
+ reader.reset();
+
+ iis = ImageIO.createImageInputStream(url.openStream());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ } while (--numReps >= 0);
+ }
+ }
+}
--- a/jdk/src/share/demo/jvmti/hprof/hprof_init.c Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/demo/jvmti/hprof/hprof_init.c Fri Mar 15 16:39:07 2013 -0700
@@ -1899,11 +1899,17 @@
*/
getSystemProperty("sun.boot.library.path", &boot_path);
md_build_library_name(lname, FILENAME_MAX, boot_path, name);
+ if ( strlen(lname) == 0 ) {
+ HPROF_ERROR(JNI_TRUE, "Could not find library");
+ }
jvmtiDeallocate(boot_path);
handle = md_load_library(lname, err_buf, (int)sizeof(err_buf));
if ( handle == NULL ) {
/* This may be necessary on Windows. */
md_build_library_name(lname, FILENAME_MAX, "", name);
+ if ( strlen(lname) == 0 ) {
+ HPROF_ERROR(JNI_TRUE, "Could not find library");
+ }
handle = md_load_library(lname, err_buf, (int)sizeof(err_buf));
if ( handle == NULL ) {
HPROF_ERROR(JNI_TRUE, err_buf);
@@ -1968,6 +1974,9 @@
getSystemProperty("sun.boot.library.path", &boot_path);
/* Load in NPT library for character conversions */
md_build_library_name(npt_lib, sizeof(npt_lib), boot_path, NPT_LIBNAME);
+ if ( strlen(npt_lib) == 0 ) {
+ HPROF_ERROR(JNI_TRUE, "Could not find npt library");
+ }
jvmtiDeallocate(boot_path);
NPT_INITIALIZE(npt_lib, &(gdata->npt), NPT_VERSION, NULL);
if ( gdata->npt == NULL ) {
--- a/jdk/src/share/lib/security/java.security-linux Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/lib/security/java.security-linux Fri Mar 15 16:39:07 2013 -0700
@@ -145,7 +145,19 @@
# passed to checkPackageAccess unless the
# corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted.
-package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.
+package.access=sun.,\
+ com.sun.xml.internal.bind.,\
+ com.sun.xml.internal.org.jvnet.staxex.,\
+ com.sun.xml.internal.ws.,\
+ com.sun.imageio.,\
+ com.sun.istack.internal.,\
+ com.sun.jmx.,\
+ com.sun.proxy.,\
+ com.sun.org.apache.xerces.internal.utils.,\
+ com.sun.org.apache.xalan.internal.utils.,\
+ com.sun.org.glassfish.external.,\
+ com.sun.org.glassfish.gmbal.,\
+ jdk.internal.
#
# List of comma-separated packages that start with or equal this string
@@ -157,7 +169,19 @@
# by default, none of the class loaders supplied with the JDK call
# checkPackageDefinition.
#
-package.definition=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.
+package.definition=sun.,\
+ com.sun.xml.internal.bind.,\
+ com.sun.xml.internal.org.jvnet.staxex.,\
+ com.sun.xml.internal.ws.,\
+ com.sun.imageio.,\
+ com.sun.istack.internal.,\
+ com.sun.jmx.,\
+ com.sun.proxy.,\
+ com.sun.org.apache.xerces.internal.utils.,\
+ com.sun.org.apache.xalan.internal.utils.,\
+ com.sun.org.glassfish.external.,\
+ com.sun.org.glassfish.gmbal.,\
+ jdk.internal.
#
# Determines whether this properties file can be appended to
--- a/jdk/src/share/lib/security/java.security-macosx Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/lib/security/java.security-macosx Fri Mar 15 16:39:07 2013 -0700
@@ -146,7 +146,20 @@
# passed to checkPackageAccess unless the
# corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted.
-package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,apple.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.
+package.access=sun.,\
+ com.sun.xml.internal.bind.,\
+ com.sun.xml.internal.org.jvnet.staxex.,\
+ com.sun.xml.internal.ws.,\
+ com.sun.imageio.,\
+ com.sun.istack.internal.,\
+ com.sun.jmx.,\
+ com.sun.proxy.,\
+ com.sun.org.apache.xerces.internal.utils.,\
+ com.sun.org.apache.xalan.internal.utils.,\
+ com.sun.org.glassfish.external.,\
+ com.sun.org.glassfish.gmbal.,\
+ jdk.internal.,\
+ apple.
#
# List of comma-separated packages that start with or equal this string
@@ -158,7 +171,20 @@
# by default, none of the class loaders supplied with the JDK call
# checkPackageDefinition.
#
-package.definition=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,apple.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.
+package.definition=sun.,\
+ com.sun.xml.internal.bind.,\
+ com.sun.xml.internal.org.jvnet.staxex.,\
+ com.sun.xml.internal.ws.,\
+ com.sun.imageio.,\
+ com.sun.istack.internal.,\
+ com.sun.jmx.,\
+ com.sun.proxy.,\
+ com.sun.org.apache.xerces.internal.utils.,\
+ com.sun.org.apache.xalan.internal.utils.,\
+ com.sun.org.glassfish.external.,\
+ com.sun.org.glassfish.gmbal.,\
+ jdk.internal.,\
+ apple.
#
# Determines whether this properties file can be appended to
--- a/jdk/src/share/lib/security/java.security-solaris Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/lib/security/java.security-solaris Fri Mar 15 16:39:07 2013 -0700
@@ -147,7 +147,19 @@
# passed to checkPackageAccess unless the
# corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted.
-package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.
+package.access=sun.,\
+ com.sun.xml.internal.bind.,\
+ com.sun.xml.internal.org.jvnet.staxex.,\
+ com.sun.xml.internal.ws.,\
+ com.sun.imageio.,\
+ com.sun.istack.internal.,\
+ com.sun.jmx.,\
+ com.sun.proxy.,\
+ com.sun.org.apache.xerces.internal.utils.,\
+ com.sun.org.apache.xalan.internal.utils.,\
+ com.sun.org.glassfish.external.,\
+ com.sun.org.glassfish.gmbal.,\
+ jdk.internal.
#
# List of comma-separated packages that start with or equal this string
@@ -159,7 +171,19 @@
# by default, none of the class loaders supplied with the JDK call
# checkPackageDefinition.
#
-package.definition=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.
+package.definition=sun.,\
+ com.sun.xml.internal.bind.,\
+ com.sun.xml.internal.org.jvnet.staxex.,\
+ com.sun.xml.internal.ws.,\
+ com.sun.imageio.,\
+ com.sun.istack.internal.,\
+ com.sun.jmx.,\
+ com.sun.proxy.,\
+ com.sun.org.apache.xerces.internal.utils.,\
+ com.sun.org.apache.xalan.internal.utils.,\
+ com.sun.org.glassfish.external.,\
+ com.sun.org.glassfish.gmbal.,\
+ jdk.internal.
#
# Determines whether this properties file can be appended to
--- a/jdk/src/share/lib/security/java.security-windows Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/lib/security/java.security-windows Fri Mar 15 16:39:07 2013 -0700
@@ -146,7 +146,19 @@
# passed to checkPackageAccess unless the
# corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted.
-package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.
+package.access=sun.,\
+ com.sun.xml.internal.bind.,\
+ com.sun.xml.internal.org.jvnet.staxex.,\
+ com.sun.xml.internal.ws.,\
+ com.sun.imageio.,\
+ com.sun.istack.internal.,\
+ com.sun.jmx.,\
+ com.sun.proxy.,\
+ com.sun.org.apache.xerces.internal.utils.,\
+ com.sun.org.apache.xalan.internal.utils.,\
+ com.sun.org.glassfish.external.,\
+ com.sun.org.glassfish.gmbal.,\
+ jdk.internal.
#
# List of comma-separated packages that start with or equal this string
@@ -158,7 +170,19 @@
# by default, none of the class loaders supplied with the JDK call
# checkPackageDefinition.
#
-package.definition=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.
+package.definition=sun.,\
+ com.sun.xml.internal.bind.,\
+ com.sun.xml.internal.org.jvnet.staxex.,\
+ com.sun.xml.internal.ws.,\
+ com.sun.imageio.,\
+ com.sun.istack.internal.,\
+ com.sun.jmx.,\
+ com.sun.proxy.,\
+ com.sun.org.apache.xerces.internal.utils.,\
+ com.sun.org.apache.xalan.internal.utils.,\
+ com.sun.org.glassfish.external.,\
+ com.sun.org.glassfish.gmbal.,\
+ jdk.internal.
#
# Determines whether this properties file can be appended to
--- a/jdk/src/share/native/com/sun/java/util/jar/pack/bands.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/native/com/sun/java/util/jar/pack/bands.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -187,6 +187,10 @@
entry* band::getRefCommon(cpindex* ix_, bool nullOKwithCaller) {
CHECK_0;
+ if (ix_ == NULL) {
+ abort("no index");
+ return NULL;
+ }
assert(ix_->ixTag == ixTag
|| ((ixTag == CONSTANT_All ||
ixTag == CONSTANT_LoadableValue ||
@@ -354,7 +358,7 @@
BAND_INIT(method_metadata_bands, -1, -1),
BAND_INIT(method_MethodParameters_NB, BYTE1_spec, 0),
BAND_INIT(method_MethodParameters_name_RUN, UNSIGNED5_spec, NULL_OR_INDEX(CONSTANT_Utf8)),
- BAND_INIT(method_MethodParameters_flag_I, UNSIGNED5_spec, 0),
+ BAND_INIT(method_MethodParameters_flag_FH, UNSIGNED5_spec, 0),
BAND_INIT(method_attr_bands, -1, -1),
BAND_INIT(class_flags_hi, UNSIGNED5_spec, 0),
BAND_INIT(class_flags_lo, UNSIGNED5_spec, 0),
--- a/jdk/src/share/native/com/sun/java/util/jar/pack/bands.h Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/native/com/sun/java/util/jar/pack/bands.h Fri Mar 15 16:39:07 2013 -0700
@@ -99,8 +99,8 @@
int getByte() { assert(ix == null); return vs[0].getByte(); }
int getInt() { assert(ix == null); return vs[0].getInt(); }
- entry* getRefN() { assert(ix != null); return getRefCommon(ix, true); }
- entry* getRef() { assert(ix != null); return getRefCommon(ix, false); }
+ entry* getRefN() { return getRefCommon(ix, true); }
+ entry* getRef() { return getRefCommon(ix, false); }
entry* getRefUsing(cpindex* ix2)
{ assert(ix == null); return getRefCommon(ix2, true); }
entry* getRefCommon(cpindex* ix, bool nullOK);
@@ -214,7 +214,7 @@
e_method_metadata_bands,
e_method_MethodParameters_NB,
e_method_MethodParameters_name_RUN,
- e_method_MethodParameters_flag_I,
+ e_method_MethodParameters_flag_FH,
e_method_attr_bands,
e_class_flags_hi,
@@ -393,7 +393,7 @@
#define method_Signature_RS all_bands[e_method_Signature_RS]
#define method_MethodParameters_NB all_bands[e_method_MethodParameters_NB]
#define method_MethodParameters_name_RUN all_bands[e_method_MethodParameters_name_RUN]
-#define method_MethodParameters_flag_I all_bands[e_method_MethodParameters_flag_I]
+#define method_MethodParameters_flag_FH all_bands[e_method_MethodParameters_flag_FH]
#define method_attr_bands all_bands[e_method_attr_bands]
#define class_flags_hi all_bands[e_class_flags_hi]
#define class_flags_lo all_bands[e_class_flags_lo]
--- a/jdk/src/share/native/com/sun/java/util/jar/pack/constants.h Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/native/com/sun/java/util/jar/pack/constants.h Fri Mar 15 16:39:07 2013 -0700
@@ -505,5 +505,9 @@
bc_qldc = _xldc_op+7,
bc_qldc_w = _xldc_op+8,
_xldc_limit = _xldc_op+9,
+ _invoke_int_op = _xldc_limit,
+ _invokespecial_int = _invoke_int_op+0,
+ _invokestatic_int = _invoke_int_op+1,
+ _invoke_int_limit = _invoke_int_op+2,
_xxx_3_end
};
--- a/jdk/src/share/native/com/sun/java/util/jar/pack/jni.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/native/com/sun/java/util/jar/pack/jni.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -50,6 +50,7 @@
static jmethodID currentInstMID;
static jmethodID readInputMID;
static jclass NIclazz;
+static jmethodID getUnpackerPtrMID;
static char* dbg = null;
@@ -60,8 +61,8 @@
static unpacker* get_unpacker(JNIEnv *env, jobject pObj, bool noCreate=false) {
unpacker* uPtr;
- uPtr = (unpacker*)jlong2ptr(env->GetLongField(pObj, unpackerPtrFID));
- //fprintf(stderr, "get_unpacker(%p) uPtr=%p\n", pObj, uPtr);
+ jlong p = env->CallLongMethod(pObj, getUnpackerPtrMID);
+ uPtr = (unpacker*)jlong2ptr(p);
if (uPtr == null) {
if (noCreate) return null;
uPtr = new unpacker();
@@ -94,11 +95,15 @@
if (env == null)
return null;
jobject pObj = env->CallStaticObjectMethod(NIclazz, currentInstMID);
- //fprintf(stderr, "get_unpacker() pObj=%p\n", pObj);
- if (pObj == null)
- return null;
- // Got pObj and env; now do it the easy way.
- return get_unpacker(env, pObj);
+ //fprintf(stderr, "get_unpacker0() pObj=%p\n", pObj);
+ if (pObj != null) {
+ // Got pObj and env; now do it the easy way.
+ return get_unpacker(env, pObj);
+ }
+ // this should really not happen, if it does something is seriously
+ // wrong throw an exception
+ THROW_IOE(ERROR_INTERNAL);
+ return null;
}
static void free_unpacker(JNIEnv *env, jobject pObj, unpacker* uPtr) {
@@ -127,18 +132,23 @@
JNIEXPORT void JNICALL
Java_com_sun_java_util_jar_pack_NativeUnpack_initIDs(JNIEnv *env, jclass clazz) {
+#ifndef PRODUCT
dbg = getenv("DEBUG_ATTACH");
while( dbg != null) { sleep(10); }
+#endif
NIclazz = (jclass) env->NewGlobalRef(clazz);
unpackerPtrFID = env->GetFieldID(clazz, "unpackerPtr", "J");
currentInstMID = env->GetStaticMethodID(clazz, "currentInstance",
"()Ljava/lang/Object;");
readInputMID = env->GetMethodID(clazz, "readInputFn",
"(Ljava/nio/ByteBuffer;J)J");
+ getUnpackerPtrMID = env->GetMethodID(clazz, "getUnpackerPtr", "()J");
+
if (unpackerPtrFID == null ||
currentInstMID == null ||
readInputMID == null ||
- NIclazz == null) {
+ NIclazz == null ||
+ getUnpackerPtrMID == null) {
THROW_IOE("cannot init class members");
}
}
@@ -146,8 +156,13 @@
JNIEXPORT jlong JNICALL
Java_com_sun_java_util_jar_pack_NativeUnpack_start(JNIEnv *env, jobject pObj,
jobject pBuf, jlong offset) {
- unpacker* uPtr = get_unpacker(env, pObj);
-
+ // try to get the unpacker pointer the hard way first, we do this to ensure
+ // valid object pointers and env is intact, if not now is good time to bail.
+ unpacker* uPtr = get_unpacker();
+ //fprintf(stderr, "start(%p) uPtr=%p initializing\n", pObj, uPtr);
+ if (uPtr == null) {
+ return -1;
+ }
// redirect our io to the default log file or whatever.
uPtr->redirect_stdio();
@@ -163,7 +178,12 @@
else
{ buf = (char*)buf + (size_t)offset; buflen -= (size_t)offset; }
}
-
+ // before we start off we make sure there is no other error by the time we
+ // get here
+ if (uPtr->aborting()) {
+ THROW_IOE(uPtr->get_abort_message());
+ return 0;
+ }
uPtr->start(buf, buflen);
if (uPtr->aborting()) {
THROW_IOE(uPtr->get_abort_message());
@@ -230,11 +250,14 @@
// We have fetched all the files.
// Now swallow up any remaining input.
- if (uPtr->input_remaining() == 0)
+ if (uPtr->input_remaining() == 0) {
return null;
- else
- return env->NewDirectByteBuffer(uPtr->input_scan(),
- uPtr->input_remaining());
+ } else {
+ bytes remaining_bytes;
+ remaining_bytes.malloc(uPtr->input_remaining());
+ remaining_bytes.copyFrom(uPtr->input_scan(), uPtr->input_remaining());
+ return env->NewDirectByteBuffer(remaining_bytes.ptr, remaining_bytes.len);
+ }
}
JNIEXPORT jlong JNICALL
--- a/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -281,11 +281,13 @@
}
inline cpindex* cpool::getFieldIndex(entry* classRef) {
+ if (classRef == NULL) { abort("missing class reference"); return NULL; }
assert(classRef->tagMatches(CONSTANT_Class));
assert((uint)classRef->inord < (uint)tag_count[CONSTANT_Class]);
return &member_indexes[classRef->inord*2+0];
}
inline cpindex* cpool::getMethodIndex(entry* classRef) {
+ if (classRef == NULL) { abort("missing class reference"); return NULL; }
assert(classRef->tagMatches(CONSTANT_Class));
assert((uint)classRef->inord < (uint)tag_count[CONSTANT_Class]);
return &member_indexes[classRef->inord*2+1];
@@ -1291,6 +1293,7 @@
entry& e = cpMap[i];
e.refs = U_NEW(entry*, e.nrefs = 2);
e.refs[0] = cp_band1.getRef();
+ CHECK;
e.refs[1] = cp_band2.getRef();
CHECK;
}
@@ -1371,6 +1374,7 @@
entry& e = cpMap[i];
e.refs = U_NEW(entry*, e.nrefs = 1);
e.refs[0] = cp_MethodType.getRef();
+ CHECK;
}
}
@@ -2106,6 +2110,7 @@
int attrc = ADH_BYTE_CONTEXT(header);
int idx = ADH_BYTE_INDEX(header);
entry* name = attr_definition_name.getRef();
+ CHECK;
entry* layout = attr_definition_layout.getRef();
CHECK;
attr_defs[attrc].defineLayout(idx, name, layout->value.b.strval());
@@ -2210,7 +2215,9 @@
if (ics[i].name == NO_ENTRY_YET) {
// Long form.
ics[i].outer = ic_outer_class.getRefN();
+ CHECK;
ics[i].name = ic_name.getRefN();
+ CHECK;
} else {
// Fill in outer and name based on inner.
bytes& n = ics[i].inner->value.b;
@@ -2488,7 +2495,7 @@
method_MethodParameters_NB.readData(count);
count = method_MethodParameters_NB.getIntTotal();
method_MethodParameters_name_RUN.readData(count);
- method_MethodParameters_flag_I.readData(count);
+ method_MethodParameters_flag_FH.readData(count);
CHECK;
break;
@@ -2733,6 +2740,7 @@
e = b.getRefUsing(cp.getKQIndex());
else
e = b.getRefN();
+ CHECK;
switch (b.le_len) {
case 0: break;
case 1: putu1ref(e); break;
@@ -2942,6 +2950,9 @@
case bc_putfield:
return &bc_fieldref;
+ case _invokespecial_int:
+ case _invokestatic_int:
+ return &bc_imethodref;
case bc_invokevirtual:
case bc_invokespecial:
case bc_invokestatic:
@@ -3118,7 +3129,7 @@
void unpacker::read_bands() {
byte* rp0 = rp;
-
+ CHECK;
read_file_header();
CHECK;
@@ -3880,10 +3891,12 @@
// packed file and len is the length of the buffer.
// If null, the callback is used to fill an internal buffer.
void unpacker::start(void* packptr, size_t len) {
+ CHECK;
NOT_PRODUCT(debug_u = this);
if (packptr != null && len != 0) {
inbytes.set((byte*) packptr, len);
}
+ CHECK;
read_bands();
}
@@ -4015,6 +4028,7 @@
NOT_PRODUCT(bc_superfield.setIndex(null));
NOT_PRODUCT(bc_supermethod.setIndex(null));
}
+ CHECK;
for (int curIP = 0; ; curIP++) {
int curPC = (int)(wpoffset() - codeBase);
@@ -4128,7 +4142,8 @@
int coding = bc_initref.getInt();
// Find the nth overloading of <init> in classRef.
entry* ref = null;
- cpindex* ix = (classRef == null)? null: cp.getMethodIndex(classRef);
+ cpindex* ix = cp.getMethodIndex(classRef);
+ CHECK;
for (int j = 0, which_init = 0; ; j++) {
ref = (ix == null)? null: ix->get(j);
if (ref == null) break; // oops, bad input
@@ -4177,6 +4192,12 @@
}
origBC = bc;
switch (bc) {
+ case _invokestatic_int:
+ origBC = bc_invokestatic;
+ break;
+ case _invokespecial_int:
+ origBC = bc_invokespecial;
+ break;
case bc_ildc:
case bc_cldc:
case bc_fldc:
@@ -4405,6 +4426,7 @@
case ADH_BYTE(ATTR_CONTEXT_CLASS, CLASS_ATTR_EnclosingMethod):
aname = cp.sym[cpool::s_EnclosingMethod];
putref(class_EnclosingMethod_RC.getRefN());
+ CHECK_0;
putref(class_EnclosingMethod_RDN.getRefN());
break;
@@ -4423,6 +4445,7 @@
putu2(count = method_Exceptions_N.getInt());
for (j = 0; j < count; j++) {
putref(method_Exceptions_RC.getRefN());
+ CHECK_0;
}
break;
@@ -4431,7 +4454,7 @@
putu1(count = method_MethodParameters_NB.getByte());
for (j = 0; j < count; j++) {
putref(method_MethodParameters_name_RUN.getRefN());
- putu4(method_MethodParameters_flag_I.getInt());
+ putu2(method_MethodParameters_flag_FH.getInt());
}
break;
@@ -4455,16 +4478,18 @@
// (253) [(1)(2)(2)]
// (254) [(1)(2)(2)(2)]
putu2(code_StackMapTable_offset.getInt());
+ CHECK_0;
for (int k = (tag - 251); k > 0; k--) {
put_stackmap_type();
+ CHECK_0;
}
} else {
// (255) [(1)NH[(2)]NH[(2)]]
putu2(code_StackMapTable_offset.getInt());
putu2(j2 = code_StackMapTable_local_N.getInt());
- while (j2-- > 0) put_stackmap_type();
+ while (j2-- > 0) {put_stackmap_type(); CHECK_0;}
putu2(j2 = code_StackMapTable_stack_N.getInt());
- while (j2-- > 0) put_stackmap_type();
+ while (j2-- > 0) {put_stackmap_type(); CHECK_0;}
}
}
break;
@@ -4488,7 +4513,9 @@
bii += code_LocalVariableTable_span_O.getInt();
putu2(to_bci(bii) - bci);
putref(code_LocalVariableTable_name_RU.getRefN());
+ CHECK_0;
putref(code_LocalVariableTable_type_RS.getRefN());
+ CHECK_0;
putu2(code_LocalVariableTable_slot.getInt());
}
break;
@@ -4503,7 +4530,9 @@
bii += code_LocalVariableTypeTable_span_O.getInt();
putu2(to_bci(bii) - bci);
putref(code_LocalVariableTypeTable_name_RU.getRefN());
+ CHECK_0;
putref(code_LocalVariableTypeTable_type_RS.getRefN());
+ CHECK_0;
putu2(code_LocalVariableTypeTable_slot.getInt());
}
break;
@@ -4531,7 +4560,7 @@
break;
}
}
-
+ CHECK_0;
if (aname == null) {
// Unparse a compressor-defined attribute.
layout_definition* lo = ad.getLayout(idx);
@@ -4687,7 +4716,9 @@
flags &= ~ACC_IC_LONG_FORM; // clear high bit if set to get clean zero
extra_ic.flags = flags;
extra_ic.outer = class_InnerClasses_outer_RCN.getRefN();
+ CHECK_0;
extra_ic.name = class_InnerClasses_name_RUN.getRefN();
+ CHECK_0;
// Detect if this is an exact copy of the global tuple.
if (global_ic != null) {
if (global_ic->flags != extra_ic.flags ||
@@ -4797,6 +4828,7 @@
julong indexMask = ad.flagIndexMask();
cur_class = class_this.getRef();
+ CHECK;
cur_super = class_super.getRef();
CHECK;
@@ -4810,6 +4842,7 @@
putu2(num = class_interface_count.getInt());
for (i = 0; i < num; i++) {
putref(class_interface.getRef());
+ CHECK;
}
write_members(class_field_count.getInt(), ATTR_CONTEXT_FIELD);
--- a/jdk/src/share/native/common/check_code.c Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/native/common/check_code.c Fri Mar 15 16:39:07 2013 -0700
@@ -206,6 +206,10 @@
#define LDC_METHOD_HANDLE_MAJOR_VERSION 51
+#define NONZERO_PADDING_BYTES_IN_SWITCH_MAJOR_VERSION 51
+
+#define STATIC_METHOD_IN_INTERFACE_MAJOR_VERSION 52
+
#define ALLOC_STACK_SIZE 16 /* big enough */
typedef struct alloc_stack_type {
@@ -1144,11 +1148,14 @@
int *saved_operand;
int keys;
int k, delta;
- /* 4639449, 4647081: Padding bytes must be zero. */
- unsigned char* bptr = (unsigned char*) (code + offset + 1);
- for (; bptr < (unsigned char*)lpc; bptr++) {
- if (*bptr != 0) {
- CCerror(context, "Non zero padding bytes in switch");
+
+ if (context->major_version < NONZERO_PADDING_BYTES_IN_SWITCH_MAJOR_VERSION) {
+ /* 4639449, 4647081: Padding bytes must be zero. */
+ unsigned char* bptr = (unsigned char*) (code + offset + 1);
+ for (; bptr < (unsigned char*)lpc; bptr++) {
+ if (*bptr != 0) {
+ CCerror(context, "Non zero padding bytes in switch");
+ }
}
}
if (opcode == JVM_OPC_tableswitch) {
@@ -1246,11 +1253,24 @@
jclass cb = context->class;
fullinfo_type clazz_info;
int is_constructor, is_internal, is_invokedynamic;
- int kind = (opcode == JVM_OPC_invokeinterface
- ? 1 << JVM_CONSTANT_InterfaceMethodref
- : opcode == JVM_OPC_invokedynamic
- ? 1 << JVM_CONSTANT_NameAndType
- : 1 << JVM_CONSTANT_Methodref);
+ int kind;
+
+ switch (opcode ) {
+ case JVM_OPC_invokestatic:
+ kind = ((context->major_version < STATIC_METHOD_IN_INTERFACE_MAJOR_VERSION)
+ ? (1 << JVM_CONSTANT_Methodref)
+ : ((1 << JVM_CONSTANT_InterfaceMethodref) | (1 << JVM_CONSTANT_Methodref)));
+ break;
+ case JVM_OPC_invokedynamic:
+ kind = 1 << JVM_CONSTANT_NameAndType;
+ break;
+ case JVM_OPC_invokeinterface:
+ kind = 1 << JVM_CONSTANT_InterfaceMethodref;
+ break;
+ default:
+ kind = 1 << JVM_CONSTANT_Methodref;
+ }
+
is_invokedynamic = opcode == JVM_OPC_invokedynamic;
/* Make sure the constant pool item is the right type. */
verify_constant_pool_type(context, key, kind);
--- a/jdk/src/share/native/java/lang/System.c Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/native/java/lang/System.c Fri Mar 15 16:39:07 2013 -0700
@@ -212,6 +212,10 @@
PUTPROP(props, "os.version", sprops->os_version);
PUTPROP(props, "os.arch", sprops->os_arch);
+#ifdef JDK_ARCH_ABI_PROP_NAME
+ PUTPROP(props, "sun.arch.abi", sprops->sun_arch_abi);
+#endif
+
/* file system properties */
PUTPROP(props, "file.separator", sprops->file_separator);
PUTPROP(props, "path.separator", sprops->path_separator);
--- a/jdk/src/share/native/java/lang/java_props.h Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/native/java/lang/java_props.h Fri Mar 15 16:39:07 2013 -0700
@@ -41,6 +41,10 @@
char *os_version;
char *os_arch;
+#ifdef JDK_ARCH_ABI_PROP_NAME
+ char *sun_arch_abi;
+#endif
+
nchar *tmp_dir;
nchar *font_dir;
nchar *user_dir;
--- a/jdk/src/share/native/java/util/zip/Inflater.c Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/native/java/util/zip/Inflater.c Fri Mar 15 16:39:07 2013 -0700
@@ -27,6 +27,7 @@
* Native method support for java.util.zip.Inflater
*/
+#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
@@ -60,12 +61,13 @@
{
z_stream *strm = calloc(1, sizeof(z_stream));
- if (strm == 0) {
+ if (strm == NULL) {
JNU_ThrowOutOfMemoryError(env, 0);
return jlong_zero;
} else {
- char *msg;
- switch (inflateInit2(strm, nowrap ? -MAX_WBITS : MAX_WBITS)) {
+ const char *msg;
+ int ret = inflateInit2(strm, nowrap ? -MAX_WBITS : MAX_WBITS);
+ switch (ret) {
case Z_OK:
return ptr_to_jlong(strm);
case Z_MEM_ERROR:
@@ -73,7 +75,13 @@
JNU_ThrowOutOfMemoryError(env, 0);
return jlong_zero;
default:
- msg = strm->msg;
+ msg = ((strm->msg != NULL) ? strm->msg :
+ (ret == Z_VERSION_ERROR) ?
+ "zlib returned Z_VERSION_ERROR: "
+ "compile time and runtime zlib implementations differ" :
+ (ret == Z_STREAM_ERROR) ?
+ "inflateInit2 returned Z_STREAM_ERROR" :
+ "unknown error initializing zlib library");
free(strm);
JNU_ThrowInternalError(env, msg);
return jlong_zero;
--- a/jdk/src/share/native/sun/awt/image/awt_parseImage.c Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/native/sun/awt/image/awt_parseImage.c Fri Mar 15 16:39:07 2013 -0700
@@ -114,6 +114,62 @@
return status;
}
+/* Verifies whether the channel offsets are sane and correspond to the type of
+ * the raster.
+ *
+ * Return value:
+ * 0: Failure: channel offsets are invalid
+ * 1: Success
+ */
+static int checkChannelOffsets(RasterS_t *rasterP, int dataArrayLength) {
+ int i, lastPixelOffset, lastScanOffset;
+ switch (rasterP->rasterType) {
+ case COMPONENT_RASTER_TYPE:
+ if (!SAFE_TO_MULT(rasterP->height, rasterP->scanlineStride)) {
+ return 0;
+ }
+ if (!SAFE_TO_MULT(rasterP->width, rasterP->pixelStride)) {
+ return 0;
+ }
+
+ lastScanOffset = (rasterP->height - 1) * rasterP->scanlineStride;
+ lastPixelOffset = (rasterP->width - 1) * rasterP->pixelStride;
+
+
+ if (!SAFE_TO_ADD(lastPixelOffset, lastScanOffset)) {
+ return 0;
+ }
+
+ lastPixelOffset += lastScanOffset;
+
+ for (i = 0; i < rasterP->numDataElements; i++) {
+ int off = rasterP->chanOffsets[i];
+ int size = lastPixelOffset + off;
+
+ if (off < 0 || !SAFE_TO_ADD(lastPixelOffset, off)) {
+ return 0;
+ }
+
+ if (size < lastPixelOffset || size >= dataArrayLength) {
+ // an overflow, or insufficient buffer capacity
+ return 0;
+ }
+ }
+ return 1;
+ case BANDED_RASTER_TYPE:
+ // NB:caller does not support the banded rasters yet,
+ // so this branch of the code must be re-defined in
+ // order to provide valid criteria for the data offsets
+ // verification, when/if banded rasters will be supported.
+ // At the moment, we prohibit banded rasters as well.
+ return 0;
+ default:
+ // PACKED_RASTER_TYPE: does not support channel offsets
+ // UNKNOWN_RASTER_TYPE: should not be used, likely indicates an error
+ return 0;
+ }
+}
+
/* Parse the raster. All of the raster information is returned in the
* rasterP structure.
*
@@ -125,7 +181,6 @@
int awt_parseRaster(JNIEnv *env, jobject jraster, RasterS_t *rasterP) {
jobject joffs = NULL;
/* int status;*/
- int isDiscrete = TRUE;
if (JNU_IsNull(env, jraster)) {
JNU_ThrowNullPointerException(env, "null Raster object");
@@ -155,6 +210,9 @@
return -1;
}
+ // make sure that the raster type is initialized
+ rasterP->rasterType = UNKNOWN_RASTER_TYPE;
+
if (rasterP->numBands <= 0 ||
rasterP->numBands > MAX_NUMBANDS)
{
@@ -165,9 +223,14 @@
return 0;
}
+ rasterP->sppsm.isUsed = 0;
+
if ((*env)->IsInstanceOf(env, rasterP->jsampleModel,
(*env)->FindClass(env,"java/awt/image/SinglePixelPackedSampleModel"))) {
jobject jmask, joffs, jnbits;
+
+ rasterP->sppsm.isUsed = 1;
+
rasterP->sppsm.maxBitSize = (*env)->GetIntField(env,
rasterP->jsampleModel,
g_SPPSMmaxBitID);
@@ -254,7 +317,6 @@
}
rasterP->chanOffsets[0] = (*env)->GetIntField(env, jraster, g_BPRdataBitOffsetID);
rasterP->dataType = BYTE_DATA_TYPE;
- isDiscrete = FALSE;
}
else {
rasterP->type = sun_awt_image_IntegerComponentRaster_TYPE_CUSTOM;
@@ -265,7 +327,19 @@
return 0;
}
- if (isDiscrete) {
+ // do basic validation of the raster structure
+ if (rasterP->width <= 0 || rasterP->height <= 0 ||
+ rasterP->pixelStride <= 0 || rasterP->scanlineStride <= 0)
+ {
+ // invalid raster
+ return -1;
+ }
+
+ // channel (data) offsets
+ switch (rasterP->rasterType) {
+ case COMPONENT_RASTER_TYPE:
+ case BANDED_RASTER_TYPE: // note that this routine does not support banded rasters at the moment
+ // get channel (data) offsets
rasterP->chanOffsets = NULL;
if (SAFE_TO_ALLOC_2(rasterP->numDataElements, sizeof(jint))) {
rasterP->chanOffsets =
@@ -278,10 +352,21 @@
}
(*env)->GetIntArrayRegion(env, joffs, 0, rasterP->numDataElements,
rasterP->chanOffsets);
+ if (rasterP->jdata == NULL) {
+ // unable to verify the raster
+ return -1;
+ }
+ // verify whether channel offsets look sane
+ if (!checkChannelOffsets(rasterP, (*env)->GetArrayLength(env, rasterP->jdata))) {
+ return -1;
+ }
+ break;
+ default:
+ ; // PACKED_RASTER_TYPE does not use the channel offsets.
}
- /* additioanl check for sppsm fields validity: make sure that
- * size of raster samples doesn't exceed the data type cpacity.
+ /* additional check for sppsm fields validity: make sure that
+ * size of raster samples doesn't exceed the data type capacity.
*/
if (rasterP->dataType > UNKNOWN_DATA_TYPE && /* data type has been recognized */
rasterP->sppsm.maxBitSize > 0 && /* raster has SPP sample model */
@@ -696,6 +781,21 @@
}
else if (cmodelP->cmType == DIRECT_CM_TYPE || cmodelP->cmType == PACKED_CM_TYPE) {
int i;
+
+ /* do some sanity check first: make sure that
+ * - sample model is SinglePixelPackedSampleModel
+ * - number of bands in the raster corresponds to the number
+ * of color components in the color model
+ */
+ if (!rasterP->sppsm.isUsed ||
+ rasterP->numBands != cmodelP->numComponents)
+ {
+ /* given raster is not compatible with the color model,
+ * so the operation has to be aborted.
+ */
+ return -1;
+ }
+
if (cmodelP->maxNbits > 8) {
hintP->needToExpand = TRUE;
hintP->expandToNbits = cmodelP->maxNbits;
--- a/jdk/src/share/native/sun/awt/image/awt_parseImage.h Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/native/sun/awt/image/awt_parseImage.h Fri Mar 15 16:39:07 2013 -0700
@@ -95,6 +95,7 @@
jint offsets[MAX_NUMBANDS];
jint nBits[MAX_NUMBANDS];
jint maxBitSize;
+ jint isUsed; // flag to indicate whether the raster sample model is SPPSM
} SPPSampleModelS_t;
/* Struct that holds information for the Raster object */
--- a/jdk/src/share/native/sun/awt/medialib/safe_alloc.h Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/native/sun/awt/medialib/safe_alloc.h Fri Mar 15 16:39:07 2013 -0700
@@ -41,5 +41,10 @@
(((w) > 0) && ((h) > 0) && ((sz) > 0) && \
(((0xffffffffu / ((juint)(w))) / ((juint)(h))) > ((juint)(sz))))
+#define SAFE_TO_MULT(a, b) \
+ (((a) > 0) && ((b) >= 0) && ((0x7fffffff / (a)) > (b)))
+
+#define SAFE_TO_ADD(a, b) \
+ (((a) >= 0) && ((b) >= 0) && ((0x7fffffff - (a)) > (b)))
#endif // __SAFE_ALLOC_H__
--- a/jdk/src/share/native/sun/awt/splashscreen/splashscreen_jpeg.c Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/native/sun/awt/splashscreen/splashscreen_jpeg.c Fri Mar 15 16:39:07 2013 -0700
@@ -133,6 +133,10 @@
ImageFormat srcFormat;
jpeg_read_header(cinfo, TRUE);
+
+ // SplashScreen jpeg converter expects data in RGB format only
+ cinfo->out_color_space = JCS_RGB;
+
jpeg_start_decompress(cinfo);
SplashCleanup(splash);
--- a/jdk/src/share/native/sun/font/layout/LookupProcessor.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/native/sun/font/layout/LookupProcessor.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -125,6 +125,10 @@
}
const LookupTable *lookupTable = lookupListTable->getLookupTable(lookupTableIndex);
+ if (lookupTable == NULL) {
+ success = LE_INTERNAL_ERROR;
+ return 0;
+ }
le_uint16 lookupFlags = SWAPW(lookupTable->lookupFlags);
GlyphIterator tempIterator(*glyphIterator, lookupFlags);
le_uint32 delta = applyLookupTable(lookupTable, &tempIterator, fontInstance, success);
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c Fri Mar 15 16:39:07 2013 -0700
@@ -117,6 +117,7 @@
static jfieldID IL_nextRowOffset_fID;
static jfieldID IL_width_fID;
static jfieldID IL_height_fID;
+static jfieldID IL_imageAtOnce_fID;
static jfieldID PF_ID_fID;
JavaVM *javaVM;
@@ -237,7 +238,7 @@
* Method: loadProfile
* Signature: ([B)J
*/
-JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_loadProfile
+JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative
(JNIEnv *env, jobject obj, jbyteArray data)
{
jbyte* dataArray;
@@ -284,7 +285,7 @@
* Method: freeProfile
* Signature: (J)V
*/
-JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_freeProfile
+JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_freeProfileNative
(JNIEnv *env, jobject obj, jlong id)
{
storeID_t sProf;
@@ -369,48 +370,22 @@
static cmsBool _setHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize);
static cmsBool _writeCookedTag(cmsHPROFILE pfTarget, cmsTagSignature sig, jbyte *pData, jint size);
-/*
- * Class: sun_java2d_cmm_lcms_LCMS
- * Method: getTagSize
- * Signature: (JI)I
- */
-JNIEXPORT jint JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagSize
- (JNIEnv *env, jobject obj, jlong id, jint tagSig)
-{
- storeID_t sProf;
- TagSignature_t sig;
- jint result = -1;
-
- sProf.j = id;
- sig.j = tagSig;
-
- if (tagSig == SigHead) {
- result = sizeof(cmsICCHeader);
- } else {
- if (cmsIsTag(sProf.pf, sig.cms)) {
- result = cmsReadRawTag(sProf.pf, sig.cms, NULL, 0);
- } else {
- JNU_ThrowByName(env, "java/awt/color/CMMException",
- "ICC profile tag not found");
- }
- }
-
- return result;
-}
/*
* Class: sun_java2d_cmm_lcms_LCMS
* Method: getTagData
* Signature: (JI[B)V
*/
-JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagData
- (JNIEnv *env, jobject obj, jlong id, jint tagSig, jbyteArray data)
+JNIEXPORT jbyteArray JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagNative
+ (JNIEnv *env, jobject obj, jlong id, jint tagSig)
{
storeID_t sProf;
TagSignature_t sig;
cmsInt32Number tagSize;
- jbyte* dataArray;
+ jbyte* dataArray = NULL;
+ jbyteArray data = NULL;
+
jint bufSize;
sProf.j = id;
@@ -419,12 +394,14 @@
if (tagSig == SigHead) {
cmsBool status;
- bufSize =(*env)->GetArrayLength(env, data);
+ // allocate java array
+ bufSize = sizeof(cmsICCHeader);
+ data = (*env)->NewByteArray(env, bufSize);
- if (bufSize < sizeof(cmsICCHeader)) {
- JNU_ThrowByName(env, "java/awt/color/CMMException",
- "Insufficient buffer capacity");
- return;
+ if (data == NULL) {
+ JNU_ThrowByName(env, "java/awt/color/CMMException",
+ "Unable to allocate buffer");
+ return NULL;
}
dataArray = (*env)->GetByteArrayElements (env, data, 0);
@@ -432,7 +409,7 @@
if (dataArray == NULL) {
JNU_ThrowByName(env, "java/awt/color/CMMException",
"Unable to get buffer");
- return;
+ return NULL;
}
status = _getHeaderInfo(sProf.pf, dataArray, bufSize);
@@ -442,9 +419,10 @@
if (!status) {
JNU_ThrowByName(env, "java/awt/color/CMMException",
"ICC Profile header not found");
+ return NULL;
}
- return;
+ return data;
}
if (cmsIsTag(sProf.pf, sig.cms)) {
@@ -452,16 +430,15 @@
} else {
JNU_ThrowByName(env, "java/awt/color/CMMException",
"ICC profile tag not found");
- return;
+ return NULL;
}
- // verify data buffer capacity
- bufSize = (*env)->GetArrayLength(env, data);
-
- if (tagSize < 0 || 0 > bufSize || tagSize > bufSize) {
+ // allocate java array
+ data = (*env)->NewByteArray(env, tagSize);
+ if (data == NULL) {
JNU_ThrowByName(env, "java/awt/color/CMMException",
- "Insufficient buffer capacity.");
- return;
+ "Unable to allocate buffer");
+ return NULL;
}
dataArray = (*env)->GetByteArrayElements (env, data, 0);
@@ -469,7 +446,7 @@
if (dataArray == NULL) {
JNU_ThrowByName(env, "java/awt/color/CMMException",
"Unable to get buffer");
- return;
+ return NULL;
}
bufSize = cmsReadRawTag(sProf.pf, sig.cms, dataArray, tagSize);
@@ -479,8 +456,9 @@
if (bufSize != tagSize) {
JNU_ThrowByName(env, "java/awt/color/CMMException",
"Can not get tag data.");
+ return NULL;
}
- return;
+ return data;
}
/*
@@ -488,7 +466,7 @@
* Method: setTagData
* Signature: (JI[B)V
*/
-JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_setTagData
+JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative
(JNIEnv *env, jobject obj, jlong id, jint tagSig, jbyteArray data)
{
storeID_t sProf;
@@ -586,6 +564,7 @@
char* inputRow;
char* outputRow;
jobject srcData, dstData;
+ jboolean srcAtOnce = JNI_FALSE, dstAtOnce = JNI_FALSE;
srcOffset = (*env)->GetIntField (env, src, IL_offset_fID);
srcNextRowOffset = (*env)->GetIntField (env, src, IL_nextRowOffset_fID);
@@ -594,6 +573,9 @@
width = (*env)->GetIntField (env, src, IL_width_fID);
height = (*env)->GetIntField (env, src, IL_height_fID);
+ srcAtOnce = (*env)->GetBooleanField(env, src, IL_imageAtOnce_fID);
+ dstAtOnce = (*env)->GetBooleanField(env, dst, IL_imageAtOnce_fID);
+
sTrans.j = (*env)->GetLongField (env, trans, Trans_ID_fID);
if (sTrans.xf == NULL) {
@@ -625,10 +607,14 @@
inputRow = (char*)inputBuffer + srcOffset;
outputRow = (char*)outputBuffer + dstOffset;
- for (i = 0; i < height; i++) {
- cmsDoTransform(sTrans.xf, inputRow, outputRow, width);
- inputRow += srcNextRowOffset;
- outputRow += dstNextRowOffset;
+ if (srcAtOnce && dstAtOnce) {
+ cmsDoTransform(sTrans.xf, inputRow, outputRow, width * height);
+ } else {
+ for (i = 0; i < height; i++) {
+ cmsDoTransform(sTrans.xf, inputRow, outputRow, width);
+ inputRow += srcNextRowOffset;
+ outputRow += dstNextRowOffset;
+ }
}
releaseILData(env, inputBuffer, srcDType, srcData);
@@ -670,6 +656,7 @@
IL_width_fID = (*env)->GetFieldID (env, IL, "width", "I");
IL_height_fID = (*env)->GetFieldID (env, IL, "height", "I");
IL_offset_fID = (*env)->GetFieldID (env, IL, "offset", "I");
+ IL_imageAtOnce_fID = (*env)->GetFieldID (env, IL, "imageAtOnce", "Z");
IL_nextRowOffset_fID = (*env)->GetFieldID (env, IL, "nextRowOffset", "I");
PF_ID_fID = (*env)->GetFieldID (env, Pf, "ID", "J");
--- a/jdk/src/share/native/sun/java2d/loops/AnyByteBinary.h Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/native/sun/java2d/loops/AnyByteBinary.h Fri Mar 15 16:39:07 2013 -0700
@@ -153,7 +153,10 @@
jint PREFIX ## rgb;
#define InitByteBinaryAlphaLoadData(TYPE, PREFIX, pRasInfo) \
- PREFIX ## Lut = (pRasInfo)->lutBase
+ do { \
+ PREFIX ## Lut = (pRasInfo)->lutBase; \
+ PREFIX ## rgb = 0; \
+ } while (0)
#define LoadAlphaFromByteBinaryFor4ByteArgb(TYPE, pRas, PREFIX, COMP_PREFIX) \
do { \
--- a/jdk/src/share/native/sun/java2d/loops/ByteIndexed.h Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/native/sun/java2d/loops/ByteIndexed.h Fri Mar 15 16:39:07 2013 -0700
@@ -202,7 +202,10 @@
jint PREFIX ## rgb;
#define InitByteIndexedAlphaLoadData(PREFIX, pRasInfo) \
- PREFIX ## Lut = (pRasInfo)->lutBase
+ do { \
+ PREFIX ## Lut = (pRasInfo)->lutBase; \
+ PREFIX ## rgb = 0; \
+ } while (0)
#define LoadAlphaFromByteIndexedFor4ByteArgb(pRas, PREFIX, COMP_PREFIX) \
do { \
--- a/jdk/src/share/native/sun/java2d/loops/IntArgb.h Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/native/sun/java2d/loops/IntArgb.h Fri Mar 15 16:39:07 2013 -0700
@@ -122,7 +122,8 @@
#define DeclareIntArgbAlphaLoadData(PREFIX) \
jint PREFIX;
-#define InitIntArgbAlphaLoadData(PREFIX, pRasInfo)
+#define InitIntArgbAlphaLoadData(PREFIX, pRasInfo) \
+ PREFIX = 0
#define LoadAlphaFromIntArgbFor4ByteArgb(pRas, PREFIX, COMP_PREFIX) \
do { \
--- a/jdk/src/share/native/sun/java2d/loops/IntArgbBm.h Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/native/sun/java2d/loops/IntArgbBm.h Fri Mar 15 16:39:07 2013 -0700
@@ -133,7 +133,8 @@
#define DeclareIntArgbBmAlphaLoadData(PREFIX) \
jint PREFIX;
-#define InitIntArgbBmAlphaLoadData(PREFIX, pRasInfo)
+#define InitIntArgbBmAlphaLoadData(PREFIX, pRasInfo) \
+ PREFIX = 0
#define LoadAlphaFromIntArgbBmFor4ByteArgb(pRas, PREFIX, COMP_PREFIX) \
do { \
--- a/jdk/src/share/native/sun/java2d/loops/IntArgbPre.h Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/native/sun/java2d/loops/IntArgbPre.h Fri Mar 15 16:39:07 2013 -0700
@@ -153,7 +153,8 @@
#define DeclareIntArgbPreAlphaLoadData(PREFIX) \
jint PREFIX;
-#define InitIntArgbPreAlphaLoadData(PREFIX, pRasInfo)
+#define InitIntArgbPreAlphaLoadData(PREFIX, pRasInfo) \
+ PREFIX = 0
#define LoadAlphaFromIntArgbPreFor4ByteArgb(pRas, PREFIX, COMP_PREFIX) \
do { \
--- a/jdk/src/share/native/sun/java2d/loops/TransformHelper.c Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/native/sun/java2d/loops/TransformHelper.c Fri Mar 15 16:39:07 2013 -0700
@@ -353,6 +353,9 @@
pInterpFunc = pBicubicFunc;
maxlinepix = LINE_SIZE / 16;
break;
+ default:
+ // Should not happen, but just in case.
+ return;
}
srcInfo.bounds.x1 = sx1;
--- a/jdk/src/share/native/sun/java2d/loops/Ushort4444Argb.h Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/native/sun/java2d/loops/Ushort4444Argb.h Fri Mar 15 16:39:07 2013 -0700
@@ -120,7 +120,8 @@
#define DeclareUshort4444ArgbAlphaLoadData(PREFIX) \
jint PREFIX;
-#define InitUshort4444ArgbAlphaLoadData(PREFIX, pRasInfo)
+#define InitUshort4444ArgbAlphaLoadData(PREFIX, pRasInfo) \
+ PREFIX = 0
#define LoadAlphaFromUshort4444ArgbFor4ByteArgb(pRas, PREFIX, COMP_PREFIX) \
do { \
--- a/jdk/src/share/native/sun/java2d/loops/UshortIndexed.h Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/native/sun/java2d/loops/UshortIndexed.h Fri Mar 15 16:39:07 2013 -0700
@@ -170,7 +170,10 @@
jint PREFIX ## rgb;
#define InitUshortIndexedAlphaLoadData(PREFIX, pRasInfo) \
- PREFIX ## Lut = (pRasInfo)->lutBase
+ do { \
+ PREFIX ## Lut = (pRasInfo)->lutBase; \
+ PREFIX ## rgb = 0; \
+ } while (0)
#define LoadAlphaFromUshortIndexedFor4ByteArgb(pRas, PREFIX, COMP_PREFIX) \
do { \
--- a/jdk/src/share/native/sun/security/pkcs11/wrapper/p11_convert.c Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/share/native/sun/security/pkcs11/wrapper/p11_convert.c Fri Mar 15 16:39:07 2013 -0700
@@ -687,8 +687,8 @@
if ((*env)->ExceptionCheck(env)) {
free(ckParam.RandomInfo.pClientRandom);
free(ckParam.RandomInfo.pServerRandom);
+ free(ckParam.pReturnedKeyMaterial->pIVClient);
free(ckParam.pReturnedKeyMaterial);
- free(ckParam.pReturnedKeyMaterial->pIVClient);
return ckParam;
}
--- a/jdk/src/solaris/back/linker_md.c Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/solaris/back/linker_md.c Fri Mar 15 16:39:07 2013 -0700
@@ -60,6 +60,7 @@
char *path_sep = PATH_SEPARATOR;
char *pathname = (char *)pname;
+ *buffer = '\0';
while (strlen(pathname) > 0) {
char *p = strchr(pathname, *path_sep);
if (p == NULL) {
@@ -69,13 +70,17 @@
if (p == pathname) {
continue;
}
- (void)snprintf(buffer, buflen, "%.*s/lib%s." LIB_SUFFIX, (p - pathname),
+ (void)snprintf(buffer, buflen, "%.*s/lib%s." LIB_SUFFIX, (int)(p - pathname),
pathname, fname);
if (access(buffer, F_OK) == 0) {
break;
}
- pathname = p + 1;
+ if (*p == '\0') {
+ pathname = p;
+ } else {
+ pathname = p + 1;
+ }
*buffer = '\0';
}
}
--- a/jdk/src/solaris/classes/sun/nio/ch/sctp/SctpChannelImpl.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/solaris/classes/sun/nio/ch/sctp/SctpChannelImpl.java Fri Mar 15 16:39:07 2013 -0700
@@ -1026,13 +1026,21 @@
boolean unordered,
int ppid)
throws IOException {
+ InetAddress addr = null; // no preferred address
+ int port = 0;
+ if (target != null) {
+ InetSocketAddress isa = Net.checkAddress(target);
+ addr = isa.getAddress();
+ port = isa.getPort();
+ }
+
int pos = bb.position();
int lim = bb.limit();
assert (pos <= lim);
int rem = (pos <= lim ? lim - pos : 0);
- int written = send0(fd, ((DirectBuffer)bb).address() + pos,
- rem, target, -1 /*121*/, streamNumber, unordered, ppid);
+ int written = send0(fd, ((DirectBuffer)bb).address() + pos, rem, addr,
+ port, -1 /*121*/, streamNumber, unordered, ppid);
if (written > 0)
bb.position(pos + written);
return written;
@@ -1091,7 +1099,7 @@
long address, int length, boolean peek) throws IOException;
static native int send0(int fd, long address, int length,
- SocketAddress target, int assocId, int streamNumber,
+ InetAddress addr, int port, int assocId, int streamNumber,
boolean unordered, int ppid) throws IOException;
private static native int checkConnect(FileDescriptor fd, boolean block,
--- a/jdk/src/solaris/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/solaris/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java Fri Mar 15 16:39:07 2013 -0700
@@ -889,13 +889,20 @@
boolean unordered,
int ppid)
throws IOException {
+ InetAddress addr = null; // no preferred address
+ int port = 0;
+ if (target != null) {
+ InetSocketAddress isa = Net.checkAddress(target);
+ addr = isa.getAddress();
+ port = isa.getPort();
+ }
int pos = bb.position();
int lim = bb.limit();
assert (pos <= lim);
int rem = (pos <= lim ? lim - pos : 0);
- int written = send0(fd, ((DirectBuffer)bb).address() + pos,
- rem, target, assocId, streamNumber, unordered, ppid);
+ int written = send0(fd, ((DirectBuffer)bb).address() + pos, rem, addr,
+ port, assocId, streamNumber, unordered, ppid);
if (written > 0)
bb.position(pos + written);
return written;
@@ -976,13 +983,14 @@
private static int send0(int fd,
long address,
int length,
- SocketAddress target,
+ InetAddress addr,
+ int port,
int assocId,
int streamNumber,
boolean unordered,
int ppid)
throws IOException {
- return SctpChannelImpl.send0(fd, address, length, target, assocId,
+ return SctpChannelImpl.send0(fd, address, length, addr, port, assocId,
streamNumber, unordered, ppid);
}
--- a/jdk/src/solaris/demo/jvmti/hprof/hprof_md.c Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/solaris/demo/jvmti/hprof/hprof_md.c Fri Mar 15 16:39:07 2013 -0700
@@ -385,6 +385,7 @@
// Loosely based on os_solaris.cpp
char *pathname = (char *)pname;
+ *buffer = '\0';
while (strlen(pathname) > 0) {
char *p = strchr(pathname, ':');
if (p == NULL) {
@@ -395,12 +396,16 @@
continue;
}
(void)snprintf(buffer, buflen, "%.*s/lib%s" JNI_LIB_SUFFIX,
- (p - pathname), pathname, fname);
+ (int)(p - pathname), pathname, fname);
if (access(buffer, F_OK) == 0) {
- break;
+ break;
}
- pathname = p + 1;
+ if (*p == '\0') {
+ pathname = p;
+ } else {
+ pathname = p + 1;
+ }
*buffer = '\0';
}
}
--- a/jdk/src/solaris/native/java/lang/java_props_md.c Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/solaris/native/java/lang/java_props_md.c Fri Mar 15 16:39:07 2013 -0700
@@ -514,6 +514,11 @@
}
}
+ /* ABI property (optional) */
+#ifdef JDK_ARCH_ABI_PROP_NAME
+ sprops.sun_arch_abi = JDK_ARCH_ABI_PROP_NAME;
+#endif
+
/* Determine the language, country, variant, and encoding from the host,
* and store these in the user.language, user.country, user.variant and
* file.encoding system properties. */
--- a/jdk/src/solaris/native/sun/nio/ch/DatagramChannelImpl.c Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/solaris/native/sun/nio/ch/DatagramChannelImpl.c Fri Mar 15 16:39:07 2013 -0700
@@ -46,8 +46,6 @@
#include "sun_nio_ch_DatagramChannelImpl.h"
-static jfieldID isa_addrID; /* address in java.net.InetSocketAddress */
-static jfieldID isa_portID; /* port in java.net.InetSocketAddress */
static jfieldID dci_senderID; /* sender in sun.nio.ch.DatagramChannelImpl */
static jfieldID dci_senderAddrID; /* sender InetAddress in sun.nio.ch.DatagramChannelImpl */
static jfieldID dci_senderPortID; /* sender port in sun.nio.ch.DatagramChannelImpl */
@@ -61,9 +59,6 @@
isa_class = (*env)->NewGlobalRef(env, clazz);
isa_ctorID = (*env)->GetMethodID(env, clazz, "<init>",
"(Ljava/net/InetAddress;I)V");
- isa_addrID = (*env)->GetFieldID(env, clazz, "addr",
- "Ljava/net/InetAddress;");
- isa_portID = (*env)->GetFieldID(env, clazz, "port", "I");
clazz = (*env)->FindClass(env, "sun/nio/ch/DatagramChannelImpl");
dci_senderID = (*env)->GetFieldID(env, clazz, "sender",
@@ -212,15 +207,13 @@
JNIEXPORT jint JNICALL
Java_sun_nio_ch_DatagramChannelImpl_send0(JNIEnv *env, jobject this,
jboolean preferIPv6, jobject fdo, jlong address,
- jint len, jobject dest)
+ jint len, jobject destAddress, jint destPort)
{
jint fd = fdval(env, fdo);
void *buf = (void *)jlong_to_ptr(address);
SOCKADDR sa;
int sa_len = SOCKADDR_LEN;
jint n = 0;
- jobject destAddress = (*env)->GetObjectField(env, dest, isa_addrID);
- jint destPort = (*env)->GetIntField(env, dest, isa_portID);
if (len > MAX_PACKET_LEN) {
len = MAX_PACKET_LEN;
--- a/jdk/src/solaris/native/sun/nio/ch/sctp/SctpChannelImpl.c Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/solaris/native/sun/nio/ch/sctp/SctpChannelImpl.c Fri Mar 15 16:39:07 2013 -0700
@@ -67,8 +67,6 @@
static jmethodID spc_ctrID; /* sun.nio.ch.sctp.PeerAddressChanged.<init> */
static jclass ss_class; /* sun.nio.ch.sctp.Shutdown */
static jmethodID ss_ctrID; /* sun.nio.ch.sctp.Shutdown.<init> */
-static jfieldID isa_addrID; /* java.net.InetSocketAddress.addr */
-static jfieldID isa_portID; /* java.net.InetSocketAddress.port */
/* defined in SctpNet.c */
jobject SockAddrToInetSocketAddress(JNIEnv* env, struct sockaddr* addr);
@@ -138,13 +136,6 @@
CHECK_NULL(ss_class);
ss_ctrID = (*env)->GetMethodID(env, cls, "<init>", "(I)V");
CHECK_NULL(ss_ctrID);
-
- /* InetSocketAddress */
- cls = (*env)->FindClass(env, "java/net/InetSocketAddress");
- CHECK_NULL(cls);
- isa_addrID = (*env)->GetFieldID(env, cls, "addr", "Ljava/net/InetAddress;");
- CHECK_NULL(isa_addrID);
- isa_portID = (*env)->GetFieldID(env, cls, "port", "I");
}
void getControlData
@@ -509,12 +500,12 @@
/*
* Class: sun_nio_ch_sctp_SctpChannelImpl
* Method: send0
- * Signature: (IJILjava/net/SocketAddress;IIZI)I
+ * Signature: (IJILjava/net/InetAddress;IIIZI)I
*/
JNIEXPORT jint JNICALL Java_sun_nio_ch_sctp_SctpChannelImpl_send0
(JNIEnv *env, jclass klass, jint fd, jlong address, jint length,
- jobject saTarget, jint assocId, jint streamNumber, jboolean unordered,
- jint ppid) {
+ jobject targetAddress, jint targetPort, jint assocId, jint streamNumber,
+ jboolean unordered, jint ppid) {
SOCKADDR sa;
int sa_len = sizeof(sa);
ssize_t rv = 0;
@@ -526,17 +517,13 @@
struct controlData cdata[1];
/* SctpChannel:
- * saTarget may contain the preferred address or NULL to use primary,
+ * targetAddress may contain the preferred address or NULL to use primary,
* assocId will always be -1
* SctpMultiChannell:
- * Setup new association, saTarget will contain address, assocId = -1
- * Association already existing, assocId != -1, saTarget = preferred addr
+ * Setup new association, targetAddress will contain address, assocId = -1
+ * Association already existing, assocId != -1, targetAddress = preferred addr
*/
- if (saTarget != NULL /*&& assocId <= 0*/) {
-
- jobject targetAddress = (*env)->GetObjectField(env, saTarget, isa_addrID);
- jint targetPort = (*env)->GetIntField(env, saTarget, isa_portID);
-
+ if (targetAddress != NULL /*&& assocId <= 0*/) {
if (NET_InetAddressToSockaddr(env, targetAddress, targetPort,
(struct sockaddr *)&sa,
&sa_len, JNI_TRUE) != 0) {
--- a/jdk/src/windows/back/linker_md.c Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/windows/back/linker_md.c Fri Mar 15 16:39:07 2013 -0700
@@ -44,6 +44,7 @@
char *path_sep = PATH_SEPARATOR;
char *pathname = (char *)pname;
+ *buffer = '\0';
while (strlen(pathname) > 0) {
char *p = strchr(pathname, *path_sep);
if (p == NULL) {
@@ -54,16 +55,20 @@
continue;
}
if (*(p-1) == ':' || *(p-1) == '\\') {
- (void)_snprintf(buffer, buflen, "%.*s%s.dll", (p - pathname),
+ (void)_snprintf(buffer, buflen, "%.*s%s.dll", (int)(p - pathname),
pathname, fname);
} else {
- (void)_snprintf(buffer, buflen, "%.*s\\%s.dll", (p - pathname),
+ (void)_snprintf(buffer, buflen, "%.*s\\%s.dll", (int)(p - pathname),
pathname, fname);
}
if (_access(buffer, 0) == 0) {
break;
}
- pathname = p + 1;
+ if (*p == '\0') {
+ pathname = p;
+ } else {
+ pathname = p + 1;
+ }
*buffer = '\0';
}
}
--- a/jdk/src/windows/bin/java_md.c Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/windows/bin/java_md.c Fri Mar 15 16:39:07 2013 -0700
@@ -101,7 +101,6 @@
/* funtion in awt.dll (src/windows/native/sun/java2d/d3d/D3DPipelineManager.cpp) */
#define D3D_PRELOAD_FUNC "preloadD3D"
-
/* Extracts value of a parameter with the specified name
* from command line argument (returns pointer in the argument).
* Returns NULL if the argument does not contains the parameter.
@@ -276,7 +275,8 @@
#endif
#ifdef CRT_DLL
if (GetJREPath(crtpath, MAXPATHLEN)) {
- if (JLI_StrLen(crtpath) + JLI_StrLen("\\bin\\") + JLI_StrLen(CRT_DLL) >= MAXPATHLEN) {
+ if (JLI_StrLen(crtpath) + JLI_StrLen("\\bin\\") +
+ JLI_StrLen(CRT_DLL) >= MAXPATHLEN) {
JLI_ReportErrorMessage(JRE_ERROR11);
return JNI_FALSE;
}
@@ -347,7 +347,8 @@
if (JLI_StrChr(jvmtype, '/') || JLI_StrChr(jvmtype, '\\')) {
JLI_Snprintf(jvmpath, jvmpathsize, "%s\\" JVM_DLL, jvmtype);
} else {
- JLI_Snprintf(jvmpath, jvmpathsize, "%s\\bin\\%s\\" JVM_DLL, jrepath, jvmtype);
+ JLI_Snprintf(jvmpath, jvmpathsize, "%s\\bin\\%s\\" JVM_DLL,
+ jrepath, jvmtype);
}
if (stat(jvmpath, &s) == 0) {
return JNI_TRUE;
@@ -525,6 +526,37 @@
}
return (counts * 1000 * 1000)/counterFrequency.QuadPart;
}
+/*
+ * windows snprintf does not guarantee a null terminator in the buffer,
+ * if the computed size is equal to or greater than the buffer size,
+ * as well as error conditions. This function guarantees a null terminator
+ * under all these conditions. An unreasonable buffer or size will return
+ * an error value. Under all other conditions this function will return the
+ * size of the bytes actually written minus the null terminator, similar
+ * to ansi snprintf api. Thus when calling this function the caller must
+ * ensure storage for the null terminator.
+ */
+int
+JLI_Snprintf(char* buffer, size_t size, const char* format, ...) {
+ int rc;
+ va_list vl;
+ if (size == 0 || buffer == NULL)
+ return -1;
+ buffer[0] = '\0';
+ va_start(vl, format);
+ rc = vsnprintf(buffer, size, format, vl);
+ va_end(vl);
+ /* force a null terminator, if something is amiss */
+ if (rc < 0) {
+ /* apply ansi semantics */
+ buffer[size - 1] = '\0';
+ return size;
+ } else if (rc == size) {
+ /* force a null terminator */
+ buffer[size - 1] = '\0';
+ }
+ return rc;
+}
void
JLI_ReportErrorMessage(const char* fmt, ...) {
@@ -880,7 +912,7 @@
*/
void
ExecJRE(char *jre, char **argv) {
- int len;
+ jint len;
char path[MAXPATHLEN + 1];
const char *progname = GetProgramName();
@@ -1417,7 +1449,10 @@
// we add the indicator
tlen = 1 + JLI_StrLen(strv[i]) + 1;
nargv[i] = (char *) JLI_MemAlloc(tlen);
- JLI_Snprintf(nargv[i], tlen, "%c%s", arg_expand ? 'T' : 'F', strv[i]);
+ if (JLI_Snprintf(nargv[i], tlen, "%c%s", arg_expand ? 'T' : 'F',
+ strv[i]) < 0) {
+ return NULL;
+ }
JLI_TraceLauncher("%s\n", nargv[i]);
}
--- a/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java Fri Mar 15 16:39:07 2013 -0700
@@ -488,14 +488,15 @@
try {
replaceSurfaceData();
} catch (InvalidPipeException e) {
- // REMIND : what do we do if our surface creation failed?
+ // REMIND : what do we do if our surface creation failed?
}
}
}
};
+ Component c = (Component)target;
// Fix 6255371.
- if (!PaintEventDispatcher.getPaintEventDispatcher().queueSurfaceDataReplacing((Component)target, r)) {
- postEvent(new InvocationEvent(Toolkit.getDefaultToolkit(), r));
+ if (!PaintEventDispatcher.getPaintEventDispatcher().queueSurfaceDataReplacing(c, r)) {
+ postEvent(new InvocationEvent(c, r));
}
}
@@ -618,7 +619,7 @@
}
public void disposeLater() {
- postEvent(new InvocationEvent(Toolkit.getDefaultToolkit(), new Runnable() {
+ postEvent(new InvocationEvent(target, new Runnable() {
public void run() {
dispose();
}
--- a/jdk/src/windows/classes/sun/awt/windows/WEmbeddedFrame.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/windows/classes/sun/awt/windows/WEmbeddedFrame.java Fri Mar 15 16:39:07 2013 -0700
@@ -27,6 +27,7 @@
import sun.awt.*;
import java.awt.*;
+import java.awt.event.InvocationEvent;
import java.awt.peer.ComponentPeer;
import java.awt.image.*;
import sun.awt.image.ByteInterleavedRaster;
@@ -232,11 +233,13 @@
} else {
// To avoid focus concurrence b/w IE and EmbeddedFrame
// activation is postponed by means of posting it to EDT.
- EventQueue.invokeLater(new Runnable() {
- public void run() {
- ((WFramePeer)getPeer()).emulateActivation(true);
- }
- });
+ Runnable r = new Runnable() {
+ public void run() {
+ ((WFramePeer)getPeer()).emulateActivation(true);
+ }
+ };
+ WToolkit.postEvent(WToolkit.targetToAppContext(this),
+ new InvocationEvent(this, r));
}
}
--- a/jdk/src/windows/classes/sun/nio/ch/WindowsSelectorImpl.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/windows/classes/sun/nio/ch/WindowsSelectorImpl.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -35,6 +35,7 @@
import java.nio.channels.Pipe;
import java.nio.channels.SelectableChannel;
import java.io.IOException;
+import java.nio.channels.CancelledKeyException;
import java.util.List;
import java.util.ArrayList;
import java.util.HashMap;
@@ -561,17 +562,19 @@
protected void implDereg(SelectionKeyImpl ski) throws IOException{
int i = ski.getIndex();
assert (i >= 0);
- if (i != totalChannels - 1) {
- // Copy end one over it
- SelectionKeyImpl endChannel = channelArray[totalChannels-1];
- channelArray[i] = endChannel;
- endChannel.setIndex(i);
- pollWrapper.replaceEntry(pollWrapper, totalChannels - 1,
+ synchronized (closeLock) {
+ if (i != totalChannels - 1) {
+ // Copy end one over it
+ SelectionKeyImpl endChannel = channelArray[totalChannels-1];
+ channelArray[i] = endChannel;
+ endChannel.setIndex(i);
+ pollWrapper.replaceEntry(pollWrapper, totalChannels - 1,
pollWrapper, i);
+ }
+ ski.setIndex(-1);
}
channelArray[totalChannels - 1] = null;
totalChannels--;
- ski.setIndex(-1);
if ( totalChannels != 1 && totalChannels % MAX_SELECTABLE_FDS == 1) {
totalChannels--;
threadsCount--; // The last thread has become redundant.
@@ -589,7 +592,11 @@
synchronized (closeLock) {
if (pollWrapper == null)
throw new ClosedSelectorException();
- pollWrapper.putEventOps(sk.getIndex(), ops);
+ // make sure this sk has not been removed yet
+ int index = sk.getIndex();
+ if (index == -1)
+ throw new CancelledKeyException();
+ pollWrapper.putEventOps(index, ops);
}
}
--- a/jdk/src/windows/demo/jvmti/hprof/hprof_md.c Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/windows/demo/jvmti/hprof/hprof_md.c Fri Mar 15 16:39:07 2013 -0700
@@ -372,6 +372,7 @@
// Loosley based on os_windows.cpp
char *pathname = (char *)pname;
+ *buffer = '\0';
while (strlen(pathname) > 0) {
char *p = strchr(pathname, ';');
if (p == NULL) {
@@ -382,16 +383,20 @@
continue;
}
if (*(p-1) == ':' || *(p-1) == '\\') {
- (void)_snprintf(buffer, buflen, "%.*s%s.dll", (p - pathname),
+ (void)_snprintf(buffer, buflen, "%.*s%s.dll", (int)(p - pathname),
pathname, fname);
} else {
- (void)_snprintf(buffer, buflen, "%.*s\\%s.dll", (p - pathname),
+ (void)_snprintf(buffer, buflen, "%.*s\\%s.dll", (int)(p - pathname),
pathname, fname);
}
if (_access(buffer, 0) == 0) {
break;
}
- pathname = p + 1;
+ if (*p == '\0') {
+ pathname = p;
+ } else {
+ pathname = p + 1;
+ }
*buffer = '\0';
}
}
--- a/jdk/src/windows/native/java/io/WinNTFileSystem_md.c Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/windows/native/java/io/WinNTFileSystem_md.c Fri Mar 15 16:39:07 2013 -0700
@@ -36,9 +36,7 @@
#include <windows.h>
#include <io.h>
-#include "jvm.h"
#include "jni.h"
-#include "jni_util.h"
#include "io_util.h"
#include "jlong.h"
#include "io_util_md.h"
@@ -115,13 +113,15 @@
DWORD len = (*GetFinalPathNameByHandle_func)(h, result, MAX_PATH, 0);
if (len >= MAX_PATH) {
/* retry with a buffer of the right size */
- result = (WCHAR*)realloc(result, (len+1) * sizeof(WCHAR));
- if (result != NULL) {
+ WCHAR* newResult = (WCHAR*)realloc(result, (len+1) * sizeof(WCHAR));
+ if (newResult != NULL) {
+ result = newResult;
len = (*GetFinalPathNameByHandle_func)(h, result, len, 0);
} else {
len = 0;
}
}
+
if (len > 0) {
/**
* Strip prefix (should be \\?\ or \\?\UNC)
--- a/jdk/src/windows/native/java/lang/ProcessImpl_md.c Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/windows/native/java/lang/ProcessImpl_md.c Fri Mar 15 16:39:07 2013 -0700
@@ -120,10 +120,12 @@
goto Catch;
}
si.hStdInput = inRead;
- SetHandleInformation(inWrite, HANDLE_FLAG_INHERIT, FALSE);
+ SetHandleInformation(inWrite, HANDLE_FLAG_INHERIT, 0);
handles[0] = (jlong) inWrite;
}
- SetHandleInformation(si.hStdInput, HANDLE_FLAG_INHERIT, TRUE);
+ SetHandleInformation(si.hStdInput,
+ HANDLE_FLAG_INHERIT,
+ HANDLE_FLAG_INHERIT);
if (handles[1] != (jlong) -1) {
si.hStdOutput = (HANDLE) handles[1];
@@ -134,10 +136,12 @@
goto Catch;
}
si.hStdOutput = outWrite;
- SetHandleInformation(outRead, HANDLE_FLAG_INHERIT, FALSE);
+ SetHandleInformation(outRead, HANDLE_FLAG_INHERIT, 0);
handles[1] = (jlong) outRead;
}
- SetHandleInformation(si.hStdOutput, HANDLE_FLAG_INHERIT, TRUE);
+ SetHandleInformation(si.hStdOutput,
+ HANDLE_FLAG_INHERIT,
+ HANDLE_FLAG_INHERIT);
if (redirectErrorStream) {
si.hStdError = si.hStdOutput;
@@ -151,10 +155,12 @@
goto Catch;
}
si.hStdError = errWrite;
- SetHandleInformation(errRead, HANDLE_FLAG_INHERIT, FALSE);
+ SetHandleInformation(errRead, HANDLE_FLAG_INHERIT, 0);
handles[2] = (jlong) errRead;
}
- SetHandleInformation(si.hStdError, HANDLE_FLAG_INHERIT, TRUE);
+ SetHandleInformation(si.hStdError,
+ HANDLE_FLAG_INHERIT,
+ HANDLE_FLAG_INHERIT);
processFlag = CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT;
ret = CreateProcessW(0, /* executable name */
--- a/jdk/src/windows/native/java/net/DualStackPlainDatagramSocketImpl.c Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/windows/native/java/net/DualStackPlainDatagramSocketImpl.c Fri Mar 15 16:39:07 2013 -0700
@@ -89,6 +89,7 @@
rv = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &opt, sizeof(opt));
if (rv == SOCKET_ERROR) {
NET_ThrowNew(env, WSAGetLastError(), "Socket creation failed");
+ closesocket(fd);
return -1;
}
--- a/jdk/src/windows/native/sun/nio/ch/DatagramChannelImpl.c Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/windows/native/sun/nio/ch/DatagramChannelImpl.c Fri Mar 15 16:39:07 2013 -0700
@@ -34,8 +34,6 @@
#include "net_util.h"
#include <winsock2.h>
-static jfieldID isa_addrID; /* address in java.net.InetSocketAddress */
-static jfieldID isa_portID; /* port in java.net.InetSocketAddress */
static jfieldID dci_senderID; /* sender in sun.nio.ch.DatagramChannelImpl */
static jfieldID dci_senderAddrID; /* sender InetAddress in sun.nio.ch.DatagramChannelImpl */
static jfieldID dci_senderPortID; /* sender port in sun.nio.ch.DatagramChannelImpl */
@@ -50,9 +48,6 @@
isa_class = (*env)->NewGlobalRef(env, clazz);
isa_ctorID = (*env)->GetMethodID(env, clazz, "<init>",
"(Ljava/net/InetAddress;I)V");
- isa_addrID = (*env)->GetFieldID(env, clazz, "addr",
- "Ljava/net/InetAddress;");
- isa_portID = (*env)->GetFieldID(env, clazz, "port", "I");
clazz = (*env)->FindClass(env, "sun/nio/ch/DatagramChannelImpl");
dci_senderID = (*env)->GetFieldID(env, clazz, "sender",
@@ -214,15 +209,14 @@
JNIEXPORT jint JNICALL
Java_sun_nio_ch_DatagramChannelImpl_send0(JNIEnv *env, jobject this,
jboolean preferIPv6, jobject fdo,
- jlong address, jint len, jobject dest)
+ jlong address, jint len,
+ jobject destAddress, jint destPort)
{
jint fd = fdval(env, fdo);
void *buf = (void *)jlong_to_ptr(address);
SOCKETADDRESS sa;
int sa_len;
jint rv = 0;
- jobject destAddress = (*env)->GetObjectField(env, dest, isa_addrID);
- jint destPort = (*env)->GetIntField(env, dest, isa_portID);
if (NET_InetAddressToSockaddr(env, destAddress, destPort,
(struct sockaddr *)&sa,
--- a/jdk/src/windows/native/sun/windows/awt_TextComponent.cpp Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/windows/native/sun/windows/awt_TextComponent.cpp Fri Mar 15 16:39:07 2013 -0700
@@ -53,14 +53,12 @@
* AwtTextComponent fields
*/
-/* java.awt.TextComponent fields */
-jfieldID AwtTextComponent::canAccessClipboardID;
-
-
/************************************************************************
* AwtTextComponent methods
*/
+jmethodID AwtTextComponent::canAccessClipboardMID;
+
AwtTextComponent::AwtTextComponent() {
m_synthetic = FALSE;
m_lStartPos = -1;
@@ -367,8 +365,7 @@
}
jobject target = GetTarget(env);
jboolean canAccessClipboard =
- env->GetBooleanField(target,
- AwtTextComponent::canAccessClipboardID);
+ env->CallBooleanMethod (target, AwtTextComponent::canAccessClipboardMID);
env->DeleteLocalRef(target);
return (canAccessClipboard) ? mrDoDefault : mrConsume;
}
@@ -854,12 +851,13 @@
{
TRY;
- cls = env->FindClass("java/awt/TextComponent");
- if (cls != NULL) {
- AwtTextComponent::canAccessClipboardID =
- env->GetFieldID(cls, "canAccessClipboard", "Z");
- DASSERT(AwtTextComponent::canAccessClipboardID != NULL);
- }
+ jclass textComponentClassID = env->FindClass("java/awt/TextComponent");
+ AwtTextComponent::canAccessClipboardMID =
+ env->GetMethodID(textComponentClassID,
+ "canAccessClipboard", "()Z");
+ env->DeleteLocalRef(textComponentClassID);
+
+ DASSERT(AwtTextComponent::canAccessClipboardMID != NULL);
CATCH_BAD_ALLOC;
}
--- a/jdk/src/windows/native/sun/windows/awt_TextComponent.h Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/src/windows/native/sun/windows/awt_TextComponent.h Fri Mar 15 16:39:07 2013 -0700
@@ -42,8 +42,7 @@
class AwtTextComponent : public AwtComponent {
public:
- /* java.awt.TextComponent canAccessClipboard field ID */
- static jfieldID canAccessClipboardID;
+ static jmethodID canAccessClipboardMID;
AwtTextComponent();
--- a/jdk/test/Makefile Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/Makefile Fri Mar 15 16:39:07 2013 -0700
@@ -513,6 +513,7 @@
javax/script \
java/sql javax/sql \
javax/smartcardio \
+ javax/xml/soap \
javax/xml/ws com/sun/internal/ws \
jdk/asm \
com/sun/org/apache/xerces \
--- a/jdk/test/ProblemList.txt Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/ProblemList.txt Fri Mar 15 16:39:07 2013 -0700
@@ -134,6 +134,9 @@
# 7196801
java/lang/management/MemoryMXBean/LowMemoryTest2.sh generic-all
+# 8008200
+java/lang/Class/asSubclass/BasicUnit.java generic-all
+
############################################################################
# jdk_management
@@ -324,12 +327,26 @@
# 7150569
tools/launcher/UnicodeTest.java macosx-all
-# 8006039
-tools/launcher/I18NJarTest.java macosx-all
-
# 8007410
tools/launcher/FXLauncherTest.java linux-all
+# 8004172
+sun/tools/jstat/jstatGcCapacityOutput1.sh generic-all
+sun/tools/jstat/jstatGcCauseOutput1.sh generic-all
+sun/tools/jstat/jstatGcOldOutput1.sh generic-all
+sun/tools/jstat/jstatGcOutput1.sh generic-all
+sun/tools/jstat/jstatGcPermCapacityOutput1.sh generic-all
+sun/tools/jstat/jstatLineCounts1.sh generic-all
+sun/tools/jstat/jstatLineCounts2.sh generic-all
+sun/tools/jstat/jstatLineCounts3.sh generic-all
+sun/tools/jstat/jstatLineCounts4.sh generic-all
+sun/tools/jstat/jstatOptions1.sh generic-all
+sun/tools/jstat/jstatTimeStamp1.sh generic-all
+sun/tools/jstatd/jstatdExternalRegistry.sh generic-all
+sun/tools/jstatd/jstatdDefaults.sh generic-all
+sun/tools/jstatd/jstatdPort.sh generic-all
+sun/tools/jstatd/jstatdServerName.sh generic-all
+
############################################################################
# jdk_jdi
--- a/jdk/test/java/lang/PrimitiveSumMinMaxTest.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/java/lang/PrimitiveSumMinMaxTest.java Fri Mar 15 16:39:07 2013 -0700
@@ -50,20 +50,20 @@
BinaryOperator<Boolean> xor = Boolean::logicalXor;
Comparator<Boolean> cmp = Boolean::compare;
- assertTrue(and.operate(true, true));
- assertFalse(and.operate(true, false));
- assertFalse(and.operate(false, true));
- assertFalse(and.operate(false, false));
+ assertTrue(and.apply(true, true));
+ assertFalse(and.apply(true, false));
+ assertFalse(and.apply(false, true));
+ assertFalse(and.apply(false, false));
- assertTrue(or.operate(true, true));
- assertTrue(or.operate(true, false));
- assertTrue(or.operate(false, true));
- assertFalse(or.operate(false, false));
+ assertTrue(or.apply(true, true));
+ assertTrue(or.apply(true, false));
+ assertTrue(or.apply(false, true));
+ assertFalse(or.apply(false, false));
- assertFalse(xor.operate(true, true));
- assertTrue(xor.operate(true, false));
- assertTrue(xor.operate(false, true));
- assertFalse(xor.operate(false, false));
+ assertFalse(xor.apply(true, true));
+ assertTrue(xor.apply(true, false));
+ assertTrue(xor.apply(false, true));
+ assertFalse(xor.apply(false, false));
assertEquals(Boolean.TRUE.compareTo(Boolean.TRUE), cmp.compare(true, true));
assertEquals(Boolean.TRUE.compareTo(Boolean.FALSE), cmp.compare(true, false));
@@ -83,12 +83,12 @@
int[] numbers = { -1, 0, 1, 100, Integer.MAX_VALUE, Integer.MIN_VALUE };
for (int i : numbers) {
for (int j : numbers) {
- assertEquals(i+j, (int) sum1.operate(i, j));
- assertEquals(i+j, sum2.operateAsInt(i, j));
- assertEquals(Math.max(i,j), (int) max1.operate(i, j));
- assertEquals(Math.max(i,j), max2.operateAsInt(i, j));
- assertEquals(Math.min(i,j), (int) min1.operate(i, j));
- assertEquals(Math.min(i,j), min2.operateAsInt(i, j));
+ assertEquals(i+j, (int) sum1.apply(i, j));
+ assertEquals(i+j, sum2.applyAsInt(i, j));
+ assertEquals(Math.max(i,j), (int) max1.apply(i, j));
+ assertEquals(Math.max(i,j), max2.applyAsInt(i, j));
+ assertEquals(Math.min(i,j), (int) min1.apply(i, j));
+ assertEquals(Math.min(i,j), min2.applyAsInt(i, j));
assertEquals(((Integer) i).compareTo(j), cmp.compare(i, j));
}
}
@@ -106,12 +106,12 @@
long[] numbers = { -1, 0, 1, 100, Long.MAX_VALUE, Long.MIN_VALUE };
for (long i : numbers) {
for (long j : numbers) {
- assertEquals(i+j, (long) sum1.operate(i, j));
- assertEquals(i+j, sum2.operateAsLong(i, j));
- assertEquals(Math.max(i,j), (long) max1.operate(i, j));
- assertEquals(Math.max(i,j), max2.operateAsLong(i, j));
- assertEquals(Math.min(i,j), (long) min1.operate(i, j));
- assertEquals(Math.min(i,j), min2.operateAsLong(i, j));
+ assertEquals(i+j, (long) sum1.apply(i, j));
+ assertEquals(i+j, sum2.applyAsLong(i, j));
+ assertEquals(Math.max(i,j), (long) max1.apply(i, j));
+ assertEquals(Math.max(i,j), max2.applyAsLong(i, j));
+ assertEquals(Math.min(i,j), (long) min1.apply(i, j));
+ assertEquals(Math.min(i,j), min2.applyAsLong(i, j));
assertEquals(((Long) i).compareTo(j), cmp.compare(i, j));
}
}
@@ -126,9 +126,9 @@
float[] numbers = { -1, 0, 1, 100, Float.MAX_VALUE, Float.MIN_VALUE };
for (float i : numbers) {
for (float j : numbers) {
- assertEquals(i+j, (float) sum1.operate(i, j));
- assertEquals(Math.max(i,j), (float) max1.operate(i, j));
- assertEquals(Math.min(i,j), (float) min1.operate(i, j));
+ assertEquals(i+j, (float) sum1.apply(i, j));
+ assertEquals(Math.max(i,j), (float) max1.apply(i, j));
+ assertEquals(Math.min(i,j), (float) min1.apply(i, j));
assertEquals(((Float) i).compareTo(j), cmp.compare(i, j));
}
}
@@ -146,12 +146,12 @@
double[] numbers = { -1, 0, 1, 100, Double.MAX_VALUE, Double.MIN_VALUE };
for (double i : numbers) {
for (double j : numbers) {
- assertEquals(i+j, (double) sum1.operate(i, j));
- assertEquals(i+j, sum2.operateAsDouble(i, j));
- assertEquals(Math.max(i,j), (double) max1.operate(i, j));
- assertEquals(Math.max(i,j), max2.operateAsDouble(i, j));
- assertEquals(Math.min(i,j), (double) min1.operate(i, j));
- assertEquals(Math.min(i,j), min2.operateAsDouble(i, j));
+ assertEquals(i+j, (double) sum1.apply(i, j));
+ assertEquals(i+j, sum2.applyAsDouble(i, j));
+ assertEquals(Math.max(i,j), (double) max1.apply(i, j));
+ assertEquals(Math.max(i,j), max2.applyAsDouble(i, j));
+ assertEquals(Math.min(i,j), (double) min1.apply(i, j));
+ assertEquals(Math.min(i,j), min2.applyAsDouble(i, j));
assertEquals(((Double) i).compareTo(j), cmp.compare(i, j));
}
}
--- a/jdk/test/java/lang/SecurityManager/NoAWT.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/java/lang/SecurityManager/NoAWT.java Fri Mar 15 16:39:07 2013 -0700
@@ -22,14 +22,43 @@
*/
/* @test
- * @bug 8004502
+ * @bug 8004502 8008793
* @summary Sanity check that SecurityManager methods that check AWTPermission
* behave as expected when AWT is not present
*/
+import java.security.AllPermission;
+import java.security.Permission;
+
public class NoAWT {
+
+ static class MySecurityManager extends SecurityManager {
+ Class<?> expectedClass;
+
+ void setExpectedPermissionClass(Class<?> c) {
+ expectedClass = c;
+ }
+
+ @Override
+ public void checkPermission(Permission perm) {
+ if (perm.getClass() != expectedClass)
+ throw new RuntimeException("Got: " + perm.getClass() + ", expected: " + expectedClass);
+ super.checkPermission(perm);
+ }
+ }
+
public static void main(String[] args) {
- SecurityManager sm = new SecurityManager();
+ Class<?> awtPermissionClass = null;
+ try {
+ awtPermissionClass = Class.forName("java.awt.AWTPermission");
+ } catch (ClassNotFoundException ignore) { }
+
+ MySecurityManager sm = new MySecurityManager();
+ if (awtPermissionClass != null) {
+ sm.setExpectedPermissionClass(awtPermissionClass);
+ } else {
+ sm.setExpectedPermissionClass(AllPermission.class);
+ }
try {
sm.checkAwtEventQueueAccess();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/RedefineMethodInBacktrace.sh Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,87 @@
+#
+# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# @test
+# @bug 7174978
+# @summary Redefine a class with a method stored in a backtrace.
+# @author Stefan Karlsson
+#
+# @run shell MakeJAR3.sh RedefineMethodInBacktraceAgent 'Can-Redefine-Classes: true'
+# @run build RedefineMethodInBacktraceTarget RedefineMethodInBacktraceApp
+# @run shell RedefineMethodInBacktrace.sh
+#
+
+if [ "${TESTJAVA}" = "" ]
+then
+ echo "TESTJAVA not set. Test cannot execute. Failed."
+ exit 1
+fi
+
+if [ "${COMPILEJAVA}" = "" ]
+then
+ COMPILEJAVA="${TESTJAVA}"
+fi
+echo "COMPILEJAVA=${COMPILEJAVA}"
+
+if [ "${TESTSRC}" = "" ]
+then
+ echo "TESTSRC not set. Test cannot execute. Failed."
+ exit 1
+fi
+
+if [ "${TESTCLASSES}" = "" ]
+then
+ echo "TESTCLASSES not set. Test cannot execute. Failed."
+ exit 1
+fi
+
+JAVAC="${COMPILEJAVA}"/bin/javac
+JAVA="${TESTJAVA}"/bin/java
+
+cp "${TESTSRC}"/RedefineMethodInBacktraceTarget_2.java \
+ RedefineMethodInBacktraceTarget.java
+"${JAVAC}" ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} -d . RedefineMethodInBacktraceTarget.java
+
+"${JAVA}" ${TESTVMOPTS} -javaagent:RedefineMethodInBacktraceAgent.jar \
+ -classpath "${TESTCLASSES}" RedefineMethodInBacktraceApp > output.log 2>&1
+RUN_RESULT=$?
+
+if [ $RUN_RESULT != 0 ]; then
+ echo "FAIL: the run failed with exit code '$RUN_RESULT'"
+ exit $RUN_RESULT
+fi
+
+cat output.log
+
+MESG="Exception"
+grep "$MESG" output.log
+result=$?
+if [ "$result" = 0 ]; then
+ echo "FAIL: found '$MESG' in the test output"
+ result=1
+else
+ echo "PASS: did NOT find '$MESG' in the test output"
+ result=0
+fi
+
+exit $result
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/RedefineMethodInBacktraceAgent.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.instrument.Instrumentation;
+
+public class RedefineMethodInBacktraceAgent {
+ private static Instrumentation instrumentation;
+
+ private RedefineMethodInBacktraceAgent() {}
+
+ public static void premain(String agentArgs, Instrumentation inst) {
+ System.out.println("Hello from RedefineMethodInBacktraceAgent!");
+ System.out.println("isRedefineClassesSupported()=" +
+ inst.isRedefineClassesSupported());
+
+ instrumentation = inst;
+ }
+
+ public static Instrumentation getInstrumentation() {
+ return instrumentation;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/RedefineMethodInBacktraceApp.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.lang.instrument.ClassDefinition;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * When an exception is thrown, the JVM collects just enough information
+ * about the stack trace to be able to create a full fledged stack trace
+ * (StackTraceElement[]). The backtrace contains this information and the
+ * JVM must make sure that the data in the backtrace is still usable after
+ * a class redefinition.
+ *
+ * After the PermGen removal there was a bug when the last reference to a Method
+ * was in the backtrace. The class of the method was kept alive, because of the
+ * mirror stored in the backtrace, but the old versions of the redefined method
+ * could be freed, since class redefinition didn't know about the backtraces.
+ */
+public class RedefineMethodInBacktraceApp {
+ public static void main(String args[]) throws Exception {
+ System.out.println("Hello from RedefineMethodInBacktraceApp!");
+
+ new RedefineMethodInBacktraceApp().doTest();
+
+ System.exit(0);
+ }
+
+ private void doTest() throws Exception {
+ doMethodInBacktraceTest();
+ }
+
+ private void doMethodInBacktraceTest() throws Exception {
+ Throwable t = getThrowableFromMethodToRedefine();
+
+ doRedefine(RedefineMethodInBacktraceTarget.class);
+
+ doClassUnloading();
+
+ touchRedefinedMethodInBacktrace(t);
+ }
+
+ private static Throwable getThrowableFromMethodToRedefine() throws Exception {
+ Class<RedefineMethodInBacktraceTarget> c =
+ RedefineMethodInBacktraceTarget.class;
+ Method method = c.getMethod("methodToRedefine");
+
+ Throwable thrownFromMethodToRedefine = null;
+ try {
+ method.invoke(null);
+ } catch (InvocationTargetException e) {
+ thrownFromMethodToRedefine = e.getCause();
+ if (!(thrownFromMethodToRedefine instanceof RuntimeException)) {
+ throw e;
+ }
+ }
+ method = null;
+ c = null;
+
+ return thrownFromMethodToRedefine;
+ }
+
+ private static void doClassUnloading() {
+ // This will clean out old, unused redefined methods.
+ System.gc();
+ }
+
+ private static void touchRedefinedMethodInBacktrace(Throwable throwable) {
+ // Make sure that we can convert the backtrace, which is referring to
+ // the redefined method, to a StrackTraceElement[] without crashing.
+ throwable.getStackTrace();
+ }
+
+ private static void doRedefine(Class<?> clazz) throws Exception {
+ // Load the second version of this class.
+ File f = new File(clazz.getName() + ".class");
+ System.out.println("Reading test class from " + f.getAbsolutePath());
+ InputStream redefineStream = new FileInputStream(f);
+
+ byte[] redefineBuffer = NamedBuffer.loadBufferFromStream(redefineStream);
+
+ ClassDefinition redefineParamBlock = new ClassDefinition(
+ clazz, redefineBuffer);
+
+ RedefineMethodInBacktraceAgent.getInstrumentation().redefineClasses(
+ new ClassDefinition[] {redefineParamBlock});
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTarget.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * The first version of this class. The second version is in
+ * RedefineMethodInBacktraceTarget_2.java.
+ */
+public class RedefineMethodInBacktraceTarget {
+ public static void methodToRedefine() {
+ throw new RuntimeException("Test exception");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTarget_2.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * This is the second version of this class. The first version is in
+ * RedefineMethodInBacktraceTarget.java.
+ */
+public class RedefineMethodInBacktraceTarget {
+ public static void methodToRedefine() {
+ throw new RuntimeException("Test exception 2");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/RedefineMethodWithAnnotations.sh Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,85 @@
+#
+# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# @test
+# @bug 7022100
+# @summary Method annotations are incorrectly set when redefining classes.
+# @author Stefan Karlsson
+#
+# @run shell MakeJAR3.sh RedefineMethodWithAnnotationsAgent 'Can-Redefine-Classes: true'
+# @run build RedefineMethodWithAnnotationsTarget RedefineMethodWithAnnotationsApp RedefineMethodWithAnnotationsAnnotations
+# @run shell RedefineMethodWithAnnotations.sh
+#
+
+if [ "${TESTJAVA}" = "" ]
+then
+ echo "TESTJAVA not set. Test cannot execute. Failed."
+ exit 1
+fi
+
+if [ "${COMPILEJAVA}" = "" ]
+then
+ COMPILEJAVA="${TESTJAVA}"
+fi
+echo "COMPILEJAVA=${COMPILEJAVA}"
+
+if [ "${TESTSRC}" = "" ]
+then
+ echo "TESTSRC not set. Test cannot execute. Failed."
+ exit 1
+fi
+
+if [ "${TESTCLASSES}" = "" ]
+then
+ echo "TESTCLASSES not set. Test cannot execute. Failed."
+ exit 1
+fi
+
+JAVAC="${COMPILEJAVA}"/bin/javac
+JAVA="${TESTJAVA}"/bin/java
+
+cp "${TESTSRC}"/RedefineMethodWithAnnotationsTarget_2.java \
+ RedefineMethodWithAnnotationsTarget.java
+cp "${TESTSRC}"/RedefineMethodWithAnnotationsAnnotations.java \
+ RedefineMethodWithAnnotationsAnnotations.java
+
+"${JAVAC}" ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} -d . \
+ RedefineMethodWithAnnotationsTarget.java \
+ RedefineMethodWithAnnotationsAnnotations.java
+
+"${JAVA}" ${TESTVMOPTS} -javaagent:RedefineMethodWithAnnotationsAgent.jar \
+ -cp "${TESTCLASSES}" RedefineMethodWithAnnotationsApp > output.log 2>&1
+cat output.log
+
+MESG="Exception"
+grep "$MESG" output.log
+result=$?
+if [ "$result" = 0 ]; then
+ echo "FAIL: found '$MESG' in the test output"
+ result=1
+else
+ echo "PASS: did NOT find '$MESG' in the test output"
+ result=0
+fi
+
+exit $result
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/RedefineMethodWithAnnotationsAgent.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.instrument.Instrumentation;
+
+public class RedefineMethodWithAnnotationsAgent {
+ private static Instrumentation instrumentation;
+
+ private RedefineMethodWithAnnotationsAgent() {}
+
+ public static void premain(String agentArgs, Instrumentation inst) {
+ System.out.println("Hello from RedefineMethodWithAnnotationsAgent!");
+ System.out.println("isRedefineClassesSupported()=" +
+ inst.isRedefineClassesSupported());
+
+ instrumentation = inst;
+ }
+
+ public static Instrumentation getInstrumentation() {
+ return instrumentation;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/RedefineMethodWithAnnotationsAnnotations.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+@interface ParameterAnnotation {
+ // Values used for the annotations in the first version of the target class.
+ static final String STRING_VALUE_1 = "String1";
+ static final String INT_VALUE_1 = "Int1";
+
+ // Values used for the annotations in the second version of the target class.
+ static final String STRING_VALUE_2 = "String2";
+ static final String INT_VALUE_2 = "Int2";
+
+ String value();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/RedefineMethodWithAnnotationsApp.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.lang.annotation.Annotation;
+import java.lang.instrument.ClassDefinition;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.reflect.Method;
+
+public class RedefineMethodWithAnnotationsApp {
+ public static void main(String args[]) throws Exception {
+ System.out.println("Hello from RedefineMethodWithAnnotationsApp!");
+
+ new RedefineMethodWithAnnotationsApp().doTest();
+
+ System.exit(0);
+ }
+
+ private void doTest() throws Exception {
+ doMethodParameterAnnotationsTest();
+ }
+
+ private void doMethodParameterAnnotationsTest() throws Exception {
+ verifyMethodParameterAnnotationsValue(
+ ParameterAnnotation.STRING_VALUE_1);
+
+ doRedefine(RedefineMethodWithAnnotationsTarget.class);
+
+ verifyMethodParameterAnnotationsValue(
+ ParameterAnnotation.STRING_VALUE_2);
+ }
+
+ private static void verifyMethodParameterAnnotationsValue(
+ String expectedValue) throws Exception {
+ Class<RedefineMethodWithAnnotationsTarget> c =
+ RedefineMethodWithAnnotationsTarget.class;
+ Method method = c.getMethod("annotatedMethod", String.class);
+
+ Annotation [][] parametersAnnotations =
+ method.getParameterAnnotations();
+ if (parametersAnnotations.length != 1) {
+ throw new Exception("Incorrect number of parameters to method: " +
+ method.getName() + "." +
+ " Expected: 1," +
+ " got: " + parametersAnnotations.length);
+ }
+
+ Annotation[] parameterAnnotations = parametersAnnotations[0];
+ if (parameterAnnotations.length != 1) {
+ throw new Exception("Incorrect number of annotations." +
+ " Expected: 1" +
+ ", got " + parameterAnnotations.length);
+ }
+
+ Annotation parameterAnnotation = parameterAnnotations[0];
+ if (!(parameterAnnotation instanceof ParameterAnnotation)) {
+ throw new Exception("Incorrect Annotation class." +
+ " Expected: " + ParameterAnnotation.class.getName() +
+ ", got: " + parameterAnnotation.getClass().getName());
+ }
+
+ ParameterAnnotation pa = (ParameterAnnotation)parameterAnnotation;
+ String annotationValue = pa.value();
+ if (!expectedValue.equals(annotationValue)) {
+ throw new Exception("Incorrect parameter annotation value." +
+ " Expected: " + expectedValue +
+ ", got: " + annotationValue);
+ }
+ }
+
+ private static void doRedefine(Class<?> clazz) throws Exception {
+ // Load the second version of this class.
+ File f = new File(clazz.getName() + ".class");
+ System.out.println("Reading test class from " + f);
+ InputStream redefineStream = new FileInputStream(f);
+
+ byte[] redefineBuffer = NamedBuffer.loadBufferFromStream(redefineStream);
+
+ ClassDefinition redefineParamBlock = new ClassDefinition(
+ clazz, redefineBuffer);
+
+ RedefineMethodWithAnnotationsAgent.getInstrumentation().redefineClasses(
+ new ClassDefinition[] {redefineParamBlock});
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/RedefineMethodWithAnnotationsTarget.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * The first version of this class. The second version is in
+ * RedefineMethodWithAnnotationsTarget_2.java.
+ */
+public class RedefineMethodWithAnnotationsTarget {
+ public void annotatedMethod(@ParameterAnnotation(
+ value = ParameterAnnotation.STRING_VALUE_1) String parameter) { }
+ public void annotatedMethod(@ParameterAnnotation(
+ value = ParameterAnnotation.INT_VALUE_1) int parameter) { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/RedefineMethodWithAnnotationsTarget_2.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * This is the second version of this class. The first version is in
+ * RedefineMethodWithAnnotationsTarget.java.
+ * <p>
+ * It has the same methods but with different annotations and order.
+ */
+public class RedefineMethodWithAnnotationsTarget {
+ public void annotatedMethod(@ParameterAnnotation(
+ value = ParameterAnnotation.INT_VALUE_2) int parameter) { }
+ public void annotatedMethod(@ParameterAnnotation(
+ value = ParameterAnnotation.STRING_VALUE_2) String parameter) { }
+}
--- a/jdk/test/java/lang/instrument/RedefineSubclassWithTwoInterfaces.sh Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/java/lang/instrument/RedefineSubclassWithTwoInterfaces.sh Fri Mar 15 16:39:07 2013 -0700
@@ -141,32 +141,30 @@
fi
PASS1_MESG="before any redefines"
-cnt=`grep "$PASS1_MESG" output.log | grep 'version-0' | wc -l | sed 's/^ *//'`
-case "$cnt" in
-2)
+cnt=`grep "$PASS1_MESG" output.log | grep 'version-0' | wc -l`
+# no quotes around $cnt so any whitespace from 'wc -l' is ignored
+if [ $cnt = 2 ]; then
echo "INFO: found 2 version-0 '$PASS1_MESG' mesgs."
- ;;
-*)
+else
echo "FAIL: did NOT find 2 version-0 '$PASS1_MESG' mesgs."
+ echo "INFO: cnt='$cnt'"
echo "INFO: grep '$PASS1_MESG' output:"
grep "$PASS1_MESG" output.log
result=1
- ;;
-esac
+fi
PASS2_MESG="after redefine"
-cnt=`grep "$PASS2_MESG" output.log | grep 'version-1' | wc -l | sed 's/^ *//'`
-case "$cnt" in
-2)
+cnt=`grep "$PASS2_MESG" output.log | grep 'version-1' | wc -l`
+# no quotes around $cnt so any whitespace from 'wc -l' is ignored
+if [ $cnt = 2 ]; then
echo "INFO: found 2 version-1 '$PASS2_MESG' mesgs."
- ;;
-*)
+else
echo "FAIL: did NOT find 2 version-1 '$PASS2_MESG' mesgs."
+ echo "INFO: cnt='$cnt'"
echo "INFO: grep '$PASS2_MESG' output:"
grep "$PASS2_MESG" output.log
result=1
- ;;
-esac
+fi
if [ "$result" = 0 ]; then
echo "PASS: test passed both positive and negative output checks."
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/7087570/Test7087570.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/* @test
+ * @bug 7087570
+ * @summary REF_invokeSpecial DMHs (which are unusual) get marked explicitly; tweak the MHI to use this bit
+ *
+ * @run main Test7087570
+ */
+
+import java.lang.invoke.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+
+public class Test7087570 {
+ // XXX may remove the following constant declarations when MethodHandleInfo is made public
+ private static final int
+ REF_getField = 1,
+ REF_getStatic = 2,
+ REF_putField = 3,
+ REF_putStatic = 4,
+ REF_invokeVirtual = 5,
+ REF_invokeStatic = 6,
+ REF_invokeSpecial = 7,
+ REF_newInvokeSpecial = 8,
+ REF_invokeInterface = 9,
+ REF_LIMIT = 10;
+
+ private static final TestMethodData[] TESTS = new TestMethodData[] {
+ // field accessors
+ data(DummyFieldHolder.class, "instanceField", getterMethodType(String.class), DummyFieldHolder.class, REF_getField),
+ data(DummyFieldHolder.class, "instanceField", setterMethodType(String.class), DummyFieldHolder.class, REF_putField),
+ data(DummyFieldHolder.class, "staticField", getterMethodType(Integer.class), DummyFieldHolder.class, REF_getStatic),
+ data(DummyFieldHolder.class, "staticField", setterMethodType(Integer.class), DummyFieldHolder.class, REF_putStatic),
+ data(DummyFieldHolder.class, "instanceByteField", getterMethodType(byte.class), DummyFieldHolder.class, REF_getField),
+ data(DummyFieldHolder.class, "instanceByteField", setterMethodType(byte.class), DummyFieldHolder.class, REF_putField),
+
+ // REF_invokeVirtual
+ data(Object.class, "hashCode", methodType(int.class), Object.class, REF_invokeVirtual),
+
+ // REF_invokeVirtual strength-reduced to REF_invokeSpecial,
+ // test if it normalizes back to REF_invokeVirtual in MethodHandleInfo as expected
+ data(String.class, "hashCode", methodType(int.class), String.class, REF_invokeVirtual),
+
+ // REF_invokeStatic
+ data(Collections.class, "sort", methodType(void.class, List.class), Collections.class, REF_invokeStatic),
+ data(Arrays.class, "asList", methodType(List.class, Object[].class), Arrays.class, REF_invokeStatic), // varargs case
+
+ // REF_invokeSpecial
+ data(Object.class, "hashCode", methodType(int.class), Object.class, REF_invokeSpecial),
+
+ // REF_newInvokeSpecial
+ data(String.class, "<init>", methodType(void.class, char[].class), String.class, REF_newInvokeSpecial),
+ data(DummyFieldHolder.class, "<init>", methodType(void.class, byte.class, Long[].class), DummyFieldHolder.class, REF_newInvokeSpecial), // varargs case
+
+ // REF_invokeInterface
+ data(List.class, "size", methodType(int.class), List.class, REF_invokeInterface)
+ };
+
+ public static void main(String... args) throws Throwable {
+ testWithLookup();
+ testWithUnreflect();
+ }
+
+ private static void doTest(MethodHandle mh, TestMethodData testMethod) {
+ Object mhi = newMethodHandleInfo(mh);
+
+ System.out.printf("%s.%s: %s, nominal refKind: %s, actual refKind: %s\n",
+ testMethod.clazz.getName(), testMethod.name, testMethod.methodType,
+ REF_KIND_NAMES[testMethod.referenceKind],
+ REF_KIND_NAMES[getReferenceKind(mhi)]);
+ assertEquals(testMethod.name, getName(mhi));
+ assertEquals(testMethod.methodType, getMethodType(mhi));
+ assertEquals(testMethod.declaringClass, getDeclaringClass(mhi));
+ assertEquals(testMethod.referenceKind == REF_invokeSpecial, isInvokeSpecial(mh));
+ assertRefKindEquals(testMethod.referenceKind, getReferenceKind(mhi));
+ }
+
+ private static void testWithLookup() throws Throwable {
+ for (TestMethodData testMethod : TESTS) {
+ MethodHandle mh = lookupFrom(testMethod);
+ doTest(mh, testMethod);
+ }
+ }
+
+ private static void testWithUnreflect() throws Throwable {
+ for (TestMethodData testMethod : TESTS) {
+ MethodHandle mh = unreflectFrom(testMethod);
+ doTest(mh, testMethod);
+ }
+ }
+
+ private static MethodType getterMethodType(Class<?> clazz) {
+ return methodType(clazz);
+ }
+
+ private static MethodType setterMethodType(Class<?> clazz) {
+ return methodType(void.class, clazz);
+ }
+
+ private static final String[] REF_KIND_NAMES = {
+ "MH::invokeBasic",
+ "REF_getField", "REF_getStatic", "REF_putField", "REF_putStatic",
+ "REF_invokeVirtual", "REF_invokeStatic", "REF_invokeSpecial",
+ "REF_newInvokeSpecial", "REF_invokeInterface"
+ };
+
+ private static final Lookup LOOKUP = lookup();
+
+ // XXX may remove the following reflective logic when MethodHandleInfo is made public
+ private static final MethodHandle MH_IS_INVOKESPECIAL;
+ private static final MethodHandle MHI_CONSTRUCTOR;
+ private static final MethodHandle MHI_GET_NAME;
+ private static final MethodHandle MHI_GET_METHOD_TYPE;
+ private static final MethodHandle MHI_GET_DECLARING_CLASS;
+ private static final MethodHandle MHI_GET_REFERENCE_KIND;
+
+ static {
+ try {
+ // This is white box testing. Use reflection to grab private implementation bits.
+ String magicName = "IMPL_LOOKUP";
+ Field magicLookup = MethodHandles.Lookup.class.getDeclaredField(magicName);
+ // This unit test will fail if a security manager is installed.
+ magicLookup.setAccessible(true);
+ // Forbidden fruit...
+ Lookup directInvokeLookup = (Lookup) magicLookup.get(null);
+ Class<?> mhiClass = Class.forName("java.lang.invoke.MethodHandleInfo", false, MethodHandle.class.getClassLoader());
+ MH_IS_INVOKESPECIAL = directInvokeLookup
+ .findVirtual(MethodHandle.class, "isInvokeSpecial", methodType(boolean.class));
+ MHI_CONSTRUCTOR = directInvokeLookup
+ .findConstructor(mhiClass, methodType(void.class, MethodHandle.class));
+ MHI_GET_NAME = directInvokeLookup
+ .findVirtual(mhiClass, "getName", methodType(String.class));
+ MHI_GET_METHOD_TYPE = directInvokeLookup
+ .findVirtual(mhiClass, "getMethodType", methodType(MethodType.class));
+ MHI_GET_DECLARING_CLASS = directInvokeLookup
+ .findVirtual(mhiClass, "getDeclaringClass", methodType(Class.class));
+ MHI_GET_REFERENCE_KIND = directInvokeLookup
+ .findVirtual(mhiClass, "getReferenceKind", methodType(int.class));
+ } catch (ReflectiveOperationException ex) {
+ throw new Error(ex);
+ }
+ }
+
+ private static class TestMethodData {
+ final Class<?> clazz;
+ final String name;
+ final MethodType methodType;
+ final Class<?> declaringClass;
+ final int referenceKind; // the nominal refKind
+
+ public TestMethodData(Class<?> clazz, String name,
+ MethodType methodType, Class<?> declaringClass,
+ int referenceKind) {
+ this.clazz = clazz;
+ this.name = name;
+ this.methodType = methodType;
+ this.declaringClass = declaringClass;
+ this.referenceKind = referenceKind;
+ }
+ }
+
+ private static TestMethodData data(Class<?> clazz, String name,
+ MethodType methodType, Class<?> declaringClass,
+ int referenceKind) {
+ return new TestMethodData(clazz, name, methodType, declaringClass, referenceKind);
+ }
+
+ private static MethodHandle lookupFrom(TestMethodData testMethod)
+ throws NoSuchMethodException, NoSuchFieldException, IllegalAccessException {
+ switch (testMethod.referenceKind) {
+ case REF_getField:
+ return LOOKUP.findGetter(testMethod.clazz, testMethod.name, testMethod.methodType.returnType());
+ case REF_putField:
+ return LOOKUP.findSetter(testMethod.clazz, testMethod.name, testMethod.methodType.parameterType(0));
+ case REF_getStatic:
+ return LOOKUP.findStaticGetter(testMethod.clazz, testMethod.name, testMethod.methodType.returnType());
+ case REF_putStatic:
+ return LOOKUP.findStaticSetter(testMethod.clazz, testMethod.name, testMethod.methodType.parameterType(0));
+ case REF_invokeVirtual:
+ case REF_invokeInterface:
+ return LOOKUP.findVirtual(testMethod.clazz, testMethod.name, testMethod.methodType);
+ case REF_invokeStatic:
+ return LOOKUP.findStatic(testMethod.clazz, testMethod.name, testMethod.methodType);
+ case REF_invokeSpecial:
+ Class<?> thisClass = LOOKUP.lookupClass();
+ return LOOKUP.findSpecial(testMethod.clazz, testMethod.name, testMethod.methodType, thisClass);
+ case REF_newInvokeSpecial:
+ return LOOKUP.findConstructor(testMethod.clazz, testMethod.methodType);
+ default:
+ throw new Error("ERROR: unexpected referenceKind in test data");
+ }
+ }
+
+ private static MethodHandle unreflectFrom(TestMethodData testMethod)
+ throws NoSuchMethodException, NoSuchFieldException, IllegalAccessException {
+ switch (testMethod.referenceKind) {
+ case REF_getField:
+ case REF_getStatic: {
+ Field f = testMethod.clazz.getDeclaredField(testMethod.name);
+ return LOOKUP.unreflectGetter(f);
+ }
+ case REF_putField:
+ case REF_putStatic: {
+ Field f = testMethod.clazz.getDeclaredField(testMethod.name);
+ return LOOKUP.unreflectSetter(f);
+ }
+ case REF_invokeVirtual:
+ case REF_invokeStatic:
+ case REF_invokeInterface: {
+ Method m = testMethod.clazz.getDeclaredMethod(testMethod.name, testMethod.methodType.parameterArray());
+ return LOOKUP.unreflect(m);
+ }
+ case REF_invokeSpecial: {
+ Method m = testMethod.clazz.getDeclaredMethod(testMethod.name, testMethod.methodType.parameterArray());
+ Class<?> thisClass = LOOKUP.lookupClass();
+ return LOOKUP.unreflectSpecial(m, thisClass);
+ }
+ case REF_newInvokeSpecial: {
+ Constructor c = testMethod.clazz.getDeclaredConstructor(testMethod.methodType.parameterArray());
+ return LOOKUP.unreflectConstructor(c);
+ }
+ default:
+ throw new Error("ERROR: unexpected referenceKind in test data");
+ }
+ }
+
+ private static Object newMethodHandleInfo(MethodHandle mh) {
+ try {
+ return MHI_CONSTRUCTOR.invoke(mh);
+ } catch (Throwable ex) {
+ throw new Error(ex);
+ }
+ }
+
+ private static boolean isInvokeSpecial(MethodHandle mh) {
+ try {
+ return (boolean) MH_IS_INVOKESPECIAL.invokeExact(mh);
+ } catch (Throwable ex) {
+ throw new Error(ex);
+ }
+ }
+
+ private static String getName(Object mhi) {
+ try {
+ return (String) MHI_GET_NAME.invoke(mhi);
+ } catch (Throwable ex) {
+ throw new Error(ex);
+ }
+ }
+
+ private static MethodType getMethodType(Object mhi) {
+ try {
+ return (MethodType) MHI_GET_METHOD_TYPE.invoke(mhi);
+ } catch (Throwable ex) {
+ throw new Error(ex);
+ }
+ }
+
+ private static Class<?> getDeclaringClass(Object mhi) {
+ try {
+ return (Class<?>) MHI_GET_DECLARING_CLASS.invoke(mhi);
+ } catch (Throwable ex) {
+ throw new Error(ex);
+ }
+ }
+
+ private static int getReferenceKind(Object mhi) {
+ try {
+ return (int) MHI_GET_REFERENCE_KIND.invoke(mhi);
+ } catch (Throwable ex) {
+ throw new Error(ex);
+ }
+ }
+
+ private static void assertRefKindEquals(int expect, int observed) {
+ if (expect == observed) return;
+
+ String msg = "expected " + REF_KIND_NAMES[(int) expect] +
+ " but observed " + REF_KIND_NAMES[(int) observed];
+ System.out.println("FAILED: " + msg);
+ throw new AssertionError(msg);
+ }
+
+ private static void assertEquals(Object expect, Object observed) {
+ if (java.util.Objects.equals(expect, observed)) return;
+
+ String msg = "expected " + expect + " but observed " + observed;
+ System.out.println("FAILED: " + msg);
+ throw new AssertionError(msg);
+ }
+}
+
+class DummyFieldHolder {
+ public static Integer staticField;
+ public String instanceField;
+ public byte instanceByteField;
+
+ public DummyFieldHolder(byte unused1, Long... unused2) {
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/lambda/LUtils.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/*
+ * support infrastructure to invoke a java class from the command line
+ */
+class LUtils {
+ static final sun.tools.jar.Main jarTool =
+ new sun.tools.jar.Main(System.out, System.err, "jar-tool");
+ static final com.sun.tools.javac.Main javac =
+ new com.sun.tools.javac.Main();
+ static final File cwd = new File(".").getAbsoluteFile();
+ static final String JAVAHOME = System.getProperty("java.home");
+ static final boolean isWindows =
+ System.getProperty("os.name", "unknown").startsWith("Windows");
+ //static final boolean isSDK = JAVAHOME.endsWith("jre");
+ static final File JAVA_BIN_FILE = new File(JAVAHOME, "bin");
+ static final File JAVA_CMD = new File(JAVA_BIN_FILE,
+ isWindows ? "java.exe" : "java");
+
+ protected LUtils() {
+ }
+
+ public static void compile(String... args) {
+ if (javac.compile(args) != 0) {
+ throw new RuntimeException("compilation fails");
+ }
+ }
+
+ static void createFile(File outFile, List<String> content) {
+ try {
+ Files.write(outFile.getAbsoluteFile().toPath(), content,
+ Charset.defaultCharset());
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ static File getClassFile(File javaFile) {
+ return javaFile.getName().endsWith(".java")
+ ? new File(javaFile.getName().replace(".java", ".class"))
+ : null;
+ }
+
+ static String getSimpleName(File inFile) {
+ String fname = inFile.getName();
+ return fname.substring(0, fname.indexOf("."));
+ }
+
+ static TestResult doExec(String... cmds) {
+ return doExec(null, null, cmds);
+ }
+
+ /*
+ * A method which executes a java cmd and returns the results in a container
+ */
+ static TestResult doExec(Map<String, String> envToSet,
+ java.util.Set<String> envToRemove, String... cmds) {
+ String cmdStr = "";
+ for (String x : cmds) {
+ cmdStr = cmdStr.concat(x + " ");
+ }
+ ProcessBuilder pb = new ProcessBuilder(cmds);
+ Map<String, String> env = pb.environment();
+ if (envToRemove != null) {
+ for (String key : envToRemove) {
+ env.remove(key);
+ }
+ }
+ if (envToSet != null) {
+ env.putAll(envToSet);
+ }
+ BufferedReader rdr = null;
+ try {
+ List<String> outputList = new ArrayList<>();
+ pb.redirectErrorStream(true);
+ Process p = pb.start();
+ rdr = new BufferedReader(new InputStreamReader(p.getInputStream()));
+ String in = rdr.readLine();
+ while (in != null) {
+ outputList.add(in);
+ in = rdr.readLine();
+ }
+ p.waitFor();
+ p.destroy();
+
+ return new TestResult(cmdStr, p.exitValue(), outputList,
+ env, new Throwable("current stack of the test"));
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ throw new RuntimeException(ex.getMessage());
+ }
+ }
+
+ static class TestResult {
+ String cmd;
+ int exitValue;
+ List<String> testOutput;
+ Map<String, String> env;
+ Throwable t;
+
+ public TestResult(String str, int rv, List<String> oList,
+ Map<String, String> env, Throwable t) {
+ cmd = str;
+ exitValue = rv;
+ testOutput = oList;
+ this.env = env;
+ this.t = t;
+ }
+
+ void assertZero(String message) {
+ if (exitValue != 0) {
+ System.err.println(this);
+ throw new RuntimeException(message);
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringWriter sw = new StringWriter();
+ PrintWriter status = new PrintWriter(sw);
+ status.println("Cmd: " + cmd);
+ status.println("Return code: " + exitValue);
+ status.println("Environment variable:");
+ for (String x : env.keySet()) {
+ status.println("\t" + x + "=" + env.get(x));
+ }
+ status.println("Output:");
+ for (String x : testOutput) {
+ status.println("\t" + x);
+ }
+ status.println("Exception:");
+ status.println(t.getMessage());
+ t.printStackTrace(status);
+
+ return sw.getBuffer().toString();
+ }
+ }
+}
--- a/jdk/test/java/lang/invoke/lambda/LambdaAccessControlDoPrivilegedTest.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/java/lang/invoke/lambda/LambdaAccessControlDoPrivilegedTest.java Fri Mar 15 16:39:07 2013 -0700
@@ -26,20 +26,12 @@
* @bug 8003881
* @summary tests DoPrivileged action (implemented as lambda expressions) by
* inserting them into the BootClassPath.
- * @compile -XDignore.symbol.file LambdaAccessControlDoPrivilegedTest.java
+ * @compile -XDignore.symbol.file LambdaAccessControlDoPrivilegedTest.java LUtils.java
* @run main/othervm LambdaAccessControlDoPrivilegedTest
*/
-import java.io.BufferedReader;
import java.io.File;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.nio.charset.Charset;
-import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
public class LambdaAccessControlDoPrivilegedTest extends LUtils {
public static void main(String... args) {
@@ -87,140 +79,3 @@
jarFile.delete();
}
}
-
-/*
- * support infrastructure to invoke a java class from the command line
- */
-class LUtils {
- static final sun.tools.jar.Main jarTool =
- new sun.tools.jar.Main(System.out, System.err, "jar-tool");
- static final com.sun.tools.javac.Main javac =
- new com.sun.tools.javac.Main();
- static final File cwd = new File(".").getAbsoluteFile();
- static final String JAVAHOME = System.getProperty("java.home");
- static final boolean isWindows =
- System.getProperty("os.name", "unknown").startsWith("Windows");
- //static final boolean isSDK = JAVAHOME.endsWith("jre");
- static final File JAVA_BIN_FILE = new File(JAVAHOME, "bin");
- static final File JAVA_CMD = new File(JAVA_BIN_FILE,
- isWindows ? "java.exe" : "java");
-
- protected LUtils() {
- }
-
- public static void compile(String... args) {
- if (javac.compile(args) != 0) {
- throw new RuntimeException("compilation fails");
- }
- }
-
- static void createFile(File outFile, List<String> content) {
- try {
- Files.write(outFile.getAbsoluteFile().toPath(), content,
- Charset.defaultCharset());
- } catch (IOException ex) {
- throw new RuntimeException(ex);
- }
- }
-
- static File getClassFile(File javaFile) {
- return javaFile.getName().endsWith(".java")
- ? new File(javaFile.getName().replace(".java", ".class"))
- : null;
- }
-
- static String getSimpleName(File inFile) {
- String fname = inFile.getName();
- return fname.substring(0, fname.indexOf("."));
- }
-
- static TestResult doExec(String... cmds) {
- return doExec(null, null, cmds);
- }
-
- /*
- * A method which executes a java cmd and returns the results in a container
- */
- static TestResult doExec(Map<String, String> envToSet,
- java.util.Set<String> envToRemove, String... cmds) {
- String cmdStr = "";
- for (String x : cmds) {
- cmdStr = cmdStr.concat(x + " ");
- }
- ProcessBuilder pb = new ProcessBuilder(cmds);
- Map<String, String> env = pb.environment();
- if (envToRemove != null) {
- for (String key : envToRemove) {
- env.remove(key);
- }
- }
- if (envToSet != null) {
- env.putAll(envToSet);
- }
- BufferedReader rdr = null;
- try {
- List<String> outputList = new ArrayList<>();
- pb.redirectErrorStream(true);
- Process p = pb.start();
- rdr = new BufferedReader(new InputStreamReader(p.getInputStream()));
- String in = rdr.readLine();
- while (in != null) {
- outputList.add(in);
- in = rdr.readLine();
- }
- p.waitFor();
- p.destroy();
-
- return new TestResult(cmdStr, p.exitValue(), outputList,
- env, new Throwable("current stack of the test"));
- } catch (Exception ex) {
- ex.printStackTrace();
- throw new RuntimeException(ex.getMessage());
- }
- }
-
- static class TestResult {
- String cmd;
- int exitValue;
- List<String> testOutput;
- Map<String, String> env;
- Throwable t;
-
- public TestResult(String str, int rv, List<String> oList,
- Map<String, String> env, Throwable t) {
- cmd = str;
- exitValue = rv;
- testOutput = oList;
- this.env = env;
- this.t = t;
- }
-
- void assertZero(String message) {
- if (exitValue != 0) {
- System.err.println(this);
- throw new RuntimeException(message);
- }
- }
-
- @Override
- public String toString() {
- StringWriter sw = new StringWriter();
- PrintWriter status = new PrintWriter(sw);
- status.println("Cmd: " + cmd);
- status.println("Return code: " + exitValue);
- status.println("Environment variable:");
- for (String x : env.keySet()) {
- status.println("\t" + x + "=" + env.get(x));
- }
- status.println("Output:");
- for (String x : testOutput) {
- status.println("\t" + x);
- }
- status.println("Exception:");
- status.println(t.getMessage());
- t.printStackTrace(status);
-
- return sw.getBuffer().toString();
- }
- }
-}
--- a/jdk/test/java/lang/invoke/lambda/LambdaAccessControlTest.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/java/lang/invoke/lambda/LambdaAccessControlTest.java Fri Mar 15 16:39:07 2013 -0700
@@ -25,7 +25,7 @@
* @test
* @bug 8003881
* @summary tests Lambda expression with a a security manager at top level
- * @compile -XDignore.symbol.file LambdaAccessControlTest.java
+ * @compile -XDignore.symbol.file LambdaAccessControlTest.java LUtils.java
*
* @run main/othervm LambdaAccessControlTest
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/lambda/LambdaClassLoaderSerialization.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+@test
+@bug 8004970
+@summary Lambda serialization in the presence of class loaders
+@author Peter Levart
+*/
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.Arrays;
+
+public class LambdaClassLoaderSerialization {
+
+ public interface SerializableRunnable extends Runnable, Serializable {}
+
+ public static class MyCode implements SerializableRunnable {
+
+ private byte[] serialize(Object o) {
+ ByteArrayOutputStream baos;
+ try (
+ ObjectOutputStream oos =
+ new ObjectOutputStream(baos = new ByteArrayOutputStream())
+ ) {
+ oos.writeObject(o);
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ return baos.toByteArray();
+ }
+
+ private <T> T deserialize(byte[] bytes) {
+ try (
+ ObjectInputStream ois =
+ new ObjectInputStream(new ByteArrayInputStream(bytes))
+ ) {
+ return (T) ois.readObject();
+ }
+ catch (IOException | ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public void run() {
+ System.out.println(" this: " + this);
+
+ SerializableRunnable deSerializedThis = deserialize(serialize(this));
+ System.out.println(" deSerializedThis: " + deSerializedThis);
+
+ SerializableRunnable runnable = () -> {System.out.println("HELLO");};
+ System.out.println(" runnable: " + runnable);
+
+ SerializableRunnable deSerializedRunnable = deserialize(serialize(runnable));
+ System.out.println("deSerializedRunnable: " + deSerializedRunnable);
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ ClassLoader myCl = new MyClassLoader(
+ LambdaClassLoaderSerialization.class.getClassLoader()
+ );
+ Class<?> myCodeClass = Class.forName(
+ LambdaClassLoaderSerialization.class.getName() + "$MyCode",
+ true,
+ myCl
+ );
+ Runnable myCode = (Runnable) myCodeClass.newInstance();
+ myCode.run();
+ }
+
+ static class MyClassLoader extends ClassLoader {
+ MyClassLoader(ClassLoader parent) {
+ super(parent);
+ }
+
+ @Override
+ protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
+ if (name.indexOf('.') < 0) {
+ synchronized (getClassLoadingLock(name)) {
+ Class<?> c = findLoadedClass(name);
+ if (c == null) {
+ c = findClass(name);
+ }
+ if (resolve) {
+ resolveClass(c);
+ }
+ return c;
+ }
+ } else {
+ return super.loadClass(name, resolve);
+ }
+ }
+
+ @Override
+ protected Class<?> findClass(String name) throws ClassNotFoundException {
+ String path = name.replace('.', '/').concat(".class");
+ try (InputStream is = getResourceAsStream(path)) {
+ if (is != null) {
+ byte[] bytes = readFully(is);
+ return defineClass(name, bytes, 0, bytes.length);
+ } else {
+ throw new ClassNotFoundException(name);
+ }
+ }
+ catch (IOException e) {
+ throw new ClassNotFoundException(name, e);
+ }
+ }
+
+ static byte[] readFully(InputStream is) throws IOException {
+ byte[] output = {};
+ int pos = 0;
+ while (true) {
+ int bytesToRead;
+ if (pos >= output.length) { // Only expand when there's no room
+ bytesToRead = output.length + 1024;
+ if (output.length < pos + bytesToRead) {
+ output = Arrays.copyOf(output, pos + bytesToRead);
+ }
+ } else {
+ bytesToRead = output.length - pos;
+ }
+ int cc = is.read(output, pos, bytesToRead);
+ if (cc < 0) {
+ if (output.length != pos) {
+ output = Arrays.copyOf(output, pos);
+ }
+ break;
+ }
+ pos += cc;
+ }
+ return output;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/lambda/LambdaSerialization.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+@test
+@bug 8004970
+@summary Lambda serialization
+*/
+
+import java.io.*;
+
+public class LambdaSerialization {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ public static void main(String[] args) throws Exception {
+ try {
+ // Write lambdas out
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutput out = new ObjectOutputStream(baos);
+
+ write(out, z -> "[" + z + "]" );
+ write(out, z -> z + z );
+ write(out, z -> "blah" );
+ out.flush();
+ out.close();
+
+ // Read them back
+ ByteArrayInputStream bais =
+ new ByteArrayInputStream(baos.toByteArray());
+ ObjectInputStream in = new ObjectInputStream(bais);
+ readAssert(in, "[X]");
+ readAssert(in, "XX");
+ readAssert(in, "blah");
+ in.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw e;
+ }
+ assertTrue(assertionCount == 3);
+ }
+
+ static void write(ObjectOutput out, LSI lamb) throws IOException {
+ out.writeObject(lamb);
+ }
+
+ static void readAssert(ObjectInputStream in, String expected) throws IOException, ClassNotFoundException {
+ LSI ls = (LSI) in.readObject();
+ String result = ls.convert("X");
+ System.out.printf("Result: %s\n", result);
+ assertTrue(result.equals(expected));
+ }
+}
+
+interface LSI extends Serializable {
+ String convert(String x);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/OldenCompilingWithDefaults.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8009267
+ * @summary Verify uses of isAnnotationPresent compile under older source versions
+ * @compile -source 1.5 -target 1.5 OldenCompilingWithDefaults.java
+ * @compile -source 1.6 -target 1.6 OldenCompilingWithDefaults.java
+ * @compile -source 1.7 -target 1.7 OldenCompilingWithDefaults.java
+ * @compile OldenCompilingWithDefaults.java
+ */
+
+import java.lang.reflect.*;
+
+public class OldenCompilingWithDefaults {
+ public OldenCompilingWithDefaults(){}
+ static Object f;
+
+ public static void main(String... args) throws Exception {
+ Class<OldenCompilingWithDefaults> clazz = OldenCompilingWithDefaults.class;
+ Package pkg = clazz.getPackage();
+ Constructor<OldenCompilingWithDefaults> ctor = clazz.getConstructor();
+ Method m = clazz.getMethod("main", String[].class);
+ Field f = clazz.getField("f");
+
+ if(clazz.isAnnotationPresent(SuppressWarnings.class) ||
+ pkg.isAnnotationPresent(SuppressWarnings.class) ||
+ ctor.isAnnotationPresent(SuppressWarnings.class) ||
+ m.isAnnotationPresent(SuppressWarnings.class) ||
+ f.isAnnotationPresent(SuppressWarnings.class))
+ System.out.println("An annotation is present.");
+ }
+}
--- a/jdk/test/java/lang/reflect/Parameter/WithParameters.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/java/lang/reflect/Parameter/WithParameters.java Fri Mar 15 16:39:07 2013 -0700
@@ -22,7 +22,6 @@
*/
/*
- * @ignore
* @test
* @compile -parameters WithParameters.java
* @run main WithParameters
@@ -85,8 +84,8 @@
error++;
}
}
- if(parameters[0].toString().equals("int quux")) {
- System.err.println("toString for quux is wrong");
+ if(!parameters[0].toString().equals("final int quux")) {
+ System.err.println("toString for quux is wrong, expected \"final int quux\", got \"" + parameters[0] + "\"");
error++;
}
if(parameters[0].getModifiers() != Modifier.FINAL) {
@@ -101,8 +100,8 @@
System.err.println("getParameterizedType for quux is wrong");
error++;
}
- if(parameters[1].toString().equals("WithParameters$Foo quuux")) {
- System.err.println("toString for quuux is wrong");
+ if(!parameters[1].toString().equals("WithParameters$Foo quuux")) {
+ System.err.println("toString for quuux is wrong, expected \"WithParameters$Foo quuux\", got \"" + parameters[1] + "\"");
error++;
}
if(parameters[1].isVarArgs()) {
@@ -121,8 +120,8 @@
System.err.println("getAnnotations has the wrong annotation");
error++;
}
- if(parameters[2].toString().equals("java.util.List<?> quuux")) {
- System.err.println("toString for l is wrong");
+ if(!parameters[2].toString().equals("java.util.List<?> l")) {
+ System.err.println("toString for l is wrong, expected \"java.util.List<?> l\", got \"" + parameters[2] + "\"");
error++;
}
if(parameters[2].isVarArgs()) {
@@ -149,8 +148,8 @@
error++;
}
}
- if(parameters[3].toString().equals("java.util.List<WithParameters$Foo> l")) {
- System.err.println("toString for l2 is wrong");
+ if(!parameters[3].toString().equals("java.util.List<WithParameters$Foo> l2")) {
+ System.err.println("toString for l2 is wrong, expected \"java.util.List<WithParameters$Foo> l2\", got \"" + parameters[3] + "\"");
error++;
}
if(parameters[3].isVarArgs()) {
@@ -177,8 +176,8 @@
error++;
}
}
- if(parameters[4].toString().equals("java.util.List<? extends WithParameters$Foo> l")) {
- System.err.println("toString for l3 is wrong");
+ if(!parameters[4].toString().equals("java.util.List<? extends WithParameters$Foo> l3")) {
+ System.err.println("toString for l3 is wrong, expected \"java.util.List<? extends WithParameters$Foo> l3\", got \"" + parameters[3] + "\"");
error++;
}
if(parameters[4].isVarArgs()) {
@@ -212,8 +211,8 @@
}
}
}
- if(parameters[5].toString().equals("java.lang.String... rest")) {
- System.err.println("toString for l is wrong");
+ if(!parameters[5].toString().equals("java.lang.String... rest")) {
+ System.err.println("toString for rest is wrong, expected \"java.lang.String... rest\", got \"" + parameters[5] + "\"");
error++;
}
if(!parameters[5].isVarArgs()) {
--- a/jdk/test/java/net/BindException/Test.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/java/net/BindException/Test.java Fri Mar 15 16:39:07 2013 -0700
@@ -46,7 +46,7 @@
static int failures;
static void doTest(Object test[], InetAddress ia1, InetAddress ia2,
- boolean silent) {
+ boolean silent) throws Exception {
String s1_type = (String)test[0];
String s2_type = (String)test[1];
int port = 0;
@@ -64,11 +64,10 @@
boolean failed = false;
Exception failed_exc = null;
+ Socket sock1 = null;
+ ServerSocket ss = null;
+ DatagramSocket dsock1 = null;
try {
- Socket sock1, sock2;
- ServerSocket ss;
- DatagramSocket dsock1, dsock2;
-
/* bind the first socket */
if (s1_type.equals("Socket")) {
@@ -90,16 +89,18 @@
/* bind the second socket */
if (s2_type.equals("Socket")) {
- sock2 = new Socket();
- sock2.bind( new InetSocketAddress(ia2, port));
+ try (Socket sock2 = new Socket()) {
+ sock2.bind( new InetSocketAddress(ia2, port));
+ }
}
if (s2_type.equals("ServerSocket")) {
- ss = new ServerSocket(port, 0, ia2);
+ try (ServerSocket ss2 = new ServerSocket(port, 0, ia2)) { }
}
if (s2_type.equals("DatagramSocket")) {
- dsock2 = new DatagramSocket( new InetSocketAddress(ia2, port) );
+ try (DatagramSocket ds =
+ new DatagramSocket(new InetSocketAddress(ia2, port))) { }
}
} catch (BindException be) {
@@ -107,6 +108,10 @@
} catch (Exception e) {
failed = true;
failed_exc = e;
+ } finally {
+ if (sock1 != null) sock1.close();
+ if (ss != null) ss.close();
+ if (dsock1 != null) dsock1.close();
}
/*
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/Socket/HttpProxy.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6370908
+ * @summary Add support for HTTP_CONNECT proxy in Socket class
+ */
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import static java.lang.System.out;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.net.ServerSocket;
+import java.net.Socket;
+import sun.net.www.MessageHeader;
+
+public class HttpProxy {
+ final String proxyHost;
+ final int proxyPort;
+ static final int SO_TIMEOUT = 15000;
+
+ public static void main(String[] args) throws Exception {
+ String host;
+ int port;
+ if (args.length == 0) {
+ // Start internal proxy
+ ConnectProxyTunnelServer proxy = new ConnectProxyTunnelServer();
+ proxy.start();
+ host = "localhost";
+ port = proxy.getLocalPort();
+ out.println("Running with internal proxy: " + host + ":" + port);
+ } else if (args.length == 2) {
+ host = args[0];
+ port = Integer.valueOf(args[1]);
+ out.println("Running against specified proxy server: " + host + ":" + port);
+ } else {
+ System.err.println("Usage: java HttpProxy [<proxy host> <proxy port>]");
+ return;
+ }
+
+ HttpProxy p = new HttpProxy(host, port);
+ p.test();
+ }
+
+ public HttpProxy(String proxyHost, int proxyPort) {
+ this.proxyHost = proxyHost;
+ this.proxyPort = proxyPort;
+ }
+
+ void test() throws Exception {
+ InetSocketAddress proxyAddress = new InetSocketAddress(proxyHost, proxyPort);
+ Proxy httpProxy = new Proxy(Proxy.Type.HTTP, proxyAddress);
+
+ try (ServerSocket ss = new ServerSocket(0);
+ Socket sock = new Socket(httpProxy)) {
+ sock.setSoTimeout(SO_TIMEOUT);
+ sock.setTcpNoDelay(false);
+
+ InetSocketAddress externalAddress =
+ new InetSocketAddress(InetAddress.getLocalHost(), ss.getLocalPort());
+
+ out.println("Trying to connect to server socket on " + externalAddress);
+ sock.connect(externalAddress);
+ try (Socket externalSock = ss.accept()) {
+ // perform some simple checks
+ check(sock.isBound(), "Socket is not bound");
+ check(sock.isConnected(), "Socket is not connected");
+ check(!sock.isClosed(), "Socket should not be closed");
+ check(sock.getSoTimeout() == SO_TIMEOUT,
+ "Socket should have a previously set timeout");
+ check(sock.getTcpNoDelay() == false, "NODELAY should be false");
+
+ simpleDataExchange(sock, externalSock);
+ }
+ }
+ }
+
+ static void check(boolean condition, String message) {
+ if (!condition) out.println(message);
+ }
+
+ static Exception unexpected(Exception e) {
+ out.println("Unexcepted Exception: " + e);
+ e.printStackTrace();
+ return e;
+ }
+
+ // performs a simple exchange of data between the two sockets
+ // and throws an exception if there is any problem.
+ void simpleDataExchange(Socket s1, Socket s2) throws Exception {
+ try (final InputStream i1 = s1.getInputStream();
+ final InputStream i2 = s2.getInputStream();
+ final OutputStream o1 = s1.getOutputStream();
+ final OutputStream o2 = s2.getOutputStream()) {
+ startSimpleWriter("simpleWriter1", o1, 100);
+ startSimpleWriter("simpleWriter2", o2, 200);
+ simpleRead(i2, 100);
+ simpleRead(i1, 200);
+ }
+ }
+
+ void startSimpleWriter(String threadName, final OutputStream os, final int start) {
+ (new Thread(new Runnable() {
+ public void run() {
+ try { simpleWrite(os, start); }
+ catch (Exception e) {unexpected(e); }
+ }}, threadName)).start();
+ }
+
+ void simpleWrite(OutputStream os, int start) throws Exception {
+ byte b[] = new byte[2];
+ for (int i=start; i<start+100; i++) {
+ b[0] = (byte) (i / 256);
+ b[1] = (byte) (i % 256);
+ os.write(b);
+ }
+ }
+
+ void simpleRead(InputStream is, int start) throws Exception {
+ byte b[] = new byte [2];
+ for (int i=start; i<start+100; i++) {
+ int x = is.read(b);
+ if (x == 1)
+ x += is.read(b,1,1);
+ if (x!=2)
+ throw new Exception("read error");
+ int r = bytes(b[0], b[1]);
+ if (r != i)
+ throw new Exception("read " + r + " expected " +i);
+ }
+ }
+
+ int bytes(byte b1, byte b2) {
+ int i1 = (int)b1 & 0xFF;
+ int i2 = (int)b2 & 0xFF;
+ return i1 * 256 + i2;
+ }
+
+ static class ConnectProxyTunnelServer extends Thread {
+
+ private final ServerSocket ss;
+
+ public ConnectProxyTunnelServer() throws IOException {
+ ss = new ServerSocket(0);
+ }
+
+ @Override
+ public void run() {
+ try (Socket clientSocket = ss.accept()) {
+ processRequest(clientSocket);
+ } catch (Exception e) {
+ out.println("Proxy Failed: " + e);
+ e.printStackTrace();
+ } finally {
+ try { ss.close(); } catch (IOException x) { unexpected(x); }
+ }
+ }
+
+ /**
+ * Returns the port on which the proxy is accepting connections.
+ */
+ public int getLocalPort() {
+ return ss.getLocalPort();
+ }
+
+ /*
+ * Processes the CONNECT request
+ */
+ private void processRequest(Socket clientSocket) throws Exception {
+ MessageHeader mheader = new MessageHeader(clientSocket.getInputStream());
+ String statusLine = mheader.getValue(0);
+
+ if (!statusLine.startsWith("CONNECT")) {
+ out.println("proxy server: processes only "
+ + "CONNECT method requests, recieved: "
+ + statusLine);
+ return;
+ }
+
+ // retrieve the host and port info from the status-line
+ InetSocketAddress serverAddr = getConnectInfo(statusLine);
+
+ //open socket to the server
+ try (Socket serverSocket = new Socket(serverAddr.getAddress(),
+ serverAddr.getPort())) {
+ Forwarder clientFW = new Forwarder(clientSocket.getInputStream(),
+ serverSocket.getOutputStream());
+ Thread clientForwarderThread = new Thread(clientFW, "ClientForwarder");
+ clientForwarderThread.start();
+ send200(clientSocket);
+ Forwarder serverFW = new Forwarder(serverSocket.getInputStream(),
+ clientSocket.getOutputStream());
+ serverFW.run();
+ clientForwarderThread.join();
+ }
+ }
+
+ private void send200(Socket clientSocket) throws IOException {
+ OutputStream out = clientSocket.getOutputStream();
+ PrintWriter pout = new PrintWriter(out);
+
+ pout.println("HTTP/1.1 200 OK");
+ pout.println();
+ pout.flush();
+ }
+
+ /*
+ * This method retrieves the hostname and port of the tunnel destination
+ * from the request line.
+ * @param connectStr
+ * of the form: <i>CONNECT server-name:server-port HTTP/1.x</i>
+ */
+ static InetSocketAddress getConnectInfo(String connectStr)
+ throws Exception
+ {
+ try {
+ int starti = connectStr.indexOf(' ');
+ int endi = connectStr.lastIndexOf(' ');
+ String connectInfo = connectStr.substring(starti+1, endi).trim();
+ // retrieve server name and port
+ endi = connectInfo.indexOf(':');
+ String name = connectInfo.substring(0, endi);
+ int port = Integer.parseInt(connectInfo.substring(endi+1));
+ return new InetSocketAddress(name, port);
+ } catch (Exception e) {
+ out.println("Proxy recieved a request: " + connectStr);
+ throw unexpected(e);
+ }
+ }
+ }
+
+ /* Reads from the given InputStream and writes to the given OutputStream */
+ static class Forwarder implements Runnable
+ {
+ private final InputStream in;
+ private final OutputStream os;
+
+ Forwarder(InputStream in, OutputStream os) {
+ this.in = in;
+ this.os = os;
+ }
+
+ @Override
+ public void run() {
+ try {
+ byte[] ba = new byte[1024];
+ int count;
+ while ((count = in.read(ba)) != -1) {
+ os.write(ba, 0, count);
+ }
+ } catch (IOException e) {
+ unexpected(e);
+ }
+ }
+ }
+}
--- a/jdk/test/java/nio/channels/DatagramChannel/SendToUnresolved.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/java/nio/channels/DatagramChannel/SendToUnresolved.java Fri Mar 15 16:39:07 2013 -0700
@@ -42,7 +42,7 @@
try {
dc.send(bb, sa);
throw new RuntimeException("Expected exception not thrown");
- } catch (IOException e) {
+ } catch (IOException | UnresolvedAddressException e) {
// Correct result
}
dc.close();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/channels/Selector/RacyDeregister.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * Portions Copyright (c) 2012 IBM Corporation
+ */
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+
+/*
+ * @test
+ * @bug 6429204
+ * @summary SelectionKey.interestOps does not update interest set on Windows.
+ * @author Frank Ding
+ */
+public class RacyDeregister {
+
+ static boolean notified;
+ static final Object selectorLock = new Object();
+ static final Object notifyLock = new Object();
+ /**
+ * null: not terminated
+ * true: passed
+ * false: failed
+ */
+ static volatile Boolean succTermination = null;
+
+ public static void main(String[] args) throws Exception {
+ InetAddress addr = InetAddress.getByName(null);
+ ServerSocketChannel sc = ServerSocketChannel.open();
+ sc.socket().bind(new InetSocketAddress(addr, 0));
+
+ SocketChannel.open(new InetSocketAddress(addr,
+ sc.socket().getLocalPort()));
+
+ SocketChannel accepted = sc.accept();
+ accepted.configureBlocking(false);
+
+ SocketChannel.open(new InetSocketAddress(addr,
+ sc.socket().getLocalPort()));
+ SocketChannel accepted2 = sc.accept();
+ accepted2.configureBlocking(false);
+
+ final Selector sel = Selector.open();
+ SelectionKey key2 = accepted2.register(sel, SelectionKey.OP_READ);
+ final SelectionKey[] key = new SelectionKey[]{
+ accepted.register(sel, SelectionKey.OP_READ)};
+
+
+ // thread that will be changing key[0].interestOps to OP_READ | OP_WRITE
+ new Thread() {
+
+ public void run() {
+ try {
+ for (int k = 0; k < 15; k++) {
+ for (int i = 0; i < 10000; i++) {
+ synchronized (notifyLock) {
+ synchronized (selectorLock) {
+ sel.wakeup();
+ key[0].interestOps(SelectionKey.OP_READ
+ | SelectionKey.OP_WRITE);
+ }
+ notified = false;
+ long beginTime = System.currentTimeMillis();
+ while (true) {
+ notifyLock.wait(5000);
+ if (notified) {
+ break;
+ }
+ long endTime = System.currentTimeMillis();
+ if (endTime - beginTime > 5000) {
+ succTermination = false;
+ // wake up main thread doing select()
+ sel.wakeup();
+ return;
+ }
+ }
+ }
+ }
+ }
+ succTermination = true;
+ // wake up main thread doing select()
+ sel.wakeup();
+ } catch (Exception e) {
+ System.out.println(e);
+ succTermination = true;
+ // wake up main thread doing select()
+ sel.wakeup();
+ }
+ }
+ }.start();
+
+ // main thread will be doing registering/deregistering with the sel
+ while (true) {
+ sel.select();
+ if (Boolean.TRUE.equals(succTermination)) {
+ System.out.println("Test passed");
+ sel.close();
+ sc.close();
+ break;
+ } else if (Boolean.FALSE.equals(succTermination)) {
+ System.out.println("Failed to pass the test");
+ sel.close();
+ sc.close();
+ throw new RuntimeException("Failed to pass the test");
+ }
+ synchronized (selectorLock) {
+ }
+ if (sel.selectedKeys().contains(key[0]) && key[0].isWritable()) {
+ synchronized (notifyLock) {
+ notified = true;
+ notifyLock.notify();
+ key[0].cancel();
+ sel.selectNow();
+ key2 = accepted2.register(sel, SelectionKey.OP_READ);
+ key[0] = accepted.register(sel, SelectionKey.OP_READ);
+ }
+ }
+ key2.cancel();
+ sel.selectedKeys().clear();
+ }
+ }
+}
--- a/jdk/test/java/nio/file/Files/CopyAndMove.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/java/nio/file/Files/CopyAndMove.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,7 +22,7 @@
*/
/* @test
- * @bug 4313887 6838333 6917021 7006126 6950237
+ * @bug 4313887 6838333 6917021 7006126 6950237 8006645
* @summary Unit test for java.nio.file.Files copy and move methods
* @library ..
* @build CopyAndMove PassThroughFileSystem
@@ -37,6 +37,7 @@
import java.nio.file.attribute.*;
import java.io.*;
import java.util.*;
+import java.util.concurrent.TimeUnit;
public class CopyAndMove {
static final Random rand = new Random();
@@ -94,8 +95,8 @@
// check last modified time if not a symbolic link
if (!attrs1.isSymbolicLink()) {
- long time1 = attrs1.lastModifiedTime().toMillis();
- long time2 = attrs2.lastModifiedTime().toMillis();
+ long time1 = attrs1.lastModifiedTime().to(TimeUnit.SECONDS);
+ long time2 = attrs2.lastModifiedTime().to(TimeUnit.SECONDS);
if (time1 != time2) {
System.err.format("File time for %s is %s\n", attrs1.fileKey(), attrs1.lastModifiedTime());
--- a/jdk/test/java/rmi/server/RMIClassLoader/loadProxyClasses/security.policy Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/java/rmi/server/RMIClassLoader/loadProxyClasses/security.policy Fri Mar 15 16:39:07 2013 -0700
@@ -13,6 +13,7 @@
permission java.io.FilePermission ".${/}-", "read,write,delete";
permission java.lang.RuntimePermission "createClassLoader";
+ permission java.lang.RuntimePermission "getClassLoader";
permission java.lang.RuntimePermission "setContextClassLoader";
// used by TestLibrary to determine test environment
--- a/jdk/test/java/rmi/testlibrary/JavaVM.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/java/rmi/testlibrary/JavaVM.java Fri Mar 15 16:39:07 2013 -0700
@@ -110,6 +110,14 @@
return TestLibrary.getExtraProperty("jcov.options","");
}
+ public void start(Runnable runnable) throws IOException {
+ if (runnable == null) {
+ throw new NullPointerException("Runnable cannot be null.");
+ }
+
+ start();
+ new JavaVMCallbackHandler(runnable).start();
+ }
/**
* Exec the VM as specified in this object's constructor.
@@ -183,4 +191,35 @@
start();
return waitFor();
}
+
+ /**
+ * Handles calling the callback.
+ */
+ private class JavaVMCallbackHandler extends Thread {
+ Runnable runnable;
+
+ JavaVMCallbackHandler(Runnable runnable) {
+ this.runnable = runnable;
+ }
+
+
+ /**
+ * Wait for the Process to terminate and notify the callback.
+ */
+ @Override
+ public void run() {
+ if (vm != null) {
+ try {
+ vm.waitFor();
+ } catch(InterruptedException ie) {
+ // Restore the interrupted status
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ if (runnable != null) {
+ runnable.run();
+ }
+ }
+ }
}
--- a/jdk/test/java/util/Calendar/JavatimeTest.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/java/util/Calendar/JavatimeTest.java Fri Mar 15 16:39:07 2013 -0700
@@ -23,7 +23,7 @@
/*
*@test
- *@bug 8007520
+ *@bug 8007520 8008254
*@summary Test those bridge methods to/from java.time date/time classes
*/
@@ -53,13 +53,10 @@
int nanos = r.nextInt(NANOS_PER_SECOND);
int nanos_ms = nanos / 1000000 * 1000000; // millis precision
long millis = secs * 1000 + r.nextInt(1000);
-
LocalDateTime ldt = LocalDateTime.ofEpochSecond(secs, nanos, ZoneOffset.UTC);
LocalDateTime ldt_ms = LocalDateTime.ofEpochSecond(secs, nanos_ms, ZoneOffset.UTC);
Instant inst = Instant.ofEpochSecond(secs, nanos);
Instant inst_ms = Instant.ofEpochSecond(secs, nanos_ms);
- //System.out.printf("ms: %16d ns: %10d ldt:[%s]%n", millis, nanos, ldt);
-
///////////// java.util.Date /////////////////////////
Date jud = new java.util.Date(millis);
Instant inst0 = jud.toInstant();
@@ -77,6 +74,8 @@
}
//////////// java.util.GregorianCalendar /////////////
GregorianCalendar cal = new GregorianCalendar();
+ // non-roundtrip of tz name between j.u.tz and j.t.zid
+ cal.setTimeZone(TimeZone.getTimeZone(ZoneId.systemDefault()));
cal.setGregorianChange(new java.util.Date(Long.MIN_VALUE));
cal.setFirstDayOfWeek(Calendar.MONDAY);
cal.setMinimalDaysInFirstWeek(4);
@@ -84,6 +83,9 @@
ZonedDateTime zdt0 = cal.toZonedDateTime();
if (cal.getTimeInMillis() != zdt0.toInstant().toEpochMilli() ||
!cal.equals(GregorianCalendar.from(zdt0))) {
+ System.out.println("cal:" + cal);
+ System.out.println("zdt:" + zdt0);
+ System.out.println("calNew:" + GregorianCalendar.from(zdt0));
System.out.printf("ms: %16d ns: %10d ldt:[%s]%n", millis, nanos, ldt);
throw new RuntimeException("FAILED: gcal -> zdt -> gcal");
}
--- a/jdk/test/java/util/Collections/ReverseOrder.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/java/util/Collections/ReverseOrder.java Fri Mar 15 16:39:07 2013 -0700
@@ -23,23 +23,56 @@
/*
* @test
- * @bug 4593209
+ * @bug 4593209 8001667
* @summary Reverse comparator was subtly broken
* @author Josh bloch
*/
import java.util.*;
+import java.io.*;
public class ReverseOrder {
+ static byte[] serialBytes(Object o) {
+ try {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(bos);
+ oos.writeObject(o);
+ oos.flush();
+ oos.close();
+ return bos.toByteArray();
+ } catch (Throwable t) {
+ throw new Error(t);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ static <T> T serialClone(T o) {
+ try {
+ ObjectInputStream ois = new ObjectInputStream
+ (new ByteArrayInputStream(serialBytes(o)));
+ T clone = (T) ois.readObject();
+ return clone;
+ } catch (Throwable t) {
+ throw new Error(t);
+ }
+ }
+
public static void main(String[] args) throws Exception {
Foo[] a = { new Foo(2), new Foo(3), new Foo(1) };
List list = Arrays.asList(a);
- Collections.sort(list, Collections.reverseOrder());
+ Comparator cmp = Collections.reverseOrder();
+ Collections.sort(list, cmp);
Foo[] golden = { new Foo(3), new Foo(2), new Foo(1) };
List goldenList = Arrays.asList(golden);
if (!list.equals(goldenList))
throw new Exception(list.toString());
+
+ Comparator clone = serialClone(cmp);
+ List list2 = Arrays.asList(a);
+ Collections.sort(list2, clone);
+ if (!list2.equals(goldenList))
+ throw new Exception(list.toString());
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ComparatorsTest.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,353 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8001667
+ * @run testng ComparatorsTest
+ */
+
+import java.util.Comparator;
+import java.util.Comparators;
+import java.util.AbstractMap;
+import java.util.Map;
+import org.testng.annotations.Test;
+
+import java.util.function.Function;
+import java.util.function.ToIntFunction;
+import java.util.function.ToLongFunction;
+import java.util.function.ToDoubleFunction;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.assertSame;
+
+/**
+ * Unit tests for helper methods in Comparators
+ */
+@Test(groups = "unit")
+public class ComparatorsTest {
+ private static class Thing {
+ public final int intField;
+ public final long longField;
+ public final double doubleField;
+ public final String stringField;
+
+ private Thing(int intField, long longField, double doubleField, String stringField) {
+ this.intField = intField;
+ this.longField = longField;
+ this.doubleField = doubleField;
+ this.stringField = stringField;
+ }
+
+ public int getIntField() {
+ return intField;
+ }
+
+ public long getLongField() {
+ return longField;
+ }
+
+ public double getDoubleField() {
+ return doubleField;
+ }
+
+ public String getStringField() {
+ return stringField;
+ }
+ }
+
+ private final int[] intValues = { -2, -2, -1, -1, 0, 0, 1, 1, 2, 2 };
+ private final long[] longValues = { -2, -2, -1, -1, 0, 0, 1, 1, 2, 2 };
+ private final double[] doubleValues = { -2, -2, -1, -1, 0, 0, 1, 1, 2, 2 };
+ private final String[] stringValues = { "a", "a", "b", "b", "c", "c", "d", "d", "e", "e" };
+ private final int[] comparisons = { 0, -1, 0, -1, 0, -1, 0, -1, 0 };
+
+ private<T> void assertComparisons(T[] things, Comparator<T> comp, int[] comparisons) {
+ for (int i=0; i<comparisons.length; i++) {
+ assertEquals(comparisons.length + 1, things.length);
+ assertEquals(comparisons[i], comp.compare(things[i], things[i+1]));
+ assertEquals(-comparisons[i], comp.compare(things[i+1], things[i]));
+ }
+ }
+
+ public void testIntComparator() {
+ Thing[] things = new Thing[intValues.length];
+ for (int i=0; i<intValues.length; i++)
+ things[i] = new Thing(intValues[i], 0L, 0.0, null);
+ Comparator<Thing> comp = Comparators.comparing(new ToIntFunction<ComparatorsTest.Thing>() {
+ @Override
+ public int applyAsInt(Thing thing) {
+ return thing.getIntField();
+ }
+ });
+
+ assertComparisons(things, comp, comparisons);
+ }
+
+ public void testLongComparator() {
+ Thing[] things = new Thing[longValues.length];
+ for (int i=0; i<longValues.length; i++)
+ things[i] = new Thing(0, longValues[i], 0.0, null);
+ Comparator<Thing> comp = Comparators.comparing(new ToLongFunction<ComparatorsTest.Thing>() {
+ @Override
+ public long applyAsLong(Thing thing) {
+ return thing.getLongField();
+ }
+ });
+
+ assertComparisons(things, comp, comparisons);
+ }
+
+ public void testDoubleComparator() {
+ Thing[] things = new Thing[doubleValues.length];
+ for (int i=0; i<doubleValues.length; i++)
+ things[i] = new Thing(0, 0L, doubleValues[i], null);
+ Comparator<Thing> comp = Comparators.comparing(new ToDoubleFunction<ComparatorsTest.Thing>() {
+ @Override
+ public double applyAsDouble(Thing thing) {
+ return thing.getDoubleField();
+ }
+ });
+
+ assertComparisons(things, comp, comparisons);
+ }
+
+ public void testComparing() {
+ Thing[] things = new Thing[doubleValues.length];
+ for (int i=0; i<doubleValues.length; i++)
+ things[i] = new Thing(0, 0L, 0.0, stringValues[i]);
+ Comparator<Thing> comp = Comparators.comparing(new Function<Thing, String>() {
+ @Override
+ public String apply(Thing thing) {
+ return thing.getStringField();
+ }
+ });
+
+ assertComparisons(things, comp, comparisons);
+ }
+
+ public void testNaturalOrderComparator() {
+ Comparator<String> comp = Comparators.naturalOrder();
+
+ assertComparisons(stringValues, comp, comparisons);
+ }
+
+ public void testReverseComparator() {
+ Comparator<String> cmpr = Comparators.reverseOrder();
+ Comparator<String> cmp = cmpr.reverseOrder();
+
+ assertEquals(cmp.reverseOrder(), cmpr);
+ assertEquals(0, cmp.compare("a", "a"));
+ assertEquals(0, cmpr.compare("a", "a"));
+ assertTrue(cmp.compare("a", "b") < 0);
+ assertTrue(cmpr.compare("a", "b") > 0);
+ assertTrue(cmp.compare("b", "a") > 0);
+ assertTrue(cmpr.compare("b", "a") < 0);
+ }
+
+ public void testReverseComparator2() {
+ Comparator<String> cmp = (s1, s2) -> s1.length() - s2.length();
+ Comparator<String> cmpr = cmp.reverseOrder();
+
+ assertEquals(cmpr.reverseOrder(), cmp);
+ assertEquals(0, cmp.compare("abc", "def"));
+ assertEquals(0, cmpr.compare("abc", "def"));
+ assertTrue(cmp.compare("abcd", "def") > 0);
+ assertTrue(cmpr.compare("abcd", "def") < 0);
+ assertTrue(cmp.compare("abc", "defg") < 0);
+ assertTrue(cmpr.compare("abc", "defg") > 0);
+ }
+
+ @Test(expectedExceptions=NullPointerException.class)
+ public void testReverseComparatorNPE() {
+ Comparator<String> cmp = Comparators.reverseOrder(null);
+ }
+
+ public void testComposeComparator() {
+ // Longer string in front
+ Comparator<String> first = (s1, s2) -> s2.length() - s1.length();
+ Comparator<String> second = Comparators.naturalOrder();
+ Comparator<String> composed = Comparators.compose(first, second);
+
+ assertTrue(composed.compare("abcdefg", "abcdef") < 0);
+ assertTrue(composed.compare("abcdef", "abcdefg") > 0);
+ assertTrue(composed.compare("abcdef", "abcdef") == 0);
+ assertTrue(composed.compare("abcdef", "ghijkl") < 0);
+ assertTrue(composed.compare("ghijkl", "abcdefg") > 0);
+ }
+
+ private <K, V> void assertPairComparison(K k1, V v1, K k2, V v2,
+ Comparator<Map.Entry<K, V>> ck,
+ Comparator<Map.Entry<K, V>> cv) {
+ final Map.Entry<K, V> p11 = new AbstractMap.SimpleImmutableEntry<>(k1, v1);
+ final Map.Entry<K, V> p12 = new AbstractMap.SimpleImmutableEntry<>(k1, v2);
+ final Map.Entry<K, V> p21 = new AbstractMap.SimpleImmutableEntry<>(k2, v1);
+ final Map.Entry<K, V> p22 = new AbstractMap.SimpleImmutableEntry<>(k2, v2);
+
+ assertTrue(ck.compare(p11, p11) == 0);
+ assertTrue(ck.compare(p12, p11) == 0);
+ assertTrue(ck.compare(p11, p12) == 0);
+ assertTrue(ck.compare(p12, p22) < 0);
+ assertTrue(ck.compare(p12, p21) < 0);
+ assertTrue(ck.compare(p21, p11) > 0);
+ assertTrue(ck.compare(p21, p12) > 0);
+
+ assertTrue(cv.compare(p11, p11) == 0);
+ assertTrue(cv.compare(p12, p11) > 0);
+ assertTrue(cv.compare(p11, p12) < 0);
+ assertTrue(cv.compare(p12, p22) == 0);
+ assertTrue(cv.compare(p12, p21) > 0);
+ assertTrue(cv.compare(p21, p11) == 0);
+ assertTrue(cv.compare(p21, p12) < 0);
+
+ Comparator<Map.Entry<K, V>> cmp = Comparators.compose(ck, cv);
+ assertTrue(cmp.compare(p11, p11) == 0);
+ assertTrue(cmp.compare(p12, p11) > 0);
+ assertTrue(cmp.compare(p11, p12) < 0);
+ assertTrue(cmp.compare(p12, p22) < 0);
+ assertTrue(cmp.compare(p12, p21) < 0);
+ assertTrue(cmp.compare(p21, p11) > 0);
+ assertTrue(cmp.compare(p21, p12) > 0);
+
+ cmp = Comparators.compose(cv, ck);
+ assertTrue(cmp.compare(p11, p11) == 0);
+ assertTrue(cmp.compare(p12, p11) > 0);
+ assertTrue(cmp.compare(p11, p12) < 0);
+ assertTrue(cmp.compare(p12, p22) < 0);
+ assertTrue(cmp.compare(p12, p21) > 0);
+ assertTrue(cmp.compare(p21, p11) > 0);
+ assertTrue(cmp.compare(p21, p12) < 0);
+ }
+
+ public void testKVComparatorable() {
+ assertPairComparison(1, "ABC", 2, "XYZ",
+ Comparators.<Integer, String>naturalOrderKeys(),
+ Comparators.<Integer, String>naturalOrderValues());
+ }
+
+ private static class People {
+ final String firstName;
+ final String lastName;
+ final int age;
+
+ People(String first, String last, int age) {
+ firstName = first;
+ lastName = last;
+ this.age = age;
+ }
+
+ String getFirstName() { return firstName; }
+ String getLastName() { return lastName; }
+ int getAge() { return age; }
+ long getAgeAsLong() { return (long) age; };
+ double getAgeAsDouble() { return (double) age; };
+ }
+
+ private final People people[] = {
+ new People("John", "Doe", 34),
+ new People("Mary", "Doe", 30),
+ new People("Maria", "Doe", 14),
+ new People("Jonah", "Doe", 10),
+ new People("John", "Cook", 54),
+ new People("Mary", "Cook", 50),
+ };
+
+ public void testKVComparators() {
+ // Comparator<People> cmp = Comparators.naturalOrder(); // Should fail to compiler as People is not comparable
+ // We can use simple comparator, but those have been tested above.
+ // Thus choose to do compose for some level of interation.
+ Comparator<People> cmp1 = Comparators.comparing((Function<People, String>) People::getFirstName);
+ Comparator<People> cmp2 = Comparators.comparing((Function<People, String>) People::getLastName);
+ Comparator<People> cmp = Comparators.compose(cmp1, cmp2);
+
+ assertPairComparison(people[0], people[0], people[1], people[1],
+ Comparators.<People, People>byKey(cmp),
+ Comparators.<People, People>byValue(cmp));
+
+ }
+
+ private <T> void assertComparison(Comparator<T> cmp, T less, T greater) {
+ assertTrue(cmp.compare(less, greater) < 0, "less");
+ assertTrue(cmp.compare(less, less) == 0, "equal");
+ assertTrue(cmp.compare(greater, less) > 0, "greater");
+ }
+
+ public void testComparatorDefaultMethods() {
+ Comparator<People> cmp = Comparators.comparing((Function<People, String>) People::getFirstName);
+ Comparator<People> cmp2 = Comparators.comparing((Function<People, String>) People::getLastName);
+ // reverseOrder
+ assertComparison(cmp.reverseOrder(), people[1], people[0]);
+ // thenComparing(Comparator)
+ assertComparison(cmp.thenComparing(cmp2), people[0], people[1]);
+ assertComparison(cmp.thenComparing(cmp2), people[4], people[0]);
+ // thenComparing(Function)
+ assertComparison(cmp.thenComparing(People::getLastName), people[0], people[1]);
+ assertComparison(cmp.thenComparing(People::getLastName), people[4], people[0]);
+ // thenComparing(ToIntFunction)
+ assertComparison(cmp.thenComparing(People::getAge), people[0], people[1]);
+ assertComparison(cmp.thenComparing(People::getAge), people[1], people[5]);
+ // thenComparing(ToLongFunction)
+ assertComparison(cmp.thenComparing(People::getAgeAsLong), people[0], people[1]);
+ assertComparison(cmp.thenComparing(People::getAgeAsLong), people[1], people[5]);
+ // thenComparing(ToDoubleFunction)
+ assertComparison(cmp.thenComparing(People::getAgeAsDouble), people[0], people[1]);
+ assertComparison(cmp.thenComparing(People::getAgeAsDouble), people[1], people[5]);
+ }
+
+ public void testGreaterOf() {
+ // lesser
+ assertSame(Comparators.greaterOf(Comparators.comparing(
+ (Function<People, String>) People::getFirstName))
+ .apply(people[0], people[1]),
+ people[1]);
+ // euqal
+ assertSame(Comparators.greaterOf(Comparators.comparing(
+ (Function<People, String>) People::getLastName))
+ .apply(people[0], people[1]),
+ people[0]);
+ // greater
+ assertSame(Comparators.greaterOf(Comparators.comparing(
+ (ToIntFunction<People>) People::getAge))
+ .apply(people[0], people[1]),
+ people[0]);
+ }
+
+ public void testLesserOf() {
+ // lesser
+ assertSame(Comparators.lesserOf(Comparators.comparing(
+ (Function<People, String>) People::getFirstName))
+ .apply(people[0], people[1]),
+ people[0]);
+ // euqal
+ assertSame(Comparators.lesserOf(Comparators.comparing(
+ (Function<People, String>) People::getLastName))
+ .apply(people[0], people[1]),
+ people[0]);
+ // greater
+ assertSame(Comparators.lesserOf(Comparators.comparing(
+ (ToIntFunction<People>) People::getAge))
+ .apply(people[0], people[1]),
+ people[1]);
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/Locale/Bug8004240.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8004240
+ * @summary Verify that getAdapterPreference returns an unmodifiable list.
+ * @compile -XDignore.symbol.file Bug8004240.java
+ * @run main Bug8004240
+ */
+
+import java.util.List;
+import sun.util.locale.provider.LocaleProviderAdapter;
+
+public class Bug8004240 {
+
+ public static void main(String[] args) {
+ List<LocaleProviderAdapter.Type> types = LocaleProviderAdapter.getAdapterPreference();
+
+ try {
+ types.set(0, null);
+ } catch (UnsupportedOperationException e) {
+ // success
+ return;
+ }
+
+ throw new RuntimeException("LocaleProviderAdapter.getAdapterPrefence() returned a modifiable list.");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/Map/ToArray.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8008785
+ * @summary Ensure toArray() implementations return correct results.
+ * @author Mike Duigou
+ */
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentSkipListMap;
+
+public class ToArray {
+
+ /**
+ * Number of elements per map.
+ */
+ private static final int TEST_SIZE = 5000;
+
+ private static void realMain(String[] args) throws Throwable {
+ Map<Integer, Long>[] maps = (Map<Integer, Long>[]) new Map[]{
+ new HashMap<>(),
+ new Hashtable<>(),
+ new IdentityHashMap<>(),
+ new LinkedHashMap<>(),
+ new TreeMap<>(),
+ new WeakHashMap<>(),
+ new ConcurrentHashMap<>(),
+ new ConcurrentSkipListMap<>()
+ };
+
+ // for each map type.
+ for (Map<Integer, Long> map : maps) {
+ try {
+ testMap(map);
+ } catch(Exception all) {
+ unexpected("Failed for " + map.getClass().getName(), all);
+ }
+ }
+ }
+
+ private static final Integer[] KEYS = new Integer[TEST_SIZE];
+
+ private static final Long[] VALUES = new Long[TEST_SIZE];
+
+ static {
+ for (int each = 0; each < TEST_SIZE; each++) {
+ KEYS[each] = Integer.valueOf(each);
+ VALUES[each] = Long.valueOf(each + TEST_SIZE);
+ }
+ }
+
+
+ private static void testMap(Map<Integer, Long> map) {
+ System.out.println("Testing " + map.getClass());
+ System.out.flush();
+
+ // Fill the map
+ for (int each = 0; each < TEST_SIZE; each++) {
+ map.put(KEYS[each], VALUES[each]);
+ }
+
+ // check the keys
+ Object[] keys = map.keySet().toArray();
+ Arrays.sort(keys);
+
+ for(int each = 0; each < TEST_SIZE; each++) {
+ check( "unexpected key", keys[each] == KEYS[each]);
+ }
+
+ // check the values
+ Object[] values = map.values().toArray();
+ Arrays.sort(values);
+
+ for(int each = 0; each < TEST_SIZE; each++) {
+ check( "unexpected value", values[each] == VALUES[each]);
+ }
+
+ // check the entries
+ Map.Entry<Integer,Long>[] entries = map.entrySet().toArray(new Map.Entry[TEST_SIZE]);
+ Arrays.sort( entries,new Comparator<Map.Entry<Integer,Long>>() {
+ public int compare(Map.Entry<Integer,Long> o1, Map.Entry<Integer,Long> o2) {
+ return o1.getKey().compareTo(o2.getKey());
+ }});
+
+ for(int each = 0; each < TEST_SIZE; each++) {
+ check( "unexpected entry", entries[each].getKey() == KEYS[each] && entries[each].getValue() == VALUES[each]);
+ }
+ }
+
+ //--------------------- Infrastructure ---------------------------
+ static volatile int passed = 0, failed = 0;
+
+ static void pass() {
+ passed++;
+ }
+
+ static void fail() {
+ failed++;
+ (new Error("Failure")).printStackTrace(System.err);
+ }
+
+ static void fail(String msg) {
+ failed++;
+ (new Error("Failure: " + msg)).printStackTrace(System.err);
+ }
+
+ static void abort() {
+ fail();
+ System.exit(1);
+ }
+
+ static void abort(String msg) {
+ fail(msg);
+ System.exit(1);
+ }
+
+ static void unexpected(String msg, Throwable t) {
+ System.err.println("Unexpected: " + msg);
+ unexpected(t);
+ }
+
+ static void unexpected(Throwable t) {
+ failed++;
+ t.printStackTrace(System.err);
+ }
+
+ static void check(boolean cond) {
+ if (cond) {
+ pass();
+ } else {
+ fail();
+ }
+ }
+
+ static void check(String desc, boolean cond) {
+ if (cond) {
+ pass();
+ } else {
+ fail(desc);
+ }
+ }
+
+ static void equal(Object x, Object y) {
+ if (Objects.equals(x, y)) {
+ pass();
+ } else {
+ fail(x + " not equal to " + y);
+ }
+ }
+
+ public static void main(String[] args) throws Throwable {
+ Thread.currentThread().setName(ToArray.class.getName());
+// Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
+ try {
+ realMain(args);
+ } catch (Throwable t) {
+ unexpected(t);
+ }
+
+ System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+ if (failed > 0) {
+ throw new Error("Some tests failed");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/concurrent/forkjoin/ThreadLessCommon.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,135 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+/*
+ * @test
+ * @bug 8008378
+ * @summary Basic checks for parallelism 0, and null returning factory
+ * @run main/othervm -Djava.util.concurrent.ForkJoinPool.common.parallelism=0 ThreadLessCommon
+ * @run main/othervm -Djava.util.concurrent.ForkJoinPool.common.threadFactory=ThreadLessCommon$NullForkJoinWorkerThreadFactory ThreadLessCommon
+ * @author Chris Hegarty
+ */
+
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory;
+import java.util.concurrent.ForkJoinWorkerThread;
+import java.util.concurrent.RecursiveTask;
+
+public class ThreadLessCommon {
+
+ static final int THRESHOLD = 1000;
+ static final boolean debug = true;
+
+ private static void realMain(String[] args) throws Throwable {
+ if (debug) {
+ String pp = System.getProperty(
+ "java.util.concurrent.ForkJoinPool.common.parallelism");
+ System.out.println(
+ "java.util.concurrent.ForkJoinPool.common.parallelism:" + pp);
+ String tf = System.getProperty(
+ "java.util.concurrent.ForkJoinPool.common.threadFactory");
+ System.out.println(
+ "java.util.concurrent.ForkJoinPool.common.threadFactory:" + tf);
+ }
+
+ long from = 0, to = 50000;
+ RecursiveTask<Long> task = new SumTask(from, to, Thread.currentThread());
+ long sum = task.invoke();
+ System.out.printf("%nSum: from [%d] to [%d] = [%d]%n", from, to, sum);
+
+ task.fork();
+ sum = task.join();
+ System.out.printf("%nSum: from [%d] to [%d] = [%d]%n", from, to, sum);
+
+ sum = ForkJoinPool.commonPool().invoke(task.fork());
+ System.out.printf("%nSum: from [%d] to [%d] = [%d]%n", from, to, sum);
+ }
+
+ static class SumTask extends RecursiveTask<Long> {
+ final Thread expectedThread;
+ final long from;
+ final long to;
+ SumTask(long from, long to, Thread thread) {
+ this.from = from; this.to = to; expectedThread = thread;
+ }
+
+ @Override
+ public Long compute() {
+ check(Thread.currentThread() == expectedThread,
+ "Expected " + expectedThread + ", got " + Thread.currentThread());
+ long range = to - from;
+ if (range < THRESHOLD) {
+ long acc = 0;
+ for (long i = from; i <= to; i++)
+ acc = acc + i;
+ return acc;
+ } else {
+ long half = from + range / 2;
+ SumTask t1 = new SumTask(from, half ,expectedThread);
+ SumTask t2 = new SumTask(half+1, to ,expectedThread);
+ if (half % 2 == 0) {
+ t1.fork();
+ return t2.compute() + t1.join();
+ } else {
+ invokeAll(t1, t2);
+ try { return t1.get() + t2.get(); }
+ catch (Exception x) { unexpected(x); return 0L;}
+ }
+ }
+ }
+ }
+
+ public static class NullForkJoinWorkerThreadFactory
+ implements ForkJoinWorkerThreadFactory
+ {
+ @Override
+ public ForkJoinWorkerThread newThread(ForkJoinPool pool) {
+ return null;
+ }
+ }
+
+ //--------------------- Infrastructure ---------------------------
+ static volatile int passed = 0, failed = 0;
+ static void pass() {passed++;}
+ static void fail() {failed++; /*Thread.dumpStack();*/}
+ static void fail(String msg) {System.out.println(msg); fail();}
+ static void unexpected(Throwable t) {failed++; t.printStackTrace();}
+ static void check(boolean cond, String msg) {if (cond) pass(); else fail(msg);}
+ static void equal(Object x, Object y) {
+ if (x == null ? y == null : x.equals(y)) pass();
+ else fail(x + " not equal to " + y);}
+ public static void main(String[] args) throws Throwable {
+ try {realMain(args);} catch (Throwable t) {unexpected(t);}
+ System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+ if (failed > 0) throw new AssertionError("Some tests failed");}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/concurrent/forkjoin/ThrowingRunnable.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,85 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+/*
+ * @test
+ * @bug 8008378
+ * @run main/othervm -Djava.util.concurrent.ForkJoinPool.common.exceptionHandler=ThrowingRunnable
+ * ThrowingRunnable
+ * @summary FJP.execute(Runnable), uncaught exception should cause worker thread
+ * to die.
+ * @author Chris Hegarty
+ */
+
+import java.lang.Thread.UncaughtExceptionHandler;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.Phaser;
+import java.util.concurrent.TimeUnit;
+
+public class ThrowingRunnable implements Runnable, UncaughtExceptionHandler {
+
+ static final Phaser phaser = new Phaser(2);
+
+ private static void realMain(String[] args) throws Throwable {
+ ThrowingRunnable r = new ThrowingRunnable();
+ ForkJoinPool.commonPool().execute(r);
+ phaser.awaitAdvanceInterruptibly(phaser.arrive(), 10, TimeUnit.SECONDS);
+ pass();
+ }
+
+ @Override
+ public void run() {
+ throw new RuntimeException("This is an exception.");
+ }
+
+ @Override
+ public void uncaughtException(Thread t, Throwable e) {
+ pass();
+ phaser.arrive();
+ }
+
+ //--------------------- Infrastructure ---------------------------
+ static volatile int passed = 0, failed = 0;
+ static void pass() {passed++;}
+ static void fail() {failed++; /*Thread.dumpStack();*/}
+ static void fail(String msg) {System.out.println(msg); fail();}
+ static void unexpected(Throwable t) {failed++; t.printStackTrace();}
+ static void check(boolean cond, String msg) {if (cond) pass(); else fail(msg);}
+ static void equal(Object x, Object y) {
+ if (x == null ? y == null : x.equals(y)) pass();
+ else fail(x + " not equal to " + y);}
+ public static void main(String[] args) throws Throwable {
+ try {realMain(args);} catch (Throwable t) {unexpected(t);}
+ System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+ if (failed > 0) throw new AssertionError("Some tests failed");}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/logging/CustomLogManager.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.*;
+import java.util.*;
+import java.util.logging.*;
+
+/*
+ * Custom LogManager implementation to verify that the implementation delegates
+ * to the LogManager subclass to register both system logger and user logger.
+ *
+ * The LogManager implementation is the one configuring the logger's property
+ * such as level, handler, etc.
+ */
+public class CustomLogManager extends LogManager {
+ static LogManager INSTANCE;
+ Map<String,Logger> namedLoggers = new HashMap<>();
+ Properties props = initConfig();
+ public CustomLogManager() {
+ if (INSTANCE != null) {
+ throw new RuntimeException("CustomLogManager already created");
+ }
+ INSTANCE = this;
+ }
+
+ public synchronized boolean addLogger(Logger logger) {
+ String name = logger.getName();
+ if (namedLoggers.containsKey(name)) {
+ return false;
+ }
+ namedLoggers.put(name, logger);
+ // set level
+ if (props.get(name + ".level") != null) {
+ logger.setLevel(Level.parse(props.getProperty(name + ".level")));
+ }
+ // add handlers
+ if (props.get(name + ".handlers") != null && logger.getHandlers().length == 0) {
+ logger.addHandler(new CustomHandler());
+ }
+ // add parent loggers
+ int ix = 1;
+ for (;;) {
+ int ix2 = name.indexOf(".", ix);
+ if (ix2 < 0) {
+ break;
+ }
+ String pname = name.substring(0, ix2);
+ if (props.get(pname + ".level") != null ||
+ props.get(pname + ".handlers") != null) {
+ // This pname has a level/handlers definition.
+ // Make sure it exists.
+ //
+ // The test doesn't set the parent for simplicity.
+ if (!namedLoggers.containsKey(pname)) {
+ Logger.getLogger(pname);
+ }
+ }
+ ix = ix2 + 1;
+ }
+ return true;
+ }
+
+ public synchronized Logger getLogger(String name) {
+ return namedLoggers.get(name);
+ }
+
+ public synchronized Enumeration<String> getLoggerNames() {
+ return Collections.enumeration(namedLoggers.keySet());
+ }
+
+ public String getProperty(String name) {
+ return props.getProperty(name);
+ }
+
+ public void readConfiguration() {
+ // do nothing
+ }
+
+ public void readConfiguration(InputStream ins) {
+ // do nothing
+ }
+
+ private Properties initConfig() {
+ Properties props = new Properties();
+ props.put(".level", "CONFIG");
+ props.put("CustomLogManagerTest.level", "WARNING");
+ props.put("CustomLogManagerTest.handlers", "CustomLogManager$CustomHandler");
+ props.put("SimpleLogManager.level", "INFO");
+ props.put("SimpleLogManager.handlers", "CustomLogManager$CustomHandler");
+ props.put("CustomLogManager$CustomHandler.level", "WARNING");
+ props.put(".handlers", "CustomLogManager$CustomHandler");
+ props.put("org.foo.bar.level", "SEVERE");
+ props.put("org.foo.handlers", "CustomLogManager$CustomHandler");
+ props.put("org.openjdk.level", "SEVERE");
+ props.put("org.openjdk.handlers", "CustomLogManager$CustomHandler");
+ props.put("org.openjdk.core.level", "INFO");
+
+ return props;
+ }
+
+ public static void checkLogger(String name) {
+ checkLogger(name, null);
+ }
+
+ public static void checkLogger(String name, String resourceBundleName) {
+ Logger logger = INSTANCE.getLogger(name);
+ if (logger == null) {
+ throw new RuntimeException("Logger \"" + name + "\" not exist");
+ }
+ System.out.format("Logger \"%s\" level=%s handlers=%s resourcebundle=%s%n",
+ name, logger.getLevel(),
+ Arrays.toString(logger.getHandlers()),
+ logger.getResourceBundleName());
+ String rb = logger.getResourceBundleName();
+ if (rb != resourceBundleName && (rb == null || rb.equals(resourceBundleName))) {
+ throw new RuntimeException("Logger \"" + name +
+ "\" unexpected resource bundle: " + rb);
+ }
+
+ String value = INSTANCE.getProperty(name + ".level");
+ String level = logger.getLevel() != null ? logger.getLevel().getName() : null;
+ if (level != value && (level == null || level.equals(value))) {
+ throw new RuntimeException("Logger \"" + name + "\" unexpected level: " + level);
+ }
+
+ Handler[] handlers = logger.getHandlers();
+ String hdl = INSTANCE.getProperty(name + ".handlers");
+ if ((hdl == null && handlers.length != 0) ||
+ (hdl != null && handlers.length != 1)) {
+ throw new RuntimeException("Logger \"" + name + "\" unexpected handler: " +
+ Arrays.toString(handlers));
+ }
+ checkParents(name);
+ }
+
+ private static void checkParents(String name) {
+ int ix = 1;
+ for (;;) {
+ int ix2 = name.indexOf(".", ix);
+ if (ix2 < 0) {
+ break;
+ }
+ String pname = name.substring(0, ix2);
+ if (INSTANCE.getProperty(pname + ".level") != null ||
+ INSTANCE.getProperty(pname + ".handlers") != null) {
+ // This pname has a level/handlers definition.
+ // Make sure it exists.
+ checkLogger(pname);
+ }
+ ix = ix2 + 1;
+ }
+ }
+
+ // only CustomLogManager can create an instance of CustomHandler
+ private class CustomHandler extends StreamHandler {
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/logging/CustomLogManagerTest.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.*;
+import java.util.*;
+
+import java.util.logging.*;
+import sun.util.logging.PlatformLogger;
+
+/*
+ * @test
+ * @bug 8005615
+ * @summary Add loggers to custom log manager
+ *
+ * @compile -XDignore.symbol.file CustomLogManagerTest.java CustomLogManager.java
+ * @run main/othervm -Djava.util.logging.manager=CustomLogManager CustomLogManagerTest
+ */
+public class CustomLogManagerTest {
+ private static final String RESOURCE_BUNDLE = "sun.util.logging.resources.logging";
+ public static void main(String[] args) {
+ String mgr = System.getProperty("java.util.logging.manager");
+ if (!mgr.equals("CustomLogManager")) {
+ throw new RuntimeException("java.util.logging.manager not set");
+ }
+
+ Logger.getLogger(CustomLogManagerTest.class.getName());
+ Logger.getLogger("org.foo.Foo");
+ Logger.getLogger("org.foo.bar.Foo", RESOURCE_BUNDLE);
+ // platform logger will be set with the default system resource bundle
+ PlatformLogger.getLogger("org.openjdk.core.logger");
+
+ if (LogManager.getLogManager() != CustomLogManager.INSTANCE) {
+ throw new RuntimeException(LogManager.getLogManager() + " not CustomLogManager");
+ }
+
+ CustomLogManager.checkLogger(CustomLogManagerTest.class.getName());
+ CustomLogManager.checkLogger("org.foo.Foo");
+ CustomLogManager.checkLogger("org.foo.bar.Foo", RESOURCE_BUNDLE);
+ CustomLogManager.checkLogger(Logger.GLOBAL_LOGGER_NAME);
+ CustomLogManager.checkLogger("");
+ CustomLogManager.checkLogger("org.openjdk.core.logger", RESOURCE_BUNDLE);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/logging/SimpleLogManager.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.*;
+import java.util.logging.*;
+import sun.util.logging.PlatformLogger;
+
+/*
+ * @test
+ * @bug 8005615
+ * @summary A LogManager subclass overrides its own implementation of named
+ * logger (see the subclassing information in the Logger class specification)
+ *
+ * @compile -XDignore.symbol.file CustomLogManager.java SimpleLogManager.java
+ * @run main/othervm -Djava.util.logging.manager=SimpleLogManager SimpleLogManager
+ */
+public class SimpleLogManager extends CustomLogManager {
+ public static void main(String[] args) {
+ String classname = System.getProperty("java.util.logging.manager");
+ if (!classname.equals("SimpleLogManager")) {
+ throw new RuntimeException("java.util.logging.manager not set");
+ }
+
+ Logger logger = Logger.getLogger(SimpleLogManager.class.getName());
+ Logger.getLogger("org.foo.bar.Foo");
+
+ // a platform logger used by the system code is just a Logger instance.
+ PlatformLogger.getLogger("org.openjdk.core.logger");
+
+ LogManager mgr = LogManager.getLogManager();
+ if (mgr != CustomLogManager.INSTANCE || !(mgr instanceof SimpleLogManager)) {
+ throw new RuntimeException(LogManager.getLogManager() + " not SimpleLogManager");
+ }
+
+ checkCustomLogger(SimpleLogManager.class.getName(), null);
+ checkCustomLogger("org.foo.bar.Foo", null);
+ checkCustomLogger("org.openjdk.core.logger", "sun.util.logging.resources.logging");
+
+ // ## The LogManager.demandLogger method does not handle custom log manager
+ // ## that overrides the getLogger method to return a custom logger
+ // ## (see the test case in 8005640). Logger.getLogger may return
+ // ## a Logger instance but LogManager overrides it with a custom Logger
+ // ## instance like this case.
+ //
+ // However, the specification of LogManager and Logger subclassing is
+ // not clear whether this is supported or not. The following check
+ // just captures the current behavior.
+ if (logger instanceof CustomLogger) {
+ throw new RuntimeException(logger + " not CustomLogger");
+ }
+ }
+
+ private static void checkCustomLogger(String name, String resourceBundleName) {
+ CustomLogManager.checkLogger(name, resourceBundleName);
+ Logger logger1 = Logger.getLogger(name);
+ Logger logger2 = LogManager.getLogManager().getLogger(name);
+ if (logger1 != logger2) {
+ throw new RuntimeException(logger1 + " != " + logger2);
+ }
+ if (!(logger1 instanceof CustomLogger)) {
+ throw new RuntimeException(logger1 + " not CustomLogger");
+ }
+ }
+
+ /*
+ * This SimpleLogManager overrides the addLogger method to replace
+ * the given logger with a custom logger.
+ *
+ * It's unclear what the recommended way to use custom logger is.
+ * A LogManager subclass might override the getLogger method to return
+ * a custom Logger and create a new custom logger if not exist so that
+ * Logger.getLogger() can return a custom Logger instance but that violates
+ * the LogManager.getLogger() spec which should return null if not found.
+ */
+ public synchronized boolean addLogger(Logger logger) {
+ String name = logger.getName();
+ if (namedLoggers.containsKey(name)) {
+ return false;
+ }
+ CustomLogger newLogger = new CustomLogger(logger);
+ super.addLogger(newLogger);
+ return true;
+ }
+
+ public class CustomLogger extends Logger {
+ CustomLogger(Logger logger) {
+ super(logger.getName(), logger.getResourceBundleName());
+ }
+ CustomLogger(String name) {
+ super(name, null);
+ }
+ }
+}
--- a/jdk/test/javax/management/remote/mandatory/subjectDelegation/SubjectDelegation2Test.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/javax/management/remote/mandatory/subjectDelegation/SubjectDelegation2Test.java Fri Mar 15 16:39:07 2013 -0700
@@ -119,9 +119,6 @@
System.out.println("Create SimpleStandard MBean");
SimpleStandard s = new SimpleStandard("monitorRole");
mbs.registerMBean(s, new ObjectName("MBeans:type=SimpleStandard"));
- // Set Security Manager
- //
- System.setSecurityManager(new SecurityManager());
// Create Properties containing the username/password entries
//
Properties props = new Properties();
@@ -132,6 +129,9 @@
HashMap env = new HashMap();
env.put("jmx.remote.authenticator",
new JMXPluggableAuthenticator(props));
+ // Set Security Manager
+ //
+ System.setSecurityManager(new SecurityManager());
// Create an RMI connector server
//
System.out.println("Create an RMI connector server");
--- a/jdk/test/javax/management/remote/mandatory/subjectDelegation/SubjectDelegation3Test.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/javax/management/remote/mandatory/subjectDelegation/SubjectDelegation3Test.java Fri Mar 15 16:39:07 2013 -0700
@@ -120,9 +120,6 @@
System.out.println("Create SimpleStandard MBean");
SimpleStandard s = new SimpleStandard("delegate");
mbs.registerMBean(s, new ObjectName("MBeans:type=SimpleStandard"));
- // Set Security Manager
- //
- System.setSecurityManager(new SecurityManager());
// Create Properties containing the username/password entries
//
Properties props = new Properties();
@@ -133,6 +130,9 @@
HashMap env = new HashMap();
env.put("jmx.remote.authenticator",
new JMXPluggableAuthenticator(props));
+ // Set Security Manager
+ //
+ System.setSecurityManager(new SecurityManager());
// Create an RMI connector server
//
System.out.println("Create an RMI connector server");
--- a/jdk/test/javax/script/CauseExceptionTest.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/javax/script/CauseExceptionTest.java Fri Mar 15 16:39:07 2013 -0700
@@ -24,7 +24,7 @@
/*
* @test
* @bug 6869617
- * @summary RhinoScriptEngine bug : ScriptException cause not set (with fix)
+ * @summary ScriptEngine bug : ScriptException cause not set (with fix)
*/
import javax.script.*;
@@ -33,12 +33,12 @@
public class CauseExceptionTest {
public static void main(String[] args) throws ScriptException, NoSuchMethodException {
ScriptEngineManager sem = new ScriptEngineManager();
- ScriptEngine engine = sem.getEngineByName("js");
+ ScriptEngine engine = sem.getEngineByName("nashorn");
if (engine == null) {
System.out.println("Warning: No js engine found; test vacuously passes.");
return;
}
- engine.eval("function hello_world() { println('hello world'); throw 'out of here'; } ");
+ engine.eval("function hello_world() { print('hello world'); throw 'out of here'; } ");
Invocable invocable = (Invocable) engine;
try {
invocable.invokeFunction("hello_world", (Object[])null);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/script/ExceptionTest.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2006, 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6474943 6705893
+ * @summary Test that script engine exception messages are
+ * available from ScriptException.
+ */
+
+import java.io.*;
+import javax.script.*;
+
+public class ExceptionTest {
+ private static final String ERROR_MSG = "error from JavaScript";
+
+ public static void main(String[] args) throws Exception {
+ ScriptEngineManager m = new ScriptEngineManager();
+ ScriptEngine engine = Helper.getJsEngine(m);
+ if (engine == null) {
+ System.out.println("Warning: No js engine found; test vacuously passes.");
+ return;
+ }
+ engine.put("msg", ERROR_MSG);
+ try {
+ engine.eval("throw new Error(msg);");
+ } catch (ScriptException exp) {
+ if (exp.getMessage().indexOf(ERROR_MSG) == -1) {
+ throw exp;
+ }
+ }
+ try {
+ engine.eval("throw (msg);");
+ } catch (ScriptException exp) {
+ if (exp.getMessage().indexOf(ERROR_MSG) == -1) {
+ throw exp;
+ }
+ }
+ try {
+ CompiledScript scr = ((Compilable)engine).compile("throw new Error(msg);");
+ scr.eval();
+ } catch (ScriptException exp) {
+ if (exp.getMessage().indexOf(ERROR_MSG) == -1) {
+ throw exp;
+ }
+ }
+ try {
+ CompiledScript scr = ((Compilable)engine).compile("throw msg;");
+ scr.eval();
+ } catch (ScriptException exp) {
+ if (exp.getMessage().indexOf(ERROR_MSG) == -1) {
+ throw exp;
+ }
+ }
+ }
+}
--- a/jdk/test/javax/script/GetInterfaceTest.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/javax/script/GetInterfaceTest.java Fri Mar 15 16:39:07 2013 -0700
@@ -22,6 +22,7 @@
*/
/*
+ * @run ignore
* @test
* @bug 6960211
* @summary JavaScript engine allows creation of interface although methods not available.
@@ -32,10 +33,10 @@
public class GetInterfaceTest {
public static void main(String[] args) throws Exception {
ScriptEngineManager manager = new ScriptEngineManager();
- ScriptEngine engine = manager.getEngineByName("js");
+ ScriptEngine engine = manager.getEngineByName("nashorn");
if (engine == null) {
- System.out.println("Warning: No engine engine found; test vacuously passes.");
+ System.out.println("Warning: No js engine engine found; test vacuously passes.");
return;
}
--- a/jdk/test/javax/script/Helper.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/javax/script/Helper.java Fri Mar 15 16:39:07 2013 -0700
@@ -24,13 +24,13 @@
/**
* Helper class to consolidate testing requirements for a js engine.
- * A js engine is required as part of Sun's product JDK.
+ * A js engine is required as part of Oracle's product JDK.
*/
public class Helper {
private Helper() {}; // Don't instantiate
public static ScriptEngine getJsEngine(ScriptEngineManager m) {
- ScriptEngine e = m.getEngineByName("js");
+ ScriptEngine e = m.getEngineByName("nashorn");
if (e == null &&
System.getProperty("java.runtime.name").startsWith("Java(TM)")) {
// A js engine is requied for Sun's product JDK
--- a/jdk/test/javax/script/RhinoExceptionTest.java Fri Mar 15 17:02:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2006, 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @bug 6474943 6705893
- * @summary Test that Rhino exception messages are
- * available from ScriptException.
- */
-
-import java.io.*;
-import javax.script.*;
-
-public class RhinoExceptionTest {
- private static final String ERROR_MSG = "error from JavaScript";
-
- public static void main(String[] args) throws Exception {
- ScriptEngineManager m = new ScriptEngineManager();
- ScriptEngine engine = Helper.getJsEngine(m);
- if (engine == null) {
- System.out.println("Warning: No js engine found; test vacuously passes.");
- return;
- }
- engine.put("msg", ERROR_MSG);
- try {
- engine.eval("throw new Error(msg);");
- } catch (ScriptException exp) {
- if (exp.getMessage().indexOf(ERROR_MSG) == -1) {
- throw exp;
- }
- }
- try {
- engine.eval("throw (msg);");
- } catch (ScriptException exp) {
- if (exp.getMessage().indexOf(ERROR_MSG) == -1) {
- throw exp;
- }
- }
- try {
- CompiledScript scr = ((Compilable)engine).compile("throw new Error(msg);");
- scr.eval();
- } catch (ScriptException exp) {
- if (exp.getMessage().indexOf(ERROR_MSG) == -1) {
- throw exp;
- }
- }
- try {
- CompiledScript scr = ((Compilable)engine).compile("throw msg;");
- scr.eval();
- } catch (ScriptException exp) {
- if (exp.getMessage().indexOf(ERROR_MSG) == -1) {
- throw exp;
- }
- }
- }
-}
--- a/jdk/test/javax/script/StringWriterPrintTest.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/javax/script/StringWriterPrintTest.java Fri Mar 15 16:39:07 2013 -0700
@@ -33,9 +33,9 @@
public class StringWriterPrintTest {
public static void main(String[] args) throws ScriptException {
ScriptEngineManager sem = new ScriptEngineManager();
- ScriptEngine engine = sem.getEngineByName("js");
+ ScriptEngine engine = sem.getEngineByName("nashorn");
if (engine == null) {
- System.out.println("Warning: No js engine found; test vacuously passes.");
+ System.out.println("Warning: No nashorn engine found; test vacuously passes.");
return;
}
StringWriter sw = new StringWriter();
--- a/jdk/test/javax/script/Test3.js Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/javax/script/Test3.js Fri Mar 15 16:39:07 2013 -0700
@@ -1,22 +1,24 @@
+var ScriptContext = javax.script.ScriptContext;
+
if (key == undefined || key != 'engine value') {
throw "unexpected engine scope value";
}
// pre-defined context variable refers to current ScriptContext
-if (context.getAttribute('key', context.GLOBAL_SCOPE) != 'global value') {
+if (context.getAttribute('key', ScriptContext.GLOBAL_SCOPE) != 'global value') {
throw "unexpected global scope value";
}
// change the engine scope value
key = 'new engine value';
-if (context.getAttribute('key', context.GLOBAL_SCOPE) != 'global value') {
+if (context.getAttribute('key', ScriptContext.GLOBAL_SCOPE) != 'global value') {
throw "global scope should not change here";
}
// delete engine scope value
delete key;
-if (key == undefined && key != 'xglobal value') {
+if (key == undefined && key != 'global value') {
throw 'global scope should be visible after engine scope removal';
}
--- a/jdk/test/javax/script/Test5.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/javax/script/Test5.java Fri Mar 15 16:39:07 2013 -0700
@@ -48,16 +48,24 @@
System.out.println("engine scope only");
e.put("count", new Integer(1));
- Reader reader = new FileReader(
- new File(System.getProperty("test.src", "."), "Test5.js"));
- engine.eval(reader,ctxt);
+ try (Reader reader = new FileReader(
+ new File(System.getProperty("test.src", "."), "Test5.js"))) {
+ engine.eval(reader,ctxt);
+ }
+
System.out.println("both scopes");
ctxt.setBindings(g, ScriptContext.GLOBAL_SCOPE);
e.put("count", new Integer(2));
- engine.eval(reader,ctxt);
+ try (Reader reader = new FileReader(
+ new File(System.getProperty("test.src", "."), "Test5.js"))) {
+ engine.eval(reader,ctxt);
+ }
System.out.println("only global");
e.put("count", new Integer(3));
- ctxt.setAttribute("key", null, ScriptContext.ENGINE_SCOPE);
- engine.eval(reader,ctxt);
+ ctxt.removeAttribute("key", ScriptContext.ENGINE_SCOPE);
+ try (Reader reader = new FileReader(
+ new File(System.getProperty("test.src", "."), "Test5.js"))) {
+ engine.eval(reader,ctxt);
+ }
}
}
--- a/jdk/test/javax/script/Test5.js Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/javax/script/Test5.js Fri Mar 15 16:39:07 2013 -0700
@@ -1,6 +1,5 @@
-var key;
-var count;
+var ScriptContext = javax.script.ScriptContext;
print(count);
switch (count) {
@@ -9,7 +8,7 @@
if (key != 'value in engine') {
throw "unexpected engine scope value";
}
- if (context.getAttribute("key", context.GLOBAL_SCOPE ) != null) {
+ if (context.getAttribute("key", ScriptContext.GLOBAL_SCOPE ) != null) {
throw "unexpected global scope value";
}
break;
@@ -19,7 +18,7 @@
if (key != 'value in engine') {
throw "unexpected engine scope value";
}
- if (context.getAttribute("key", context.GLOBAL_SCOPE ) !=
+ if (context.getAttribute("key", ScriptContext.GLOBAL_SCOPE ) !=
"value in global") {
throw "unexpected global scope value";
}
@@ -30,7 +29,7 @@
if (key != 'value in global') {
throw "unexpected global scope value";
}
- if (context.getAttribute("key", context.GLOBAL_SCOPE ) !=
+ if (context.getAttribute("key", ScriptContext.GLOBAL_SCOPE ) !=
"value in global") {
throw "unexpected global scope value";
}
--- a/jdk/test/javax/script/Test6.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/javax/script/Test6.java Fri Mar 15 16:39:07 2013 -0700
@@ -40,11 +40,23 @@
System.out.println("Warning: No js engine found; test vacuously passes.");
return;
}
- Reader reader = new FileReader(
- new File(System.getProperty("test.src", "."), "Test6.js"));
- engine.eval(reader);
+
+ try (Reader reader = new FileReader(
+ new File(System.getProperty("test.src", "."), "Test6.js"))) {
+ engine.eval(reader);
+ }
Object res = engine.get("res");
- CompiledScript scr = ((Compilable)engine).compile(reader);
+
+ CompiledScript scr = null;
+ try (Reader reader = new FileReader(
+ new File(System.getProperty("test.src", "."), "Test6.js"))) {
+ scr = ((Compilable)engine).compile(reader);
+ }
+
+ if (scr == null) {
+ throw new RuntimeException("compilation failed!");
+ }
+
scr.eval();
Object res1 = engine.get("res");
if (! res.equals(res1)) {
--- a/jdk/test/javax/script/Test7.js Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/javax/script/Test7.js Fri Mar 15 16:39:07 2013 -0700
@@ -1,9 +1,14 @@
//this is the first line of Test7.js
var filename;
+try {
+ load("nashorn:mozilla_compat.js");
+} catch (e) {
+ //ignored
+}
importPackage(java.io);
importPackage(java);
var f = new File(filename);
var r = new BufferedReader(new InputStreamReader(new FileInputStream(f)));
-var firstLine = r.readLine() + '';
+var firstLine = r.readLine();
print(firstLine);
--- a/jdk/test/javax/script/UnescapedBracketRegExTest.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/javax/script/UnescapedBracketRegExTest.java Fri Mar 15 16:39:07 2013 -0700
@@ -24,7 +24,7 @@
/*
* @test
* @bug 7012701
- * @summary 7012701 Add a test to check that Rhino's RegExp parser accepts unescaped '['
+ * @summary 7012701 Add a test to check that RegExp parser accepts unescaped '['
*/
import javax.script.*;
@@ -33,9 +33,9 @@
public class UnescapedBracketRegExTest {
public static void main(String[] args) throws ScriptException {
ScriptEngineManager sem = new ScriptEngineManager();
- ScriptEngine engine = sem.getEngineByName("js");
+ ScriptEngine engine = sem.getEngineByName("nashorn");
if (engine == null) {
- System.out.println("Warning: No js engine found; test vacuously passes.");
+ System.out.println("Warning: No nashorn engine found; test vacuously passes.");
return;
}
// the following throws exception
--- a/jdk/test/javax/script/VersionTest.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/javax/script/VersionTest.java Fri Mar 15 16:39:07 2013 -0700
@@ -31,9 +31,7 @@
import java.io.*;
public class VersionTest {
-
- private static final String JS_LANG_VERSION = "1.8";
- private static final String JS_ENGINE_VERSION = "1.7 release 3 PRERELEASE";
+ private static final String JS_LANG_VERSION = "ECMA - 262 Edition 5.1";
public static void main(String[] args) throws Exception {
ScriptEngineManager manager = new ScriptEngineManager();
@@ -48,9 +46,18 @@
JS_LANG_VERSION);
}
String engineVersion = jsengine.getFactory().getEngineVersion();
- if (! engineVersion.equals(JS_ENGINE_VERSION)) {
- throw new RuntimeException("Expected Rhino version is " +
- JS_ENGINE_VERSION);
+ String expectedVersion = getNashornVersion();
+ if (! engineVersion.equals(expectedVersion)) {
+ throw new RuntimeException("Expected version is " + expectedVersion);
+ }
+ }
+
+ private static String getNashornVersion() {
+ try {
+ Class versionClass = Class.forName("jdk.nashorn.internal.runtime.Version");
+ return (String) versionClass.getMethod("version").invoke(null);
+ } catch (Exception e) {
+ return "Version Unknown!";
}
}
}
--- a/jdk/test/javax/security/auth/kerberos/KerberosTixDateTest.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/javax/security/auth/kerberos/KerberosTixDateTest.java Fri Mar 15 16:39:07 2013 -0700
@@ -34,7 +34,7 @@
import javax.security.auth.kerberos.KerberosKey;
import javax.security.auth.kerberos.KerberosPrincipal;
import javax.security.auth.kerberos.KerberosTicket;
-import sun.misc.BASE64Decoder;
+import java.util.Base64;
public class KerberosTixDateTest {
@@ -127,7 +127,7 @@
System.out.println("Testing against KerberosTicket from JDK6...");
byte[] serializedBytes =
- new BASE64Decoder().decodeBuffer(serializedKerberosTix);
+ Base64.getMimeDecoder().decode(serializedKerberosTix);
checkEqualsAndHashCode(serializedBytes, t);
System.out.println("Testing against KerberosTicket from current rel...");
--- a/jdk/test/lib/testlibrary/jdk/testlibrary/JdkFinder.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/JdkFinder.java Fri Mar 15 16:39:07 2013 -0700
@@ -38,10 +38,6 @@
}
binPath += File.separatorChar + "bin" + File.separatorChar + executable;
- File toolFile = new File(binPath);
- if (!toolFile.exists()) {
- throw new RuntimeException(binPath + " does not exist");
- }
return binPath;
}
--- a/jdk/test/sun/misc/Cleaner/ExitOnThrow.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/sun/misc/Cleaner/ExitOnThrow.java Fri Mar 15 16:39:07 2013 -0700
@@ -28,21 +28,17 @@
public class ExitOnThrow {
- private static volatile boolean ran = false;
-
public static void main(String[] args) throws Exception {
Cleaner.create(new Object(),
new Runnable() {
public void run() {
- ran = true;
throw new RuntimeException("Foo!");
}
});
- while (!ran) {
+ while (true) {
System.gc();
Thread.sleep(100);
}
- System.exit(0);
}
}
--- a/jdk/test/sun/misc/Cleaner/exitOnThrow.sh Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/sun/misc/Cleaner/exitOnThrow.sh Fri Mar 15 16:39:07 2013 -0700
@@ -25,7 +25,7 @@
#
# @test
-# @bug 4954921
+# @bug 4954921 8009259
# @summary Ensure that if a cleaner throws an exception then the VM exits
#
# @build ExitOnThrow
--- a/jdk/test/sun/net/www/protocol/http/HttpOnly.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/sun/net/www/protocol/http/HttpOnly.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,7 +22,7 @@
*/
/**
* @test
- * @bug 7095980
+ * @bug 7095980 8007315
* @summary Ensure HttpURLConnection (and supporting APIs) don't expose
* HttpOnly cookies
*/
@@ -52,6 +52,8 @@
* 4) check HttpOnly cookies received by server
* 5) server reply with Set-Cookie containing HttpOnly cookie
* 6) check HttpOnly cookies are not accessible from Http client
+ * 7) check that non-null (empty string) values are returned for
+ scenario where all values are stripped from original key values
*/
public class HttpOnly {
@@ -177,6 +179,36 @@
" value " + val);
}
}
+
+ // TEST 7 : check that header keys containing empty key values don't return null
+ int i = 1;
+ String key = "";
+ String value = "";
+
+ while (true) {
+ key = uc.getHeaderFieldKey(i);
+ value = uc.getHeaderField(i++);
+ if (key == null && value == null)
+ break;
+
+ if (key != null)
+ check(value != null,
+ "Encountered a null value for key value : " + key);
+ }
+
+ // TEST 7.5 similar test but use getHeaderFields
+ respHeaders = uc.getHeaderFields();
+ respEntries = respHeaders.entrySet();
+ for (Map.Entry<String,List<String>> entry : respEntries) {
+ String header = entry.getKey();
+ if (header != null) {
+ List<String> listValues = entry.getValue();
+ for (String value1 : listValues)
+ check(value1 != null,
+ "getHeaderFields returned null values for header:, "
+ + header);
+ }
+ }
}
// HTTP Server
--- a/jdk/test/sun/security/krb5/auto/Context.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/sun/security/krb5/auto/Context.java Fri Mar 15 16:39:07 2013 -0700
@@ -297,6 +297,13 @@
}
/**
+ * Returns the cred inside, if there is one
+ */
+ public GSSCredential cred() {
+ return cred;
+ }
+
+ /**
* Disposes the GSSContext within
* @throws org.ietf.jgss.GSSException
*/
--- a/jdk/test/sun/security/krb5/auto/HttpNegotiateServer.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/sun/security/krb5/auto/HttpNegotiateServer.java Fri Mar 15 16:39:07 2013 -0700
@@ -55,6 +55,7 @@
import org.ietf.jgss.GSSManager;
import sun.security.jgss.GSSUtil;
import sun.security.krb5.Config;
+import java.util.Base64;
/**
* Basic JGSS/krb5 test with 3 parties: client, server, backend server. Each
@@ -341,12 +342,11 @@
exch.getHttpContext().getAttributes().put("GSSContext", c);
return new com.sun.net.httpserver.Authenticator.Retry(err);
} else { // Later requests
- byte[] token = new sun.misc.BASE64Decoder()
- .decodeBuffer(auth.split(" ")[1]);
+ byte[] token = Base64.getMimeDecoder().decode(auth.split(" ")[1]);
token = c.acceptSecContext(token, 0, token.length);
Headers map = exch.getResponseHeaders();
- map.set (reqHdr, scheme + " " + new sun.misc.BASE64Encoder()
- .encode(token).replaceAll("\\s", ""));
+ map.set (reqHdr, scheme + " " + Base64.getMimeEncoder()
+ .encodeToString(token).replaceAll("\\s", ""));
if (c.isEstablished()) {
return new com.sun.net.httpserver.Authenticator.Success(
new HttpPrincipal(c.getSrcName().toString(), ""));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/auto/SpnegoLifeTime.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8000653
+ * @summary SPNEGO tests fail at context.getDelegCred().getRemainingInitLifetime(mechOid)
+ * @compile -XDignore.symbol.file SpnegoLifeTime.java
+ * @run main/othervm SpnegoLifeTime
+ */
+
+import org.ietf.jgss.Oid;
+import org.ietf.jgss.GSSCredential;
+import sun.security.jgss.GSSUtil;
+
+public class SpnegoLifeTime {
+
+ public static void main(String[] args) throws Exception {
+
+ Oid oid = GSSUtil.GSS_SPNEGO_MECH_OID;
+ new OneKDC(null).writeJAASConf();
+
+ Context c, s;
+ c = Context.fromJAAS("client");
+ s = Context.fromJAAS("server");
+
+ c.startAsClient(OneKDC.SERVER, oid);
+ c.x().requestCredDeleg(true);
+ s.startAsServer(oid);
+
+ Context.handshake(c, s);
+
+ GSSCredential cred = s.delegated().cred();
+ cred.getRemainingInitLifetime(oid);
+ cred.getUsage(oid);
+ }
+}
+
--- a/jdk/test/sun/security/mscapi/ShortRSAKeyWithinTLS.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/sun/security/mscapi/ShortRSAKeyWithinTLS.java Fri Mar 15 16:39:07 2013 -0700
@@ -29,7 +29,7 @@
import javax.net.ssl.*;
import java.lang.reflect.*;
-import sun.security.util.KeyLength;
+import sun.security.util.KeyUtil;
public class ShortRSAKeyWithinTLS {
@@ -175,13 +175,13 @@
privateKey = (PrivateKey)ks.getKey(keyAlias, null);
publicKey = (PublicKey)ks.getCertificate(keyAlias).getPublicKey();
- int privateKeySize = KeyLength.getKeySize(privateKey);
+ int privateKeySize = KeyUtil.getKeySize(privateKey);
if (privateKeySize != keySize) {
throw new Exception("Expected key size is " + keySize +
", but the private key size is " + privateKeySize);
}
- int publicKeySize = KeyLength.getKeySize(publicKey);
+ int publicKeySize = KeyUtil.getKeySize(publicKey);
if (publicKeySize != keySize) {
throw new Exception("Expected key size is " + keySize +
", but the public key size is " + publicKeySize);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/provider/PolicyFile/WildcardPrincipalName.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8008908
+ * @summary wildcard principal names are not processed correctly
+ * @run main/othervm/policy=wildcard.policy WildcardPrincipalName
+ */
+
+import java.security.AccessController;
+import java.security.Permission;
+import java.security.Principal;
+import java.security.PrivilegedAction;
+import java.util.HashSet;
+import java.util.PropertyPermission;
+import java.util.Set;
+import javax.security.auth.Subject;
+import javax.security.auth.x500.X500Principal;
+
+public class WildcardPrincipalName {
+
+ public static void main(String[] args) throws Exception {
+
+ X500Principal duke = new X500Principal("CN=Duke");
+ PropertyPermission pp = new PropertyPermission("user.home", "read");
+ RunAsPrivilegedUserAction runAsPrivilegedUserAction
+ = new RunAsPrivilegedUserAction(duke,
+ new CheckPermissionAction(pp));
+ AccessController.doPrivileged(runAsPrivilegedUserAction);
+ System.out.println("test PASSED");
+ }
+
+ private static class RunAsPrivilegedUserAction
+ implements PrivilegedAction<Void> {
+ private final PrivilegedAction<Void> action;
+ private final Principal principal;
+
+ RunAsPrivilegedUserAction(Principal principal,
+ PrivilegedAction<Void> action) {
+ this.principal = principal;
+ this.action = action;
+ }
+
+ @Override public Void run() {
+ Set<Principal> principals = new HashSet<>();
+ Set<Object> publicCredentials = new HashSet<>();
+ Set<Object> privateCredentials = new HashSet<>();
+
+ principals.add(principal);
+ Subject subject = new Subject(true,
+ principals,
+ publicCredentials,
+ privateCredentials);
+
+ Subject.doAsPrivileged(subject, action, null);
+ return null;
+ }
+ }
+
+ private static class CheckPermissionAction
+ implements PrivilegedAction<Void> {
+ private final Permission permission;
+
+ CheckPermissionAction(Permission permission) {
+ this.permission = permission;
+ }
+
+ @Override public Void run() {
+ AccessController.checkPermission(permission);
+ return null;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/provider/PolicyFile/wildcard.policy Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,7 @@
+grant principal javax.security.auth.x500.X500Principal * {
+ permission java.util.PropertyPermission "user.home", "read";
+};
+
+grant {
+ permission javax.security.auth.AuthPermission "doAsPrivileged";
+};
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLContextImpl/MD2InTrustAnchor.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLContextImpl/MD2InTrustAnchor.java Fri Mar 15 16:39:07 2013 -0700
@@ -46,8 +46,7 @@
import java.security.cert.CertificateFactory;
import java.security.spec.*;
import java.security.interfaces.*;
-import sun.misc.BASE64Decoder;
-
+import java.util.Base64;
public class MD2InTrustAnchor {
@@ -238,7 +237,7 @@
if (keyCertStr != null) {
// generate the private key.
PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(
- new BASE64Decoder().decodeBuffer(keySpecStr));
+ Base64.getMimeDecoder().decode(keySpecStr));
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPrivateKey priKey =
(RSAPrivateKey)kf.generatePrivate(priKeySpec);
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLContextImpl/TrustTrustedCert.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLContextImpl/TrustTrustedCert.java Fri Mar 15 16:39:07 2013 -0700
@@ -44,7 +44,7 @@
import java.security.cert.*;
import java.security.spec.*;
import java.security.interfaces.*;
-import sun.misc.BASE64Decoder;
+import java.util.Base64;
public class TrustTrustedCert {
@@ -230,7 +230,7 @@
// generate the private key.
PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(
- new BASE64Decoder().decodeBuffer(targetPrivateKey));
+ Base64.getMimeDecoder().decode(targetPrivateKey));
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPrivateKey priKey =
(RSAPrivateKey)kf.generatePrivate(priKeySpec);
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/X509TrustManagerImpl/BasicConstraints.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/X509TrustManagerImpl/BasicConstraints.java Fri Mar 15 16:39:07 2013 -0700
@@ -44,7 +44,7 @@
import java.security.interfaces.*;
import java.math.BigInteger;
-import sun.misc.BASE64Decoder;
+import java.util.Base64;
public class BasicConstraints {
@@ -400,11 +400,11 @@
PKCS8EncodedKeySpec priKeySpec = null;
if (isServer) {
priKeySpec = new PKCS8EncodedKeySpec(
- new BASE64Decoder().decodeBuffer(serverPrivateKey));
+ Base64.getMimeDecoder().decode(serverPrivateKey));
is = new ByteArrayInputStream(serverCertStr.getBytes());
} else {
priKeySpec = new PKCS8EncodedKeySpec(
- new BASE64Decoder().decodeBuffer(clientPrivateKey));
+ Base64.getMimeDecoder().decode(clientPrivateKey));
is = new ByteArrayInputStream(clientCertStr.getBytes());
}
KeyFactory kf = KeyFactory.getInstance("RSA");
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/X509TrustManagerImpl/SelfIssuedCert.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/X509TrustManagerImpl/SelfIssuedCert.java Fri Mar 15 16:39:07 2013 -0700
@@ -45,7 +45,7 @@
import java.security.interfaces.*;
import java.math.BigInteger;
-import sun.misc.BASE64Decoder;
+import java.util.Base64;
public class SelfIssuedCert {
@@ -242,7 +242,7 @@
if (keyCertStr != null) {
// generate the private key.
PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(
- new BASE64Decoder().decodeBuffer(keySpecStr));
+ Base64.getMimeDecoder().decode(keySpecStr));
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPrivateKey priKey =
(RSAPrivateKey)kf.generatePrivate(priKeySpec);
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/www/protocol/https/HttpsClient/ProxyTunnelServer.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/www/protocol/https/HttpsClient/ProxyTunnelServer.java Fri Mar 15 16:39:07 2013 -0700
@@ -33,6 +33,7 @@
import javax.net.ssl.*;
import javax.net.ServerSocketFactory;
import sun.net.www.*;
+import java.util.Base64;
public class ProxyTunnelServer extends Thread {
@@ -292,12 +293,12 @@
authInfo.trim();
int ind = authInfo.indexOf(' ');
String recvdUserPlusPass = authInfo.substring(ind + 1).trim();
+
// extract encoded (username:passwd
if (userPlusPass.equals(
- new String(
- (new sun.misc.BASE64Decoder()).
- decodeBuffer(recvdUserPlusPass)
- ))) {
+ new String( Base64.getMimeDecoder()
+ .decode(recvdUserPlusPass))))
+ {
matched = true;
}
} catch (Exception e) {
--- a/jdk/test/sun/security/ssl/javax/net/ssl/ServerName/SSLSocketSNISensitive.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/ServerName/SSLSocketSNISensitive.java Fri Mar 15 16:39:07 2013 -0700
@@ -51,7 +51,7 @@
import java.security.cert.CertificateFactory;
import java.security.spec.*;
import java.security.interfaces.*;
-import sun.misc.BASE64Decoder;
+import java.util.Base64;
public class SSLSocketSNISensitive {
@@ -391,7 +391,7 @@
// generate the private key.
String keySpecStr = keyStrs[i];
PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(
- new BASE64Decoder().decodeBuffer(keySpecStr));
+ Base64.getMimeDecoder().decode(keySpecStr));
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPrivateKey priKey =
(RSAPrivateKey)kf.generatePrivate(priKeySpec);
--- a/jdk/test/sun/security/ssl/javax/net/ssl/TLSv12/DisabledShortRSAKeys.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/TLSv12/DisabledShortRSAKeys.java Fri Mar 15 16:39:07 2013 -0700
@@ -53,7 +53,7 @@
import java.security.cert.CertificateFactory;
import java.security.spec.*;
import java.security.interfaces.*;
-import sun.misc.BASE64Decoder;
+import java.util.Base64;
public class DisabledShortRSAKeys {
@@ -244,7 +244,7 @@
if (keyCertStr != null) {
// generate the private key.
PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(
- new BASE64Decoder().decodeBuffer(keySpecStr));
+ Base64.getMimeDecoder().decode(keySpecStr));
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPrivateKey priKey =
(RSAPrivateKey)kf.generatePrivate(priKeySpec);
--- a/jdk/test/sun/security/ssl/javax/net/ssl/TLSv12/ShortRSAKey512.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/TLSv12/ShortRSAKey512.java Fri Mar 15 16:39:07 2013 -0700
@@ -48,7 +48,7 @@
import java.security.cert.CertificateFactory;
import java.security.spec.*;
import java.security.interfaces.*;
-import sun.misc.BASE64Decoder;
+import java.util.Base64;
public class ShortRSAKey512 {
@@ -229,7 +229,7 @@
if (keyCertStr != null) {
// generate the private key.
PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(
- new BASE64Decoder().decodeBuffer(keySpecStr));
+ Base64.getMimeDecoder().decode(keySpecStr));
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPrivateKey priKey =
(RSAPrivateKey)kf.generatePrivate(priKeySpec);
--- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/ProxyTunnelServer.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/ProxyTunnelServer.java Fri Mar 15 16:39:07 2013 -0700
@@ -35,6 +35,7 @@
import javax.net.ssl.*;
import javax.net.ServerSocketFactory;
import sun.net.www.*;
+import java.util.Base64;
public class ProxyTunnelServer extends Thread {
@@ -296,10 +297,9 @@
String recvdUserPlusPass = authInfo.substring(ind + 1).trim();
// extract encoded (username:passwd
if (userPlusPass.equals(
- new String(
- (new sun.misc.BASE64Decoder()).
- decodeBuffer(recvdUserPlusPass)
- ))) {
+ new String( Base64.getMimeDecoder()
+ .decode(recvdUserPlusPass))))
+ {
matched = true;
}
} catch (Exception e) {
--- a/jdk/test/sun/tools/jrunscript/CheckEngine.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/sun/tools/jrunscript/CheckEngine.java Fri Mar 15 16:39:07 2013 -0700
@@ -33,7 +33,7 @@
public static void main(String... args) {
int exitCode = 0;
ScriptEngine engine =
- (new ScriptEngineManager()).getEngineByName("js");
+ (new ScriptEngineManager()).getEngineByName("nashorn");
if (engine == null &&
!(System.getProperty("java.runtime.name").startsWith("Java(TM)"))) {
--- a/jdk/test/sun/tools/jrunscript/jrunscript-DTest.sh Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/sun/tools/jrunscript/jrunscript-DTest.sh Fri Mar 15 16:39:07 2013 -0700
@@ -43,7 +43,7 @@
# to script as java.lang.System property. sysProps is
# jrunscript shell built-in variable for System properties.
-${JRUNSCRIPT} -Djrunscript.foo=bar <<EOF
+${JRUNSCRIPT} -l nashorn -Djrunscript.foo=bar <<EOF
if (sysProps["jrunscript.foo"] == "bar") { println("Passed"); exit(0); }
// unexpected value
println("Unexpected System property value");
--- a/jdk/test/sun/tools/jrunscript/jrunscript-argsTest.sh Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/sun/tools/jrunscript/jrunscript-argsTest.sh Fri Mar 15 16:39:07 2013 -0700
@@ -41,7 +41,7 @@
# we check whether "excess" args are passed as script arguments
-${JRUNSCRIPT} -J-Djava.awt.headless=true -f - hello world <<EOF
+${JRUNSCRIPT} -l nashorn -J-Djava.awt.headless=true -f - hello world <<EOF
if (typeof(arguments) == 'undefined') { println("arguments expected"); exit(1); }
--- a/jdk/test/sun/tools/jrunscript/jrunscript-cpTest.sh Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/sun/tools/jrunscript/jrunscript-cpTest.sh Fri Mar 15 16:39:07 2013 -0700
@@ -46,7 +46,7 @@
# work with jrunscript. Script should be able to
# access Java class "Hello".
-${JRUNSCRIPT} -cp . <<EOF
+${JRUNSCRIPT} -l nashorn -cp . <<EOF
var v;
try { v = new Packages.Hello(); } catch (e) { println(e); exit(1) }
if (v.string != 'hello') { println("Unexpected property value"); exit(1); }
@@ -58,7 +58,7 @@
# -classpath and -cp are synonyms
-${JRUNSCRIPT} -classpath . <<EOF
+${JRUNSCRIPT} -l nashorn -classpath . <<EOF
var v;
try { v = new Packages.Hello(); } catch (e) { println(e); exit(1) }
if (v.string != 'hello') { println("unexpected property value"); exit(1); }
--- a/jdk/test/sun/tools/jrunscript/jrunscript-eTest.sh Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/sun/tools/jrunscript/jrunscript-eTest.sh Fri Mar 15 16:39:07 2013 -0700
@@ -39,21 +39,10 @@
exit 0
fi
-rm -f jrunscript-eTest.out 2>/dev/null
-${JRUNSCRIPT} -J-Djava.awt.headless=true -e "println('hello')" > jrunscript-eTest.out 2>&1
-
-$golden_diff jrunscript-eTest.out ${TESTSRC}/dash-e.out
-if [ $? != 0 ]
-then
- echo "Output of jrunscript -e differ from expected output. Failed."
- rm -f jrunscript-eTest.out 2>/dev/null
- exit 1
-fi
-
# -e option with JavaScript explicitly choosen as language
rm -f jrunscript-eTest.out 2>/dev/null
-${JRUNSCRIPT} -J-Djava.awt.headless=true -l js -e "println('hello')" > jrunscript-eTest.out 2>&1
+${JRUNSCRIPT} -J-Djava.awt.headless=true -l nashorn -e "println('hello')" > jrunscript-eTest.out 2>&1
$golden_diff jrunscript-eTest.out ${TESTSRC}/dash-e.out
if [ $? != 0 ]
--- a/jdk/test/sun/tools/jrunscript/jrunscript-fTest.sh Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/sun/tools/jrunscript/jrunscript-fTest.sh Fri Mar 15 16:39:07 2013 -0700
@@ -39,22 +39,11 @@
exit 0
fi
-rm -f jrunscript-fTest.out 2>/dev/null
-${JRUNSCRIPT} -J-Djava.awt.headless=true -f ${TESTSRC}/hello.js > jrunscript-fTest.out 2>&1
-
-$golden_diff jrunscript-fTest.out ${TESTSRC}/dash-f.out
-if [ $? != 0 ]
-then
- echo "Output of jrunscript -f differ from expected output. Failed."
- rm -f jrunscript-fTest.out 2>/dev/null
- exit 1
-fi
-
# -f option used with JavaScript as language chosen explicitly
# with -l option
rm -f jrunscript-fTest.out 2>/dev/null
-${JRUNSCRIPT} -J-Djava.awt.headless=true -l js -f ${TESTSRC}/hello.js > jrunscript-fTest.out 2>&1
+${JRUNSCRIPT} -J-Djava.awt.headless=true -l nashorn -f ${TESTSRC}/hello.js > jrunscript-fTest.out 2>&1
$golden_diff jrunscript-fTest.out ${TESTSRC}/dash-f.out
if [ $? != 0 ]
--- a/jdk/test/sun/tools/jrunscript/jrunscriptTest.sh Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/sun/tools/jrunscript/jrunscriptTest.sh Fri Mar 15 16:39:07 2013 -0700
@@ -40,7 +40,7 @@
fi
rm -f jrunscriptTest.out 2>/dev/null
-${JRUNSCRIPT} -J-Djava.awt.headless=true > jrunscriptTest.out 2>&1 <<EOF
+${JRUNSCRIPT} -J-Djava.awt.headless=true -l nashorn > jrunscriptTest.out 2>&1 <<EOF
v = 2 + 5;
v *= 5;
v = v + " is the value";
@@ -52,25 +52,7 @@
$golden_diff jrunscriptTest.out ${TESTSRC}/repl.out
if [ $? != 0 ]
then
- echo "Output of jrunscript session differ from expected output. Failed."
- rm -f jrunscriptTest.out 2>/dev/null
- exit 1
-fi
-
-rm -f jrunscriptTest.out 2>/dev/null
-${JRUNSCRIPT} -J-Djava.awt.headless=true -l js > jrunscriptTest.out 2>&1 <<EOF
-v = 2 + 5;
-v *= 5;
-v = v + " is the value";
-if (v != 0) { println('yes v != 0'); }
-java.lang.System.out.println('hello world from script');
-new java.lang.Runnable() { run: function() { println('I am runnable'); }}.run();
-EOF
-
-$golden_diff jrunscriptTest.out ${TESTSRC}/repl.out
-if [ $? != 0 ]
-then
- echo "Output of jrunscript -l js differ from expected output. Failed."
+ echo "Output of jrunscript -l nashorn differ from expected output. Failed."
rm -f jrunscriptTest.out 2>/dev/null
exit 1
fi
--- a/jdk/test/sun/tools/jrunscript/repl.out Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/sun/tools/jrunscript/repl.out Fri Mar 15 16:39:07 2013 -0700
@@ -1,7 +1,7 @@
-js> 7.0
-js> 35.0
-js> 35 is the value
-js> yes v != 0
-js> hello world from script
-js> I am runnable
-js>
\ No newline at end of file
+nashorn> 7
+nashorn> 35.0
+nashorn> 35 is the value
+nashorn> yes v != 0
+nashorn> hello world from script
+nashorn> I am runnable
+nashorn>
\ No newline at end of file
--- a/jdk/test/tools/launcher/I18NJarTest.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/tools/launcher/I18NJarTest.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -52,6 +52,8 @@
private static final File cwd = new File(".");
private static final File dir = new File("\uFF66\uFF67\uFF68\uFF69");
private static final String encoding = System.getProperty("sun.jnu.encoding", "");
+ private static final String LANG = System.getenv("LANG");
+ private static final String LC_ALL = System.getenv("LC_ALL");
public static void main(String... args) throws Exception {
boolean localeAvailable = false;
@@ -63,7 +65,16 @@
}
if (!localeAvailable) {
System.out.println("Warning: locale: " + Locale.JAPAN
- + " not found, test passes vacuosly");
+ + " not found, test passes vacuously");
+ return;
+ }
+ if ("C".equals(LC_ALL) || "C".equals(LANG)) {
+ System.out.println("Warning: The LANG and/or LC_ALL env vars are " +
+ "set to \"C\":\n" +
+ " LANG=" + LANG + "\n" +
+ " LC_ALL=" + LC_ALL + "\n" +
+ "This test requires support for multi-byte filenames.\n" +
+ "Test passes vacuously.");
return;
}
if (encoding.equals("MS932") || encoding.equals("UTF-8")) {
@@ -73,7 +84,7 @@
} else {
System.out.println("Warning: current encoding is " + encoding +
"this test requires MS932 <Ja> or UTF-8," +
- " test passes vacuosly");
+ " test passes vacuously");
return;
}
dir.mkdir();
--- a/jdk/test/tools/launcher/ToolsOpts.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/tools/launcher/ToolsOpts.java Fri Mar 15 16:39:07 2013 -0700
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 8002091
* @summary Test options patterns for javac,javah,javap and javadoc using
* javac as a test launcher. Create a dummy javac and intercept options to check
* reception of options as passed through the launcher without having to launch
--- a/jdk/test/tools/launcher/VersionCheck.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/tools/launcher/VersionCheck.java Fri Mar 15 16:39:07 2013 -0700
@@ -74,6 +74,7 @@
"jmap",
"jps",
"jrunscript",
+ "jjs",
"jsadebugd",
"jstack",
"jstat",
--- a/jdk/test/tools/pack200/AttributeTests.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/tools/pack200/AttributeTests.java Fri Mar 15 16:39:07 2013 -0700
@@ -29,7 +29,7 @@
import static java.nio.file.StandardOpenOption.*;
/*
* @test
- * @bug 6746111 8005252
+ * @bug 6746111 8005252 8008262
* @summary tests various classfile format and attribute handling by pack200
* @compile -XDignore.symbol.file Utils.java AttributeTests.java
* @run main AttributeTests
@@ -67,17 +67,7 @@
File testjarFile = new File(cwd, "test" + Utils.JAR_FILE_EXT);
Utils.jar("cvf", testjarFile.getName(), javaClassName);
- // pack using --repack
- File outjarFile = new File(cwd, "out" + Utils.JAR_FILE_EXT);
- scratch.clear();
- scratch.add(Utils.getPack200Cmd());
- scratch.add("--repack");
- scratch.add("--unknown-attribute=error");
- scratch.add(outjarFile.getName());
- scratch.add(testjarFile.getName());
- Utils.runExec(scratch);
-
- Utils.doCompareVerify(testjarFile, outjarFile);
+ Utils.testWithRepack(testjarFile, "--unknown-attribute=error");
}
/*
* this test checks to see if we get the expected strings for output
--- a/jdk/test/tools/pack200/InstructionTests.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/tools/pack200/InstructionTests.java Fri Mar 15 16:39:07 2013 -0700
@@ -26,11 +26,10 @@
import java.util.ArrayList;
import java.util.List;
import static java.nio.file.StandardOpenOption.*;
-import java.util.regex.Pattern;
/*
* @test
- * @bug 8003549
+ * @bug 8003549 8007297
* @summary tests class files instruction formats introduced in JSR-335
* @compile -XDignore.symbol.file Utils.java InstructionTests.java
* @run main InstructionTests
@@ -48,52 +47,34 @@
List<String> scratch = new ArrayList<>();
final String fname = "A";
String javaFileName = fname + Utils.JAVA_FILE_EXT;
- scratch.add("interface IntIterator {");
+ scratch.add("interface I {");
scratch.add(" default void forEach(){}");
scratch.add(" static void next() {}");
scratch.add("}");
- scratch.add("class A implements IntIterator {");
- scratch.add("public void forEach(Object o){");
- scratch.add("IntIterator.super.forEach();");
- scratch.add("IntIterator.next();");
- scratch.add("}");
+ scratch.add("class A implements I {");
+ scratch.add(" public void forEach(Object o){");
+ scratch.add(" I.super.forEach();");
+ scratch.add(" I.next();");
+ scratch.add(" }");
scratch.add("}");
File cwd = new File(".");
File javaFile = new File(cwd, javaFileName);
Files.write(javaFile.toPath(), scratch, Charset.defaultCharset(),
CREATE, TRUNCATE_EXISTING);
- // make sure we have -g so that we compare LVT and LNT entries
+ // -g to compare LVT and LNT entries
Utils.compiler("-g", javaFile.getName());
+ File propsFile = new File("pack.props");
+ scratch.clear();
+ scratch.add("com.sun.java.util.jar.pack.class.format.error=error");
+ scratch.add("pack.unknown.attribute=error");
+ Files.write(propsFile.toPath(), scratch, Charset.defaultCharset(),
+ CREATE, TRUNCATE_EXISTING);
// jar the file up
File testjarFile = new File(cwd, "test" + Utils.JAR_FILE_EXT);
Utils.jar("cvf", testjarFile.getName(), ".");
- // pack using --repack
- File outjarFile = new File(cwd, "out" + Utils.JAR_FILE_EXT);
- scratch.clear();
- scratch.add(Utils.getPack200Cmd());
- scratch.add("-J-ea");
- scratch.add("-J-esa");
- scratch.add("--repack");
- scratch.add(outjarFile.getName());
- scratch.add(testjarFile.getName());
- List<String> output = Utils.runExec(scratch);
- // TODO remove this when we get bc escapes working correctly
- // this test anyhow would fail at that time
- findString("WARNING: Passing.*" + fname + Utils.CLASS_FILE_EXT,
- output);
-
- Utils.doCompareVerify(testjarFile, outjarFile);
- }
-
- static boolean findString(String str, List<String> list) {
- Pattern p = Pattern.compile(str);
- for (String x : list) {
- if (p.matcher(x).matches())
- return true;
- }
- throw new RuntimeException("Error: " + str + " not found in output");
+ Utils.testWithRepack(testjarFile, "--config-file=" + propsFile.getName());
}
}
--- a/jdk/test/tools/pack200/Utils.java Fri Mar 15 17:02:24 2013 +0400
+++ b/jdk/test/tools/pack200/Utils.java Fri Mar 15 16:39:07 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -315,6 +315,41 @@
}
}
+ static void testWithRepack(File inFile, String... repackOpts) throws IOException {
+ File cwd = new File(".");
+ // pack using --repack in native mode
+ File nativejarFile = new File(cwd, "out-n" + Utils.JAR_FILE_EXT);
+ repack(inFile, nativejarFile, false, repackOpts);
+ doCompareVerify(inFile, nativejarFile);
+
+ // ensure bit compatibility between the unpacker variants
+ File javajarFile = new File(cwd, "out-j" + Utils.JAR_FILE_EXT);
+ repack(inFile, javajarFile, true, repackOpts);
+ doCompareBitWise(javajarFile, nativejarFile);
+ }
+
+ static List<String> repack(File inFile, File outFile,
+ boolean disableNative, String... extraOpts) {
+ List<String> cmdList = new ArrayList<>();
+ cmdList.clear();
+ cmdList.add(Utils.getJavaCmd());
+ cmdList.add("-ea");
+ cmdList.add("-esa");
+ if (disableNative) {
+ cmdList.add("-Dcom.sun.java.util.jar.pack.disable.native=true");
+ }
+ cmdList.add("com.sun.java.util.jar.pack.Driver");
+ cmdList.add("--repack");
+ if (extraOpts != null) {
+ for (String opt: extraOpts) {
+ cmdList.add(opt);
+ }
+ }
+ cmdList.add(outFile.getName());
+ cmdList.add(inFile.getName());
+ return Utils.runExec(cmdList);
+ }
+
// given a jar file foo.jar will write to foo.pack
static void pack(JarFile jarFile, File packFile) throws IOException {
Pack200.Packer packer = Pack200.newPacker();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/vm/verifier/TestStaticIF.java Fri Mar 15 16:39:07 2013 -0700
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * @test
+ * @bug 8007736
+ * @summary Test static interface method.
+ * @run main/othervm -Xverify:all -XX:-UseSplitVerifier TestStaticIF
+ */
+
+public class TestStaticIF implements StaticMethodInInterface {
+
+ public static void main(String[] args) {
+ System.out.printf("main: %s%n", StaticMethodInInterface.get());
+ }
+}
+
+interface StaticMethodInInterface {
+
+ public static String get() {
+ return "Hello from StaticMethodInInterface.get()";
+ }
+}
--- a/langtools/.hgtags Fri Mar 15 17:02:24 2013 +0400
+++ b/langtools/.hgtags Fri Mar 15 16:39:07 2013 -0700
@@ -199,3 +199,6 @@
c2e11e2ec4a3682513e566849e5562f31ded8c65 jdk8-b75
e81839b3233792415daaab051698edc6067f1a16 jdk8-b76
89c66415168925dffe492356ff893ff248bb5603 jdk8-b77
+af8417e590f4e76e0dfed09e71239fb102ef0d43 jdk8-b78
+56dfafbb9e1ad7548a4415316dc003296fb498cb jdk8-b79
+a8227c61768499dac847ea718af6719027c949f2 jdk8-b80