--- a/.hgtags-top-repo Tue Mar 22 12:12:31 2011 -0700
+++ b/.hgtags-top-repo Wed Jul 05 17:38:16 2017 +0200
@@ -108,3 +108,4 @@
5d86d951426aaf340b1ba84ae2d5ab5da65a71e2 jdk7-b131
0f62a65fb666b337caa585015ab6ea2e60e709ca jdk7-b132
c6f380693342feadccc5fe2c5adf500e861361aa jdk7-b133
+ddc2fcb3682ffd27f44354db666128827be7e3c3 jdk7-b134
--- a/README Tue Mar 22 12:12:31 2011 -0700
+++ b/README Wed Jul 05 17:38:16 2017 +0200
@@ -29,13 +29,14 @@
Set the environment variable ALT_BOOTDIR to the location of JDK 6.
2. Check the sanity of doing a build with your current system:
- gnumake sanity
+ make sanity
See README-builds.html if you run into problems.
3. Do a complete build of the OpenJDK:
- gnumake all
+ make all
The resulting JDK image should be found in build/*/j2sdk-image
-where gnumake is GNU make 3.81 or newer, /usr/bin/make on Linux and
-/usr/sfw/bin/gmake or /opt/sfw/bin/gmake on Solaris.
+where make is GNU make 3.81 or newer, /usr/bin/make on Linux usually
+is 3.81 or newer.
+Complete details are available in README-builds.html.
--- a/README-builds.html Tue Mar 22 12:12:31 2011 -0700
+++ b/README-builds.html Wed Jul 05 17:38:16 2017 +0200
@@ -54,7 +54,11 @@
<li><a href="#opensolaris">OpenSolaris</a></li>
</ul>
</li>
- <li><a href="#directories">Source Directory Structure</a> </li>
+ <li><a href="#directories">Source Directory Structure</a>
+ <ul>
+ <li><a href="#drops">Managing the Source Drops</a></li>
+ </ul>
+ </li>
<li><a href="#building">Build Information</a>
<ul>
<li><a href="#gmake">GNU Make (<tt><i>gmake</i></tt>)</a> </li>
@@ -65,7 +69,7 @@
<ul>
<li><a href="#bootjdk">Bootstrap JDK</a> </li>
<li><a href="#importjdk">Optional Import JDK</a> </li>
- <li><a href="#ant">Ant</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>
@@ -114,13 +118,13 @@
<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>.
+ 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>
For using Mercurial with the OpenJDK refer to the
- <a href=""http://openjdk.java.net/guide/repositories.html#installConfig">
- Developer Guide: Installing and Configuring Mercurial</a>
+ <a href="http://openjdk.java.net/guide/repositories.html#installConfig">
+ Developer Guide: Installing and Configuring Mercurial</a>
section for more information.
The Forest Extension is not part of the Mercurial install,
and is optional,
@@ -146,14 +150,14 @@
using the Forest Extension:
<blockquote>
<tt>
- hg fclone http://openjdk.java.net/jdk7/jdk7 <i>YourOpenJDK</i>
+ hg fclone http://hg.openjdk.java.net/jdk7/jdk7 <i>YourOpenJDK</i>
</tt>
</blockquote>
To get the entire set of OpenJDK Mercurial repositories
without using the Forest Extension:
<blockquote>
<tt>
- hg clone http://openjdk.java.net/jdk7/jdk7 <i>YourOpenJDK</i>
+ hg clone http://hg.openjdk.java.net/jdk7/jdk7 <i>YourOpenJDK</i>
<br>cd <i>YourOpenJDK</i>
<br>sh ./get_source.sh
</tt>
@@ -207,66 +211,50 @@
<tr>
<td>Linux X86 (32-bit)</td>
<td>Fedora 9</td>
- <td>gcc 4 </td>
- <td>JDK 6u14 FCS </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 </td>
- <td>JDK 6u14 FCS </td>
+ <td>gcc 4.3 </td>
+ <td>JDK 6u18</td>
</tr>
<tr>
<td>Solaris SPARC (32-bit)</td>
- <td>Solaris 10u2 + patches
- <br>
- See <a href="http://sunsolve.sun.com/pub-cgi/show.pl?target=patches/JavaSE" target="_blank">
- SunSolve</a> for patch downloads.
- </td>
+ <td>Solaris 10 Update 6</td>
<td>Sun Studio 12 Update 1 + patches</td>
- <td>JDK 6u14 FCS </td>
+ <td>JDK 6u18</td>
</tr>
<tr>
<td>Solaris SPARCV9 (64-bit)</td>
- <td>Solaris 10u2 + patches
- <br>
- See <a href="http://sunsolve.sun.com/pub-cgi/show.pl?target=patches/JavaSE" target="_blank">
- SunSolve</a> for patch downloads.
- </td>
+ <td>Solaris 10 Update 6</td>
<td>Sun Studio 12 Update 1 + patches</td>
- <td>JDK 6u14 FCS </td>
+ <td>JDK 6u18</td>
</tr>
<tr>
<td>Solaris X86 (32-bit)</td>
- <td>Solaris 10u2 + patches
- <br>
- See <a href="http://sunsolve.sun.com/pub-cgi/show.pl?target=patches/JavaSE" target="_blank">
- SunSolve</a> for patch downloads.
- </td>
+ <td>Solaris 10 Update 6</td>
<td>Sun Studio 12 Update 1 + patches</td>
- <td>JDK 6u14 FCS </td>
+ <td>JDK 6u18</td>
</tr>
<tr>
<td>Solaris X64 (64-bit)</td>
- <td>Solaris 10u2 + patches
- <br>
- See <a href="http://sunsolve.sun.com/pub-cgi/show.pl?target=patches/JavaSE" target="_blank">
- SunSolve</a> for patch downloads.
- </td>
+ <td>Solaris 10 Update 6</td>
<td>Sun Studio 12 Update 1 + patches</td>
- <td>JDK 6u14 FCS </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 6u14 FCS </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 6u14 FCS </td>
+ <td>JDK 6u18</td>
</tr>
</tbody>
</table>
@@ -300,7 +288,7 @@
way to do it is to execute the following commands as user
<tt>root</tt>:
<p/>
- <code>yum-builddep java-openjdk</code>
+ <code>yum-builddep java-1.6.0-openjdk</code>
<p/>
<code>yum install gcc gcc-c++</code>
<p/>
@@ -345,10 +333,10 @@
</blockquote>
</blockquote>
<!-- ------------------------------------------------------ -->
- <h3><a name="centos">CentOS 5.2</a></h3>
+ <h3><a name="centos">CentOS 5.5</a></h3>
<blockquote>
After installing
- <a href="http://www.centos.org/">CentOS 5.2</a>
+ <a href="http://www.centos.org/">CentOS 5.5</a>
you need to make sure you have
the following Development bundles installed:
<blockquote>
@@ -356,7 +344,7 @@
<li>Development Libraries</li>
<li>Development Tools</li>
<li>Java Development</li>
- <li>X Software Development</li>
+ <li>X Software Development (Including XFree86-devel)</li>
</ul>
</blockquote>
<p>
@@ -552,15 +540,105 @@
building the OpenJDK runtime libraries and misc files.
The top level <tt>Makefile</tt>
is used to build the entire OpenJDK.
+
+ <h3><a name="drops">Managing the Source Drops</a></h3>
+ <blockquote>
+ <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.
+ <br>
+ <b>NOTE:</b> The <a href="http://download.java.net/openjdk/jdk7/">
+ Complete OpenJDK Source Bundles</a> <u>will</u> contain the JAXP and
+ JAX-WS sources.
+ </p>
+
+ <h4><a name="dropcreation">Creation of New Source Drop Bundles</a></h4>
+ <blockquote>
+ <ol>
+ <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.
+ </li>
+ <li>
+ The OpenJDK team copies this new bundle into shared
+ area (e.g. <tt>/java/devtools/share/jdk7-drops</tt>).
+ Older bundles are never deleted so we retain the history.
+ </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>)
+ </li>
+ <li>
+ OpenJDK team reviews and commits those changes with the
+ given CRs.
+ </li>
+ </ol>
+ </blockquote>
+
+ <h4><a name="dropusage">Using Source Drop Bundles</a></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>
+ </blockquote>
+ </blockquote>
</blockquote>
<!-- ------------------------------------------------------ -->
<hr>
<h2><a name="building">Build Information</a></h2>
<blockquote>
Building the OpenJDK
- is done with a <tt><i>gmake</i></tt>
- command line and various
- environment or make variable settings that direct the make rules
+ 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
@@ -578,7 +656,7 @@
<pre><tt>
bash
. jdk/make/jdk_generic_profile.sh
- <i>gmake</i> sanity && <i>gmake</i>
+ <a href="#gmake"><tt>make</tt></a> sanity && <a href="#gmake"><tt>make</tt></a>
</tt></pre>
</blockquote>
<p>
@@ -599,25 +677,31 @@
A few notes about using GNU make:
<ul>
<li>
- In general, you need GNU make version 3.81 or newer.
+ You need GNU make version 3.81 or newer.
</li>
<li>
Place the location of the GNU make binary in the <tt>PATH</tt>.
</li>
<li>
<strong>Linux:</strong>
- The <tt>/usr/bin/make</tt> command should work fine for you.
+ 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.
</li>
<li>
<strong>Solaris:</strong>
Do NOT use <tt>/usr/bin/make</tt> on Solaris.
If your Solaris system has the software
from the Solaris Companion CD installed,
- you should use <tt>gmake</tt>
+ 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 can be found
- at <tt>/usr/bin/gmake</tt>.
+ 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.
</li>
<li>
<strong>Windows:</strong>
@@ -627,30 +711,25 @@
as a <tt>make.exe</tt> built for something like
<a href="http://www.mkssoftware.com/">MKS</a>).
<br>
- <b>WARNING:</b> Watch out for make version 3.81, it may
+ <b>WARNING:</b> Watch out on some make 3.81 versions, it may
not work due to a lack of support for MS-DOS drive letter paths
like <tt>C:/</tt> or <tt>C:\</tt>.
- Use a 3.80 version, or find a newer
- version that has this problem fixed.
- The older 3.80 version of make.exe can be downloaded with this
- <a href="http://cygwin.paracoda.com/release/make/make-3.80-1.tar.bz2" target="_blank">
- link</a>.
- Use of this older 3.80 make.exe may require that you install the
- libintl2.dll library or libintl2 cygwin package which is
- no longer installed by default by the cygwin installer.
<br>
- Also see the
+ You may be able to use the information at the
<a href="http://developer.mozilla.org/en/docs/Windows_build_prerequisites_using_cygwin#make" target="_blank">
mozilla developer center</a>
on this topic.
<br>
It's hoped that when make 3.82 starts shipping in a future cygwin
release that this MS-DOS path issue will be fixed.
- In addition to the above 3.80 make.exe you can download
- this
+ <br>
+ It may be possible to download the version at
<a href="http://www.cmake.org/files/cygwin/make.exe">
- www.cmake.org make.exe</a> which will not have a libintl2.dll
- dependency.
+ www.cmake.org make.exe</a>.
+ <br>
+ It might be necessary for you to build your own GNU make 3.81,
+ see the <a href="#buildgmake">"Building GNU make"</a> section
+ in that case.
</li>
</ul>
<p>
@@ -662,6 +741,34 @@
The latest source to GNU make is available at
<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>
+ <blockquote>
+ First step is to get the GNU make 3.81 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>
+ <tt>./configure && make</tt>
+ </li>
+ <li>
+ <strong>Windows for MKS: (CYGWIN is recommended)</strong>
+ <tt>./configure && make -f Makefile.win32</tt>
+ </li>
+ </ul>
+ </blockquote>
</blockquote>
<!-- ------------------------------------------------------ -->
<hr>
@@ -713,7 +820,7 @@
</li>
<li>
Install
- <a href="#ant">Ant</a>,
+ <a href="#ant">Ant 1.7.1 or newer</a>,
make sure it is in your PATH.
</li>
</ol>
@@ -776,7 +883,7 @@
</li>
<li>
Install
- <a href="#ant">Ant</a>,
+ <a href="#ant">Ant 1.7.1 or newer</a>,
make sure it is in your PATH.
</li>
</ol>
@@ -862,7 +969,7 @@
</li>
<li>
Install
- <a href="#ant">Ant</a>,
+ <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>
@@ -923,14 +1030,20 @@
<blockquote>
All OpenJDK builds require access to least Ant 1.7.1.
The Ant tool is available from the
- <a href="http://ant.apache.org" target="_blank">
- Ant download site</a>.
+ <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>
@@ -962,7 +1075,7 @@
<blockquote>
<strong><a name="gcc">Linux gcc/binutils</a></strong>
<blockquote>
- The GNU gcc compiler version should be 4 or newer.
+ 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>
@@ -1047,21 +1160,16 @@
<strong><a name="msvc32">Windows i586: Microsoft Visual Studio 2010 Compilers</a></strong>
<blockquote>
<p>
- <b>BEGIN WARNING</b>: At this time (Spring/Summer 2010) JDK 7 is starting a transition to
- use the newest VS2010 Microsoft compilers. These build instructions are updated
- to show where we are going. We have a QA process to go through before
- official builds actually use VS2010. So for now, official builds are
- still using VS2003. No other compilers are known to build the entire JDK,
+ <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.
- So for now you should be able to build with either VS2003 or VS2010.
- We do not guarantee that VS2008 will work, although there is sufficient
- makefile support to make at least basic JDK builds plausible.
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>
+ Windows binaries use the the 7.1 Windows SDK.
+ <b>END WARNING.</b>
<p>
- The 32-bit OpenJDK Windows build
- requires
+ 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
@@ -1088,11 +1196,10 @@
</blockquote>
<strong><a name="msvc64">Windows x64: Microsoft Visual Studio 2010 Professional Compiler</a></strong>
<blockquote>
- For <b>X64</b>, builds, when using the VS2010 Professional
- compiler, the 64 bit build set up is much the same as 32 bit
+ 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 used the 64 bit compiler in
+ 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>
@@ -1614,6 +1721,13 @@
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/jdk7-drops</tt>.
+ </dd>
<dt><a name="ALT_UNIXCCS_PATH"><tt>ALT_UNIXCCS_PATH</tt></a></dt>
<dd>
<strong>Solaris only:</strong>
@@ -1659,9 +1773,8 @@
located.
The default is whatever WINDOWSSDKDIR is set to
(or WindowsSdkDir) or the path
- <pre>
- c:\Program Files\Microsoft SDKs\Windows\v6.1a
- </pre>
+ <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>
@@ -1682,6 +1795,81 @@
</blockquote>
<!-- ------------------------------------------------------ -->
<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 jdk7 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>
+ <!-- ------------------------------------------------------ -->
+ <hr>
<h2><a name="troubleshooting">Troubleshooting</a></h2>
<blockquote>
A build can fail for any number of reasons.
@@ -1707,6 +1895,19 @@
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
@@ -1801,7 +2002,11 @@
</blockquote>
</li>
<li>
- <b>Windows Error Message: <tt>*** fatal error - couldn't allocate heap, ... </tt></b>
+ <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
@@ -1810,12 +2015,11 @@
</blockquote>
</li>
<li>
- <b>Windows Error Message: <tt>*** multiple target patterns. Stop.</tt></b>
+ <b>Windows Error Message: <tt>spawn failed</tt></b>
<blockquote>
- The CYGWIN make version 3.81 may not like the Windows <tt>C:/</tt>
- style paths, it may not like the ':' character in the path
- when used in a makefile target definition.
- See the <a href="#gmake"><tt><i>gmake</i></tt></a> section.
+ 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>
--- a/hotspot/.hgtags Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/.hgtags Wed Jul 05 17:38:16 2017 +0200
@@ -154,3 +154,5 @@
0e531ab5ba04967a0e9aa6aef65e6eb3a0dcf632 jdk7-b132
a8d643a4db47c7b58e0bcb49c77b5c3610de86a8 hs21-b03
1b3a350709e4325d759bb453ff3fb6a463270488 jdk7-b133
+447e6faab4a8755d4860c2366630729dbaec111c jdk7-b134
+3c76374706ea8a77e15aec8310e831e5734f8775 hs21-b04
--- a/hotspot/make/hotspot_version Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/make/hotspot_version Wed Jul 05 17:38:16 2017 +0200
@@ -35,7 +35,7 @@
HS_MAJOR_VER=21
HS_MINOR_VER=0
-HS_BUILD_NUMBER=04
+HS_BUILD_NUMBER=05
JDK_MAJOR_VER=1
JDK_MINOR_VER=7
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -3179,7 +3179,7 @@
Label& wrong_method_type) {
assert_different_registers(mtype_reg, mh_reg, temp_reg);
// compare method type against that of the receiver
- RegisterOrConstant mhtype_offset = delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg);
+ RegisterOrConstant mhtype_offset = delayed_value(java_lang_invoke_MethodHandle::type_offset_in_bytes, temp_reg);
load_heap_oop(mh_reg, mhtype_offset, temp_reg);
cmp(temp_reg, mtype_reg);
br(Assembler::notEqual, false, Assembler::pn, wrong_method_type);
@@ -3195,14 +3195,14 @@
Register temp_reg) {
assert_different_registers(vmslots_reg, mh_reg, temp_reg);
// load mh.type.form.vmslots
- if (java_dyn_MethodHandle::vmslots_offset_in_bytes() != 0) {
+ if (java_lang_invoke_MethodHandle::vmslots_offset_in_bytes() != 0) {
// hoist vmslots into every mh to avoid dependent load chain
- ld( Address(mh_reg, delayed_value(java_dyn_MethodHandle::vmslots_offset_in_bytes, temp_reg)), vmslots_reg);
+ ld( Address(mh_reg, delayed_value(java_lang_invoke_MethodHandle::vmslots_offset_in_bytes, temp_reg)), vmslots_reg);
} else {
Register temp2_reg = vmslots_reg;
- load_heap_oop(Address(mh_reg, delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg)), temp2_reg);
- load_heap_oop(Address(temp2_reg, delayed_value(java_dyn_MethodType::form_offset_in_bytes, temp_reg)), temp2_reg);
- ld( Address(temp2_reg, delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, temp_reg)), vmslots_reg);
+ load_heap_oop(Address(mh_reg, delayed_value(java_lang_invoke_MethodHandle::type_offset_in_bytes, temp_reg)), temp2_reg);
+ load_heap_oop(Address(temp2_reg, delayed_value(java_lang_invoke_MethodType::form_offset_in_bytes, temp_reg)), temp2_reg);
+ ld( Address(temp2_reg, delayed_value(java_lang_invoke_MethodTypeForm::vmslots_offset_in_bytes, temp_reg)), vmslots_reg);
}
}
@@ -3213,7 +3213,7 @@
// pick out the interpreted side of the handler
// NOTE: vmentry is not an oop!
- ld_ptr(mh_reg, delayed_value(java_dyn_MethodHandle::vmentry_offset_in_bytes, temp_reg), temp_reg);
+ ld_ptr(mh_reg, delayed_value(java_lang_invoke_MethodHandle::vmentry_offset_in_bytes, temp_reg), temp_reg);
// off we go...
ld_ptr(temp_reg, MethodHandleEntry::from_interpreted_entry_offset_in_bytes(), temp_reg);
--- a/hotspot/src/cpu/sparc/vm/cppInterpreter_sparc.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/cpu/sparc/vm/cppInterpreter_sparc.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -1188,7 +1188,7 @@
__ st_ptr(O2, XXX_STATE(_stack)); // PREPUSH
__ lduh(max_stack, O3); // Full size expression stack
- guarantee(!EnableMethodHandles, "no support yet for java.dyn.MethodHandle"); //6815692
+ guarantee(!EnableMethodHandles, "no support yet for java.lang.invoke.MethodHandle"); //6815692
//6815692//if (EnableMethodHandles)
//6815692// __ inc(O3, methodOopDesc::extra_stack_entries());
__ sll(O3, LogBytesPerWord, O3);
--- a/hotspot/src/cpu/sparc/vm/globals_sparc.hpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/cpu/sparc/vm/globals_sparc.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -51,6 +51,7 @@
define_pd_global(intx, OptoLoopAlignment, 16); // = 4*wordSize
define_pd_global(intx, InlineFrequencyCount, 50); // we can use more inlining on the SPARC
define_pd_global(intx, InlineSmallCode, 1500);
+
#ifdef _LP64
// Stack slots are 2X larger in LP64 than in the 32 bit VM.
define_pd_global(intx, ThreadStackSize, 1024);
@@ -71,4 +72,6 @@
define_pd_global(bool, UseMembar, false);
+// GC Ergo Flags
+define_pd_global(intx, CMSYoungGenPerWorker, 16*M); // default max size of CMS young gen, per GC worker thread
#endif // CPU_SPARC_VM_GLOBALS_SPARC_HPP
--- a/hotspot/src/cpu/sparc/vm/interpreter_sparc.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/cpu/sparc/vm/interpreter_sparc.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -260,7 +260,7 @@
// Method handle invoker
-// Dispatch a method of the form java.dyn.MethodHandles::invoke(...)
+// Dispatch a method of the form java.lang.invoke.MethodHandles::invoke(...)
address InterpreterGenerator::generate_method_handle_entry(void) {
if (!EnableMethodHandles) {
return generate_abstract_entry();
--- a/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -112,8 +112,8 @@
}
// given the MethodType, find out where the MH argument is buried
- __ load_heap_oop(Address(O0_mtype, __ delayed_value(java_dyn_MethodType::form_offset_in_bytes, O1_scratch)), O4_argslot);
- __ ldsw( Address(O4_argslot, __ delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, O1_scratch)), O4_argslot);
+ __ load_heap_oop(Address(O0_mtype, __ delayed_value(java_lang_invoke_MethodType::form_offset_in_bytes, O1_scratch)), O4_argslot);
+ __ ldsw( Address(O4_argslot, __ delayed_value(java_lang_invoke_MethodTypeForm::vmslots_offset_in_bytes, O1_scratch)), O4_argslot);
__ add(Gargs, __ argument_offset(O4_argslot, 1), O4_argbase);
// Note: argument_address uses its input as a scratch register!
__ ld_ptr(Address(O4_argbase, -Interpreter::stackElementSize), G3_method_handle);
@@ -141,10 +141,10 @@
// load up an adapter from the calling type (Java weaves this)
Register O2_form = O2_scratch;
Register O3_adapter = O3_scratch;
- __ load_heap_oop(Address(O0_mtype, __ delayed_value(java_dyn_MethodType::form_offset_in_bytes, O1_scratch)), O2_form);
- // load_heap_oop(Address(O2_form, __ delayed_value(java_dyn_MethodTypeForm::genericInvoker_offset_in_bytes, O1_scratch)), O3_adapter);
+ __ load_heap_oop(Address(O0_mtype, __ delayed_value(java_lang_invoke_MethodType::form_offset_in_bytes, O1_scratch)), O2_form);
+ // load_heap_oop(Address(O2_form, __ delayed_value(java_lang_invoke_MethodTypeForm::genericInvoker_offset_in_bytes, O1_scratch)), O3_adapter);
// deal with old JDK versions:
- __ add( Address(O2_form, __ delayed_value(java_dyn_MethodTypeForm::genericInvoker_offset_in_bytes, O1_scratch)), O3_adapter);
+ __ add( Address(O2_form, __ delayed_value(java_lang_invoke_MethodTypeForm::genericInvoker_offset_in_bytes, O1_scratch)), O3_adapter);
__ cmp(O3_adapter, O2_form);
Label sorry_no_invoke_generic;
__ brx(Assembler::lessUnsigned, false, Assembler::pn, sorry_no_invoke_generic);
@@ -376,16 +376,16 @@
// which conversion op types are implemented here?
int MethodHandles::adapter_conversion_ops_supported_mask() {
- return ((1<<sun_dyn_AdapterMethodHandle::OP_RETYPE_ONLY)
- |(1<<sun_dyn_AdapterMethodHandle::OP_RETYPE_RAW)
- |(1<<sun_dyn_AdapterMethodHandle::OP_CHECK_CAST)
- |(1<<sun_dyn_AdapterMethodHandle::OP_PRIM_TO_PRIM)
- |(1<<sun_dyn_AdapterMethodHandle::OP_REF_TO_PRIM)
- |(1<<sun_dyn_AdapterMethodHandle::OP_SWAP_ARGS)
- |(1<<sun_dyn_AdapterMethodHandle::OP_ROT_ARGS)
- |(1<<sun_dyn_AdapterMethodHandle::OP_DUP_ARGS)
- |(1<<sun_dyn_AdapterMethodHandle::OP_DROP_ARGS)
- //|(1<<sun_dyn_AdapterMethodHandle::OP_SPREAD_ARGS) //BUG!
+ return ((1<<java_lang_invoke_AdapterMethodHandle::OP_RETYPE_ONLY)
+ |(1<<java_lang_invoke_AdapterMethodHandle::OP_RETYPE_RAW)
+ |(1<<java_lang_invoke_AdapterMethodHandle::OP_CHECK_CAST)
+ |(1<<java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_PRIM)
+ |(1<<java_lang_invoke_AdapterMethodHandle::OP_REF_TO_PRIM)
+ |(1<<java_lang_invoke_AdapterMethodHandle::OP_SWAP_ARGS)
+ |(1<<java_lang_invoke_AdapterMethodHandle::OP_ROT_ARGS)
+ |(1<<java_lang_invoke_AdapterMethodHandle::OP_DUP_ARGS)
+ |(1<<java_lang_invoke_AdapterMethodHandle::OP_DROP_ARGS)
+ //|(1<<java_lang_invoke_AdapterMethodHandle::OP_SPREAD_ARGS) //BUG!
);
// FIXME: MethodHandlesTest gets a crash if we enable OP_SPREAD_ARGS.
}
@@ -413,22 +413,22 @@
const Register O1_actual = O1;
const Register O2_required = O2;
- guarantee(java_dyn_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets");
+ guarantee(java_lang_invoke_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets");
// Some handy addresses:
Address G5_method_fie( G5_method, in_bytes(methodOopDesc::from_interpreted_offset()));
Address G5_method_fce( G5_method, in_bytes(methodOopDesc::from_compiled_offset()));
- Address G3_mh_vmtarget( G3_method_handle, java_dyn_MethodHandle::vmtarget_offset_in_bytes());
+ Address G3_mh_vmtarget( G3_method_handle, java_lang_invoke_MethodHandle::vmtarget_offset_in_bytes());
- Address G3_dmh_vmindex( G3_method_handle, sun_dyn_DirectMethodHandle::vmindex_offset_in_bytes());
+ Address G3_dmh_vmindex( G3_method_handle, java_lang_invoke_DirectMethodHandle::vmindex_offset_in_bytes());
- Address G3_bmh_vmargslot( G3_method_handle, sun_dyn_BoundMethodHandle::vmargslot_offset_in_bytes());
- Address G3_bmh_argument( G3_method_handle, sun_dyn_BoundMethodHandle::argument_offset_in_bytes());
+ Address G3_bmh_vmargslot( G3_method_handle, java_lang_invoke_BoundMethodHandle::vmargslot_offset_in_bytes());
+ Address G3_bmh_argument( G3_method_handle, java_lang_invoke_BoundMethodHandle::argument_offset_in_bytes());
- Address G3_amh_vmargslot( G3_method_handle, sun_dyn_AdapterMethodHandle::vmargslot_offset_in_bytes());
- Address G3_amh_argument ( G3_method_handle, sun_dyn_AdapterMethodHandle::argument_offset_in_bytes());
- Address G3_amh_conversion(G3_method_handle, sun_dyn_AdapterMethodHandle::conversion_offset_in_bytes());
+ Address G3_amh_vmargslot( G3_method_handle, java_lang_invoke_AdapterMethodHandle::vmargslot_offset_in_bytes());
+ Address G3_amh_argument ( G3_method_handle, java_lang_invoke_AdapterMethodHandle::argument_offset_in_bytes());
+ Address G3_amh_conversion(G3_method_handle, java_lang_invoke_AdapterMethodHandle::conversion_offset_in_bytes());
const int java_mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes();
@@ -453,7 +453,7 @@
__ mov(O5_savedSP, SP); // Cut the stack back to where the caller started.
Label L_no_method;
- // FIXME: fill in _raise_exception_method with a suitable sun.dyn method
+ // FIXME: fill in _raise_exception_method with a suitable java.lang.invoke method
__ set(AddressLiteral((address) &_raise_exception_method), G5_method);
__ ld_ptr(Address(G5_method, 0), G5_method);
__ tst(G5_method);
--- a/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -3303,7 +3303,7 @@
__ sll(Rret, LogBytesPerWord, Rret);
__ ld_ptr(Rtemp, Rret, Rret); // get return address
- __ load_heap_oop(G5_callsite, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, Rscratch), G3_method_handle);
+ __ load_heap_oop(G5_callsite, __ delayed_value(java_lang_invoke_CallSite::target_offset_in_bytes, Rscratch), G3_method_handle);
__ null_check(G3_method_handle);
// Adjust Rret first so Llast_SP can be same as Rret
--- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -7831,7 +7831,7 @@
void MacroAssembler::check_method_handle_type(Register mtype_reg, Register mh_reg,
Register temp_reg,
Label& wrong_method_type) {
- Address type_addr(mh_reg, delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg));
+ Address type_addr(mh_reg, delayed_value(java_lang_invoke_MethodHandle::type_offset_in_bytes, temp_reg));
// compare method type against that of the receiver
if (UseCompressedOops) {
load_heap_oop(temp_reg, type_addr);
@@ -7851,14 +7851,14 @@
Register temp_reg) {
assert_different_registers(vmslots_reg, mh_reg, temp_reg);
// load mh.type.form.vmslots
- if (java_dyn_MethodHandle::vmslots_offset_in_bytes() != 0) {
+ if (java_lang_invoke_MethodHandle::vmslots_offset_in_bytes() != 0) {
// hoist vmslots into every mh to avoid dependent load chain
- movl(vmslots_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::vmslots_offset_in_bytes, temp_reg)));
+ movl(vmslots_reg, Address(mh_reg, delayed_value(java_lang_invoke_MethodHandle::vmslots_offset_in_bytes, temp_reg)));
} else {
Register temp2_reg = vmslots_reg;
- load_heap_oop(temp2_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg)));
- load_heap_oop(temp2_reg, Address(temp2_reg, delayed_value(java_dyn_MethodType::form_offset_in_bytes, temp_reg)));
- movl(vmslots_reg, Address(temp2_reg, delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, temp_reg)));
+ load_heap_oop(temp2_reg, Address(mh_reg, delayed_value(java_lang_invoke_MethodHandle::type_offset_in_bytes, temp_reg)));
+ load_heap_oop(temp2_reg, Address(temp2_reg, delayed_value(java_lang_invoke_MethodType::form_offset_in_bytes, temp_reg)));
+ movl(vmslots_reg, Address(temp2_reg, delayed_value(java_lang_invoke_MethodTypeForm::vmslots_offset_in_bytes, temp_reg)));
}
}
@@ -7873,7 +7873,7 @@
// pick out the interpreted side of the handler
// NOTE: vmentry is not an oop!
- movptr(temp_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::vmentry_offset_in_bytes, temp_reg)));
+ movptr(temp_reg, Address(mh_reg, delayed_value(java_lang_invoke_MethodHandle::vmentry_offset_in_bytes, temp_reg)));
// off we go...
jmp(Address(temp_reg, MethodHandleEntry::from_interpreted_entry_offset_in_bytes()));
--- a/hotspot/src/cpu/x86/vm/globals_x86.hpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/cpu/x86/vm/globals_x86.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -72,4 +72,6 @@
define_pd_global(bool, UseMembar, false);
+// GC Ergo Flags
+define_pd_global(intx, CMSYoungGenPerWorker, 64*M); // default max size of CMS young gen, per GC worker thread
#endif // CPU_X86_VM_GLOBALS_X86_HPP
--- a/hotspot/src/cpu/x86/vm/interpreter_x86_32.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/cpu/x86/vm/interpreter_x86_32.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -231,7 +231,7 @@
// Method handle invoker
-// Dispatch a method of the form java.dyn.MethodHandles::invoke(...)
+// Dispatch a method of the form java.lang.invoke.MethodHandles::invoke(...)
address InterpreterGenerator::generate_method_handle_entry(void) {
if (!EnableMethodHandles) {
return generate_abstract_entry();
--- a/hotspot/src/cpu/x86/vm/interpreter_x86_64.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/cpu/x86/vm/interpreter_x86_64.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -318,7 +318,7 @@
// Method handle invoker
-// Dispatch a method of the form java.dyn.MethodHandles::invoke(...)
+// Dispatch a method of the form java.lang.invoke.MethodHandles::invoke(...)
address InterpreterGenerator::generate_method_handle_entry(void) {
if (!EnableMethodHandles) {
return generate_abstract_entry();
--- a/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -125,9 +125,9 @@
}
// given the MethodType, find out where the MH argument is buried
- __ load_heap_oop(rdx_temp, Address(rax_mtype, __ delayed_value(java_dyn_MethodType::form_offset_in_bytes, rdi_temp)));
+ __ load_heap_oop(rdx_temp, Address(rax_mtype, __ delayed_value(java_lang_invoke_MethodType::form_offset_in_bytes, rdi_temp)));
Register rdx_vmslots = rdx_temp;
- __ movl(rdx_vmslots, Address(rdx_temp, __ delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, rdi_temp)));
+ __ movl(rdx_vmslots, Address(rdx_temp, __ delayed_value(java_lang_invoke_MethodTypeForm::vmslots_offset_in_bytes, rdi_temp)));
__ movptr(rcx_recv, __ argument_address(rdx_vmslots));
trace_method_handle(_masm, "invokeExact");
@@ -154,11 +154,11 @@
rcx_argslot, rbx_temp, rdx_temp);
// load up an adapter from the calling type (Java weaves this)
- __ load_heap_oop(rdx_temp, Address(rax_mtype, __ delayed_value(java_dyn_MethodType::form_offset_in_bytes, rdi_temp)));
+ __ load_heap_oop(rdx_temp, Address(rax_mtype, __ delayed_value(java_lang_invoke_MethodType::form_offset_in_bytes, rdi_temp)));
Register rdx_adapter = rdx_temp;
- // __ load_heap_oop(rdx_adapter, Address(rdx_temp, java_dyn_MethodTypeForm::genericInvoker_offset_in_bytes()));
+ // __ load_heap_oop(rdx_adapter, Address(rdx_temp, java_lang_invoke_MethodTypeForm::genericInvoker_offset_in_bytes()));
// deal with old JDK versions:
- __ lea(rdi_temp, Address(rdx_temp, __ delayed_value(java_dyn_MethodTypeForm::genericInvoker_offset_in_bytes, rdi_temp)));
+ __ lea(rdi_temp, Address(rdx_temp, __ delayed_value(java_lang_invoke_MethodTypeForm::genericInvoker_offset_in_bytes, rdi_temp)));
__ cmpptr(rdi_temp, rdx_temp);
Label sorry_no_invoke_generic;
__ jcc(Assembler::below, sorry_no_invoke_generic);
@@ -371,16 +371,16 @@
// which conversion op types are implemented here?
int MethodHandles::adapter_conversion_ops_supported_mask() {
- return ((1<<sun_dyn_AdapterMethodHandle::OP_RETYPE_ONLY)
- |(1<<sun_dyn_AdapterMethodHandle::OP_RETYPE_RAW)
- |(1<<sun_dyn_AdapterMethodHandle::OP_CHECK_CAST)
- |(1<<sun_dyn_AdapterMethodHandle::OP_PRIM_TO_PRIM)
- |(1<<sun_dyn_AdapterMethodHandle::OP_REF_TO_PRIM)
- |(1<<sun_dyn_AdapterMethodHandle::OP_SWAP_ARGS)
- |(1<<sun_dyn_AdapterMethodHandle::OP_ROT_ARGS)
- |(1<<sun_dyn_AdapterMethodHandle::OP_DUP_ARGS)
- |(1<<sun_dyn_AdapterMethodHandle::OP_DROP_ARGS)
- //|(1<<sun_dyn_AdapterMethodHandle::OP_SPREAD_ARGS) //BUG!
+ return ((1<<java_lang_invoke_AdapterMethodHandle::OP_RETYPE_ONLY)
+ |(1<<java_lang_invoke_AdapterMethodHandle::OP_RETYPE_RAW)
+ |(1<<java_lang_invoke_AdapterMethodHandle::OP_CHECK_CAST)
+ |(1<<java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_PRIM)
+ |(1<<java_lang_invoke_AdapterMethodHandle::OP_REF_TO_PRIM)
+ |(1<<java_lang_invoke_AdapterMethodHandle::OP_SWAP_ARGS)
+ |(1<<java_lang_invoke_AdapterMethodHandle::OP_ROT_ARGS)
+ |(1<<java_lang_invoke_AdapterMethodHandle::OP_DUP_ARGS)
+ |(1<<java_lang_invoke_AdapterMethodHandle::OP_DROP_ARGS)
+ //|(1<<java_lang_invoke_AdapterMethodHandle::OP_SPREAD_ARGS) //BUG!
);
// FIXME: MethodHandlesTest gets a crash if we enable OP_SPREAD_ARGS.
}
@@ -415,21 +415,21 @@
const Register rarg2_required = LP64_ONLY(j_rarg2) NOT_LP64(rdi);
assert_different_registers(rarg0_code, rarg1_actual, rarg2_required, saved_last_sp);
- guarantee(java_dyn_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets");
+ guarantee(java_lang_invoke_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets");
// some handy addresses
Address rbx_method_fie( rbx, methodOopDesc::from_interpreted_offset() );
Address rbx_method_fce( rbx, methodOopDesc::from_compiled_offset() );
- Address rcx_mh_vmtarget( rcx_recv, java_dyn_MethodHandle::vmtarget_offset_in_bytes() );
- Address rcx_dmh_vmindex( rcx_recv, sun_dyn_DirectMethodHandle::vmindex_offset_in_bytes() );
+ Address rcx_mh_vmtarget( rcx_recv, java_lang_invoke_MethodHandle::vmtarget_offset_in_bytes() );
+ Address rcx_dmh_vmindex( rcx_recv, java_lang_invoke_DirectMethodHandle::vmindex_offset_in_bytes() );
- Address rcx_bmh_vmargslot( rcx_recv, sun_dyn_BoundMethodHandle::vmargslot_offset_in_bytes() );
- Address rcx_bmh_argument( rcx_recv, sun_dyn_BoundMethodHandle::argument_offset_in_bytes() );
+ Address rcx_bmh_vmargslot( rcx_recv, java_lang_invoke_BoundMethodHandle::vmargslot_offset_in_bytes() );
+ Address rcx_bmh_argument( rcx_recv, java_lang_invoke_BoundMethodHandle::argument_offset_in_bytes() );
- Address rcx_amh_vmargslot( rcx_recv, sun_dyn_AdapterMethodHandle::vmargslot_offset_in_bytes() );
- Address rcx_amh_argument( rcx_recv, sun_dyn_AdapterMethodHandle::argument_offset_in_bytes() );
- Address rcx_amh_conversion( rcx_recv, sun_dyn_AdapterMethodHandle::conversion_offset_in_bytes() );
+ Address rcx_amh_vmargslot( rcx_recv, java_lang_invoke_AdapterMethodHandle::vmargslot_offset_in_bytes() );
+ Address rcx_amh_argument( rcx_recv, java_lang_invoke_AdapterMethodHandle::argument_offset_in_bytes() );
+ Address rcx_amh_conversion( rcx_recv, java_lang_invoke_AdapterMethodHandle::conversion_offset_in_bytes() );
Address vmarg; // __ argument_address(vmargslot)
const int java_mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes();
@@ -460,7 +460,7 @@
Register rbx_method = rbx_temp;
Label L_no_method;
- // FIXME: fill in _raise_exception_method with a suitable sun.dyn method
+ // FIXME: fill in _raise_exception_method with a suitable java.lang.invoke method
__ movptr(rbx_method, ExternalAddress((address) &_raise_exception_method));
__ testptr(rbx_method, rbx_method);
__ jccb(Assembler::zero, L_no_method);
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -3110,7 +3110,7 @@
__ profile_call(rsi);
}
- __ movptr(rcx_method_handle, Address(rax_callsite, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, rcx)));
+ __ movptr(rcx_method_handle, Address(rax_callsite, __ delayed_value(java_lang_invoke_CallSite::target_offset_in_bytes, rcx)));
__ null_check(rcx_method_handle);
__ prepare_to_jump_from_interpreted();
__ jump_to_method_handle_entry(rcx_method_handle, rdx);
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -3145,7 +3145,7 @@
__ profile_call(r13);
}
- __ load_heap_oop(rcx_method_handle, Address(rax_callsite, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, rcx)));
+ __ load_heap_oop(rcx_method_handle, Address(rax_callsite, __ delayed_value(java_lang_invoke_CallSite::target_offset_in_bytes, rcx)));
__ null_check(rcx_method_handle);
__ prepare_to_jump_from_interpreted();
__ jump_to_method_handle_entry(rcx_method_handle, rdx);
--- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -436,6 +436,13 @@
UseCountLeadingZerosInstruction = true;
}
}
+
+ // On family 21 processors default is no sw prefetch
+ if ( cpu_family() == 21 ) {
+ if (FLAG_IS_DEFAULT(AllocatePrefetchStyle)) {
+ AllocatePrefetchStyle = 0;
+ }
+ }
}
if( is_intel() ) { // Intel cpus specific settings
--- a/hotspot/src/os/solaris/dtrace/libjvm_db.c Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/os/solaris/dtrace/libjvm_db.c Wed Jul 05 17:38:16 2017 +0200
@@ -524,6 +524,8 @@
CHECK_FAIL(err);
err = read_pointer(J, constantPool + nameIndex * POINTER_SIZE + SIZE_constantPoolOopDesc, &nameSymbol);
CHECK_FAIL(err);
+ // The symbol is a CPSlot and has lower bit set to indicate metadata
+ nameSymbol &= (~1); // remove metadata lsb
err = ps_pread(J->P, nameSymbol + OFFSET_Symbol_length, &nameSymbolLength, 2);
CHECK_FAIL(err);
nameString = (char*)calloc(nameSymbolLength + 1, 1);
@@ -535,6 +537,7 @@
CHECK_FAIL(err);
err = read_pointer(J, constantPool + signatureIndex * POINTER_SIZE + SIZE_constantPoolOopDesc, &signatureSymbol);
CHECK_FAIL(err);
+ signatureSymbol &= (~1); // remove metadata lsb
err = ps_pread(J->P, signatureSymbol + OFFSET_Symbol_length, &signatureSymbolLength, 2);
CHECK_FAIL(err);
signatureString = (char*)calloc(signatureSymbolLength + 1, 1);
--- a/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -209,7 +209,7 @@
// limit this optimization to current block
if (value != NULL && in_current_block(conv)) {
set_canonical(new StoreField(x->obj(), x->offset(), x->field(), value, x->is_static(),
- x->state_before(), x->is_loaded(), x->is_initialized()));
+ x->state_before(), x->needs_patching()));
return;
}
}
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -1456,12 +1456,12 @@
BasicType field_type = field->type()->basic_type();
ValueType* type = as_ValueType(field_type);
// call will_link again to determine if the field is valid.
- const bool is_loaded = holder->is_loaded() &&
- field->will_link(method()->holder(), code);
- const bool is_initialized = is_loaded && holder->is_initialized();
+ const bool needs_patching = !holder->is_loaded() ||
+ !field->will_link(method()->holder(), code) ||
+ PatchALot;
ValueStack* state_before = NULL;
- if (!is_initialized || PatchALot) {
+ if (!holder->is_initialized() || needs_patching) {
// save state before instruction for debug info when
// deoptimization happens during patching
state_before = copy_state_before();
@@ -1469,10 +1469,6 @@
Value obj = NULL;
if (code == Bytecodes::_getstatic || code == Bytecodes::_putstatic) {
- // commoning of class constants should only occur if the class is
- // fully initialized and resolved in this constant pool. The will_link test
- // above essentially checks if this class is resolved in this constant pool
- // so, the is_initialized flag should be suffiect.
if (state_before != NULL) {
// build a patching constant
obj = new Constant(new ClassConstant(holder), state_before);
@@ -1482,7 +1478,7 @@
}
- const int offset = is_loaded ? field->offset() : -1;
+ const int offset = !needs_patching ? field->offset() : -1;
switch (code) {
case Bytecodes::_getstatic: {
// check for compile-time constants, i.e., initialized static final fields
@@ -1509,7 +1505,7 @@
state_before = copy_state_for_exception();
}
push(type, append(new LoadField(append(obj), offset, field, true,
- state_before, is_loaded, is_initialized)));
+ state_before, needs_patching)));
}
break;
}
@@ -1518,7 +1514,7 @@
if (state_before == NULL) {
state_before = copy_state_for_exception();
}
- append(new StoreField(append(obj), offset, field, val, true, state_before, is_loaded, is_initialized));
+ append(new StoreField(append(obj), offset, field, val, true, state_before, needs_patching));
}
break;
case Bytecodes::_getfield :
@@ -1526,8 +1522,8 @@
if (state_before == NULL) {
state_before = copy_state_for_exception();
}
- LoadField* load = new LoadField(apop(), offset, field, false, state_before, is_loaded, true);
- Value replacement = is_loaded ? _memory->load(load) : load;
+ LoadField* load = new LoadField(apop(), offset, field, false, state_before, needs_patching);
+ Value replacement = !needs_patching ? _memory->load(load) : load;
if (replacement != load) {
assert(replacement->is_linked() || !replacement->can_be_linked(), "should already by linked");
push(type, replacement);
@@ -1542,8 +1538,8 @@
if (state_before == NULL) {
state_before = copy_state_for_exception();
}
- StoreField* store = new StoreField(apop(), offset, field, val, false, state_before, is_loaded, true);
- if (is_loaded) store = _memory->store(store);
+ StoreField* store = new StoreField(apop(), offset, field, val, false, state_before, needs_patching);
+ if (!needs_patching) store = _memory->store(store);
if (store != NULL) {
append(store);
}
--- a/hotspot/src/share/vm/c1/c1_Instruction.hpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/c1/c1_Instruction.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -323,8 +323,6 @@
CanTrapFlag,
DirectCompareFlag,
IsEliminatedFlag,
- IsInitializedFlag,
- IsLoadedFlag,
IsSafepointFlag,
IsStaticFlag,
IsStrictfpFlag,
@@ -693,7 +691,7 @@
public:
// creation
AccessField(Value obj, int offset, ciField* field, bool is_static,
- ValueStack* state_before, bool is_loaded, bool is_initialized)
+ ValueStack* state_before, bool needs_patching)
: Instruction(as_ValueType(field->type()->basic_type()), state_before)
, _obj(obj)
, _offset(offset)
@@ -701,16 +699,9 @@
, _explicit_null_check(NULL)
{
set_needs_null_check(!is_static);
- set_flag(IsLoadedFlag, is_loaded);
- set_flag(IsInitializedFlag, is_initialized);
set_flag(IsStaticFlag, is_static);
+ set_flag(NeedsPatchingFlag, needs_patching);
ASSERT_VALUES
- if (!is_loaded || (PatchALot && !field->is_volatile())) {
- // need to patch if the holder wasn't loaded or we're testing
- // using PatchALot. Don't allow PatchALot for fields which are
- // known to be volatile they aren't patchable.
- set_flag(NeedsPatchingFlag, true);
- }
// pin of all instructions with memory access
pin();
}
@@ -721,11 +712,14 @@
ciField* field() const { return _field; }
BasicType field_type() const { return _field->type()->basic_type(); }
bool is_static() const { return check_flag(IsStaticFlag); }
- bool is_loaded() const { return check_flag(IsLoadedFlag); }
- bool is_initialized() const { return check_flag(IsInitializedFlag); }
NullCheck* explicit_null_check() const { return _explicit_null_check; }
bool needs_patching() const { return check_flag(NeedsPatchingFlag); }
+ // Unresolved getstatic and putstatic can cause initialization.
+ // Technically it occurs at the Constant that materializes the base
+ // of the static fields but it's simpler to model it here.
+ bool is_init_point() const { return is_static() && (needs_patching() || !_field->holder()->is_initialized()); }
+
// manipulation
// Under certain circumstances, if a previous NullCheck instruction
@@ -745,15 +739,15 @@
public:
// creation
LoadField(Value obj, int offset, ciField* field, bool is_static,
- ValueStack* state_before, bool is_loaded, bool is_initialized)
- : AccessField(obj, offset, field, is_static, state_before, is_loaded, is_initialized)
+ ValueStack* state_before, bool needs_patching)
+ : AccessField(obj, offset, field, is_static, state_before, needs_patching)
{}
ciType* declared_type() const;
ciType* exact_type() const;
// generic
- HASHING2(LoadField, is_loaded() && !field()->is_volatile(), obj()->subst(), offset()) // cannot be eliminated if not yet loaded or if volatile
+ HASHING2(LoadField, !needs_patching() && !field()->is_volatile(), obj()->subst(), offset()) // cannot be eliminated if needs patching or if volatile
};
@@ -764,8 +758,8 @@
public:
// creation
StoreField(Value obj, int offset, ciField* field, Value value, bool is_static,
- ValueStack* state_before, bool is_loaded, bool is_initialized)
- : AccessField(obj, offset, field, is_static, state_before, is_loaded, is_initialized)
+ ValueStack* state_before, bool needs_patching)
+ : AccessField(obj, offset, field, is_static, state_before, needs_patching)
, _value(value)
{
set_flag(NeedsWriteBarrierFlag, as_ValueType(field_type())->is_object());
--- a/hotspot/src/share/vm/c1/c1_LIR.hpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIR.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -1156,7 +1156,7 @@
return
is_invokedynamic() // An invokedynamic is always a MethodHandle call site.
||
- (method()->holder()->name() == ciSymbol::java_dyn_MethodHandle() &&
+ (method()->holder()->name() == ciSymbol::java_lang_invoke_MethodHandle() &&
methodOopDesc::is_method_handle_invoke_name(method()->name()->sid()));
}
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -1559,9 +1559,7 @@
(info ? new CodeEmitInfo(info) : NULL));
}
- if (is_volatile) {
- assert(!needs_patching && x->is_loaded(),
- "how do we know it's volatile if it's not loaded");
+ if (is_volatile && !needs_patching) {
volatile_field_store(value.result(), address, info);
} else {
LIR_PatchCode patch_code = needs_patching ? lir_patch_normal : lir_patch_none;
@@ -1627,9 +1625,7 @@
address = generate_address(object.result(), x->offset(), field_type);
}
- if (is_volatile) {
- assert(!needs_patching && x->is_loaded(),
- "how do we know it's volatile if it's not loaded");
+ if (is_volatile && !needs_patching) {
volatile_field_load(address, reg, info);
} else {
LIR_PatchCode patch_code = needs_patching ? lir_patch_normal : lir_patch_none;
@@ -2516,7 +2512,7 @@
__ load(new LIR_Address(tmp, call_site_offset, T_OBJECT), tmp);
// Load target MethodHandle from CallSite object.
- __ load(new LIR_Address(tmp, java_dyn_CallSite::target_offset_in_bytes(), T_OBJECT), receiver);
+ __ load(new LIR_Address(tmp, java_lang_invoke_CallSite::target_offset_in_bytes(), T_OBJECT), receiver);
__ call_dynamic(target, receiver, result_register,
SharedRuntime::get_resolve_opt_virtual_call_stub(),
--- a/hotspot/src/share/vm/c1/c1_LinearScan.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/c1/c1_LinearScan.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -2703,7 +2703,7 @@
assert(_fpu_stack_allocator != NULL, "must be present");
opr = _fpu_stack_allocator->to_fpu_stack(opr);
- assert(opr->fpu_regnrLo() == opr->fpu_regnrHi(), "assumed in calculation (only fpu_regnrHi is used)");
+ assert(opr->fpu_regnrLo() == opr->fpu_regnrHi(), "assumed in calculation (only fpu_regnrLo is used)");
#endif
#ifdef SPARC
assert(opr->fpu_regnrLo() == opr->fpu_regnrHi() + 1, "assumed in calculation (only fpu_regnrHi is used)");
@@ -2715,7 +2715,12 @@
assert(opr->fpu_regnrLo() == opr->fpu_regnrHi(), "assumed in calculation (only fpu_regnrHi is used)");
#endif
+#ifdef VM_LITTLE_ENDIAN
+ VMReg rname_first = frame_map()->fpu_regname(opr->fpu_regnrLo());
+#else
VMReg rname_first = frame_map()->fpu_regname(opr->fpu_regnrHi());
+#endif
+
#ifdef _LP64
first = new LocationValue(Location::new_reg_loc(Location::dbl, rname_first));
second = &_int_0_scope_value;
--- a/hotspot/src/share/vm/c1/c1_ValueMap.hpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/c1/c1_ValueMap.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -141,7 +141,8 @@
// visitor functions
void do_StoreField (StoreField* x) {
- if (!x->is_initialized()) {
+ if (x->is_init_point()) {
+ // putstatic is an initialization point so treat it as a wide kill
kill_memory();
} else {
kill_field(x->field());
@@ -159,7 +160,8 @@
void do_Local (Local* x) { /* nothing to do */ }
void do_Constant (Constant* x) { /* nothing to do */ }
void do_LoadField (LoadField* x) {
- if (!x->is_initialized()) {
+ if (x->is_init_point()) {
+ // getstatic is an initialization point so treat it as a wide kill
kill_memory();
}
}
--- a/hotspot/src/share/vm/ci/ciCallSite.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/ci/ciCallSite.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,7 +34,7 @@
// Return the target MethodHandle of this CallSite.
ciMethodHandle* ciCallSite::get_target() const {
VM_ENTRY_MARK;
- oop method_handle_oop = java_dyn_CallSite::target(get_oop());
+ oop method_handle_oop = java_lang_invoke_CallSite::target(get_oop());
return CURRENT_ENV->get_object(method_handle_oop)->as_method_handle();
}
--- a/hotspot/src/share/vm/ci/ciCallSite.hpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/ci/ciCallSite.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,7 @@
// ciCallSite
//
-// The class represents a java.dyn.CallSite object.
+// The class represents a java.lang.invoke.CallSite object.
class ciCallSite : public ciInstance {
public:
ciCallSite(instanceHandle h_i) : ciInstance(h_i) {}
--- a/hotspot/src/share/vm/ci/ciField.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/ci/ciField.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -177,7 +177,7 @@
// Never trust strangely unstable finals: System.out, etc.
return false;
// Even if general trusting is disabled, trust system-built closures in these packages.
- if (holder->is_in_package("java/dyn") || holder->is_in_package("sun/dyn"))
+ if (holder->is_in_package("java/lang/invoke") || holder->is_in_package("sun/invoke"))
return true;
return TrustFinalNonStaticFields;
}
@@ -191,8 +191,9 @@
// Check to see if the field is constant.
if (_holder->is_initialized() && this->is_final()) {
if (!this->is_static()) {
- // A field can be constant if it's a final static field or if it's
- // a final non-static field of a trusted class ({java,sun}.dyn).
+ // A field can be constant if it's a final static field or if
+ // it's a final non-static field of a trusted class (classes in
+ // java.lang.invoke and sun.invoke packages and subpackages).
if (trust_final_non_static_fields(_holder)) {
_is_constant = true;
return;
--- a/hotspot/src/share/vm/ci/ciMethod.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/ci/ciMethod.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -769,7 +769,7 @@
// signature-polymorphic MethodHandle methods, invokeExact or invokeGeneric.
bool ciMethod::is_method_handle_invoke() const {
if (!is_loaded()) {
- bool flag = (holder()->name() == ciSymbol::java_dyn_MethodHandle() &&
+ bool flag = (holder()->name() == ciSymbol::java_lang_invoke_MethodHandle() &&
methodOopDesc::is_method_handle_invoke_name(name()->sid()));
return flag;
}
--- a/hotspot/src/share/vm/ci/ciMethodHandle.hpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/ci/ciMethodHandle.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,7 @@
// ciMethodHandle
//
-// The class represents a java.dyn.MethodHandle object.
+// The class represents a java.lang.invoke.MethodHandle object.
class ciMethodHandle : public ciInstance {
private:
ciMethod* _callee;
--- a/hotspot/src/share/vm/ci/ciObjectFactory.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/ci/ciObjectFactory.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -342,9 +342,9 @@
return new (arena()) ciMethodData(h_md);
} else if (o->is_instance()) {
instanceHandle h_i(THREAD, (instanceOop)o);
- if (java_dyn_CallSite::is_instance(o))
+ if (java_lang_invoke_CallSite::is_instance(o))
return new (arena()) ciCallSite(h_i);
- else if (java_dyn_MethodHandle::is_instance(o))
+ else if (java_lang_invoke_MethodHandle::is_instance(o))
return new (arena()) ciMethodHandle(h_i);
else
return new (arena()) ciInstance(h_i);
--- a/hotspot/src/share/vm/ci/ciStreams.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/ci/ciStreams.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -380,7 +380,7 @@
bool ignore;
// report as InvokeDynamic for invokedynamic, which is syntactically classless
if (cur_bc() == Bytecodes::_invokedynamic)
- return CURRENT_ENV->get_klass_by_name(_holder, ciSymbol::java_dyn_InvokeDynamic(), false);
+ return CURRENT_ENV->get_klass_by_name(_holder, ciSymbol::java_lang_invoke_InvokeDynamic(), false);
return CURRENT_ENV->get_klass_by_index(cpool, get_method_holder_index(), ignore, _holder);
}
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -146,12 +146,14 @@
break;
case JVM_CONSTANT_MethodHandle :
case JVM_CONSTANT_MethodType :
- if (!EnableMethodHandles ||
- _major_version < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
+ if (_major_version < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
classfile_parse_error(
- (!EnableMethodHandles ?
- "This JVM does not support constant tag %u in class file %s" :
- "Class file version does not support constant tag %u in class file %s"),
+ "Class file version does not support constant tag %u in class file %s",
+ tag, CHECK);
+ }
+ if (!EnableMethodHandles) {
+ classfile_parse_error(
+ "This JVM does not support constant tag %u in class file %s",
tag, CHECK);
}
if (tag == JVM_CONSTANT_MethodHandle) {
@@ -170,12 +172,14 @@
case JVM_CONSTANT_InvokeDynamicTrans : // this tag appears only in old classfiles
case JVM_CONSTANT_InvokeDynamic :
{
- if (!EnableInvokeDynamic ||
- _major_version < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
+ if (_major_version < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
classfile_parse_error(
- (!EnableInvokeDynamic ?
- "This JVM does not support constant tag %u in class file %s" :
- "Class file version does not support constant tag %u in class file %s"),
+ "Class file version does not support constant tag %u in class file %s",
+ tag, CHECK);
+ }
+ if (!EnableInvokeDynamic) {
+ classfile_parse_error(
+ "This JVM does not support constant tag %u in class file %s",
tag, CHECK);
}
cfs->guarantee_more(5, CHECK); // bsm_index, nt, tag/access_flags
@@ -1616,8 +1620,13 @@
AccessFlags access_flags;
if (name == vmSymbols::class_initializer_name()) {
- // We ignore the access flags for a class initializer. (JVM Spec. p. 116)
- flags = JVM_ACC_STATIC;
+ // We ignore the other access flags for a valid class initializer.
+ // (JVM Spec 2nd ed., chapter 4.6)
+ if (_major_version < 51) { // backward compatibility
+ flags = JVM_ACC_STATIC;
+ } else if ((flags & JVM_ACC_STATIC) == JVM_ACC_STATIC) {
+ flags &= JVM_ACC_STATIC | JVM_ACC_STRICT;
+ }
} else {
verify_legal_method_modifiers(flags, is_interface, name, CHECK_(nullHandle));
}
@@ -2797,11 +2806,11 @@
// Force MethodHandle.vmentry to be an unmanaged pointer.
// There is no way for a classfile to express this, so we must help it.
-void ClassFileParser::java_dyn_MethodHandle_fix_pre(constantPoolHandle cp,
+void ClassFileParser::java_lang_invoke_MethodHandle_fix_pre(constantPoolHandle cp,
typeArrayHandle fields,
FieldAllocationCount *fac_ptr,
TRAPS) {
- // Add fake fields for java.dyn.MethodHandle instances
+ // Add fake fields for java.lang.invoke.MethodHandle instances
//
// This is not particularly nice, but since there is no way to express
// a native wordSize field in Java, we must do it at this level.
@@ -2818,9 +2827,10 @@
}
}
+ if (AllowTransitionalJSR292 && word_sig_index == 0) return;
if (word_sig_index == 0)
THROW_MSG(vmSymbols::java_lang_VirtualMachineError(),
- "missing I or J signature (for vmentry) in java.dyn.MethodHandle");
+ "missing I or J signature (for vmentry) in java.lang.invoke.MethodHandle");
// Find vmentry field and change the signature.
bool found_vmentry = false;
@@ -2857,9 +2867,10 @@
}
}
+ if (AllowTransitionalJSR292 && !found_vmentry) return;
if (!found_vmentry)
THROW_MSG(vmSymbols::java_lang_VirtualMachineError(),
- "missing vmentry byte field in java.dyn.MethodHandle");
+ "missing vmentry byte field in java.lang.invoke.MethodHandle");
}
@@ -3224,9 +3235,18 @@
java_lang_Class_fix_pre(&methods, &fac, CHECK_(nullHandle));
}
- // adjust the vmentry field declaration in java.dyn.MethodHandle
- if (EnableMethodHandles && class_name == vmSymbols::sun_dyn_MethodHandleImpl() && class_loader.is_null()) {
- java_dyn_MethodHandle_fix_pre(cp, fields, &fac, CHECK_(nullHandle));
+ // adjust the vmentry field declaration in java.lang.invoke.MethodHandle
+ if (EnableMethodHandles && class_name == vmSymbols::java_lang_invoke_MethodHandle() && class_loader.is_null()) {
+ java_lang_invoke_MethodHandle_fix_pre(cp, fields, &fac, CHECK_(nullHandle));
+ }
+ if (AllowTransitionalJSR292 &&
+ EnableMethodHandles && class_name == vmSymbols::java_dyn_MethodHandle() && class_loader.is_null()) {
+ java_lang_invoke_MethodHandle_fix_pre(cp, fields, &fac, CHECK_(nullHandle));
+ }
+ if (AllowTransitionalJSR292 &&
+ EnableMethodHandles && class_name == vmSymbols::sun_dyn_MethodHandleImpl() && class_loader.is_null()) {
+ // allow vmentry field in MethodHandleImpl also
+ java_lang_invoke_MethodHandle_fix_pre(cp, fields, &fac, CHECK_(nullHandle));
}
// Add a fake "discovered" field if it is not present
--- a/hotspot/src/share/vm/classfile/classFileParser.hpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -162,9 +162,9 @@
// Adjust the next_nonstatic_oop_offset to place the fake fields
// before any Java fields.
void java_lang_Class_fix_post(int* next_nonstatic_oop_offset);
- // Adjust the field allocation counts for java.dyn.MethodHandle to add
+ // Adjust the field allocation counts for java.lang.invoke.MethodHandle to add
// a fake address (void*) field.
- void java_dyn_MethodHandle_fix_pre(constantPoolHandle cp,
+ void java_lang_invoke_MethodHandle_fix_pre(constantPoolHandle cp,
typeArrayHandle fields,
FieldAllocationCount *fac_ptr, TRAPS);
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -66,6 +66,28 @@
return ik->find_local_field(name_symbol, signature_symbol, fd);
}
+static bool find_hacked_field(instanceKlass* ik,
+ Symbol* name_symbol, Symbol* signature_symbol,
+ fieldDescriptor* fd,
+ bool allow_super = false) {
+ bool found = find_field(ik, name_symbol, signature_symbol, fd, allow_super);
+ if (!found && AllowTransitionalJSR292) {
+ Symbol* backup_sig = SystemDictionary::find_backup_signature(signature_symbol);
+ if (backup_sig != NULL) {
+ found = find_field(ik, name_symbol, backup_sig, fd, allow_super);
+ if (TraceMethodHandles) {
+ ResourceMark rm;
+ tty->print_cr("MethodHandles: %s.%s: backup for %s => %s%s",
+ ik->name()->as_C_string(), name_symbol->as_C_string(),
+ signature_symbol->as_C_string(), backup_sig->as_C_string(),
+ (found ? "" : " (NOT FOUND)"));
+ }
+ }
+ }
+ return found;
+}
+#define find_field find_hacked_field /* remove after AllowTransitionalJSR292 */
+
// Helpful routine for computing field offsets at run time rather than hardcoding them
static void
compute_offset(int &dest_offset,
@@ -2176,41 +2198,43 @@
}
-// Support for java_dyn_MethodHandle
-
-int java_dyn_MethodHandle::_type_offset;
-int java_dyn_MethodHandle::_vmtarget_offset;
-int java_dyn_MethodHandle::_vmentry_offset;
-int java_dyn_MethodHandle::_vmslots_offset;
-
-int sun_dyn_MemberName::_clazz_offset;
-int sun_dyn_MemberName::_name_offset;
-int sun_dyn_MemberName::_type_offset;
-int sun_dyn_MemberName::_flags_offset;
-int sun_dyn_MemberName::_vmtarget_offset;
-int sun_dyn_MemberName::_vmindex_offset;
-
-int sun_dyn_DirectMethodHandle::_vmindex_offset;
-
-int sun_dyn_BoundMethodHandle::_argument_offset;
-int sun_dyn_BoundMethodHandle::_vmargslot_offset;
-
-int sun_dyn_AdapterMethodHandle::_conversion_offset;
-
-void java_dyn_MethodHandle::compute_offsets() {
+// Support for java_lang_invoke_MethodHandle
+
+int java_lang_invoke_MethodHandle::_type_offset;
+int java_lang_invoke_MethodHandle::_vmtarget_offset;
+int java_lang_invoke_MethodHandle::_vmentry_offset;
+int java_lang_invoke_MethodHandle::_vmslots_offset;
+
+int java_lang_invoke_MemberName::_clazz_offset;
+int java_lang_invoke_MemberName::_name_offset;
+int java_lang_invoke_MemberName::_type_offset;
+int java_lang_invoke_MemberName::_flags_offset;
+int java_lang_invoke_MemberName::_vmtarget_offset;
+int java_lang_invoke_MemberName::_vmindex_offset;
+
+int java_lang_invoke_DirectMethodHandle::_vmindex_offset;
+
+int java_lang_invoke_BoundMethodHandle::_argument_offset;
+int java_lang_invoke_BoundMethodHandle::_vmargslot_offset;
+
+int java_lang_invoke_AdapterMethodHandle::_conversion_offset;
+
+void java_lang_invoke_MethodHandle::compute_offsets() {
klassOop k = SystemDictionary::MethodHandle_klass();
if (k != NULL && EnableMethodHandles) {
- compute_offset(_type_offset, k, vmSymbols::type_name(), vmSymbols::java_dyn_MethodType_signature(), true);
- compute_offset(_vmtarget_offset, k, vmSymbols::vmtarget_name(), vmSymbols::object_signature(), true);
- compute_offset(_vmentry_offset, k, vmSymbols::vmentry_name(), vmSymbols::machine_word_signature(), true);
+ bool allow_super = false;
+ if (AllowTransitionalJSR292) allow_super = true; // temporary, to access java.dyn.MethodHandleImpl
+ compute_offset(_type_offset, k, vmSymbols::type_name(), vmSymbols::java_lang_invoke_MethodType_signature(), allow_super);
+ compute_offset(_vmtarget_offset, k, vmSymbols::vmtarget_name(), vmSymbols::object_signature(), allow_super);
+ compute_offset(_vmentry_offset, k, vmSymbols::vmentry_name(), vmSymbols::machine_word_signature(), allow_super);
// Note: MH.vmslots (if it is present) is a hoisted copy of MH.type.form.vmslots.
// It is optional pending experiments to keep or toss.
- compute_optional_offset(_vmslots_offset, k, vmSymbols::vmslots_name(), vmSymbols::int_signature(), true);
+ compute_optional_offset(_vmslots_offset, k, vmSymbols::vmslots_name(), vmSymbols::int_signature(), allow_super);
}
}
-void sun_dyn_MemberName::compute_offsets() {
+void java_lang_invoke_MemberName::compute_offsets() {
klassOop k = SystemDictionary::MemberName_klass();
if (k != NULL && EnableMethodHandles) {
compute_offset(_clazz_offset, k, vmSymbols::clazz_name(), vmSymbols::class_signature());
@@ -2222,14 +2246,14 @@
}
}
-void sun_dyn_DirectMethodHandle::compute_offsets() {
+void java_lang_invoke_DirectMethodHandle::compute_offsets() {
klassOop k = SystemDictionary::DirectMethodHandle_klass();
if (k != NULL && EnableMethodHandles) {
compute_offset(_vmindex_offset, k, vmSymbols::vmindex_name(), vmSymbols::int_signature(), true);
}
}
-void sun_dyn_BoundMethodHandle::compute_offsets() {
+void java_lang_invoke_BoundMethodHandle::compute_offsets() {
klassOop k = SystemDictionary::BoundMethodHandle_klass();
if (k != NULL && EnableMethodHandles) {
compute_offset(_vmargslot_offset, k, vmSymbols::vmargslot_name(), vmSymbols::int_signature(), true);
@@ -2237,22 +2261,22 @@
}
}
-void sun_dyn_AdapterMethodHandle::compute_offsets() {
+void java_lang_invoke_AdapterMethodHandle::compute_offsets() {
klassOop k = SystemDictionary::AdapterMethodHandle_klass();
if (k != NULL && EnableMethodHandles) {
compute_offset(_conversion_offset, k, vmSymbols::conversion_name(), vmSymbols::int_signature(), true);
}
}
-oop java_dyn_MethodHandle::type(oop mh) {
+oop java_lang_invoke_MethodHandle::type(oop mh) {
return mh->obj_field(_type_offset);
}
-void java_dyn_MethodHandle::set_type(oop mh, oop mtype) {
+void java_lang_invoke_MethodHandle::set_type(oop mh, oop mtype) {
mh->obj_field_put(_type_offset, mtype);
}
-int java_dyn_MethodHandle::vmslots(oop mh) {
+int java_lang_invoke_MethodHandle::vmslots(oop mh) {
int vmslots_offset = _vmslots_offset;
if (vmslots_offset != 0) {
#ifdef ASSERT
@@ -2267,7 +2291,7 @@
}
// if MH.vmslots exists, hoist into it the value of type.form.vmslots
-void java_dyn_MethodHandle::init_vmslots(oop mh) {
+void java_lang_invoke_MethodHandle::init_vmslots(oop mh) {
int vmslots_offset = _vmslots_offset;
if (vmslots_offset != 0) {
mh->int_field_put(vmslots_offset, compute_vmslots(mh));
@@ -2276,20 +2300,20 @@
// fetch type.form.vmslots, which is the number of JVM stack slots
// required to carry the arguments of this MH
-int java_dyn_MethodHandle::compute_vmslots(oop mh) {
+int java_lang_invoke_MethodHandle::compute_vmslots(oop mh) {
oop mtype = type(mh);
if (mtype == NULL) return 0; // Java code would get NPE
- oop form = java_dyn_MethodType::form(mtype);
+ oop form = java_lang_invoke_MethodType::form(mtype);
if (form == NULL) return 0; // Java code would get NPE
- return java_dyn_MethodTypeForm::vmslots(form);
+ return java_lang_invoke_MethodTypeForm::vmslots(form);
}
// fetch the low-level entry point for this mh
-MethodHandleEntry* java_dyn_MethodHandle::vmentry(oop mh) {
+MethodHandleEntry* java_lang_invoke_MethodHandle::vmentry(oop mh) {
return (MethodHandleEntry*) mh->address_field(_vmentry_offset);
}
-void java_dyn_MethodHandle::set_vmentry(oop mh, MethodHandleEntry* me) {
+void java_lang_invoke_MethodHandle::set_vmentry(oop mh, MethodHandleEntry* me) {
assert(_vmentry_offset != 0, "must be present");
// This is always the final step that initializes a valid method handle:
@@ -2303,123 +2327,123 @@
/// MemberName accessors
-oop sun_dyn_MemberName::clazz(oop mname) {
+oop java_lang_invoke_MemberName::clazz(oop mname) {
assert(is_instance(mname), "wrong type");
return mname->obj_field(_clazz_offset);
}
-void sun_dyn_MemberName::set_clazz(oop mname, oop clazz) {
+void java_lang_invoke_MemberName::set_clazz(oop mname, oop clazz) {
assert(is_instance(mname), "wrong type");
mname->obj_field_put(_clazz_offset, clazz);
}
-oop sun_dyn_MemberName::name(oop mname) {
+oop java_lang_invoke_MemberName::name(oop mname) {
assert(is_instance(mname), "wrong type");
return mname->obj_field(_name_offset);
}
-void sun_dyn_MemberName::set_name(oop mname, oop name) {
+void java_lang_invoke_MemberName::set_name(oop mname, oop name) {
assert(is_instance(mname), "wrong type");
mname->obj_field_put(_name_offset, name);
}
-oop sun_dyn_MemberName::type(oop mname) {
+oop java_lang_invoke_MemberName::type(oop mname) {
assert(is_instance(mname), "wrong type");
return mname->obj_field(_type_offset);
}
-void sun_dyn_MemberName::set_type(oop mname, oop type) {
+void java_lang_invoke_MemberName::set_type(oop mname, oop type) {
assert(is_instance(mname), "wrong type");
mname->obj_field_put(_type_offset, type);
}
-int sun_dyn_MemberName::flags(oop mname) {
+int java_lang_invoke_MemberName::flags(oop mname) {
assert(is_instance(mname), "wrong type");
return mname->int_field(_flags_offset);
}
-void sun_dyn_MemberName::set_flags(oop mname, int flags) {
+void java_lang_invoke_MemberName::set_flags(oop mname, int flags) {
assert(is_instance(mname), "wrong type");
mname->int_field_put(_flags_offset, flags);
}
-oop sun_dyn_MemberName::vmtarget(oop mname) {
+oop java_lang_invoke_MemberName::vmtarget(oop mname) {
assert(is_instance(mname), "wrong type");
return mname->obj_field(_vmtarget_offset);
}
-void sun_dyn_MemberName::set_vmtarget(oop mname, oop ref) {
+void java_lang_invoke_MemberName::set_vmtarget(oop mname, oop ref) {
assert(is_instance(mname), "wrong type");
mname->obj_field_put(_vmtarget_offset, ref);
}
-int sun_dyn_MemberName::vmindex(oop mname) {
+int java_lang_invoke_MemberName::vmindex(oop mname) {
assert(is_instance(mname), "wrong type");
return mname->int_field(_vmindex_offset);
}
-void sun_dyn_MemberName::set_vmindex(oop mname, int index) {
+void java_lang_invoke_MemberName::set_vmindex(oop mname, int index) {
assert(is_instance(mname), "wrong type");
mname->int_field_put(_vmindex_offset, index);
}
-oop java_dyn_MethodHandle::vmtarget(oop mh) {
+oop java_lang_invoke_MethodHandle::vmtarget(oop mh) {
assert(is_instance(mh), "MH only");
return mh->obj_field(_vmtarget_offset);
}
-void java_dyn_MethodHandle::set_vmtarget(oop mh, oop ref) {
+void java_lang_invoke_MethodHandle::set_vmtarget(oop mh, oop ref) {
assert(is_instance(mh), "MH only");
mh->obj_field_put(_vmtarget_offset, ref);
}
-int sun_dyn_DirectMethodHandle::vmindex(oop mh) {
+int java_lang_invoke_DirectMethodHandle::vmindex(oop mh) {
assert(is_instance(mh), "DMH only");
return mh->int_field(_vmindex_offset);
}
-void sun_dyn_DirectMethodHandle::set_vmindex(oop mh, int index) {
+void java_lang_invoke_DirectMethodHandle::set_vmindex(oop mh, int index) {
assert(is_instance(mh), "DMH only");
mh->int_field_put(_vmindex_offset, index);
}
-int sun_dyn_BoundMethodHandle::vmargslot(oop mh) {
+int java_lang_invoke_BoundMethodHandle::vmargslot(oop mh) {
assert(is_instance(mh), "BMH only");
return mh->int_field(_vmargslot_offset);
}
-oop sun_dyn_BoundMethodHandle::argument(oop mh) {
+oop java_lang_invoke_BoundMethodHandle::argument(oop mh) {
assert(is_instance(mh), "BMH only");
return mh->obj_field(_argument_offset);
}
-int sun_dyn_AdapterMethodHandle::conversion(oop mh) {
+int java_lang_invoke_AdapterMethodHandle::conversion(oop mh) {
assert(is_instance(mh), "AMH only");
return mh->int_field(_conversion_offset);
}
-void sun_dyn_AdapterMethodHandle::set_conversion(oop mh, int conv) {
+void java_lang_invoke_AdapterMethodHandle::set_conversion(oop mh, int conv) {
assert(is_instance(mh), "AMH only");
mh->int_field_put(_conversion_offset, conv);
}
-// Support for java_dyn_MethodType
-
-int java_dyn_MethodType::_rtype_offset;
-int java_dyn_MethodType::_ptypes_offset;
-int java_dyn_MethodType::_form_offset;
-
-void java_dyn_MethodType::compute_offsets() {
+// Support for java_lang_invoke_MethodType
+
+int java_lang_invoke_MethodType::_rtype_offset;
+int java_lang_invoke_MethodType::_ptypes_offset;
+int java_lang_invoke_MethodType::_form_offset;
+
+void java_lang_invoke_MethodType::compute_offsets() {
klassOop k = SystemDictionary::MethodType_klass();
if (k != NULL) {
compute_offset(_rtype_offset, k, vmSymbols::rtype_name(), vmSymbols::class_signature());
compute_offset(_ptypes_offset, k, vmSymbols::ptypes_name(), vmSymbols::class_array_signature());
- compute_offset(_form_offset, k, vmSymbols::form_name(), vmSymbols::java_dyn_MethodTypeForm_signature());
+ compute_offset(_form_offset, k, vmSymbols::form_name(), vmSymbols::java_lang_invoke_MethodTypeForm_signature());
}
}
-void java_dyn_MethodType::print_signature(oop mt, outputStream* st) {
+void java_lang_invoke_MethodType::print_signature(oop mt, outputStream* st) {
st->print("(");
objArrayOop pts = ptypes(mt);
for (int i = 0, limit = pts->length(); i < limit; i++) {
@@ -2429,7 +2453,7 @@
java_lang_Class::print_signature(rtype(mt), st);
}
-Symbol* java_dyn_MethodType::as_signature(oop mt, bool intern_if_not_found, TRAPS) {
+Symbol* java_lang_invoke_MethodType::as_signature(oop mt, bool intern_if_not_found, TRAPS) {
ResourceMark rm;
stringStream buffer(128);
print_signature(mt, &buffer);
@@ -2444,103 +2468,83 @@
return name;
}
-oop java_dyn_MethodType::rtype(oop mt) {
+oop java_lang_invoke_MethodType::rtype(oop mt) {
assert(is_instance(mt), "must be a MethodType");
return mt->obj_field(_rtype_offset);
}
-objArrayOop java_dyn_MethodType::ptypes(oop mt) {
+objArrayOop java_lang_invoke_MethodType::ptypes(oop mt) {
assert(is_instance(mt), "must be a MethodType");
return (objArrayOop) mt->obj_field(_ptypes_offset);
}
-oop java_dyn_MethodType::form(oop mt) {
+oop java_lang_invoke_MethodType::form(oop mt) {
assert(is_instance(mt), "must be a MethodType");
return mt->obj_field(_form_offset);
}
-oop java_dyn_MethodType::ptype(oop mt, int idx) {
+oop java_lang_invoke_MethodType::ptype(oop mt, int idx) {
return ptypes(mt)->obj_at(idx);
}
-int java_dyn_MethodType::ptype_count(oop mt) {
+int java_lang_invoke_MethodType::ptype_count(oop mt) {
return ptypes(mt)->length();
}
-// Support for java_dyn_MethodTypeForm
-
-int java_dyn_MethodTypeForm::_vmslots_offset;
-int java_dyn_MethodTypeForm::_erasedType_offset;
-int java_dyn_MethodTypeForm::_genericInvoker_offset;
-
-void java_dyn_MethodTypeForm::compute_offsets() {
+// Support for java_lang_invoke_MethodTypeForm
+
+int java_lang_invoke_MethodTypeForm::_vmslots_offset;
+int java_lang_invoke_MethodTypeForm::_erasedType_offset;
+int java_lang_invoke_MethodTypeForm::_genericInvoker_offset;
+
+void java_lang_invoke_MethodTypeForm::compute_offsets() {
klassOop k = SystemDictionary::MethodTypeForm_klass();
if (k != NULL) {
compute_optional_offset(_vmslots_offset, k, vmSymbols::vmslots_name(), vmSymbols::int_signature(), true);
- compute_optional_offset(_erasedType_offset, k, vmSymbols::erasedType_name(), vmSymbols::java_dyn_MethodType_signature(), true);
- compute_optional_offset(_genericInvoker_offset, k, vmSymbols::genericInvoker_name(), vmSymbols::java_dyn_MethodHandle_signature(), true);
+ compute_optional_offset(_erasedType_offset, k, vmSymbols::erasedType_name(), vmSymbols::java_lang_invoke_MethodType_signature(), true);
+ compute_optional_offset(_genericInvoker_offset, k, vmSymbols::genericInvoker_name(), vmSymbols::java_lang_invoke_MethodHandle_signature(), true);
if (_genericInvoker_offset == 0) _genericInvoker_offset = -1; // set to explicit "empty" value
}
}
-int java_dyn_MethodTypeForm::vmslots(oop mtform) {
+int java_lang_invoke_MethodTypeForm::vmslots(oop mtform) {
assert(mtform->klass() == SystemDictionary::MethodTypeForm_klass(), "MTForm only");
return mtform->int_field(_vmslots_offset);
}
-oop java_dyn_MethodTypeForm::erasedType(oop mtform) {
+oop java_lang_invoke_MethodTypeForm::erasedType(oop mtform) {
assert(mtform->klass() == SystemDictionary::MethodTypeForm_klass(), "MTForm only");
return mtform->obj_field(_erasedType_offset);
}
-oop java_dyn_MethodTypeForm::genericInvoker(oop mtform) {
+oop java_lang_invoke_MethodTypeForm::genericInvoker(oop mtform) {
assert(mtform->klass() == SystemDictionary::MethodTypeForm_klass(), "MTForm only");
return mtform->obj_field(_genericInvoker_offset);
}
-// Support for java_dyn_CallSite
-
-int java_dyn_CallSite::_target_offset;
-int java_dyn_CallSite::_caller_method_offset;
-int java_dyn_CallSite::_caller_bci_offset;
-
-void java_dyn_CallSite::compute_offsets() {
+// Support for java_lang_invoke_CallSite
+
+int java_lang_invoke_CallSite::_target_offset;
+
+void java_lang_invoke_CallSite::compute_offsets() {
if (!EnableInvokeDynamic) return;
klassOop k = SystemDictionary::CallSite_klass();
if (k != NULL) {
- compute_offset(_target_offset, k, vmSymbols::target_name(), vmSymbols::java_dyn_MethodHandle_signature());
- compute_offset(_caller_method_offset, k, vmSymbols::vmmethod_name(), vmSymbols::sun_dyn_MemberName_signature());
- compute_offset(_caller_bci_offset, k, vmSymbols::vmindex_name(), vmSymbols::int_signature());
+ compute_offset(_target_offset, k, vmSymbols::target_name(), vmSymbols::java_lang_invoke_MethodHandle_signature());
}
}
-oop java_dyn_CallSite::target(oop site) {
+oop java_lang_invoke_CallSite::target(oop site) {
return site->obj_field(_target_offset);
}
-void java_dyn_CallSite::set_target(oop site, oop target) {
+void java_lang_invoke_CallSite::set_target(oop site, oop target) {
site->obj_field_put(_target_offset, target);
}
-oop java_dyn_CallSite::caller_method(oop site) {
- return site->obj_field(_caller_method_offset);
-}
-
-void java_dyn_CallSite::set_caller_method(oop site, oop ref) {
- site->obj_field_put(_caller_method_offset, ref);
-}
-
-jint java_dyn_CallSite::caller_bci(oop site) {
- return site->int_field(_caller_bci_offset);
-}
-
-void java_dyn_CallSite::set_caller_bci(oop site, jint bci) {
- site->int_field_put(_caller_bci_offset, bci);
-}
-
// Support for java_security_AccessControlContext
@@ -2877,16 +2881,16 @@
java_lang_Thread::compute_offsets();
java_lang_ThreadGroup::compute_offsets();
if (EnableMethodHandles) {
- java_dyn_MethodHandle::compute_offsets();
- sun_dyn_MemberName::compute_offsets();
- sun_dyn_DirectMethodHandle::compute_offsets();
- sun_dyn_BoundMethodHandle::compute_offsets();
- sun_dyn_AdapterMethodHandle::compute_offsets();
- java_dyn_MethodType::compute_offsets();
- java_dyn_MethodTypeForm::compute_offsets();
+ java_lang_invoke_MethodHandle::compute_offsets();
+ java_lang_invoke_MemberName::compute_offsets();
+ java_lang_invoke_DirectMethodHandle::compute_offsets();
+ java_lang_invoke_BoundMethodHandle::compute_offsets();
+ java_lang_invoke_AdapterMethodHandle::compute_offsets();
+ java_lang_invoke_MethodType::compute_offsets();
+ java_lang_invoke_MethodTypeForm::compute_offsets();
}
if (EnableInvokeDynamic) {
- java_dyn_CallSite::compute_offsets();
+ java_lang_invoke_CallSite::compute_offsets();
}
java_security_AccessControlContext::compute_offsets();
// Initialize reflection classes. The layouts of these classes
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -794,11 +794,11 @@
};
-// Interface to java.dyn.MethodHandle objects
+// Interface to java.lang.invoke.MethodHandle objects
class MethodHandleEntry;
-class java_dyn_MethodHandle: AllStatic {
+class java_lang_invoke_MethodHandle: AllStatic {
friend class JavaClasses;
private:
@@ -839,7 +839,7 @@
static int vmslots_offset_in_bytes() { return _vmslots_offset; }
};
-class sun_dyn_DirectMethodHandle: public java_dyn_MethodHandle {
+class java_lang_invoke_DirectMethodHandle: public java_lang_invoke_MethodHandle {
friend class JavaClasses;
private:
@@ -864,7 +864,7 @@
static int vmindex_offset_in_bytes() { return _vmindex_offset; }
};
-class sun_dyn_BoundMethodHandle: public java_dyn_MethodHandle {
+class java_lang_invoke_BoundMethodHandle: public java_lang_invoke_MethodHandle {
friend class JavaClasses;
private:
@@ -891,7 +891,7 @@
static int vmargslot_offset_in_bytes() { return _vmargslot_offset; }
};
-class sun_dyn_AdapterMethodHandle: public sun_dyn_BoundMethodHandle {
+class java_lang_invoke_AdapterMethodHandle: public java_lang_invoke_BoundMethodHandle {
friend class JavaClasses;
private:
@@ -942,14 +942,14 @@
};
-// Interface to sun.dyn.MemberName objects
+// Interface to java.lang.invoke.MemberName objects
// (These are a private interface for Java code to query the class hierarchy.)
-class sun_dyn_MemberName: AllStatic {
+class java_lang_invoke_MemberName: AllStatic {
friend class JavaClasses;
private:
- // From java.dyn.MemberName:
+ // From java.lang.invoke.MemberName:
// private Class<?> clazz; // class in which the method is defined
// private String name; // may be null if not yet materialized
// private Object type; // may be null if not yet materialized
@@ -1018,9 +1018,9 @@
};
-// Interface to java.dyn.MethodType objects
+// Interface to java.lang.invoke.MethodType objects
-class java_dyn_MethodType: AllStatic {
+class java_lang_invoke_MethodType: AllStatic {
friend class JavaClasses;
private:
@@ -1052,7 +1052,7 @@
static int form_offset_in_bytes() { return _form_offset; }
};
-class java_dyn_MethodTypeForm: AllStatic {
+class java_lang_invoke_MethodTypeForm: AllStatic {
friend class JavaClasses;
private:
@@ -1075,9 +1075,9 @@
};
-// Interface to java.dyn.CallSite objects
+// Interface to java.lang.invoke.CallSite objects
-class java_dyn_CallSite: AllStatic {
+class java_lang_invoke_CallSite: AllStatic {
friend class JavaClasses;
private:
--- a/hotspot/src/share/vm/classfile/symbolTable.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/classfile/symbolTable.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -88,7 +88,7 @@
void SymbolTable::unlink() {
int removed = 0;
int total = 0;
- int memory_total = 0;
+ size_t memory_total = 0;
for (int i = 0; i < the_table()->table_size(); ++i) {
for (HashtableEntry<Symbol*>** p = the_table()->bucket_addr(i); *p != NULL; ) {
HashtableEntry<Symbol*>* entry = *p;
@@ -112,8 +112,10 @@
}
symbols_removed += removed;
symbols_counted += total;
- if (PrintGCDetails) {
- gclog_or_tty->print(" [Symbols=%d size=%dK] ", total,
+ // Exclude printing for normal PrintGCDetails because people parse
+ // this output.
+ if (PrintGCDetails && Verbose && WizardMode) {
+ gclog_or_tty->print(" [Symbols=%d size=" SIZE_FORMAT "K] ", total,
(memory_total*HeapWordSize)/1024);
}
}
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -1887,27 +1887,99 @@
0
};
+Symbol* SystemDictionary::find_backup_symbol(Symbol* symbol,
+ const char* from_prefix,
+ const char* to_prefix) {
+ assert(AllowTransitionalJSR292, ""); // delete this subroutine
+ Symbol* backup_symbol = NULL;
+ size_t from_len = strlen(from_prefix);
+ if (strncmp((const char*) symbol->base(), from_prefix, from_len) != 0)
+ return NULL;
+ char buf[100];
+ size_t to_len = strlen(to_prefix);
+ size_t tail_len = symbol->utf8_length() - from_len;
+ size_t new_len = to_len + tail_len;
+ guarantee(new_len < sizeof(buf), "buf too small");
+ memcpy(buf, to_prefix, to_len);
+ memcpy(buf + to_len, symbol->base() + from_len, tail_len);
+ buf[new_len] = '\0';
+ vmSymbols::SID backup_sid = vmSymbols::find_sid(buf);
+ if (backup_sid != vmSymbols::NO_SID) {
+ backup_symbol = vmSymbols::symbol_at(backup_sid);
+ }
+ return backup_symbol;
+}
+
+Symbol* SystemDictionary::find_backup_class_name(Symbol* symbol) {
+ assert(AllowTransitionalJSR292, ""); // delete this subroutine
+ if (symbol == NULL) return NULL;
+ Symbol* backup_symbol = find_backup_symbol(symbol, "java/lang/invoke/", "java/dyn/"); // AllowTransitionalJSR292 ONLY
+ if (backup_symbol == NULL)
+ backup_symbol = find_backup_symbol(symbol, "java/dyn/", "sun/dyn/"); // AllowTransitionalJSR292 ONLY
+ return backup_symbol;
+}
+
+Symbol* SystemDictionary::find_backup_signature(Symbol* symbol) {
+ assert(AllowTransitionalJSR292, ""); // delete this subroutine
+ if (symbol == NULL) return NULL;
+ return find_backup_symbol(symbol, "Ljava/lang/invoke/", "Ljava/dyn/");
+}
+
bool SystemDictionary::initialize_wk_klass(WKID id, int init_opt, TRAPS) {
assert(id >= (int)FIRST_WKID && id < (int)WKID_LIMIT, "oob");
int info = wk_init_info[id - FIRST_WKID];
int sid = (info >> CEIL_LG_OPTION_LIMIT);
Symbol* symbol = vmSymbols::symbol_at((vmSymbols::SID)sid);
klassOop* klassp = &_well_known_klasses[id];
- bool must_load = (init_opt < SystemDictionary::Opt);
- bool try_load = true;
+ bool pre_load = (init_opt < SystemDictionary::Opt);
+ bool try_load = true;
if (init_opt == SystemDictionary::Opt_Kernel) {
#ifndef KERNEL
try_load = false;
#endif //KERNEL
}
- if ((*klassp) == NULL && try_load) {
+ Symbol* backup_symbol = NULL; // symbol to try if the current symbol fails
+ if (init_opt == SystemDictionary::Pre_JSR292) {
+ if (!EnableMethodHandles) try_load = false; // do not bother to load such classes
+ if (AllowTransitionalJSR292) {
+ backup_symbol = find_backup_class_name(symbol);
+ if (try_load && PreferTransitionalJSR292) {
+ while (backup_symbol != NULL) {
+ (*klassp) = resolve_or_null(backup_symbol, CHECK_0); // try backup early
+ if (TraceMethodHandles) {
+ ResourceMark rm;
+ tty->print_cr("MethodHandles: try backup first for %s => %s (%s)",
+ symbol->as_C_string(), backup_symbol->as_C_string(),
+ ((*klassp) == NULL) ? "no such class" : "backup load succeeded");
+ }
+ if ((*klassp) != NULL) return true;
+ backup_symbol = find_backup_class_name(backup_symbol); // find next backup
+ }
+ }
+ }
+ }
+ if ((*klassp) != NULL) return true;
+ if (!try_load) return false;
+ while (symbol != NULL) {
+ bool must_load = (pre_load && (backup_symbol == NULL));
if (must_load) {
(*klassp) = resolve_or_fail(symbol, true, CHECK_0); // load required class
} else {
(*klassp) = resolve_or_null(symbol, CHECK_0); // load optional klass
}
+ if ((*klassp) != NULL) return true;
+ // Go around again. Example of long backup sequence:
+ // java.lang.invoke.MemberName, java.dyn.MemberName, sun.dyn.MemberName, ONLY if AllowTransitionalJSR292
+ if (TraceMethodHandles && (backup_symbol != NULL)) {
+ ResourceMark rm;
+ tty->print_cr("MethodHandles: backup for %s => %s",
+ symbol->as_C_string(), backup_symbol->as_C_string());
+ }
+ symbol = backup_symbol;
+ if (AllowTransitionalJSR292)
+ backup_symbol = find_backup_class_name(symbol);
}
- return ((*klassp) != NULL);
+ return false;
}
void SystemDictionary::initialize_wk_klasses_until(WKID limit_id, WKID &start_id, TRAPS) {
@@ -2348,6 +2420,8 @@
if (THREAD->is_Compiler_thread())
return NULL; // do not attempt from within compiler
bool for_invokeGeneric = (name_id == vmSymbols::VM_SYMBOL_ENUM_NAME(invokeGeneric_name));
+ if (AllowInvokeForInvokeGeneric && name_id == vmSymbols::VM_SYMBOL_ENUM_NAME(invoke_name))
+ for_invokeGeneric = true;
bool found_on_bcp = false;
Handle mt = find_method_handle_type(signature, accessing_klass,
for_invokeGeneric,
@@ -2376,7 +2450,7 @@
}
}
-// Ask Java code to find or construct a java.dyn.MethodType for the given
+// Ask Java code to find or construct a java.lang.invoke.MethodType for the given
// signature, as interpreted relative to the given class loader.
// Because of class loader constraints, all method handle usage must be
// consistent with this loader.
@@ -2430,25 +2504,33 @@
}
assert(arg == npts, "");
- // call sun.dyn.MethodHandleNatives::findMethodType(Class rt, Class[] pts) -> MethodType
+ // call java.lang.invoke.MethodHandleNatives::findMethodType(Class rt, Class[] pts) -> MethodType
JavaCallArguments args(Handle(THREAD, rt()));
args.push_oop(pts());
JavaValue result(T_OBJECT);
+ Symbol* findMethodHandleType_signature = vmSymbols::findMethodHandleType_signature();
+ if (AllowTransitionalJSR292 && SystemDictionaryHandles::MethodType_klass()->name() == vmSymbols::java_dyn_MethodType()) {
+ findMethodHandleType_signature = vmSymbols::findMethodHandleType_TRANS_signature();
+ }
JavaCalls::call_static(&result,
SystemDictionary::MethodHandleNatives_klass(),
vmSymbols::findMethodHandleType_name(),
- vmSymbols::findMethodHandleType_signature(),
+ findMethodHandleType_signature,
&args, CHECK_(empty));
Handle method_type(THREAD, (oop) result.get_jobject());
if (for_invokeGeneric) {
- // call sun.dyn.MethodHandleNatives::notifyGenericMethodType(MethodType) -> void
+ // call java.lang.invoke.MethodHandleNatives::notifyGenericMethodType(MethodType) -> void
JavaCallArguments args(Handle(THREAD, method_type()));
JavaValue no_result(T_VOID);
+ Symbol* notifyGenericMethodType_signature = vmSymbols::notifyGenericMethodType_signature();
+ if (AllowTransitionalJSR292 && SystemDictionaryHandles::MethodType_klass()->name() == vmSymbols::java_dyn_MethodType()) {
+ notifyGenericMethodType_signature = vmSymbols::notifyGenericMethodType_TRANS_signature();
+ }
JavaCalls::call_static(&no_result,
SystemDictionary::MethodHandleNatives_klass(),
vmSymbols::notifyGenericMethodType_name(),
- vmSymbols::notifyGenericMethodType_signature(),
+ notifyGenericMethodType_signature,
&args, THREAD);
if (HAS_PENDING_EXCEPTION) {
// If the notification fails, just kill it.
@@ -2489,7 +2571,7 @@
THROW_MSG_(vmSymbols::java_lang_LinkageError(), "bad signature", empty);
}
- // call sun.dyn.MethodHandleNatives::linkMethodHandleConstant(Class caller, int refKind, Class callee, String name, Object type) -> MethodHandle
+ // call java.lang.invoke.MethodHandleNatives::linkMethodHandleConstant(Class caller, int refKind, Class callee, String name, Object type) -> MethodHandle
JavaCallArguments args;
args.push_oop(caller->java_mirror()); // the referring class
args.push_int(ref_kind);
@@ -2497,15 +2579,19 @@
args.push_oop(name());
args.push_oop(type());
JavaValue result(T_OBJECT);
+ Symbol* linkMethodHandleConstant_signature = vmSymbols::linkMethodHandleConstant_signature();
+ if (AllowTransitionalJSR292 && SystemDictionaryHandles::MethodHandle_klass()->name() == vmSymbols::java_dyn_MethodHandle()) {
+ linkMethodHandleConstant_signature = vmSymbols::linkMethodHandleConstant_TRANS_signature();
+ }
JavaCalls::call_static(&result,
SystemDictionary::MethodHandleNatives_klass(),
vmSymbols::linkMethodHandleConstant_name(),
- vmSymbols::linkMethodHandleConstant_signature(),
+ linkMethodHandleConstant_signature,
&args, CHECK_(empty));
return Handle(THREAD, (oop) result.get_jobject());
}
-// Ask Java code to find or construct a java.dyn.CallSite for the given
+// Ask Java code to find or construct a java.lang.invoke.CallSite for the given
// name and signature, as interpreted relative to the given class loader.
Handle SystemDictionary::make_dynamic_call_site(Handle bootstrap_method,
Symbol* name,
@@ -2516,13 +2602,13 @@
TRAPS) {
Handle empty;
guarantee(bootstrap_method.not_null() &&
- java_dyn_MethodHandle::is_instance(bootstrap_method()),
+ java_lang_invoke_MethodHandle::is_instance(bootstrap_method()),
"caller must supply a valid BSM");
Handle caller_mname = MethodHandles::new_MemberName(CHECK_(empty));
MethodHandles::init_MemberName(caller_mname(), caller_method());
- // call sun.dyn.MethodHandleNatives::makeDynamicCallSite(bootm, name, mtype, info, caller_mname, caller_pos)
+ // call java.lang.invoke.MethodHandleNatives::makeDynamicCallSite(bootm, name, mtype, info, caller_mname, caller_pos)
oop name_str_oop = StringTable::intern(name, CHECK_(empty)); // not a handle!
JavaCallArguments args(Handle(THREAD, bootstrap_method()));
args.push_oop(name_str_oop);
@@ -2531,14 +2617,21 @@
args.push_oop(caller_mname());
args.push_int(caller_bci);
JavaValue result(T_OBJECT);
+ Symbol* makeDynamicCallSite_signature = vmSymbols::makeDynamicCallSite_signature();
+ if (AllowTransitionalJSR292 && SystemDictionaryHandles::MethodHandleNatives_klass()->name() == vmSymbols::sun_dyn_MethodHandleNatives()) {
+ makeDynamicCallSite_signature = vmSymbols::makeDynamicCallSite_TRANS_signature();
+ }
+ if (AllowTransitionalJSR292 && SystemDictionaryHandles::MethodHandleNatives_klass()->name() == vmSymbols::java_dyn_MethodHandleNatives()) {
+ makeDynamicCallSite_signature = vmSymbols::makeDynamicCallSite_TRANS2_signature();
+ }
JavaCalls::call_static(&result,
SystemDictionary::MethodHandleNatives_klass(),
vmSymbols::makeDynamicCallSite_name(),
- vmSymbols::makeDynamicCallSite_signature(),
+ makeDynamicCallSite_signature,
&args, CHECK_(empty));
oop call_site_oop = (oop) result.get_jobject();
assert(call_site_oop->is_oop()
- /*&& java_dyn_CallSite::is_instance(call_site_oop)*/, "must be sane");
+ /*&& java_lang_invoke_CallSite::is_instance(call_site_oop)*/, "must be sane");
if (TraceMethodHandles) {
#ifndef PRODUCT
tty->print_cr("Linked invokedynamic bci=%d site="INTPTR_FORMAT":", caller_bci, call_site_oop);
--- a/hotspot/src/share/vm/classfile/systemDictionary.hpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -144,18 +144,18 @@
template(reflect_UnsafeStaticFieldAccessorImpl_klass, sun_reflect_UnsafeStaticFieldAccessorImpl, Opt_Only_JDK15) \
\
/* support for dynamic typing; it's OK if these are NULL in earlier JDKs */ \
- template(MethodHandle_klass, java_dyn_MethodHandle, Opt) \
- template(MemberName_klass, sun_dyn_MemberName, Opt) \
- template(MethodHandleImpl_klass, sun_dyn_MethodHandleImpl, Opt) \
- template(MethodHandleNatives_klass, sun_dyn_MethodHandleNatives, Opt) \
- template(AdapterMethodHandle_klass, sun_dyn_AdapterMethodHandle, Opt) \
- template(BoundMethodHandle_klass, sun_dyn_BoundMethodHandle, Opt) \
- template(DirectMethodHandle_klass, sun_dyn_DirectMethodHandle, Opt) \
- template(MethodType_klass, java_dyn_MethodType, Opt) \
- template(MethodTypeForm_klass, java_dyn_MethodTypeForm, Opt) \
- template(WrongMethodTypeException_klass, java_dyn_WrongMethodTypeException, Opt) \
- template(Linkage_klass, java_dyn_Linkage, Opt) \
- template(CallSite_klass, java_dyn_CallSite, Opt) \
+ template(MethodHandle_klass, java_lang_invoke_MethodHandle, Pre_JSR292) \
+ template(MemberName_klass, java_lang_invoke_MemberName, Pre_JSR292) \
+ template(MethodHandleImpl_klass, sun_dyn_MethodHandleImpl, Opt) /* AllowTransitionalJSR292 ONLY */ \
+ template(MethodHandleNatives_klass, java_lang_invoke_MethodHandleNatives, Pre_JSR292) \
+ template(AdapterMethodHandle_klass, java_lang_invoke_AdapterMethodHandle, Pre_JSR292) \
+ template(BoundMethodHandle_klass, java_lang_invoke_BoundMethodHandle, Pre_JSR292) \
+ template(DirectMethodHandle_klass, java_lang_invoke_DirectMethodHandle, Pre_JSR292) \
+ template(MethodType_klass, java_lang_invoke_MethodType, Pre_JSR292) \
+ template(MethodTypeForm_klass, java_lang_invoke_MethodTypeForm, Pre_JSR292) \
+ template(WrongMethodTypeException_klass, java_lang_invoke_WrongMethodTypeException, Pre_JSR292) \
+ template(Linkage_klass, java_lang_invoke_Linkage, Opt) /* AllowTransitionalJSR292 ONLY */ \
+ template(CallSite_klass, java_lang_invoke_CallSite, Pre_JSR292) \
/* Note: MethodHandle must be first, and CallSite last in group */ \
\
template(StringBuffer_klass, java_lang_StringBuffer, Pre) \
@@ -207,6 +207,7 @@
enum InitOption {
Pre, // preloaded; error if not present
+ Pre_JSR292, // preloaded if EnableMethodHandles
// Order is significant. Options before this point require resolve_or_fail.
// Options after this point will use resolve_or_null instead.
@@ -401,6 +402,7 @@
}
static klassOop check_klass_Pre(klassOop k) { return check_klass(k); }
+ static klassOop check_klass_Pre_JSR292(klassOop k) { return EnableInvokeDynamic ? check_klass(k) : k; }
static klassOop check_klass_Opt(klassOop k) { return k; }
static klassOop check_klass_Opt_Kernel(klassOop k) { return k; } //== Opt
static klassOop check_klass_Opt_Only_JDK15(klassOop k) {
@@ -420,6 +422,8 @@
initialize_wk_klasses_until((WKID) limit, start_id, THREAD);
}
+ static Symbol* find_backup_symbol(Symbol* symbol, const char* from_prefix, const char* to_prefix);
+
public:
#define WK_KLASS_DECLARE(name, ignore_symbol, option) \
static klassOop name() { return check_klass_##option(_well_known_klasses[WK_KLASS_ENUM_NAME(name)]); }
@@ -441,6 +445,9 @@
static void load_abstract_ownable_synchronizer_klass(TRAPS);
+ static Symbol* find_backup_class_name(Symbol* class_name_symbol);
+ static Symbol* find_backup_signature(Symbol* signature_symbol);
+
private:
// Tells whether ClassLoader.loadClassInternal is present
static bool has_loadClassInternal() { return _has_loadClassInternal; }
@@ -475,18 +482,18 @@
Handle loader2, bool is_method, TRAPS);
// JSR 292
- // find the java.dyn.MethodHandles::invoke method for a given signature
+ // find the java.lang.invoke.MethodHandles::invoke method for a given signature
static methodOop find_method_handle_invoke(Symbol* name,
Symbol* signature,
KlassHandle accessing_klass,
TRAPS);
- // ask Java to compute a java.dyn.MethodType object for a given signature
+ // ask Java to compute a java.lang.invoke.MethodType object for a given signature
static Handle find_method_handle_type(Symbol* signature,
KlassHandle accessing_klass,
bool for_invokeGeneric,
bool& return_bcp_flag,
TRAPS);
- // ask Java to compute a java.dyn.MethodHandle object for a given CP entry
+ // ask Java to compute a java.lang.invoke.MethodHandle object for a given CP entry
static Handle link_method_handle_constant(KlassHandle caller,
int ref_kind, //e.g., JVM_REF_invokeVirtual
KlassHandle callee,
--- a/hotspot/src/share/vm/classfile/verifier.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/classfile/verifier.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -1671,13 +1671,19 @@
VerificationType::long_type(),
VerificationType::long2_type(), CHECK_VERIFY(this));
} else if (tag.is_method_handle()) {
+ Symbol* methodHandle_name = vmSymbols::java_lang_invoke_MethodHandle();
+ if (AllowTransitionalJSR292 && !Universe::is_bootstrapping())
+ methodHandle_name = SystemDictionaryHandles::MethodHandle_klass()->name();
current_frame->push_stack(
VerificationType::reference_type(
- vmSymbols::java_dyn_MethodHandle()), CHECK_VERIFY(this));
+ methodHandle_name), CHECK_VERIFY(this));
} else if (tag.is_method_type()) {
+ Symbol* methodType_name = vmSymbols::java_lang_invoke_MethodType();
+ if (AllowTransitionalJSR292 && !Universe::is_bootstrapping())
+ methodType_name = SystemDictionaryHandles::MethodType_klass()->name();
current_frame->push_stack(
VerificationType::reference_type(
- vmSymbols::java_dyn_MethodType()), CHECK_VERIFY(this));
+ methodType_name), CHECK_VERIFY(this));
} else {
verify_error(bci, "Invalid index in ldc");
return;
--- a/hotspot/src/share/vm/classfile/vmSymbols.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/classfile/vmSymbols.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -277,6 +277,12 @@
return sid;
}
+vmSymbols::SID vmSymbols::find_sid(const char* symbol_name) {
+ Symbol* symbol = SymbolTable::probe(symbol_name, (int) strlen(symbol_name));
+ if (symbol == NULL) return NO_SID;
+ return find_sid(symbol);
+}
+
static vmIntrinsics::ID wrapper_intrinsic(BasicType type, bool unboxing) {
#define TYPE2(type, unboxing) ((int)(type)*2 + ((unboxing) ? 1 : 0))
switch (TYPE2(type, unboxing)) {
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -229,33 +229,60 @@
template(base_name, "base") \
\
/* Support for JSR 292 & invokedynamic (JDK 1.7 and above) */ \
- template(java_dyn_InvokeDynamic, "java/dyn/InvokeDynamic") \
- template(java_dyn_Linkage, "java/dyn/Linkage") \
- template(java_dyn_CallSite, "java/dyn/CallSite") \
- template(java_dyn_MethodHandle, "java/dyn/MethodHandle") \
- template(java_dyn_MethodType, "java/dyn/MethodType") \
- template(java_dyn_WrongMethodTypeException, "java/dyn/WrongMethodTypeException") \
- template(java_dyn_MethodType_signature, "Ljava/dyn/MethodType;") \
- template(java_dyn_MethodHandle_signature, "Ljava/dyn/MethodHandle;") \
+ template(java_lang_invoke_InvokeDynamic, "java/lang/invoke/InvokeDynamic") \
+ template(java_lang_invoke_Linkage, "java/lang/invoke/Linkage") \
+ template(java_lang_invoke_CallSite, "java/lang/invoke/CallSite") \
+ template(java_lang_invoke_MethodHandle, "java/lang/invoke/MethodHandle") \
+ template(java_lang_invoke_MethodType, "java/lang/invoke/MethodType") \
+ template(java_lang_invoke_WrongMethodTypeException, "java/lang/invoke/WrongMethodTypeException") \
+ template(java_lang_invoke_MethodType_signature, "Ljava/lang/invoke/MethodType;") \
+ template(java_lang_invoke_MethodHandle_signature, "Ljava/lang/invoke/MethodHandle;") \
/* internal classes known only to the JVM: */ \
- template(java_dyn_MethodTypeForm, "java/dyn/MethodTypeForm") \
- template(java_dyn_MethodTypeForm_signature, "Ljava/dyn/MethodTypeForm;") \
- template(sun_dyn_MemberName, "sun/dyn/MemberName") \
- template(sun_dyn_MemberName_signature, "Lsun/dyn/MemberName;") \
- template(sun_dyn_MethodHandleImpl, "sun/dyn/MethodHandleImpl") \
- template(sun_dyn_MethodHandleNatives, "sun/dyn/MethodHandleNatives") \
- template(sun_dyn_AdapterMethodHandle, "sun/dyn/AdapterMethodHandle") \
- template(sun_dyn_BoundMethodHandle, "sun/dyn/BoundMethodHandle") \
- template(sun_dyn_DirectMethodHandle, "sun/dyn/DirectMethodHandle") \
- /* internal up-calls made only by the JVM, via class sun.dyn.MethodHandleNatives: */ \
+ template(java_lang_invoke_MethodTypeForm, "java/lang/invoke/MethodTypeForm") \
+ template(java_lang_invoke_MethodTypeForm_signature, "Ljava/lang/invoke/MethodTypeForm;") \
+ template(java_lang_invoke_MemberName, "java/lang/invoke/MemberName") \
+ template(java_lang_invoke_MethodHandleNatives, "java/lang/invoke/MethodHandleNatives") \
+ template(java_lang_invoke_AdapterMethodHandle, "java/lang/invoke/AdapterMethodHandle") \
+ template(java_lang_invoke_BoundMethodHandle, "java/lang/invoke/BoundMethodHandle") \
+ template(java_lang_invoke_DirectMethodHandle, "java/lang/invoke/DirectMethodHandle") \
+ /* temporary transitional public names from 6839872: */ \
+ template(java_dyn_InvokeDynamic, "java/dyn/InvokeDynamic") /* AllowTransitionalJSR292 ONLY */ \
+ template(java_dyn_Linkage, "java/dyn/Linkage") /* AllowTransitionalJSR292 ONLY */ \
+ template(java_dyn_CallSite, "java/dyn/CallSite") /* AllowTransitionalJSR292 ONLY */ \
+ template(java_dyn_MethodHandle, "java/dyn/MethodHandle") /* AllowTransitionalJSR292 ONLY */ \
+ template(java_dyn_MethodType, "java/dyn/MethodType") /* AllowTransitionalJSR292 ONLY */ \
+ template(java_dyn_WrongMethodTypeException, "java/dyn/WrongMethodTypeException") /* AllowTransitionalJSR292 ONLY */ \
+ template(java_dyn_MethodType_signature, "Ljava/dyn/MethodType;") /* AllowTransitionalJSR292 ONLY */ \
+ template(java_dyn_MethodHandle_signature, "Ljava/dyn/MethodHandle;") /* AllowTransitionalJSR292 ONLY */ \
+ /* temporary transitional internal names from 6839872: */ \
+ template(java_dyn_MethodTypeForm, "java/dyn/MethodTypeForm") /* AllowTransitionalJSR292 ONLY */ \
+ template(java_dyn_MethodTypeForm_signature, "Ljava/dyn/MethodTypeForm;") /* AllowTransitionalJSR292 ONLY */ \
+ template(java_dyn_MemberName, "java/dyn/MemberName") /* AllowTransitionalJSR292 ONLY */ \
+ template(java_dyn_MethodHandleNatives, "java/dyn/MethodHandleNatives") /* AllowTransitionalJSR292 ONLY */ \
+ template(java_dyn_AdapterMethodHandle, "java/dyn/AdapterMethodHandle") /* AllowTransitionalJSR292 ONLY */ \
+ template(java_dyn_BoundMethodHandle, "java/dyn/BoundMethodHandle") /* AllowTransitionalJSR292 ONLY */ \
+ template(java_dyn_DirectMethodHandle, "java/dyn/DirectMethodHandle") /* AllowTransitionalJSR292 ONLY */ \
+ /* temporary transitional internal names from EDR: */ \
+ template(sun_dyn_MemberName, "sun/dyn/MemberName") /* AllowTransitionalJSR292 ONLY */ \
+ template(sun_dyn_MethodHandleImpl, "sun/dyn/MethodHandleImpl") /* AllowTransitionalJSR292 ONLY */ \
+ template(sun_dyn_MethodHandleNatives, "sun/dyn/MethodHandleNatives") /* AllowTransitionalJSR292 ONLY */ \
+ template(sun_dyn_AdapterMethodHandle, "sun/dyn/AdapterMethodHandle") /* AllowTransitionalJSR292 ONLY */ \
+ template(sun_dyn_BoundMethodHandle, "sun/dyn/BoundMethodHandle") /* AllowTransitionalJSR292 ONLY */ \
+ template(sun_dyn_DirectMethodHandle, "sun/dyn/DirectMethodHandle") /* AllowTransitionalJSR292 ONLY */ \
+ /* internal up-calls made only by the JVM, via class sun.invoke.MethodHandleNatives: */ \
template(findMethodHandleType_name, "findMethodHandleType") \
- template(findMethodHandleType_signature, "(Ljava/lang/Class;[Ljava/lang/Class;)Ljava/dyn/MethodType;") \
+ template(findMethodHandleType_signature, "(Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/invoke/MethodType;") \
+ template(findMethodHandleType_TRANS_signature, "(Ljava/lang/Class;[Ljava/lang/Class;)Ljava/dyn/MethodType;") /* AllowTransitionalJSR292 ONLY */ \
template(notifyGenericMethodType_name, "notifyGenericMethodType") \
- template(notifyGenericMethodType_signature, "(Ljava/dyn/MethodType;)V") \
+ template(notifyGenericMethodType_signature, "(Ljava/lang/invoke/MethodType;)V") \
+ template(notifyGenericMethodType_TRANS_signature, "(Ljava/dyn/MethodType;)V") /* AllowTransitionalJSR292 ONLY */ \
template(linkMethodHandleConstant_name, "linkMethodHandleConstant") \
- template(linkMethodHandleConstant_signature, "(Ljava/lang/Class;ILjava/lang/Class;Ljava/lang/String;Ljava/lang/Object;)Ljava/dyn/MethodHandle;") \
+ template(linkMethodHandleConstant_signature, "(Ljava/lang/Class;ILjava/lang/Class;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/invoke/MethodHandle;") \
+ template(linkMethodHandleConstant_TRANS_signature, "(Ljava/lang/Class;ILjava/lang/Class;Ljava/lang/String;Ljava/lang/Object;)Ljava/dyn/MethodHandle;") /* AllowTransitionalJSR292 ONLY */ \
template(makeDynamicCallSite_name, "makeDynamicCallSite") \
- template(makeDynamicCallSite_signature, "(Ljava/dyn/MethodHandle;Ljava/lang/String;Ljava/dyn/MethodType;Ljava/lang/Object;Lsun/dyn/MemberName;I)Ljava/dyn/CallSite;") \
+ template(makeDynamicCallSite_signature, "(Ljava/lang/invoke/MethodHandle;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/Object;Ljava/lang/invoke/MemberName;I)Ljava/lang/invoke/CallSite;") \
+ template(makeDynamicCallSite_TRANS_signature, "(Ljava/dyn/MethodHandle;Ljava/lang/String;Ljava/dyn/MethodType;Ljava/lang/Object;Lsun/dyn/MemberName;I)Ljava/dyn/CallSite;") /* AllowTransitionalJSR292 ONLY */ \
+ template(makeDynamicCallSite_TRANS2_signature, "(Ljava/dyn/MethodHandle;Ljava/lang/String;Ljava/dyn/MethodType;Ljava/lang/Object;Ljava/dyn/MemberName;I)Ljava/dyn/CallSite;") /* AllowTransitionalJSR292 ONLY */ \
NOT_LP64( do_alias(machine_word_signature, int_signature) ) \
LP64_ONLY( do_alias(machine_word_signature, long_signature) ) \
\
@@ -882,13 +909,15 @@
\
do_intrinsic(_invoke, java_lang_reflect_Method, invoke_name, object_object_array_object_signature, F_R) \
/* (symbols invoke_name and invoke_signature defined above) */ \
- do_intrinsic(_checkSpreadArgument, sun_dyn_MethodHandleImpl, checkSpreadArgument_name, checkSpreadArgument_signature, F_S) \
+ do_intrinsic(_checkSpreadArgument, java_lang_invoke_MethodHandleNatives, checkSpreadArgument_name, checkSpreadArgument_signature, F_S) \
+ do_intrinsic(_checkSpreadArgument_TRANS,sun_dyn_MethodHandleImpl, checkSpreadArgument_name, checkSpreadArgument_signature, F_S) /* AllowTransitionalJSR292 ONLY */ \
+ do_intrinsic(_checkSpreadArgument_TRANS2,java_dyn_MethodHandleNatives, checkSpreadArgument_name, checkSpreadArgument_signature, F_S) /* AllowTransitionalJSR292 ONLY */ \
do_name( checkSpreadArgument_name, "checkSpreadArgument") \
do_name( checkSpreadArgument_signature, "(Ljava/lang/Object;I)V") \
- do_intrinsic(_invokeExact, java_dyn_MethodHandle, invokeExact_name, object_array_object_signature, F_RN) \
- do_intrinsic(_invokeGeneric, java_dyn_MethodHandle, invokeGeneric_name, object_array_object_signature, F_RN) \
- do_intrinsic(_invokeVarargs, java_dyn_MethodHandle, invokeVarargs_name, object_array_object_signature, F_R) \
- do_intrinsic(_invokeDynamic, java_dyn_InvokeDynamic, star_name, object_array_object_signature, F_SN) \
+ do_intrinsic(_invokeExact, java_lang_invoke_MethodHandle, invokeExact_name, object_array_object_signature, F_RN) \
+ do_intrinsic(_invokeGeneric, java_lang_invoke_MethodHandle, invokeGeneric_name, object_array_object_signature, F_RN) \
+ do_intrinsic(_invokeVarargs, java_lang_invoke_MethodHandle, invokeVarargs_name, object_array_object_signature, F_R) \
+ do_intrinsic(_invokeDynamic, java_lang_invoke_InvokeDynamic, star_name, object_array_object_signature, F_SN) \
\
/* unboxing methods: */ \
do_intrinsic(_booleanValue, java_lang_Boolean, booleanValue_name, void_boolean_signature, F_R) \
@@ -995,6 +1024,7 @@
// Returns symbol's SID if one is assigned, else NO_SID.
static SID find_sid(Symbol* symbol);
+ static SID find_sid(const char* symbol_name);
#ifndef PRODUCT
// No need for this in the product:
--- a/hotspot/src/share/vm/code/codeCache.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/code/codeCache.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -939,9 +939,16 @@
_heap->high(),
_heap->high_boundary());
st->print_cr(" total_blobs=" UINT32_FORMAT " nmethods=" UINT32_FORMAT
- " adapters=" UINT32_FORMAT " free_code_cache=" SIZE_FORMAT
+ " adapters=" UINT32_FORMAT " free_code_cache=" SIZE_FORMAT "Kb"
" largest_free_block=" SIZE_FORMAT,
- CodeCache::nof_blobs(), CodeCache::nof_nmethods(),
- CodeCache::nof_adapters(), CodeCache::unallocated_capacity(),
- CodeCache::largest_free_block());
+ nof_blobs(), nof_nmethods(), nof_adapters(),
+ unallocated_capacity()/K, largest_free_block());
}
+
+void CodeCache::log_state(outputStream* st) {
+ st->print(" total_blobs='" UINT32_FORMAT "' nmethods='" UINT32_FORMAT "'"
+ " adapters='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'"
+ " largest_free_block='" SIZE_FORMAT "'",
+ nof_blobs(), nof_nmethods(), nof_adapters(),
+ unallocated_capacity(), largest_free_block());
+}
--- a/hotspot/src/share/vm/code/codeCache.hpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/code/codeCache.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -147,6 +147,7 @@
static void verify(); // verifies the code cache
static void print_trace(const char* event, CodeBlob* cb, int size = 0) PRODUCT_RETURN;
static void print_bounds(outputStream* st); // Prints a summary of the bounds of the code cache
+ static void log_state(outputStream* st);
// The full limits of the codeCache
static address low_bound() { return (address) _heap->low_boundary(); }
@@ -159,7 +160,7 @@
static size_t max_capacity() { return _heap->max_capacity(); }
static size_t unallocated_capacity() { return _heap->unallocated_capacity(); }
static size_t largest_free_block() { return _heap->largest_free_block(); }
- static bool needs_flushing() { return unallocated_capacity() < CodeCacheFlushingMinimumFreeSpace; }
+ static bool needs_flushing() { return largest_free_block() < CodeCacheFlushingMinimumFreeSpace; }
static bool needs_cache_clean() { return _needs_cache_clean; }
static void set_needs_cache_clean(bool v) { _needs_cache_clean = v; }
--- a/hotspot/src/share/vm/code/nmethod.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/code/nmethod.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -170,7 +170,7 @@
int pc_desc_resets; // number of resets (= number of caches)
int pc_desc_queries; // queries to nmethod::find_pc_desc
int pc_desc_approx; // number of those which have approximate true
- int pc_desc_repeats; // number of _last_pc_desc hits
+ int pc_desc_repeats; // number of _pc_descs[0] hits
int pc_desc_hits; // number of LRU cache hits
int pc_desc_tests; // total number of PcDesc examinations
int pc_desc_searches; // total number of quasi-binary search steps
@@ -278,40 +278,44 @@
void PcDescCache::reset_to(PcDesc* initial_pc_desc) {
if (initial_pc_desc == NULL) {
- _last_pc_desc = NULL; // native method
+ _pc_descs[0] = NULL; // native method; no PcDescs at all
return;
}
NOT_PRODUCT(++nmethod_stats.pc_desc_resets);
// reset the cache by filling it with benign (non-null) values
assert(initial_pc_desc->pc_offset() < 0, "must be sentinel");
- _last_pc_desc = initial_pc_desc + 1; // first valid one is after sentinel
for (int i = 0; i < cache_size; i++)
_pc_descs[i] = initial_pc_desc;
}
PcDesc* PcDescCache::find_pc_desc(int pc_offset, bool approximate) {
NOT_PRODUCT(++nmethod_stats.pc_desc_queries);
- NOT_PRODUCT(if (approximate) ++nmethod_stats.pc_desc_approx);
+ NOT_PRODUCT(if (approximate) ++nmethod_stats.pc_desc_approx);
+
+ // Note: one might think that caching the most recently
+ // read value separately would be a win, but one would be
+ // wrong. When many threads are updating it, the cache
+ // line it's in would bounce between caches, negating
+ // any benefit.
// In order to prevent race conditions do not load cache elements
// repeatedly, but use a local copy:
PcDesc* res;
- // Step one: Check the most recently returned value.
- res = _last_pc_desc;
- if (res == NULL) return NULL; // native method; no PcDescs at all
+ // Step one: Check the most recently added value.
+ res = _pc_descs[0];
+ if (res == NULL) return NULL; // native method; no PcDescs at all
if (match_desc(res, pc_offset, approximate)) {
NOT_PRODUCT(++nmethod_stats.pc_desc_repeats);
return res;
}
- // Step two: Check the LRU cache.
- for (int i = 0; i < cache_size; i++) {
+ // Step two: Check the rest of the LRU cache.
+ for (int i = 1; i < cache_size; ++i) {
res = _pc_descs[i];
- if (res->pc_offset() < 0) break; // optimization: skip empty cache
+ if (res->pc_offset() < 0) break; // optimization: skip empty cache
if (match_desc(res, pc_offset, approximate)) {
NOT_PRODUCT(++nmethod_stats.pc_desc_hits);
- _last_pc_desc = res; // record this cache hit in case of repeat
return res;
}
}
@@ -322,24 +326,23 @@
void PcDescCache::add_pc_desc(PcDesc* pc_desc) {
NOT_PRODUCT(++nmethod_stats.pc_desc_adds);
- // Update the LRU cache by shifting pc_desc forward:
+ // Update the LRU cache by shifting pc_desc forward.
for (int i = 0; i < cache_size; i++) {
PcDesc* next = _pc_descs[i];
_pc_descs[i] = pc_desc;
pc_desc = next;
}
- // Note: Do not update _last_pc_desc. It fronts for the LRU cache.
}
// adjust pcs_size so that it is a multiple of both oopSize and
// sizeof(PcDesc) (assumes that if sizeof(PcDesc) is not a multiple
// of oopSize, then 2*sizeof(PcDesc) is)
-static int adjust_pcs_size(int pcs_size) {
+static int adjust_pcs_size(int pcs_size) {
int nsize = round_to(pcs_size, oopSize);
if ((nsize % sizeof(PcDesc)) != 0) {
nsize = pcs_size + sizeof(PcDesc);
}
- assert((nsize % oopSize) == 0, "correct alignment");
+ assert((nsize % oopSize) == 0, "correct alignment");
return nsize;
}
@@ -762,7 +765,7 @@
void* nmethod::operator new(size_t size, int nmethod_size) {
// Always leave some room in the CodeCache for I2C/C2I adapters
- if (CodeCache::unallocated_capacity() < CodeCacheMinimumFreeSpace) return NULL;
+ if (CodeCache::largest_free_block() < CodeCacheMinimumFreeSpace) return NULL;
return CodeCache::allocate(nmethod_size);
}
@@ -1180,14 +1183,17 @@
set_stack_traversal_mark(NMethodSweeper::traversal_count());
}
-// Tell if a non-entrant method can be converted to a zombie (i.e., there is no activations on the stack)
+// Tell if a non-entrant method can be converted to a zombie (i.e.,
+// there are no activations on the stack, not in use by the VM,
+// and not in use by the ServiceThread)
bool nmethod::can_not_entrant_be_converted() {
assert(is_not_entrant(), "must be a non-entrant method");
// Since the nmethod sweeper only does partial sweep the sweeper's traversal
// count can be greater than the stack traversal count before it hits the
// nmethod for the second time.
- return stack_traversal_mark()+1 < NMethodSweeper::traversal_count();
+ return stack_traversal_mark()+1 < NMethodSweeper::traversal_count() &&
+ !is_locked_by_vm();
}
void nmethod::inc_decompile_count() {
@@ -1294,6 +1300,7 @@
// Common functionality for both make_not_entrant and make_zombie
bool nmethod::make_not_entrant_or_zombie(unsigned int state) {
assert(state == zombie || state == not_entrant, "must be zombie or not_entrant");
+ assert(!is_zombie(), "should not already be a zombie");
// Make sure neither the nmethod nor the method is flushed in case of a safepoint in code below.
nmethodLocker nml(this);
@@ -1301,11 +1308,6 @@
No_Safepoint_Verifier nsv;
{
- // If the method is already zombie there is nothing to do
- if (is_zombie()) {
- return false;
- }
-
// invalidate osr nmethod before acquiring the patching lock since
// they both acquire leaf locks and we don't want a deadlock.
// This logic is equivalent to the logic below for patching the
@@ -1375,13 +1377,12 @@
flush_dependencies(NULL);
}
- {
- // zombie only - if a JVMTI agent has enabled the CompiledMethodUnload event
- // and it hasn't already been reported for this nmethod then report it now.
- // (the event may have been reported earilier if the GC marked it for unloading).
- Pause_No_Safepoint_Verifier pnsv(&nsv);
- post_compiled_method_unload();
- }
+ // zombie only - if a JVMTI agent has enabled the CompiledMethodUnload
+ // event and it hasn't already been reported for this nmethod then
+ // report it now. The event may have been reported earilier if the GC
+ // marked it for unloading). JvmtiDeferredEventQueue support means
+ // we no longer go to a safepoint here.
+ post_compiled_method_unload();
#ifdef ASSERT
// It's no longer safe to access the oops section since zombie
@@ -1566,7 +1567,7 @@
if (_jmethod_id != NULL && JvmtiExport::should_post_compiled_method_unload()) {
assert(!unload_reported(), "already unloaded");
JvmtiDeferredEvent event =
- JvmtiDeferredEvent::compiled_method_unload_event(
+ JvmtiDeferredEvent::compiled_method_unload_event(this,
_jmethod_id, insts_begin());
if (SafepointSynchronize::is_at_safepoint()) {
// Don't want to take the queueing lock. Add it as pending and
@@ -1881,7 +1882,7 @@
oop nmethod::embeddedOop_at(u_char* p) {
- RelocIterator iter(this, p, p + oopSize);
+ RelocIterator iter(this, p, p + 1);
while (iter.next())
if (iter.type() == relocInfo::oop_type) {
return iter.oop_reloc()->oop_value();
@@ -2171,10 +2172,12 @@
lock_nmethod(_nm);
}
-void nmethodLocker::lock_nmethod(nmethod* nm) {
+// Only JvmtiDeferredEvent::compiled_method_unload_event()
+// should pass zombie_ok == true.
+void nmethodLocker::lock_nmethod(nmethod* nm, bool zombie_ok) {
if (nm == NULL) return;
Atomic::inc(&nm->_lock_count);
- guarantee(!nm->is_zombie(), "cannot lock a zombie method");
+ guarantee(zombie_ok || !nm->is_zombie(), "cannot lock a zombie method");
}
void nmethodLocker::unlock_nmethod(nmethod* nm) {
--- a/hotspot/src/share/vm/code/nmethod.hpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/code/nmethod.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -69,14 +69,13 @@
friend class VMStructs;
private:
enum { cache_size = 4 };
- PcDesc* _last_pc_desc; // most recent pc_desc found
PcDesc* _pc_descs[cache_size]; // last cache_size pc_descs found
public:
- PcDescCache() { debug_only(_last_pc_desc = NULL); }
+ PcDescCache() { debug_only(_pc_descs[0] = NULL); }
void reset_to(PcDesc* initial_pc_desc);
PcDesc* find_pc_desc(int pc_offset, bool approximate);
void add_pc_desc(PcDesc* pc_desc);
- PcDesc* last_pc_desc() { return _last_pc_desc; }
+ PcDesc* last_pc_desc() { return _pc_descs[0]; }
};
@@ -178,7 +177,7 @@
unsigned int _has_method_handle_invokes:1; // Has this method MethodHandle invokes?
// Protected by Patching_lock
- unsigned char _state; // {alive, not_entrant, zombie, unloaded)
+ unsigned char _state; // {alive, not_entrant, zombie, unloaded}
#ifdef ASSERT
bool _oops_are_stale; // indicates that it's no longer safe to access oops section
@@ -194,7 +193,10 @@
NOT_PRODUCT(bool _has_debug_info; )
- // Nmethod Flushing lock (if non-zero, then the nmethod is not removed)
+ // Nmethod Flushing lock. If non-zero, then the nmethod is not removed
+ // and is not made into a zombie. However, once the nmethod is made into
+ // a zombie, it will be locked one final time if CompiledMethodUnload
+ // event processing needs to be done.
jint _lock_count;
// not_entrant method removal. Each mark_sweep pass will update
@@ -522,8 +524,9 @@
void flush();
public:
- // If returning true, it is unsafe to remove this nmethod even though it is a zombie
- // nmethod, since the VM might have a reference to it. Should only be called from a safepoint.
+ // When true is returned, it is unsafe to remove this nmethod even if
+ // it is a zombie, since the VM or the ServiceThread might still be
+ // using it.
bool is_locked_by_vm() const { return _lock_count >0; }
// See comment at definition of _last_seen_on_stack
@@ -689,13 +692,20 @@
};
-// Locks an nmethod so its code will not get removed, even if it is a zombie/not_entrant method
+// Locks an nmethod so its code will not get removed and it will not
+// be made into a zombie, even if it is a not_entrant method. After the
+// nmethod becomes a zombie, if CompiledMethodUnload event processing
+// needs to be done, then lock_nmethod() is used directly to keep the
+// generated code from being reused too early.
class nmethodLocker : public StackObj {
nmethod* _nm;
public:
- static void lock_nmethod(nmethod* nm); // note: nm can be NULL
+ // note: nm can be NULL
+ // Only JvmtiDeferredEvent::compiled_method_unload_event()
+ // should pass zombie_ok == true.
+ static void lock_nmethod(nmethod* nm, bool zombie_ok = false);
static void unlock_nmethod(nmethod* nm); // (ditto)
nmethodLocker(address pc); // derive nm from pc
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -1364,7 +1364,7 @@
// We need this HandleMark to avoid leaking VM handles.
HandleMark hm(thread);
- if (CodeCache::unallocated_capacity() < CodeCacheMinimumFreeSpace) {
+ if (CodeCache::largest_free_block() < CodeCacheMinimumFreeSpace) {
// the code cache is really full
handle_full_code_cache();
} else if (UseCodeCacheFlushing && CodeCache::needs_flushing()) {
@@ -1645,11 +1645,13 @@
if (UseCompiler || AlwaysCompileLoopMethods ) {
if (xtty != NULL) {
xtty->begin_elem("code_cache_full");
+ CodeCache::log_state(xtty);
xtty->stamp();
xtty->end_elem();
}
warning("CodeCache is full. Compiler has been disabled.");
warning("Try increasing the code cache size using -XX:ReservedCodeCacheSize=");
+ CodeCache::print_bounds(tty);
#ifndef PRODUCT
if (CompileTheWorld || ExitOnFullCodeCache) {
before_exit(JavaThread::current());
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -292,13 +292,15 @@
void CMSCollector::ref_processor_init() {
if (_ref_processor == NULL) {
// Allocate and initialize a reference processor
- _ref_processor = ReferenceProcessor::create_ref_processor(
- _span, // span
- _cmsGen->refs_discovery_is_atomic(), // atomic_discovery
- _cmsGen->refs_discovery_is_mt(), // mt_discovery
- &_is_alive_closure,
- ParallelGCThreads,
- ParallelRefProcEnabled);
+ _ref_processor =
+ new ReferenceProcessor(_span, // span
+ (ParallelGCThreads > 1) && ParallelRefProcEnabled, // mt processing
+ (int) ParallelGCThreads, // mt processing degree
+ _cmsGen->refs_discovery_is_mt(), // mt discovery
+ (int) MAX2(ConcGCThreads, ParallelGCThreads), // mt discovery degree
+ _cmsGen->refs_discovery_is_atomic(), // discovery is not atomic
+ &_is_alive_closure, // closure for liveness info
+ false); // next field updates do not need write barrier
// Initialize the _ref_processor field of CMSGen
_cmsGen->set_ref_processor(_ref_processor);
@@ -641,7 +643,7 @@
}
// Support for multi-threaded concurrent phases
- if (CollectedHeap::use_parallel_gc_threads() && CMSConcurrentMTEnabled) {
+ if (CMSConcurrentMTEnabled) {
if (FLAG_IS_DEFAULT(ConcGCThreads)) {
// just for now
FLAG_SET_DEFAULT(ConcGCThreads, (ParallelGCThreads + 3)/4);
@@ -1689,6 +1691,8 @@
MutexLockerEx y(CGC_lock, Mutex::_no_safepoint_check_flag);
_full_gc_requested = true;
CGC_lock->notify(); // nudge CMS thread
+ } else {
+ assert(gc_count > full_gc_count, "Error: causal loop");
}
}
@@ -1988,17 +1992,16 @@
// Temporarily widen the span of the weak reference processing to
// the entire heap.
MemRegion new_span(GenCollectedHeap::heap()->reserved_region());
- ReferenceProcessorSpanMutator x(ref_processor(), new_span);
-
+ ReferenceProcessorSpanMutator rp_mut_span(ref_processor(), new_span);
// Temporarily, clear the "is_alive_non_header" field of the
// reference processor.
- ReferenceProcessorIsAliveMutator y(ref_processor(), NULL);
-
+ ReferenceProcessorIsAliveMutator rp_mut_closure(ref_processor(), NULL);
// Temporarily make reference _processing_ single threaded (non-MT).
- ReferenceProcessorMTProcMutator z(ref_processor(), false);
-
+ ReferenceProcessorMTProcMutator rp_mut_mt_processing(ref_processor(), false);
// Temporarily make refs discovery atomic
- ReferenceProcessorAtomicMutator w(ref_processor(), true);
+ ReferenceProcessorAtomicMutator rp_mut_atomic(ref_processor(), true);
+ // Temporarily make reference _discovery_ single threaded (non-MT)
+ ReferenceProcessorMTDiscoveryMutator rp_mut_discovery(ref_processor(), false);
ref_processor()->set_enqueuing_is_done(false);
ref_processor()->enable_discovery();
@@ -4263,9 +4266,7 @@
// Refs discovery is already non-atomic.
assert(!ref_processor()->discovery_is_atomic(), "Should be non-atomic");
- // Mutate the Refs discovery so it is MT during the
- // multi-threaded marking phase.
- ReferenceProcessorMTMutator mt(ref_processor(), num_workers > 1);
+ assert(ref_processor()->discovery_is_mt(), "Discovery should be MT");
DEBUG_ONLY(RememberKlassesChecker cmx(should_unload_classes());)
conc_workers()->start_task(&tsk);
while (tsk.yielded()) {
@@ -4318,6 +4319,8 @@
ResourceMark rm;
HandleMark hm;
+ // Temporarily make refs discovery single threaded (non-MT)
+ ReferenceProcessorMTDiscoveryMutator rp_mut_discovery(ref_processor(), false);
MarkFromRootsClosure markFromRootsClosure(this, _span, &_markBitMap,
&_markStack, &_revisitStack, CMSYield && asynch);
// the last argument to iterate indicates whether the iteration
@@ -4356,10 +4359,6 @@
verify_overflow_empty();
_abort_preclean = false;
if (CMSPrecleaningEnabled) {
- // Precleaning is currently not MT but the reference processor
- // may be set for MT. Disable it temporarily here.
- ReferenceProcessor* rp = ref_processor();
- ReferenceProcessorMTProcMutator z(rp, false);
_eden_chunk_index = 0;
size_t used = get_eden_used();
size_t capacity = get_eden_capacity();
@@ -4502,11 +4501,16 @@
_collectorState == AbortablePreclean, "incorrect state");
ResourceMark rm;
HandleMark hm;
+
+ // Precleaning is currently not MT but the reference processor
+ // may be set for MT. Disable it temporarily here.
+ ReferenceProcessor* rp = ref_processor();
+ ReferenceProcessorMTDiscoveryMutator rp_mut_discovery(rp, false);
+
// Do one pass of scrubbing the discovered reference lists
// to remove any reference objects with strongly-reachable
// referents.
if (clean_refs) {
- ReferenceProcessor* rp = ref_processor();
CMSPrecleanRefsYieldClosure yield_cl(this);
assert(rp->span().equals(_span), "Spans should be equal");
CMSKeepAliveClosure keep_alive(this, _span, &_markBitMap,
@@ -5576,8 +5580,10 @@
// in the multi-threaded case, but we special-case n=1 here to get
// repeatable measurements of the 1-thread overhead of the parallel code.
if (n_workers > 1) {
- // Make refs discovery MT-safe
- ReferenceProcessorMTMutator mt(ref_processor(), true);
+ // Make refs discovery MT-safe, if it isn't already: it may not
+ // necessarily be so, since it's possible that we are doing
+ // ST marking.
+ ReferenceProcessorMTDiscoveryMutator mt(ref_processor(), true);
GenCollectedHeap::StrongRootsScope srs(gch);
workers->run_task(&tsk);
} else {
@@ -5703,14 +5709,19 @@
CMSBitMap* mark_bit_map,
AbstractWorkGang* workers,
OopTaskQueueSet* task_queues):
+ // XXX Should superclass AGTWOQ also know about AWG since it knows
+ // about the task_queues used by the AWG? Then it could initialize
+ // the terminator() object. See 6984287. The set_for_termination()
+ // below is a temporary band-aid for the regression in 6984287.
AbstractGangTaskWOopQueues("Process referents by policy in parallel",
task_queues),
_task(task),
_collector(collector), _span(span), _mark_bit_map(mark_bit_map)
- {
- assert(_collector->_span.equals(_span) && !_span.is_empty(),
- "Inconsistency in _span");
- }
+ {
+ assert(_collector->_span.equals(_span) && !_span.is_empty(),
+ "Inconsistency in _span");
+ set_for_termination(workers->active_workers());
+ }
OopTaskQueueSet* task_queues() { return queues(); }
@@ -5872,8 +5883,7 @@
// That is OK as long as the Reference lists are balanced (see
// balance_all_queues() and balance_queues()).
-
- rp->set_mt_degree(ParallelGCThreads);
+ rp->set_active_mt_degree(ParallelGCThreads);
CMSRefProcTaskExecutor task_executor(*this);
rp->process_discovered_references(&_is_alive_closure,
&cmsKeepAliveClosure,
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -1133,7 +1133,7 @@
// rare that the cost of the CAS's involved is in the
// noise. That's a measurement that should be done, and
// the code simplified if that turns out to be the case.
- return false;
+ return ConcGCThreads > 1;
}
// Override
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -51,7 +51,7 @@
volatile jint ConcurrentMarkSweepThread::_pending_yields = 0;
volatile jint ConcurrentMarkSweepThread::_pending_decrements = 0;
-volatile bool ConcurrentMarkSweepThread::_icms_enabled = false;
+volatile jint ConcurrentMarkSweepThread::_icms_disabled = 0;
volatile bool ConcurrentMarkSweepThread::_should_run = false;
// When icms is enabled, the icms thread is stopped until explicitly
// started.
@@ -84,7 +84,7 @@
}
}
_sltMonitor = SLT_lock;
- set_icms_enabled(CMSIncrementalMode);
+ assert(!CMSIncrementalMode || icms_is_enabled(), "Error");
}
void ConcurrentMarkSweepThread::run() {
@@ -341,11 +341,11 @@
void ConcurrentMarkSweepThread::icms_wait() {
assert(UseConcMarkSweepGC && CMSIncrementalMode, "just checking");
- if (_should_stop && icms_enabled()) {
+ if (_should_stop && icms_is_enabled()) {
MutexLockerEx x(iCMS_lock, Mutex::_no_safepoint_check_flag);
trace_state("pause_icms");
_collector->stats().stop_cms_timer();
- while(!_should_run && icms_enabled()) {
+ while(!_should_run && icms_is_enabled()) {
iCMS_lock->wait(Mutex::_no_safepoint_check_flag);
}
_collector->stats().start_cms_timer();
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -40,7 +40,7 @@
class ConcurrentMarkSweepGeneration;
class CMSCollector;
-// The Concurrent Mark Sweep GC Thread (could be several in the future).
+// The Concurrent Mark Sweep GC Thread
class ConcurrentMarkSweepThread: public ConcurrentGCThread {
friend class VMStructs;
friend class ConcurrentMarkSweepGeneration; // XXX should remove friendship
@@ -55,8 +55,6 @@
static SurrogateLockerThread::SLT_msg_type _sltBuffer;
static Monitor* _sltMonitor;
- ConcurrentMarkSweepThread* _next;
-
static bool _should_terminate;
enum CMS_flag_type {
@@ -84,7 +82,7 @@
// Tracing messages, enabled by CMSTraceThreadState.
static inline void trace_state(const char* desc);
- static volatile bool _icms_enabled; // iCMS enabled?
+ static volatile int _icms_disabled; // a counter to track #iCMS disable & enable
static volatile bool _should_run; // iCMS may run
static volatile bool _should_stop; // iCMS should stop
@@ -214,10 +212,25 @@
// Incremental mode is enabled globally by the flag CMSIncrementalMode. It
// must also be enabled/disabled dynamically to allow foreground collections.
- static inline void enable_icms() { _icms_enabled = true; }
- static inline void disable_icms() { _icms_enabled = false; }
- static inline void set_icms_enabled(bool val) { _icms_enabled = val; }
- static inline bool icms_enabled() { return _icms_enabled; }
+#define ICMS_ENABLING_ASSERT \
+ assert((CMSIncrementalMode && _icms_disabled >= 0) || \
+ (!CMSIncrementalMode && _icms_disabled <= 0), "Error")
+
+ static inline void enable_icms() {
+ ICMS_ENABLING_ASSERT;
+ Atomic::dec(&_icms_disabled);
+ }
+ static inline void disable_icms() {
+ ICMS_ENABLING_ASSERT;
+ Atomic::inc(&_icms_disabled);
+ }
+ static inline bool icms_is_disabled() {
+ ICMS_ENABLING_ASSERT;
+ return _icms_disabled > 0;
+ }
+ static inline bool icms_is_enabled() {
+ return !icms_is_disabled();
+ }
};
inline void ConcurrentMarkSweepThread::trace_state(const char* desc) {
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -192,14 +192,18 @@
"total_collections() should be monotonically increasing");
MutexLockerEx x(FullGCCount_lock, Mutex::_no_safepoint_check_flag);
+ assert(_full_gc_count_before <= gch->total_full_collections(), "Error");
if (gch->total_full_collections() == _full_gc_count_before) {
- // Disable iCMS until the full collection is done.
+ // Disable iCMS until the full collection is done, and
+ // remember that we did so.
CMSCollector::disable_icms();
+ _disabled_icms = true;
// In case CMS thread was in icms_wait(), wake it up.
CMSCollector::start_icms();
// Nudge the CMS thread to start a concurrent collection.
CMSCollector::request_full_gc(_full_gc_count_before);
} else {
+ assert(_full_gc_count_before < gch->total_full_collections(), "Error");
FullGCCount_lock->notify_all(); // Inform the Java thread its work is done
}
}
@@ -259,6 +263,8 @@
FullGCCount_lock->wait(Mutex::_no_safepoint_check_flag);
}
}
- // Enable iCMS back.
- CMSCollector::enable_icms();
+ // Enable iCMS back if we disabled it earlier.
+ if (_disabled_icms) {
+ CMSCollector::enable_icms();
+ }
}
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.hpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -128,11 +128,14 @@
// VM operation to invoke a concurrent collection of the heap as a
// GenCollectedHeap heap.
class VM_GenCollectFullConcurrent: public VM_GC_Operation {
+ bool _disabled_icms;
public:
VM_GenCollectFullConcurrent(unsigned int gc_count_before,
unsigned int full_gc_count_before,
GCCause::Cause gc_cause)
- : VM_GC_Operation(gc_count_before, gc_cause, full_gc_count_before, true /* full */) {
+ : VM_GC_Operation(gc_count_before, gc_cause, full_gc_count_before, true /* full */),
+ _disabled_icms(false)
+ {
assert(FullGCCount_lock != NULL, "Error");
assert(UseAsyncConcMarkSweepGC, "Else will hang caller");
}
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -373,7 +373,7 @@
// RSet updating while within an evacuation pause.
// In this case worker_i should be the id of a GC worker thread
assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");
- assert(worker_i < (int) DirtyCardQueueSet::num_par_ids(), "incorrect worker id");
+ assert(worker_i < (int) (ParallelGCThreads == 0 ? 1 : ParallelGCThreads), "incorrect worker id");
into_cset_dcq->enqueue(entry);
}
}
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -1828,7 +1828,7 @@
G1CollectedHeap* g1h = G1CollectedHeap::heap();
_cleanup_list.verify_optional();
- FreeRegionList local_free_list("Local Cleanup List");
+ FreeRegionList tmp_free_list("Tmp Free List");
if (G1ConcRegionFreeingVerbose) {
gclog_or_tty->print_cr("G1ConcRegionFreeing [complete cleanup] : "
@@ -1842,7 +1842,7 @@
HeapRegion* hr = _cleanup_list.remove_head();
assert(hr != NULL, "the list was not empty");
hr->rem_set()->clear();
- local_free_list.add_as_tail(hr);
+ tmp_free_list.add_as_tail(hr);
// Instead of adding one region at a time to the secondary_free_list,
// we accumulate them in the local list and move them a few at a
@@ -1850,20 +1850,20 @@
// we do during this process. We'll also append the local list when
// _cleanup_list is empty (which means we just removed the last
// region from the _cleanup_list).
- if ((local_free_list.length() % G1SecondaryFreeListAppendLength == 0) ||
+ if ((tmp_free_list.length() % G1SecondaryFreeListAppendLength == 0) ||
_cleanup_list.is_empty()) {
if (G1ConcRegionFreeingVerbose) {
gclog_or_tty->print_cr("G1ConcRegionFreeing [complete cleanup] : "
"appending "SIZE_FORMAT" entries to the "
"secondary_free_list, clean list still has "
SIZE_FORMAT" entries",
- local_free_list.length(),
+ tmp_free_list.length(),
_cleanup_list.length());
}
{
MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag);
- g1h->secondary_free_list_add_as_tail(&local_free_list);
+ g1h->secondary_free_list_add_as_tail(&tmp_free_list);
SecondaryFreeList_lock->notify_all();
}
@@ -1874,7 +1874,7 @@
}
}
}
- assert(local_free_list.is_empty(), "post-condition");
+ assert(tmp_free_list.is_empty(), "post-condition");
}
// Support closures for reference procssing in G1
@@ -2141,21 +2141,22 @@
G1CMKeepAliveClosure g1_keep_alive(g1h, this, nextMarkBitMap());
G1CMDrainMarkingStackClosure
g1_drain_mark_stack(nextMarkBitMap(), &_markStack, &g1_keep_alive);
-
// We use the work gang from the G1CollectedHeap and we utilize all
// the worker threads.
- int active_workers = MAX2(MIN2(g1h->workers()->total_workers(), (int)_max_task_num), 1);
+ int active_workers = g1h->workers() ? g1h->workers()->total_workers() : 1;
+ active_workers = MAX2(MIN2(active_workers, (int)_max_task_num), 1);
G1RefProcTaskExecutor par_task_executor(g1h, this, nextMarkBitMap(),
g1h->workers(), active_workers);
+
if (rp->processing_is_mt()) {
// Set the degree of MT here. If the discovery is done MT, there
// may have been a different number of threads doing the discovery
// and a different number of discovered lists may have Ref objects.
// That is OK as long as the Reference lists are balanced (see
// balance_all_queues() and balance_queues()).
- rp->set_mt_degree(active_workers);
+ rp->set_active_mt_degree(active_workers);
rp->process_discovered_references(&g1_is_alive,
&g1_keep_alive,
@@ -3182,7 +3183,7 @@
template <class T> void do_oop_work(T* p) {
assert( _g1h->is_in_g1_reserved((HeapWord*) p), "invariant");
- assert(!_g1h->is_on_free_list(
+ assert(!_g1h->is_on_master_free_list(
_g1h->heap_region_containing((HeapWord*) p)), "invariant");
oop obj = oopDesc::load_decode_heap_oop(p);
@@ -3403,7 +3404,7 @@
void CMTask::push(oop obj) {
HeapWord* objAddr = (HeapWord*) obj;
assert(_g1h->is_in_g1_reserved(objAddr), "invariant");
- assert(!_g1h->is_on_free_list(
+ assert(!_g1h->is_on_master_free_list(
_g1h->heap_region_containing((HeapWord*) objAddr)), "invariant");
assert(!_g1h->is_obj_ill(obj), "invariant");
assert(_nextMarkBitMap->isMarked(objAddr), "invariant");
@@ -3649,7 +3650,7 @@
(void*) obj);
assert(_g1h->is_in_g1_reserved((HeapWord*) obj), "invariant" );
- assert(!_g1h->is_on_free_list(
+ assert(!_g1h->is_on_master_free_list(
_g1h->heap_region_containing((HeapWord*) obj)), "invariant");
scan_object(obj);
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -237,9 +237,9 @@
// The following will finish freeing up any regions that we
// found to be empty during cleanup. We'll do this part
// without joining the suspendible set. If an evacuation pause
- // takes places, then we would carry on freeing regions in
+ // takes place, then we would carry on freeing regions in
// case they are needed by the pause. If a Full GC takes
- // places, it would wait for us to process the regions
+ // place, it would wait for us to process the regions
// reclaimed by cleanup.
double cleanup_start_sec = os::elapsedTime();
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -479,7 +479,7 @@
// Private methods.
HeapRegion*
-G1CollectedHeap::new_region_try_secondary_free_list(size_t word_size) {
+G1CollectedHeap::new_region_try_secondary_free_list() {
MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag);
while (!_secondary_free_list.is_empty() || free_regions_coming()) {
if (!_secondary_free_list.is_empty()) {
@@ -531,7 +531,7 @@
gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : "
"forced to look at the secondary_free_list");
}
- res = new_region_try_secondary_free_list(word_size);
+ res = new_region_try_secondary_free_list();
if (res != NULL) {
return res;
}
@@ -543,7 +543,7 @@
gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : "
"res == NULL, trying the secondary_free_list");
}
- res = new_region_try_secondary_free_list(word_size);
+ res = new_region_try_secondary_free_list();
}
if (res == NULL && do_expand) {
if (expand(word_size * HeapWordSize)) {
@@ -579,6 +579,9 @@
int G1CollectedHeap::humongous_obj_allocate_find_first(size_t num_regions,
size_t word_size) {
+ assert(isHumongous(word_size), "word_size should be humongous");
+ assert(num_regions * HeapRegion::GrainWords >= word_size, "pre-condition");
+
int first = -1;
if (num_regions == 1) {
// Only one region to allocate, no need to go through the slower
@@ -600,7 +603,7 @@
// request. If we are only allocating one region we use the common
// region allocation code (see above).
wait_while_free_regions_coming();
- append_secondary_free_list_if_not_empty();
+ append_secondary_free_list_if_not_empty_with_lock();
if (free_regions() >= num_regions) {
first = _hrs->find_contiguous(num_regions);
@@ -608,7 +611,7 @@
for (int i = first; i < first + (int) num_regions; ++i) {
HeapRegion* hr = _hrs->at(i);
assert(hr->is_empty(), "sanity");
- assert(is_on_free_list(hr), "sanity");
+ assert(is_on_master_free_list(hr), "sanity");
hr->set_pending_removal(true);
}
_free_list.remove_all_pending(num_regions);
@@ -618,6 +621,126 @@
return first;
}
+HeapWord*
+G1CollectedHeap::humongous_obj_allocate_initialize_regions(int first,
+ size_t num_regions,
+ size_t word_size) {
+ assert(first != -1, "pre-condition");
+ assert(isHumongous(word_size), "word_size should be humongous");
+ assert(num_regions * HeapRegion::GrainWords >= word_size, "pre-condition");
+
+ // Index of last region in the series + 1.
+ int last = first + (int) num_regions;
+
+ // We need to initialize the region(s) we just discovered. This is
+ // a bit tricky given that it can happen concurrently with
+ // refinement threads refining cards on these regions and
+ // potentially wanting to refine the BOT as they are scanning
+ // those cards (this can happen shortly after a cleanup; see CR
+ // 6991377). So we have to set up the region(s) carefully and in
+ // a specific order.
+
+ // The word size sum of all the regions we will allocate.
+ size_t word_size_sum = num_regions * HeapRegion::GrainWords;
+ assert(word_size <= word_size_sum, "sanity");
+
+ // This will be the "starts humongous" region.
+ HeapRegion* first_hr = _hrs->at(first);
+ // The header of the new object will be placed at the bottom of
+ // the first region.
+ HeapWord* new_obj = first_hr->bottom();
+ // This will be the new end of the first region in the series that
+ // should also match the end of the last region in the seriers.
+ HeapWord* new_end = new_obj + word_size_sum;
+ // This will be the new top of the first region that will reflect
+ // this allocation.
+ HeapWord* new_top = new_obj + word_size;
+
+ // First, we need to zero the header of the space that we will be
+ // allocating. When we update top further down, some refinement
+ // threads might try to scan the region. By zeroing the header we
+ // ensure that any thread that will try to scan the region will
+ // come across the zero klass word and bail out.
+ //
+ // NOTE: It would not have been correct to have used
+ // CollectedHeap::fill_with_object() and make the space look like
+ // an int array. The thread that is doing the allocation will
+ // later update the object header to a potentially different array
+ // type and, for a very short period of time, the klass and length
+ // fields will be inconsistent. This could cause a refinement
+ // thread to calculate the object size incorrectly.
+ Copy::fill_to_words(new_obj, oopDesc::header_size(), 0);
+
+ // We will set up the first region as "starts humongous". This
+ // will also update the BOT covering all the regions to reflect
+ // that there is a single object that starts at the bottom of the
+ // first region.
+ first_hr->set_startsHumongous(new_top, new_end);
+
+ // Then, if there are any, we will set up the "continues
+ // humongous" regions.
+ HeapRegion* hr = NULL;
+ for (int i = first + 1; i < last; ++i) {
+ hr = _hrs->at(i);
+ hr->set_continuesHumongous(first_hr);
+ }
+ // If we have "continues humongous" regions (hr != NULL), then the
+ // end of the last one should match new_end.
+ assert(hr == NULL || hr->end() == new_end, "sanity");
+
+ // Up to this point no concurrent thread would have been able to
+ // do any scanning on any region in this series. All the top
+ // fields still point to bottom, so the intersection between
+ // [bottom,top] and [card_start,card_end] will be empty. Before we
+ // update the top fields, we'll do a storestore to make sure that
+ // no thread sees the update to top before the zeroing of the
+ // object header and the BOT initialization.
+ OrderAccess::storestore();
+
+ // Now that the BOT and the object header have been initialized,
+ // we can update top of the "starts humongous" region.
+ assert(first_hr->bottom() < new_top && new_top <= first_hr->end(),
+ "new_top should be in this region");
+ first_hr->set_top(new_top);
+
+ // Now, we will update the top fields of the "continues humongous"
+ // regions. The reason we need to do this is that, otherwise,
+ // these regions would look empty and this will confuse parts of
+ // G1. For example, the code that looks for a consecutive number
+ // of empty regions will consider them empty and try to
+ // re-allocate them. We can extend is_empty() to also include
+ // !continuesHumongous(), but it is easier to just update the top
+ // fields here. The way we set top for all regions (i.e., top ==
+ // end for all regions but the last one, top == new_top for the
+ // last one) is actually used when we will free up the humongous
+ // region in free_humongous_region().
+ hr = NULL;
+ for (int i = first + 1; i < last; ++i) {
+ hr = _hrs->at(i);
+ if ((i + 1) == last) {
+ // last continues humongous region
+ assert(hr->bottom() < new_top && new_top <= hr->end(),
+ "new_top should fall on this region");
+ hr->set_top(new_top);
+ } else {
+ // not last one
+ assert(new_top > hr->end(), "new_top should be above this region");
+ hr->set_top(hr->end());
+ }
+ }
+ // If we have continues humongous regions (hr != NULL), then the
+ // end of the last one should match new_end and its top should
+ // match new_top.
+ assert(hr == NULL ||
+ (hr->end() == new_end && hr->top() == new_top), "sanity");
+
+ assert(first_hr->used() == word_size * HeapWordSize, "invariant");
+ _summary_bytes_used += first_hr->used();
+ _humongous_set.add(first_hr);
+
+ return new_obj;
+}
+
// If could fit into free regions w/o expansion, try.
// Otherwise, if can expand, do so.
// Otherwise, if using ex regions might help, try with ex given back.
@@ -653,121 +776,16 @@
}
}
+ HeapWord* result = NULL;
if (first != -1) {
- // Index of last region in the series + 1.
- int last = first + (int) num_regions;
-
- // We need to initialize the region(s) we just discovered. This is
- // a bit tricky given that it can happen concurrently with
- // refinement threads refining cards on these regions and
- // potentially wanting to refine the BOT as they are scanning
- // those cards (this can happen shortly after a cleanup; see CR
- // 6991377). So we have to set up the region(s) carefully and in
- // a specific order.
-
- // The word size sum of all the regions we will allocate.
- size_t word_size_sum = num_regions * HeapRegion::GrainWords;
- assert(word_size <= word_size_sum, "sanity");
-
- // This will be the "starts humongous" region.
- HeapRegion* first_hr = _hrs->at(first);
- // The header of the new object will be placed at the bottom of
- // the first region.
- HeapWord* new_obj = first_hr->bottom();
- // This will be the new end of the first region in the series that
- // should also match the end of the last region in the seriers.
- HeapWord* new_end = new_obj + word_size_sum;
- // This will be the new top of the first region that will reflect
- // this allocation.
- HeapWord* new_top = new_obj + word_size;
-
- // First, we need to zero the header of the space that we will be
- // allocating. When we update top further down, some refinement
- // threads might try to scan the region. By zeroing the header we
- // ensure that any thread that will try to scan the region will
- // come across the zero klass word and bail out.
- //
- // NOTE: It would not have been correct to have used
- // CollectedHeap::fill_with_object() and make the space look like
- // an int array. The thread that is doing the allocation will
- // later update the object header to a potentially different array
- // type and, for a very short period of time, the klass and length
- // fields will be inconsistent. This could cause a refinement
- // thread to calculate the object size incorrectly.
- Copy::fill_to_words(new_obj, oopDesc::header_size(), 0);
-
- // We will set up the first region as "starts humongous". This
- // will also update the BOT covering all the regions to reflect
- // that there is a single object that starts at the bottom of the
- // first region.
- first_hr->set_startsHumongous(new_top, new_end);
-
- // Then, if there are any, we will set up the "continues
- // humongous" regions.
- HeapRegion* hr = NULL;
- for (int i = first + 1; i < last; ++i) {
- hr = _hrs->at(i);
- hr->set_continuesHumongous(first_hr);
- }
- // If we have "continues humongous" regions (hr != NULL), then the
- // end of the last one should match new_end.
- assert(hr == NULL || hr->end() == new_end, "sanity");
-
- // Up to this point no concurrent thread would have been able to
- // do any scanning on any region in this series. All the top
- // fields still point to bottom, so the intersection between
- // [bottom,top] and [card_start,card_end] will be empty. Before we
- // update the top fields, we'll do a storestore to make sure that
- // no thread sees the update to top before the zeroing of the
- // object header and the BOT initialization.
- OrderAccess::storestore();
-
- // Now that the BOT and the object header have been initialized,
- // we can update top of the "starts humongous" region.
- assert(first_hr->bottom() < new_top && new_top <= first_hr->end(),
- "new_top should be in this region");
- first_hr->set_top(new_top);
-
- // Now, we will update the top fields of the "continues humongous"
- // regions. The reason we need to do this is that, otherwise,
- // these regions would look empty and this will confuse parts of
- // G1. For example, the code that looks for a consecutive number
- // of empty regions will consider them empty and try to
- // re-allocate them. We can extend is_empty() to also include
- // !continuesHumongous(), but it is easier to just update the top
- // fields here. The way we set top for all regions (i.e., top ==
- // end for all regions but the last one, top == new_top for the
- // last one) is actually used when we will free up the humongous
- // region in free_humongous_region().
- hr = NULL;
- for (int i = first + 1; i < last; ++i) {
- hr = _hrs->at(i);
- if ((i + 1) == last) {
- // last continues humongous region
- assert(hr->bottom() < new_top && new_top <= hr->end(),
- "new_top should fall on this region");
- hr->set_top(new_top);
- } else {
- // not last one
- assert(new_top > hr->end(), "new_top should be above this region");
- hr->set_top(hr->end());
- }
- }
- // If we have continues humongous regions (hr != NULL), then the
- // end of the last one should match new_end and its top should
- // match new_top.
- assert(hr == NULL ||
- (hr->end() == new_end && hr->top() == new_top), "sanity");
-
- assert(first_hr->used() == word_size * HeapWordSize, "invariant");
- _summary_bytes_used += first_hr->used();
- _humongous_set.add(first_hr);
-
- return new_obj;
+ result =
+ humongous_obj_allocate_initialize_regions(first, num_regions, word_size);
+ assert(result != NULL, "it should always return a valid result");
}
verify_region_sets_optional();
- return NULL;
+
+ return result;
}
void
@@ -1389,7 +1407,7 @@
g1_policy()->record_full_collection_start();
wait_while_free_regions_coming();
- append_secondary_free_list_if_not_empty();
+ append_secondary_free_list_if_not_empty_with_lock();
gc_prologue(true);
increment_total_collections(true /* full gc */);
@@ -1444,7 +1462,7 @@
// how reference processing currently works in G1.
// Temporarily make reference _discovery_ single threaded (non-MT).
- ReferenceProcessorMTMutator rp_disc_ser(ref_processor(), false);
+ ReferenceProcessorMTDiscoveryMutator rp_disc_ser(ref_processor(), false);
// Temporarily make refs discovery atomic
ReferenceProcessorAtomicMutator rp_disc_atomic(ref_processor(), true);
@@ -2201,16 +2219,16 @@
SharedHeap::ref_processing_init();
MemRegion mr = reserved_region();
- _ref_processor = ReferenceProcessor::create_ref_processor(
- mr, // span
- false, // Reference discovery is not atomic
- true, // mt_discovery
- &_is_alive_closure, // is alive closure
- // for efficiency
- ParallelGCThreads,
- ParallelRefProcEnabled,
- true); // Setting next fields of discovered
- // lists requires a barrier.
+ _ref_processor =
+ new ReferenceProcessor(mr, // span
+ ParallelRefProcEnabled && (ParallelGCThreads > 1), // mt processing
+ (int) ParallelGCThreads, // degree of mt processing
+ ParallelGCThreads > 1 || ConcGCThreads > 1, // mt discovery
+ (int) MAX2(ParallelGCThreads, ConcGCThreads), // degree of mt discovery
+ false, // Reference discovery is not atomic
+ &_is_alive_closure, // is alive closure for efficiency
+ true); // Setting next fields of discovered
+ // lists requires a barrier.
}
size_t G1CollectedHeap::capacity() const {
@@ -3377,15 +3395,14 @@
TraceMemoryManagerStats tms(false /* fullGC */);
- // If there are any free regions available on the secondary_free_list
- // make sure we append them to the free_list. However, we don't
- // have to wait for the rest of the cleanup operation to
- // finish. If it's still going on that's OK. If we run out of
- // regions, the region allocation code will check the
- // secondary_free_list and potentially wait if more free regions
- // are coming (see new_region_try_secondary_free_list()).
+ // If the secondary_free_list is not empty, append it to the
+ // free_list. No need to wait for the cleanup operation to finish;
+ // the region allocation code will check the secondary_free_list
+ // and wait if necessary. If the G1StressConcRegionFreeing flag is
+ // set, skip this step so that the region allocation code has to
+ // get entries from the secondary_free_list.
if (!G1StressConcRegionFreeing) {
- append_secondary_free_list_if_not_empty();
+ append_secondary_free_list_if_not_empty_with_lock();
}
increment_gc_time_stamp();
@@ -5199,7 +5216,7 @@
size_t rs_lengths = 0;
while (cur != NULL) {
- assert(!is_on_free_list(cur), "sanity");
+ assert(!is_on_master_free_list(cur), "sanity");
if (non_young) {
if (cur->is_young()) {
@@ -5543,13 +5560,10 @@
return;
}
- {
- MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag);
- // Make sure we append the secondary_free_list on the free_list so
- // that all free regions we will come across can be safely
- // attributed to the free_list.
- append_secondary_free_list();
- }
+ // Make sure we append the secondary_free_list on the free_list so
+ // that all free regions we will come across can be safely
+ // attributed to the free_list.
+ append_secondary_free_list_if_not_empty_with_lock();
// Finally, make sure that the region accounting in the lists is
// consistent with what we see in the heap.
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -56,7 +56,6 @@
class ConcurrentMark;
class ConcurrentMarkThread;
class ConcurrentG1Refine;
-class ConcurrentZFThread;
typedef OverflowTaskQueue<StarTask> RefToScanQueue;
typedef GenericTaskQueueSet<RefToScanQueue> RefToScanQueueSet;
@@ -64,12 +63,6 @@
typedef int RegionIdx_t; // needs to hold [ 0..max_regions() )
typedef int CardIdx_t; // needs to hold [ 0..CardsPerRegion )
-enum G1GCThreadGroups {
- G1CRGroup = 0,
- G1ZFGroup = 1,
- G1CMGroup = 2
-};
-
enum GCAllocPurpose {
GCAllocForTenured,
GCAllocForSurvived,
@@ -294,9 +287,9 @@
// These are macros so that, if the assert fires, we get the correct
// line number, file, etc.
-#define heap_locking_asserts_err_msg(__extra_message) \
+#define heap_locking_asserts_err_msg(_extra_message_) \
err_msg("%s : Heap_lock locked: %s, at safepoint: %s, is VM thread: %s", \
- (__extra_message), \
+ (_extra_message_), \
BOOL_TO_STR(Heap_lock->owned_by_self()), \
BOOL_TO_STR(SafepointSynchronize::is_at_safepoint()), \
BOOL_TO_STR(Thread::current()->is_VM_thread()))
@@ -307,11 +300,11 @@
heap_locking_asserts_err_msg("should be holding the Heap_lock")); \
} while (0)
-#define assert_heap_locked_or_at_safepoint(__should_be_vm_thread) \
+#define assert_heap_locked_or_at_safepoint(_should_be_vm_thread_) \
do { \
assert(Heap_lock->owned_by_self() || \
(SafepointSynchronize::is_at_safepoint() && \
- ((__should_be_vm_thread) == Thread::current()->is_VM_thread())), \
+ ((_should_be_vm_thread_) == Thread::current()->is_VM_thread())), \
heap_locking_asserts_err_msg("should be holding the Heap_lock or " \
"should be at a safepoint")); \
} while (0)
@@ -338,10 +331,10 @@
"should not be at a safepoint")); \
} while (0)
-#define assert_at_safepoint(__should_be_vm_thread) \
+#define assert_at_safepoint(_should_be_vm_thread_) \
do { \
assert(SafepointSynchronize::is_at_safepoint() && \
- ((__should_be_vm_thread) == Thread::current()->is_VM_thread()), \
+ ((_should_be_vm_thread_) == Thread::current()->is_VM_thread()), \
heap_locking_asserts_err_msg("should be at a safepoint")); \
} while (0)
@@ -371,35 +364,40 @@
// will check whether there's anything available in the
// secondary_free_list and/or wait for more regions to appear in that
// list, if _free_regions_coming is set.
- HeapRegion* new_region_try_secondary_free_list(size_t word_size);
+ HeapRegion* new_region_try_secondary_free_list();
- // It will try to allocate a single non-humongous HeapRegion
- // sufficient for an allocation of the given word_size. If
- // do_expand is true, it will attempt to expand the heap if
- // necessary to satisfy the allocation request. Note that word_size
- // is only used to make sure that we expand sufficiently but, given
- // that the allocation request is assumed not to be humongous,
- // having word_size is not strictly necessary (expanding by a single
- // region will always be sufficient). But let's keep that parameter
- // in case we need it in the future.
+ // Try to allocate a single non-humongous HeapRegion sufficient for
+ // an allocation of the given word_size. If do_expand is true,
+ // attempt to expand the heap if necessary to satisfy the allocation
+ // request.
HeapRegion* new_region_work(size_t word_size, bool do_expand);
- // It will try to allocate a new region to be used for allocation by
- // mutator threads. It will not try to expand the heap if not region
- // is available.
+ // Try to allocate a new region to be used for allocation by a
+ // mutator thread. Attempt to expand the heap if no region is
+ // available.
HeapRegion* new_alloc_region(size_t word_size) {
return new_region_work(word_size, false /* do_expand */);
}
- // It will try to allocate a new region to be used for allocation by
- // a GC thread. It will try to expand the heap if no region is
- // available.
+ // Try to allocate a new region to be used for allocation by a GC
+ // thread. Attempt to expand the heap if no region is available.
HeapRegion* new_gc_alloc_region(int purpose, size_t word_size);
+ // Attempt to satisfy a humongous allocation request of the given
+ // size by finding a contiguous set of free regions of num_regions
+ // length and remove them from the master free list. Return the
+ // index of the first region or -1 if the search was unsuccessful.
int humongous_obj_allocate_find_first(size_t num_regions, size_t word_size);
- // Attempt to allocate an object of the given (very large) "word_size".
- // Returns "NULL" on failure.
+ // Initialize a contiguous set of free regions of length num_regions
+ // and starting at index first so that they appear as a single
+ // humongous region.
+ HeapWord* humongous_obj_allocate_initialize_regions(int first,
+ size_t num_regions,
+ size_t word_size);
+
+ // Attempt to allocate a humongous object of the given size. Return
+ // NULL if unsuccessful.
HeapWord* humongous_obj_allocate(size_t word_size);
// The following two methods, allocate_new_tlab() and
@@ -776,7 +774,7 @@
// Invoke "save_marks" on all heap regions.
void save_marks();
- // It frees a non-humongous region by initializing its contents and
+ // Frees a non-humongous region by initializing its contents and
// adding it to the free list that's passed as a parameter (this is
// usually a local list which will be appended to the master free
// list later). The used bytes of freed regions are accumulated in
@@ -787,13 +785,13 @@
FreeRegionList* free_list,
bool par);
- // It frees a humongous region by collapsing it into individual
- // regions and calling free_region() for each of them. The freed
- // regions will be added to the free list that's passed as a parameter
- // (this is usually a local list which will be appended to the
- // master free list later). The used bytes of freed regions are
- // accumulated in pre_used. If par is true, the region's RSet will
- // not be freed up. The assumption is that this will be done later.
+ // Frees a humongous region by collapsing it into individual regions
+ // and calling free_region() for each of them. The freed regions
+ // will be added to the free list that's passed as a parameter (this
+ // is usually a local list which will be appended to the master free
+ // list later). The used bytes of freed regions are accumulated in
+ // pre_used. If par is true, the region's RSet will not be freed
+ // up. The assumption is that this will be done later.
void free_humongous_region(HeapRegion* hr,
size_t* pre_used,
FreeRegionList* free_list,
@@ -1046,13 +1044,13 @@
#endif // HEAP_REGION_SET_FORCE_VERIFY
#ifdef ASSERT
- bool is_on_free_list(HeapRegion* hr) {
+ bool is_on_master_free_list(HeapRegion* hr) {
return hr->containing_set() == &_free_list;
}
- bool is_on_humongous_set(HeapRegion* hr) {
+ bool is_in_humongous_set(HeapRegion* hr) {
return hr->containing_set() == &_humongous_set;
-}
+ }
#endif // ASSERT
// Wrapper for the region list operations that can be called from
@@ -1066,7 +1064,9 @@
_free_list.add_as_tail(&_secondary_free_list);
}
- void append_secondary_free_list_if_not_empty() {
+ void append_secondary_free_list_if_not_empty_with_lock() {
+ // If the secondary free list looks empty there's no reason to
+ // take the lock and then try to append it.
if (!_secondary_free_list.is_empty()) {
MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag);
append_secondary_free_list();
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -81,6 +81,57 @@
// </NEW PREDICTION>
+// Help class for avoiding interleaved logging
+class LineBuffer: public StackObj {
+
+private:
+ static const int BUFFER_LEN = 1024;
+ static const int INDENT_CHARS = 3;
+ char _buffer[BUFFER_LEN];
+ int _indent_level;
+ int _cur;
+
+ void vappend(const char* format, va_list ap) {
+ int res = vsnprintf(&_buffer[_cur], BUFFER_LEN - _cur, format, ap);
+ if (res != -1) {
+ _cur += res;
+ } else {
+ DEBUG_ONLY(warning("buffer too small in LineBuffer");)
+ _buffer[BUFFER_LEN -1] = 0;
+ _cur = BUFFER_LEN; // vsnprintf above should not add to _buffer if we are called again
+ }
+ }
+
+public:
+ explicit LineBuffer(int indent_level): _indent_level(indent_level), _cur(0) {
+ for (; (_cur < BUFFER_LEN && _cur < (_indent_level * INDENT_CHARS)); _cur++) {
+ _buffer[_cur] = ' ';
+ }
+ }
+
+#ifndef PRODUCT
+ ~LineBuffer() {
+ assert(_cur == _indent_level * INDENT_CHARS, "pending data in buffer - append_and_print_cr() not called?");
+ }
+#endif
+
+ void append(const char* format, ...) {
+ va_list ap;
+ va_start(ap, format);
+ vappend(format, ap);
+ va_end(ap);
+ }
+
+ void append_and_print_cr(const char* format, ...) {
+ va_list ap;
+ va_start(ap, format);
+ vappend(format, ap);
+ va_end(ap);
+ gclog_or_tty->print_cr("%s", _buffer);
+ _cur = _indent_level * INDENT_CHARS;
+ }
+};
+
G1CollectorPolicy::G1CollectorPolicy() :
_parallel_gc_threads(G1CollectedHeap::use_parallel_gc_threads()
? ParallelGCThreads : 1),
@@ -1016,10 +1067,8 @@
bool summary) {
double min = data[0], max = data[0];
double total = 0.0;
- int j;
- for (j = 0; j < level; ++j)
- gclog_or_tty->print(" ");
- gclog_or_tty->print("[%s (ms):", str);
+ LineBuffer buf(level);
+ buf.append("[%s (ms):", str);
for (uint i = 0; i < ParallelGCThreads; ++i) {
double val = data[i];
if (val < min)
@@ -1027,18 +1076,16 @@
if (val > max)
max = val;
total += val;
- gclog_or_tty->print(" %3.1lf", val);
+ buf.append(" %3.1lf", val);
}
if (summary) {
- gclog_or_tty->print_cr("");
+ buf.append_and_print_cr("");
double avg = total / (double) ParallelGCThreads;
- gclog_or_tty->print(" ");
- for (j = 0; j < level; ++j)
- gclog_or_tty->print(" ");
- gclog_or_tty->print("Avg: %5.1lf, Min: %5.1lf, Max: %5.1lf",
+ buf.append(" ");
+ buf.append("Avg: %5.1lf, Min: %5.1lf, Max: %5.1lf",
avg, min, max);
}
- gclog_or_tty->print_cr("]");
+ buf.append_and_print_cr("]");
}
void G1CollectorPolicy::print_par_sizes(int level,
@@ -1047,10 +1094,8 @@
bool summary) {
double min = data[0], max = data[0];
double total = 0.0;
- int j;
- for (j = 0; j < level; ++j)
- gclog_or_tty->print(" ");
- gclog_or_tty->print("[%s :", str);
+ LineBuffer buf(level);
+ buf.append("[%s :", str);
for (uint i = 0; i < ParallelGCThreads; ++i) {
double val = data[i];
if (val < min)
@@ -1058,34 +1103,28 @@
if (val > max)
max = val;
total += val;
- gclog_or_tty->print(" %d", (int) val);
+ buf.append(" %d", (int) val);
}
if (summary) {
- gclog_or_tty->print_cr("");
+ buf.append_and_print_cr("");
double avg = total / (double) ParallelGCThreads;
- gclog_or_tty->print(" ");
- for (j = 0; j < level; ++j)
- gclog_or_tty->print(" ");
- gclog_or_tty->print("Sum: %d, Avg: %d, Min: %d, Max: %d",
+ buf.append(" ");
+ buf.append("Sum: %d, Avg: %d, Min: %d, Max: %d",
(int)total, (int)avg, (int)min, (int)max);
}
- gclog_or_tty->print_cr("]");
+ buf.append_and_print_cr("]");
}
void G1CollectorPolicy::print_stats (int level,
const char* str,
double value) {
- for (int j = 0; j < level; ++j)
- gclog_or_tty->print(" ");
- gclog_or_tty->print_cr("[%s: %5.1lf ms]", str, value);
+ LineBuffer(level).append_and_print_cr("[%s: %5.1lf ms]", str, value);
}
void G1CollectorPolicy::print_stats (int level,
const char* str,
int value) {
- for (int j = 0; j < level; ++j)
- gclog_or_tty->print(" ");
- gclog_or_tty->print_cr("[%s: %d]", str, value);
+ LineBuffer(level).append_and_print_cr("[%s: %d]", str, value);
}
double G1CollectorPolicy::avg_value (double* data) {
@@ -2060,17 +2099,11 @@
_g1->collection_set_iterate(&cs_closure);
}
-static void print_indent(int level) {
- for (int j = 0; j < level+1; ++j)
- gclog_or_tty->print(" ");
-}
-
void G1CollectorPolicy::print_summary (int level,
const char* str,
NumberSeq* seq) const {
double sum = seq->sum();
- print_indent(level);
- gclog_or_tty->print_cr("%-24s = %8.2lf s (avg = %8.2lf ms)",
+ LineBuffer(level + 1).append_and_print_cr("%-24s = %8.2lf s (avg = %8.2lf ms)",
str, sum / 1000.0, seq->avg());
}
@@ -2078,8 +2111,7 @@
const char* str,
NumberSeq* seq) const {
print_summary(level, str, seq);
- print_indent(level + 5);
- gclog_or_tty->print_cr("(num = %5d, std dev = %8.2lf ms, max = %8.2lf ms)",
+ LineBuffer(level + 6).append_and_print_cr("(num = %5d, std dev = %8.2lf ms, max = %8.2lf ms)",
seq->num(), seq->sd(), seq->maximum());
}
@@ -2087,6 +2119,7 @@
NumberSeq* other_times_ms,
NumberSeq* calc_other_times_ms) const {
bool should_print = false;
+ LineBuffer buf(level + 2);
double max_sum = MAX2(fabs(other_times_ms->sum()),
fabs(calc_other_times_ms->sum()));
@@ -2095,8 +2128,7 @@
double sum_ratio = max_sum / min_sum;
if (sum_ratio > 1.1) {
should_print = true;
- print_indent(level + 1);
- gclog_or_tty->print_cr("## CALCULATED OTHER SUM DOESN'T MATCH RECORDED ###");
+ buf.append_and_print_cr("## CALCULATED OTHER SUM DOESN'T MATCH RECORDED ###");
}
double max_avg = MAX2(fabs(other_times_ms->avg()),
@@ -2106,30 +2138,25 @@
double avg_ratio = max_avg / min_avg;
if (avg_ratio > 1.1) {
should_print = true;
- print_indent(level + 1);
- gclog_or_tty->print_cr("## CALCULATED OTHER AVG DOESN'T MATCH RECORDED ###");
+ buf.append_and_print_cr("## CALCULATED OTHER AVG DOESN'T MATCH RECORDED ###");
}
if (other_times_ms->sum() < -0.01) {
- print_indent(level + 1);
- gclog_or_tty->print_cr("## RECORDED OTHER SUM IS NEGATIVE ###");
+ buf.append_and_print_cr("## RECORDED OTHER SUM IS NEGATIVE ###");
}
if (other_times_ms->avg() < -0.01) {
- print_indent(level + 1);
- gclog_or_tty->print_cr("## RECORDED OTHER AVG IS NEGATIVE ###");
+ buf.append_and_print_cr("## RECORDED OTHER AVG IS NEGATIVE ###");
}
if (calc_other_times_ms->sum() < -0.01) {
should_print = true;
- print_indent(level + 1);
- gclog_or_tty->print_cr("## CALCULATED OTHER SUM IS NEGATIVE ###");
+ buf.append_and_print_cr("## CALCULATED OTHER SUM IS NEGATIVE ###");
}
if (calc_other_times_ms->avg() < -0.01) {
should_print = true;
- print_indent(level + 1);
- gclog_or_tty->print_cr("## CALCULATED OTHER AVG IS NEGATIVE ###");
+ buf.append_and_print_cr("## CALCULATED OTHER AVG IS NEGATIVE ###");
}
if (should_print)
@@ -2210,10 +2237,9 @@
}
}
} else {
- print_indent(0);
- gclog_or_tty->print_cr("none");
+ LineBuffer(1).append_and_print_cr("none");
}
- gclog_or_tty->print_cr("");
+ LineBuffer(0).append_and_print_cr("");
}
void G1CollectorPolicy::print_tracing_info() const {
@@ -2532,7 +2558,7 @@
jint regions_added = parKnownGarbageCl.marked_regions_added();
_hrSorted->incNumMarkedHeapRegions(regions_added);
if (G1PrintParCleanupStats) {
- gclog_or_tty->print(" Thread %d called %d times, added %d regions to list.\n",
+ gclog_or_tty->print_cr(" Thread %d called %d times, added %d regions to list.",
i, parKnownGarbageCl.invokes(), regions_added);
}
}
--- a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -185,22 +185,22 @@
G1CollectedHeap* _g1h;
ModRefBarrierSet* _mrbs;
CompactPoint _cp;
- size_t _pre_used;
- FreeRegionList _free_list;
HumongousRegionSet _humongous_proxy_set;
void free_humongous_region(HeapRegion* hr) {
HeapWord* end = hr->end();
+ size_t dummy_pre_used;
+ FreeRegionList dummy_free_list("Dummy Free List for G1MarkSweep");
+
assert(hr->startsHumongous(),
"Only the start of a humongous region should be freed.");
- _g1h->free_humongous_region(hr, &_pre_used, &_free_list,
+ _g1h->free_humongous_region(hr, &dummy_pre_used, &dummy_free_list,
&_humongous_proxy_set, false /* par */);
- // Do we also need to do this for the continues humongous regions
- // we just collapsed?
hr->prepare_for_compaction(&_cp);
// Also clear the part of the card table that will be unused after
// compaction.
_mrbs->clear(MemRegion(hr->compaction_top(), end));
+ dummy_free_list.remove_all();
}
public:
@@ -208,8 +208,6 @@
: _g1h(G1CollectedHeap::heap()),
_mrbs(G1CollectedHeap::heap()->mr_bs()),
_cp(NULL, cs, cs->initialize_threshold()),
- _pre_used(0),
- _free_list("Local Free List for G1MarkSweep"),
_humongous_proxy_set("G1MarkSweep Humongous Proxy Set") { }
void update_sets() {
@@ -219,7 +217,6 @@
NULL, /* free_list */
&_humongous_proxy_set,
false /* par */);
- _free_list.remove_all();
}
bool doHeapRegion(HeapRegion* hr) {
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -86,28 +86,6 @@
bool idempotent() { return true; }
};
-class IntoCSRegionClosure: public HeapRegionClosure {
- IntoCSOopClosure _blk;
- G1CollectedHeap* _g1;
-public:
- IntoCSRegionClosure(G1CollectedHeap* g1, OopsInHeapRegionClosure* blk) :
- _g1(g1), _blk(g1, blk) {}
- bool doHeapRegion(HeapRegion* r) {
- if (!r->in_collection_set()) {
- _blk.set_region(r);
- if (r->isHumongous()) {
- if (r->startsHumongous()) {
- oop obj = oop(r->bottom());
- obj->oop_iterate(&_blk);
- }
- } else {
- r->oop_before_save_marks_iterate(&_blk);
- }
- }
- return false;
- }
-};
-
class VerifyRSCleanCardOopClosure: public OopClosure {
G1CollectedHeap* _g1;
public:
@@ -329,7 +307,7 @@
// is during RSet updating within an evacuation pause.
// In this case worker_i should be the id of a GC worker thread.
assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");
- assert(worker_i < (int) DirtyCardQueueSet::num_par_ids(), "should be a GC worker");
+ assert(worker_i < (int) (ParallelGCThreads == 0 ? 1 : ParallelGCThreads), "should be a GC worker");
if (_g1rs->concurrentRefineOneCard(card_ptr, worker_i, true)) {
// 'card_ptr' contains references that point into the collection
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -53,8 +53,8 @@
class HeapRegionSetBase;
#define HR_FORMAT "%d:["PTR_FORMAT","PTR_FORMAT","PTR_FORMAT"]"
-#define HR_FORMAT_PARAMS(__hr) (__hr)->hrs_index(), (__hr)->bottom(), \
- (__hr)->top(), (__hr)->end()
+#define HR_FORMAT_PARAMS(_hr_) (_hr_)->hrs_index(), (_hr_)->bottom(), \
+ (_hr_)->top(), (_hr_)->end()
// A dirty card to oop closure for heap regions. It
// knows how to get the G1 heap and how to use the bitmap
@@ -518,13 +518,13 @@
containing_set, _containing_set));
_containing_set = containing_set;
-}
+ }
HeapRegionSetBase* containing_set() { return _containing_set; }
#else // ASSERT
void set_containing_set(HeapRegionSetBase* containing_set) { }
- // containing_set() is only used in asserts so there's not reason
+ // containing_set() is only used in asserts so there's no reason
// to provide a dummy version of it.
#endif // ASSERT
@@ -535,14 +535,15 @@
bool pending_removal() { return _pending_removal; }
void set_pending_removal(bool pending_removal) {
- // We can only set pending_removal to true, if it's false and the
- // region belongs to a set.
- assert(!pending_removal ||
- (!_pending_removal && containing_set() != NULL), "pre-condition");
- // We can only set pending_removal to false, if it's true and the
- // region does not belong to a set.
- assert( pending_removal ||
- ( _pending_removal && containing_set() == NULL), "pre-condition");
+ if (pending_removal) {
+ assert(!_pending_removal && containing_set() != NULL,
+ "can only set pending removal to true if it's false and "
+ "the region belongs to a region set");
+ } else {
+ assert( _pending_removal && containing_set() == NULL,
+ "can only set pending removal to false if it's true and "
+ "the region does not belong to a region set");
+ }
_pending_removal = pending_removal;
}
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -165,7 +165,7 @@
assert(num_so_far <= num, "post-condition");
if (num_so_far == num) {
- // we find enough space for the humongous object
+ // we found enough space for the humongous object
assert(from <= first && first < _regions.length(), "post-condition");
assert(first < curr && (curr - first) == (int) num, "post-condition");
for (int i = first; i < first + (int) num; ++i) {
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.hpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -76,7 +76,8 @@
// that are available for allocation.
size_t free_suffix();
- // Finds a contiguous set of empty regions of length num.
+ // Find a contiguous set of empty regions of length num and return
+ // the index of the first region or -1 if the search was unsuccessful.
int find_contiguous(size_t num);
// Apply the "doHeapRegion" method of "blk" to all regions in "this",
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -42,7 +42,7 @@
return region_num;
}
-void HeapRegionSetBase::fill_in_ext_msg(hrl_ext_msg* msg, const char* message) {
+void HeapRegionSetBase::fill_in_ext_msg(hrs_ext_msg* msg, const char* message) {
msg->append("[%s] %s "
"ln: "SIZE_FORMAT" rn: "SIZE_FORMAT" "
"cy: "SIZE_FORMAT" ud: "SIZE_FORMAT,
@@ -109,30 +109,30 @@
// for the verification calls. If we do verification without the
// appropriate locks and the set changes underneath our feet
// verification might fail and send us on a wild goose chase.
- hrl_assert_mt_safety_ok(this);
+ hrs_assert_mt_safety_ok(this);
guarantee(( is_empty() && length() == 0 && region_num() == 0 &&
total_used_bytes() == 0 && total_capacity_bytes() == 0) ||
(!is_empty() && length() >= 0 && region_num() >= 0 &&
total_used_bytes() >= 0 && total_capacity_bytes() >= 0),
- hrl_ext_msg(this, "invariant"));
+ hrs_ext_msg(this, "invariant"));
guarantee((!regions_humongous() && region_num() == length()) ||
( regions_humongous() && region_num() >= length()),
- hrl_ext_msg(this, "invariant"));
+ hrs_ext_msg(this, "invariant"));
guarantee(!regions_empty() || total_used_bytes() == 0,
- hrl_ext_msg(this, "invariant"));
+ hrs_ext_msg(this, "invariant"));
guarantee(total_used_bytes() <= total_capacity_bytes(),
- hrl_ext_msg(this, "invariant"));
+ hrs_ext_msg(this, "invariant"));
}
void HeapRegionSetBase::verify_start() {
// See comment in verify() about MT safety and verification.
- hrl_assert_mt_safety_ok(this);
+ hrs_assert_mt_safety_ok(this);
assert(!_verify_in_progress,
- hrl_ext_msg(this, "verification should not be in progress"));
+ hrs_ext_msg(this, "verification should not be in progress"));
// Do the basic verification first before we do the checks over the regions.
HeapRegionSetBase::verify();
@@ -146,11 +146,11 @@
void HeapRegionSetBase::verify_next_region(HeapRegion* hr) {
// See comment in verify() about MT safety and verification.
- hrl_assert_mt_safety_ok(this);
+ hrs_assert_mt_safety_ok(this);
assert(_verify_in_progress,
- hrl_ext_msg(this, "verification should be in progress"));
+ hrs_ext_msg(this, "verification should be in progress"));
- guarantee(verify_region(hr, this), hrl_ext_msg(this, "region verification"));
+ guarantee(verify_region(hr, this), hrs_ext_msg(this, "region verification"));
_calc_length += 1;
if (!hr->isHumongous()) {
@@ -164,28 +164,28 @@
void HeapRegionSetBase::verify_end() {
// See comment in verify() about MT safety and verification.
- hrl_assert_mt_safety_ok(this);
+ hrs_assert_mt_safety_ok(this);
assert(_verify_in_progress,
- hrl_ext_msg(this, "verification should be in progress"));
+ hrs_ext_msg(this, "verification should be in progress"));
guarantee(length() == _calc_length,
- hrl_err_msg("[%s] length: "SIZE_FORMAT" should be == "
+ hrs_err_msg("[%s] length: "SIZE_FORMAT" should be == "
"calc length: "SIZE_FORMAT,
name(), length(), _calc_length));
guarantee(region_num() == _calc_region_num,
- hrl_err_msg("[%s] region num: "SIZE_FORMAT" should be == "
+ hrs_err_msg("[%s] region num: "SIZE_FORMAT" should be == "
"calc region num: "SIZE_FORMAT,
name(), region_num(), _calc_region_num));
guarantee(total_capacity_bytes() == _calc_total_capacity_bytes,
- hrl_err_msg("[%s] capacity bytes: "SIZE_FORMAT" should be == "
+ hrs_err_msg("[%s] capacity bytes: "SIZE_FORMAT" should be == "
"calc capacity bytes: "SIZE_FORMAT,
name(),
total_capacity_bytes(), _calc_total_capacity_bytes));
guarantee(total_used_bytes() == _calc_total_used_bytes,
- hrl_err_msg("[%s] used bytes: "SIZE_FORMAT" should be == "
+ hrs_err_msg("[%s] used bytes: "SIZE_FORMAT" should be == "
"calc used bytes: "SIZE_FORMAT,
name(), total_used_bytes(), _calc_total_used_bytes));
@@ -221,9 +221,9 @@
//////////////////// HeapRegionSet ////////////////////
void HeapRegionSet::update_from_proxy(HeapRegionSet* proxy_set) {
- hrl_assert_mt_safety_ok(this);
- hrl_assert_mt_safety_ok(proxy_set);
- hrl_assert_sets_match(this, proxy_set);
+ hrs_assert_mt_safety_ok(this);
+ hrs_assert_mt_safety_ok(proxy_set);
+ hrs_assert_sets_match(this, proxy_set);
verify_optional();
proxy_set->verify_optional();
@@ -231,19 +231,19 @@
if (proxy_set->is_empty()) return;
assert(proxy_set->length() <= _length,
- hrl_err_msg("[%s] proxy set length: "SIZE_FORMAT" "
+ hrs_err_msg("[%s] proxy set length: "SIZE_FORMAT" "
"should be <= length: "SIZE_FORMAT,
name(), proxy_set->length(), _length));
_length -= proxy_set->length();
assert(proxy_set->region_num() <= _region_num,
- hrl_err_msg("[%s] proxy set region num: "SIZE_FORMAT" "
+ hrs_err_msg("[%s] proxy set region num: "SIZE_FORMAT" "
"should be <= region num: "SIZE_FORMAT,
name(), proxy_set->region_num(), _region_num));
_region_num -= proxy_set->region_num();
assert(proxy_set->total_used_bytes() <= _total_used_bytes,
- hrl_err_msg("[%s] proxy set used bytes: "SIZE_FORMAT" "
+ hrs_err_msg("[%s] proxy set used bytes: "SIZE_FORMAT" "
"should be <= used bytes: "SIZE_FORMAT,
name(), proxy_set->total_used_bytes(),
_total_used_bytes));
@@ -257,13 +257,13 @@
//////////////////// HeapRegionLinkedList ////////////////////
-void HeapRegionLinkedList::fill_in_ext_msg_extra(hrl_ext_msg* msg) {
+void HeapRegionLinkedList::fill_in_ext_msg_extra(hrs_ext_msg* msg) {
msg->append(" hd: "PTR_FORMAT" tl: "PTR_FORMAT, head(), tail());
}
void HeapRegionLinkedList::add_as_tail(HeapRegionLinkedList* from_list) {
- hrl_assert_mt_safety_ok(this);
- hrl_assert_mt_safety_ok(from_list);
+ hrs_assert_mt_safety_ok(this);
+ hrs_assert_mt_safety_ok(from_list);
verify_optional();
from_list->verify_optional();
@@ -283,10 +283,10 @@
#endif // ASSERT
if (_tail != NULL) {
- assert(length() > 0 && _head != NULL, hrl_ext_msg(this, "invariant"));
+ assert(length() > 0 && _head != NULL, hrs_ext_msg(this, "invariant"));
_tail->set_next(from_list->_head);
} else {
- assert(length() == 0 && _head == NULL, hrl_ext_msg(this, "invariant"));
+ assert(length() == 0 && _head == NULL, hrs_ext_msg(this, "invariant"));
_head = from_list->_head;
}
_tail = from_list->_tail;
@@ -301,12 +301,12 @@
}
void HeapRegionLinkedList::remove_all() {
- hrl_assert_mt_safety_ok(this);
+ hrs_assert_mt_safety_ok(this);
verify_optional();
HeapRegion* curr = _head;
while (curr != NULL) {
- hrl_assert_region_ok(this, curr, this);
+ hrs_assert_region_ok(this, curr, this);
HeapRegion* next = curr->next();
curr->set_next(NULL);
@@ -319,9 +319,9 @@
}
void HeapRegionLinkedList::remove_all_pending(size_t target_count) {
- hrl_assert_mt_safety_ok(this);
- assert(target_count > 1, hrl_ext_msg(this, "pre-condition"));
- assert(!is_empty(), hrl_ext_msg(this, "pre-condition"));
+ hrs_assert_mt_safety_ok(this);
+ assert(target_count > 1, hrs_ext_msg(this, "pre-condition"));
+ assert(!is_empty(), hrs_ext_msg(this, "pre-condition"));
verify_optional();
DEBUG_ONLY(size_t old_length = length();)
@@ -330,27 +330,27 @@
HeapRegion* prev = NULL;
size_t count = 0;
while (curr != NULL) {
- hrl_assert_region_ok(this, curr, this);
+ hrs_assert_region_ok(this, curr, this);
HeapRegion* next = curr->next();
if (curr->pending_removal()) {
assert(count < target_count,
- hrl_err_msg("[%s] should not come across more regions "
+ hrs_err_msg("[%s] should not come across more regions "
"pending for removal than target_count: "SIZE_FORMAT,
name(), target_count));
if (prev == NULL) {
- assert(_head == curr, hrl_ext_msg(this, "invariant"));
+ assert(_head == curr, hrs_ext_msg(this, "invariant"));
_head = next;
} else {
- assert(_head != curr, hrl_ext_msg(this, "invariant"));
+ assert(_head != curr, hrs_ext_msg(this, "invariant"));
prev->set_next(next);
}
if (next == NULL) {
- assert(_tail == curr, hrl_ext_msg(this, "invariant"));
+ assert(_tail == curr, hrs_ext_msg(this, "invariant"));
_tail = prev;
} else {
- assert(_tail != curr, hrl_ext_msg(this, "invariant"));
+ assert(_tail != curr, hrs_ext_msg(this, "invariant"));
}
curr->set_next(NULL);
@@ -371,10 +371,10 @@
}
assert(count == target_count,
- hrl_err_msg("[%s] count: "SIZE_FORMAT" should be == "
+ hrs_err_msg("[%s] count: "SIZE_FORMAT" should be == "
"target_count: "SIZE_FORMAT, name(), count, target_count));
assert(length() + target_count == old_length,
- hrl_err_msg("[%s] new length should be consistent "
+ hrs_err_msg("[%s] new length should be consistent "
"new length: "SIZE_FORMAT" old length: "SIZE_FORMAT" "
"target_count: "SIZE_FORMAT,
name(), length(), old_length, target_count));
@@ -385,7 +385,7 @@
void HeapRegionLinkedList::verify() {
// See comment in HeapRegionSetBase::verify() about MT safety and
// verification.
- hrl_assert_mt_safety_ok(this);
+ hrs_assert_mt_safety_ok(this);
// This will also do the basic verification too.
verify_start();
@@ -399,7 +399,7 @@
count += 1;
guarantee(count < _unrealistically_long_length,
- hrl_err_msg("[%s] the calculated length: "SIZE_FORMAT" "
+ hrs_err_msg("[%s] the calculated length: "SIZE_FORMAT" "
"seems very long, is there maybe a cycle? "
"curr: "PTR_FORMAT" prev0: "PTR_FORMAT" "
"prev1: "PTR_FORMAT" length: "SIZE_FORMAT,
@@ -410,7 +410,7 @@
curr = curr->next();
}
- guarantee(_tail == prev0, hrl_ext_msg(this, "post-condition"));
+ guarantee(_tail == prev0, hrs_ext_msg(this, "post-condition"));
verify_end();
}
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.hpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -28,8 +28,8 @@
#include "gc_implementation/g1/heapRegion.hpp"
// Large buffer for some cases where the output might be larger than normal.
-#define HRL_ERR_MSG_BUFSZ 512
-typedef FormatBuffer<HRL_ERR_MSG_BUFSZ> hrl_err_msg;
+#define HRS_ERR_MSG_BUFSZ 512
+typedef FormatBuffer<HRS_ERR_MSG_BUFSZ> hrs_err_msg;
// Set verification will be forced either if someone defines
// HEAP_REGION_SET_FORCE_VERIFY to be 1, or in builds in which
@@ -45,10 +45,10 @@
// (e.g., length, region num, used bytes sum) plus any shared
// functionality (e.g., verification).
-class hrl_ext_msg;
+class hrs_ext_msg;
class HeapRegionSetBase VALUE_OBJ_CLASS_SPEC {
- friend class hrl_ext_msg;
+ friend class hrs_ext_msg;
protected:
static size_t calculate_region_num(HeapRegion* hr);
@@ -104,10 +104,10 @@
virtual bool check_mt_safety() { return true; }
// fill_in_ext_msg() writes the the values of the set's attributes
- // in the custom err_msg (hrl_ext_msg). fill_in_ext_msg_extra()
+ // in the custom err_msg (hrs_ext_msg). fill_in_ext_msg_extra()
// allows subclasses to append further information.
- virtual void fill_in_ext_msg_extra(hrl_ext_msg* msg) { }
- void fill_in_ext_msg(hrl_ext_msg* msg, const char* message);
+ virtual void fill_in_ext_msg_extra(hrs_ext_msg* msg) { }
+ void fill_in_ext_msg(hrs_ext_msg* msg, const char* message);
// It updates the fields of the set to reflect hr being added to
// the set.
@@ -170,9 +170,9 @@
// the fields of the associated set. This can be very helpful in
// diagnosing failures.
-class hrl_ext_msg : public hrl_err_msg {
+class hrs_ext_msg : public hrs_err_msg {
public:
- hrl_ext_msg(HeapRegionSetBase* set, const char* message) : hrl_err_msg("") {
+ hrs_ext_msg(HeapRegionSetBase* set, const char* message) : hrs_err_msg("") {
set->fill_in_ext_msg(this, message);
}
};
@@ -180,25 +180,25 @@
// These two macros are provided for convenience, to keep the uses of
// these two asserts a bit more concise.
-#define hrl_assert_mt_safety_ok(_set_) \
+#define hrs_assert_mt_safety_ok(_set_) \
do { \
- assert((_set_)->check_mt_safety(), hrl_ext_msg((_set_), "MT safety")); \
+ assert((_set_)->check_mt_safety(), hrs_ext_msg((_set_), "MT safety")); \
} while (0)
-#define hrl_assert_region_ok(_set_, _hr_, _expected_) \
+#define hrs_assert_region_ok(_set_, _hr_, _expected_) \
do { \
assert((_set_)->verify_region((_hr_), (_expected_)), \
- hrl_ext_msg((_set_), "region verification")); \
+ hrs_ext_msg((_set_), "region verification")); \
} while (0)
//////////////////// HeapRegionSet ////////////////////
-#define hrl_assert_sets_match(_set1_, _set2_) \
+#define hrs_assert_sets_match(_set1_, _set2_) \
do { \
assert(((_set1_)->regions_humongous() == \
(_set2_)->regions_humongous()) && \
((_set1_)->regions_empty() == (_set2_)->regions_empty()), \
- hrl_err_msg("the contents of set %s and set %s should match", \
+ hrs_err_msg("the contents of set %s and set %s should match", \
(_set1_)->name(), (_set2_)->name())); \
} while (0)
@@ -267,7 +267,7 @@
HeapRegion* tail() { return _tail; }
protected:
- virtual void fill_in_ext_msg_extra(hrl_ext_msg* msg);
+ virtual void fill_in_ext_msg_extra(hrs_ext_msg* msg);
// See the comment for HeapRegionSetBase::clear()
virtual void clear();
@@ -309,10 +309,10 @@
virtual void print_on(outputStream* out, bool print_contents = false);
};
-//////////////////// HeapRegionLinkedList ////////////////////
+//////////////////// HeapRegionLinkedListIterator ////////////////////
-// Iterator class that provides a convenient way to iterator over the
-// regions in a HeapRegionLinkedList instance.
+// Iterator class that provides a convenient way to iterate over the
+// regions of a HeapRegionLinkedList instance.
class HeapRegionLinkedListIterator : public StackObj {
private:
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.inline.hpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.inline.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -42,8 +42,8 @@
}
inline void HeapRegionSetBase::add_internal(HeapRegion* hr) {
- hrl_assert_region_ok(this, hr, NULL);
- assert(hr->next() == NULL, hrl_ext_msg(this, "should not already be linked"));
+ hrs_assert_region_ok(this, hr, NULL);
+ assert(hr->next() == NULL, hrs_ext_msg(this, "should not already be linked"));
update_for_addition(hr);
hr->set_containing_set(this);
@@ -51,7 +51,7 @@
inline void HeapRegionSetBase::update_for_removal(HeapRegion* hr) {
// Assumes the caller has already verified the region.
- assert(_length > 0, hrl_ext_msg(this, "pre-condition"));
+ assert(_length > 0, hrs_ext_msg(this, "pre-condition"));
_length -= 1;
size_t region_num_diff;
@@ -61,22 +61,22 @@
region_num_diff = calculate_region_num(hr);
}
assert(region_num_diff <= _region_num,
- hrl_err_msg("[%s] region's region num: "SIZE_FORMAT" "
+ hrs_err_msg("[%s] region's region num: "SIZE_FORMAT" "
"should be <= region num: "SIZE_FORMAT,
name(), region_num_diff, _region_num));
_region_num -= region_num_diff;
size_t used_bytes = hr->used();
assert(used_bytes <= _total_used_bytes,
- hrl_err_msg("[%s] region's used bytes: "SIZE_FORMAT" "
+ hrs_err_msg("[%s] region's used bytes: "SIZE_FORMAT" "
"should be <= used bytes: "SIZE_FORMAT,
name(), used_bytes, _total_used_bytes));
_total_used_bytes -= used_bytes;
}
inline void HeapRegionSetBase::remove_internal(HeapRegion* hr) {
- hrl_assert_region_ok(this, hr, this);
- assert(hr->next() == NULL, hrl_ext_msg(this, "should already be unlinked"));
+ hrs_assert_region_ok(this, hr, this);
+ assert(hr->next() == NULL, hrs_ext_msg(this, "should already be unlinked"));
hr->set_containing_set(NULL);
update_for_removal(hr);
@@ -85,13 +85,13 @@
//////////////////// HeapRegionSet ////////////////////
inline void HeapRegionSet::add(HeapRegion* hr) {
- hrl_assert_mt_safety_ok(this);
+ hrs_assert_mt_safety_ok(this);
// add_internal() will verify the region.
add_internal(hr);
}
inline void HeapRegionSet::remove(HeapRegion* hr) {
- hrl_assert_mt_safety_ok(this);
+ hrs_assert_mt_safety_ok(this);
// remove_internal() will verify the region.
remove_internal(hr);
}
@@ -101,8 +101,8 @@
// No need to fo the MT safety check here given that this method
// does not update the contents of the set but instead accumulates
// the changes in proxy_set which is assumed to be thread-local.
- hrl_assert_sets_match(this, proxy_set);
- hrl_assert_region_ok(this, hr, this);
+ hrs_assert_sets_match(this, proxy_set);
+ hrs_assert_region_ok(this, hr, this);
hr->set_containing_set(NULL);
proxy_set->update_for_addition(hr);
@@ -111,10 +111,10 @@
//////////////////// HeapRegionLinkedList ////////////////////
inline void HeapRegionLinkedList::add_as_tail(HeapRegion* hr) {
- hrl_assert_mt_safety_ok(this);
+ hrs_assert_mt_safety_ok(this);
assert((length() == 0 && _head == NULL && _tail == NULL) ||
(length() > 0 && _head != NULL && _tail != NULL),
- hrl_ext_msg(this, "invariant"));
+ hrs_ext_msg(this, "invariant"));
// add_internal() will verify the region.
add_internal(hr);
@@ -128,10 +128,10 @@
}
inline HeapRegion* HeapRegionLinkedList::remove_head() {
- hrl_assert_mt_safety_ok(this);
- assert(!is_empty(), hrl_ext_msg(this, "the list should not be empty"));
+ hrs_assert_mt_safety_ok(this);
+ assert(!is_empty(), hrs_ext_msg(this, "the list should not be empty"));
assert(length() > 0 && _head != NULL && _tail != NULL,
- hrl_ext_msg(this, "invariant"));
+ hrs_ext_msg(this, "invariant"));
// We need to unlink it first.
HeapRegion* hr = _head;
@@ -147,7 +147,7 @@
}
inline HeapRegion* HeapRegionLinkedList::remove_head_or_null() {
- hrl_assert_mt_safety_ok(this);
+ hrs_assert_mt_safety_ok(this);
if (!is_empty()) {
return remove_head();
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSets.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSets.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -52,7 +52,7 @@
FreeList_lock->owned_by_self())) ||
(!SafepointSynchronize::is_at_safepoint() &&
Heap_lock->owned_by_self()),
- hrl_ext_msg(this, "master free list MT safety protocol"));
+ hrs_ext_msg(this, "master free list MT safety protocol"));
return FreeRegionList::check_mt_safety();
}
@@ -65,7 +65,7 @@
// while holding the SecondaryFreeList_lock.
guarantee(SecondaryFreeList_lock->owned_by_self(),
- hrl_ext_msg(this, "secondary free list MT safety protocol"));
+ hrs_ext_msg(this, "secondary free list MT safety protocol"));
return FreeRegionList::check_mt_safety();
}
@@ -81,7 +81,7 @@
return HeapRegionSet::verify_region_extra(hr);
}
-//////////////////// HumongousRegionSet ////////////////////
+//////////////////// MasterHumongousRegionSet ////////////////////
bool MasterHumongousRegionSet::check_mt_safety() {
// Master Humongous Set MT safety protocol:
@@ -97,6 +97,6 @@
OldSets_lock->owned_by_self())) ||
(!SafepointSynchronize::is_at_safepoint() &&
Heap_lock->owned_by_self()),
- hrl_ext_msg(this, "master humongous set MT safety protocol"));
+ hrs_ext_msg(this, "master humongous set MT safety protocol"));
return HumongousRegionSet::check_mt_safety();
}
--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -1530,13 +1530,15 @@
{
if (_ref_processor == NULL) {
// Allocate and initialize a reference processor
- _ref_processor = ReferenceProcessor::create_ref_processor(
- _reserved, // span
- refs_discovery_is_atomic(), // atomic_discovery
- refs_discovery_is_mt(), // mt_discovery
- NULL, // is_alive_non_header
- ParallelGCThreads,
- ParallelRefProcEnabled);
+ _ref_processor =
+ new ReferenceProcessor(_reserved, // span
+ ParallelRefProcEnabled && (ParallelGCThreads > 1), // mt processing
+ (int) ParallelGCThreads, // mt processing degree
+ refs_discovery_is_mt(), // mt discovery
+ (int) ParallelGCThreads, // mt discovery degree
+ refs_discovery_is_atomic(), // atomic_discovery
+ NULL, // is_alive_non_header
+ false); // write barrier for next field updates
}
}
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -58,9 +58,7 @@
void PSMarkSweep::initialize() {
MemRegion mr = Universe::heap()->reserved_region();
- _ref_processor = new ReferenceProcessor(mr,
- true, // atomic_discovery
- false); // mt_discovery
+ _ref_processor = new ReferenceProcessor(mr); // a vanilla ref proc
_counters = new CollectorCounters("PSMarkSweep", 1);
}
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -827,13 +827,15 @@
assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
MemRegion mr = heap->reserved_region();
- _ref_processor = ReferenceProcessor::create_ref_processor(
- mr, // span
- true, // atomic_discovery
- true, // mt_discovery
- &_is_alive_closure,
- ParallelGCThreads,
- ParallelRefProcEnabled);
+ _ref_processor =
+ new ReferenceProcessor(mr, // span
+ ParallelRefProcEnabled && (ParallelGCThreads > 1), // mt processing
+ (int) ParallelGCThreads, // mt processing degree
+ true, // mt discovery
+ (int) ParallelGCThreads, // mt discovery degree
+ true, // atomic_discovery
+ &_is_alive_closure, // non-header is alive closure
+ false); // write barrier for next field updates
_counters = new CollectorCounters("PSParallelCompact", 1);
// Initialize static fields in ParCompactionManager.
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -411,7 +411,7 @@
template <class T> void PSPromotionManager::process_array_chunk_work(
oop obj,
int start, int end) {
- assert(start < end, "invariant");
+ assert(start <= end, "invariant");
T* const base = (T*)objArrayOop(obj)->base();
T* p = base + start;
T* const chunk_end = base + end;
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -796,13 +796,15 @@
// Initialize ref handling object for scavenging.
MemRegion mr = young_gen->reserved();
- _ref_processor = ReferenceProcessor::create_ref_processor(
- mr, // span
- true, // atomic_discovery
- true, // mt_discovery
- NULL, // is_alive_non_header
- ParallelGCThreads,
- ParallelRefProcEnabled);
+ _ref_processor =
+ new ReferenceProcessor(mr, // span
+ ParallelRefProcEnabled && (ParallelGCThreads > 1), // mt processing
+ (int) ParallelGCThreads, // mt processing degree
+ true, // mt discovery
+ (int) ParallelGCThreads, // mt discovery degree
+ true, // atomic_discovery
+ NULL, // header provides liveness info
+ false); // next field updates do not need write barrier
// Cache the cardtable
BarrierSet* bs = Universe::heap()->barrier_set();
--- a/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -96,7 +96,7 @@
empty, // empty method (code: _return)
accessor, // accessor method (code: _aload_0, _getfield, _(a|i)return)
abstract, // abstract method (throws an AbstractMethodException)
- method_handle, // java.dyn.MethodHandles::invoke
+ method_handle, // java.lang.invoke.MethodHandles::invoke
java_lang_math_sin, // implementation of java.lang.Math.sin (x)
java_lang_math_cos, // implementation of java.lang.Math.cos (x)
java_lang_math_tan, // implementation of java.lang.Math.tan (x)
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -369,7 +369,10 @@
}
// create exception
- THROW_MSG(vmSymbols::java_dyn_WrongMethodTypeException(), message);
+ Symbol* java_lang_invoke_WrongMethodTypeException = vmSymbols::java_lang_invoke_WrongMethodTypeException();
+ if (AllowTransitionalJSR292)
+ java_lang_invoke_WrongMethodTypeException = SystemDictionaryHandles::WrongMethodTypeException_klass()->name();
+ THROW_MSG(java_lang_invoke_WrongMethodTypeException, message);
}
IRT_END
@@ -794,7 +797,7 @@
Handle info; // optional argument(s) in JVM_CONSTANT_InvokeDynamic
Handle bootm = SystemDictionary::find_bootstrap_method(caller_method, caller_bci,
main_index, info, CHECK);
- if (!java_dyn_MethodHandle::is_instance(bootm())) {
+ if (!java_lang_invoke_MethodHandle::is_instance(bootm())) {
THROW_MSG(vmSymbols::java_lang_IllegalStateException(),
"no bootstrap method found for invokedynamic");
}
--- a/hotspot/src/share/vm/interpreter/linkResolver.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -217,11 +217,13 @@
if (EnableMethodHandles &&
klass() == SystemDictionary::MethodHandle_klass() &&
methodOopDesc::is_method_handle_invoke_name(name)) {
- if (!MethodHandles::enabled()) {
+ if (!THREAD->is_Compiler_thread() && !MethodHandles::enabled()) {
// Make sure the Java part of the runtime has been booted up.
klassOop natives = SystemDictionary::MethodHandleNatives_klass();
if (natives == NULL || instanceKlass::cast(natives)->is_not_initialized()) {
- SystemDictionary::resolve_or_fail(vmSymbols::sun_dyn_MethodHandleNatives(),
+ Symbol* natives_name = vmSymbols::java_lang_invoke_MethodHandleNatives();
+ if (natives != NULL && AllowTransitionalJSR292) natives_name = Klass::cast(natives)->name();
+ SystemDictionary::resolve_or_fail(natives_name,
Handle(),
Handle(),
true,
@@ -298,7 +300,7 @@
}
void LinkResolver::resolve_dynamic_method(methodHandle& resolved_method, KlassHandle& resolved_klass, constantPoolHandle pool, int index, TRAPS) {
- // The class is java.dyn.MethodHandle
+ // The class is java.lang.invoke.MethodHandle
resolved_klass = SystemDictionaryHandles::MethodHandle_klass();
Symbol* method_name = vmSymbols::invokeExact_name();
--- a/hotspot/src/share/vm/memory/collectorPolicy.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/memory/collectorPolicy.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -293,10 +293,11 @@
// Determine maximum size of gen0
size_t max_new_size = 0;
- if (FLAG_IS_CMDLINE(MaxNewSize)) {
+ if (FLAG_IS_CMDLINE(MaxNewSize) || FLAG_IS_ERGO(MaxNewSize)) {
if (MaxNewSize < min_alignment()) {
max_new_size = min_alignment();
- } else if (MaxNewSize >= max_heap_byte_size()) {
+ }
+ if (MaxNewSize >= max_heap_byte_size()) {
max_new_size = align_size_down(max_heap_byte_size() - min_alignment(),
min_alignment());
warning("MaxNewSize (" SIZE_FORMAT "k) is equal to or "
@@ -333,7 +334,7 @@
assert(max_new_size > 0, "All paths should set max_new_size");
// Given the maximum gen0 size, determine the initial and
- // minimum sizes.
+ // minimum gen0 sizes.
if (max_heap_byte_size() == min_heap_byte_size()) {
// The maximum and minimum heap sizes are the same so
@@ -396,7 +397,7 @@
}
if (PrintGCDetails && Verbose) {
- gclog_or_tty->print_cr("Minimum gen0 " SIZE_FORMAT " Initial gen0 "
+ gclog_or_tty->print_cr("1: Minimum gen0 " SIZE_FORMAT " Initial gen0 "
SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT,
min_gen0_size(), initial_gen0_size(), max_gen0_size());
}
@@ -448,7 +449,7 @@
// At this point the minimum, initial and maximum sizes
// of the overall heap and of gen0 have been determined.
// The maximum gen1 size can be determined from the maximum gen0
- // and maximum heap size since not explicit flags exits
+ // and maximum heap size since no explicit flags exits
// for setting the gen1 maximum.
_max_gen1_size = max_heap_byte_size() - _max_gen0_size;
_max_gen1_size =
@@ -494,13 +495,13 @@
"generation sizes: using maximum heap = " SIZE_FORMAT
" -XX:OldSize flag is being ignored",
max_heap_byte_size());
- }
+ }
// If there is an inconsistency between the OldSize and the minimum and/or
// initial size of gen0, since OldSize was explicitly set, OldSize wins.
if (adjust_gen0_sizes(&_min_gen0_size, &_min_gen1_size,
min_heap_byte_size(), OldSize)) {
if (PrintGCDetails && Verbose) {
- gclog_or_tty->print_cr("Minimum gen0 " SIZE_FORMAT " Initial gen0 "
+ gclog_or_tty->print_cr("2: Minimum gen0 " SIZE_FORMAT " Initial gen0 "
SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT,
min_gen0_size(), initial_gen0_size(), max_gen0_size());
}
@@ -509,7 +510,7 @@
if (adjust_gen0_sizes(&_initial_gen0_size, &_initial_gen1_size,
initial_heap_byte_size(), OldSize)) {
if (PrintGCDetails && Verbose) {
- gclog_or_tty->print_cr("Minimum gen0 " SIZE_FORMAT " Initial gen0 "
+ gclog_or_tty->print_cr("3: Minimum gen0 " SIZE_FORMAT " Initial gen0 "
SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT,
min_gen0_size(), initial_gen0_size(), max_gen0_size());
}
--- a/hotspot/src/share/vm/memory/generation.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/memory/generation.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -83,14 +83,11 @@
}
// By default we get a single threaded default reference processor;
-// generations needing multi-threaded refs discovery override this method.
+// generations needing multi-threaded refs processing or discovery override this method.
void Generation::ref_processor_init() {
assert(_ref_processor == NULL, "a reference processor already exists");
assert(!_reserved.is_empty(), "empty generation?");
- _ref_processor =
- new ReferenceProcessor(_reserved, // span
- refs_discovery_is_atomic(), // atomic_discovery
- refs_discovery_is_mt()); // mt_discovery
+ _ref_processor = new ReferenceProcessor(_reserved); // a vanilla reference processor
if (_ref_processor == NULL) {
vm_exit_during_initialization("Could not allocate ReferenceProcessor object");
}
--- a/hotspot/src/share/vm/memory/heap.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/memory/heap.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -316,12 +316,19 @@
}
size_t CodeHeap::largest_free_block() const {
+ // First check unused space excluding free blocks.
+ size_t free_sz = size(_free_segments);
+ size_t unused = max_capacity() - allocated_capacity() - free_sz;
+ if (unused >= free_sz)
+ return unused;
+
+ // Now check largest free block.
size_t len = 0;
for (FreeBlock* b = _freelist; b != NULL; b = b->link()) {
if (b->length() > len)
len = b->length();
}
- return size(len);
+ return MAX2(unused, size(len));
}
// Free list management
--- a/hotspot/src/share/vm/memory/referenceProcessor.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/memory/referenceProcessor.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -102,40 +102,17 @@
"Unrecongnized RefDiscoveryPolicy");
}
-ReferenceProcessor*
-ReferenceProcessor::create_ref_processor(MemRegion span,
- bool atomic_discovery,
- bool mt_discovery,
- BoolObjectClosure* is_alive_non_header,
- int parallel_gc_threads,
- bool mt_processing,
- bool dl_needs_barrier) {
- int mt_degree = 1;
- if (parallel_gc_threads > 1) {
- mt_degree = parallel_gc_threads;
- }
- ReferenceProcessor* rp =
- new ReferenceProcessor(span, atomic_discovery,
- mt_discovery, mt_degree,
- mt_processing && (parallel_gc_threads > 0),
- dl_needs_barrier);
- if (rp == NULL) {
- vm_exit_during_initialization("Could not allocate ReferenceProcessor object");
- }
- rp->set_is_alive_non_header(is_alive_non_header);
- rp->setup_policy(false /* default soft ref policy */);
- return rp;
-}
-
ReferenceProcessor::ReferenceProcessor(MemRegion span,
- bool atomic_discovery,
+ bool mt_processing,
+ int mt_processing_degree,
bool mt_discovery,
- int mt_degree,
- bool mt_processing,
+ int mt_discovery_degree,
+ bool atomic_discovery,
+ BoolObjectClosure* is_alive_non_header,
bool discovered_list_needs_barrier) :
_discovering_refs(false),
_enqueuing_is_done(false),
- _is_alive_non_header(NULL),
+ _is_alive_non_header(is_alive_non_header),
_discovered_list_needs_barrier(discovered_list_needs_barrier),
_bs(NULL),
_processing_is_mt(mt_processing),
@@ -144,8 +121,8 @@
_span = span;
_discovery_is_atomic = atomic_discovery;
_discovery_is_mt = mt_discovery;
- _num_q = mt_degree;
- _max_num_q = mt_degree;
+ _num_q = MAX2(1, mt_processing_degree);
+ _max_num_q = MAX2(_num_q, mt_discovery_degree);
_discoveredSoftRefs = NEW_C_HEAP_ARRAY(DiscoveredList, _max_num_q * subclasses_of_ref);
if (_discoveredSoftRefs == NULL) {
vm_exit_during_initialization("Could not allocated RefProc Array");
@@ -163,6 +140,7 @@
if (discovered_list_needs_barrier) {
_bs = Universe::heap()->barrier_set();
}
+ setup_policy(false /* default soft ref policy */);
}
#ifndef PRODUCT
@@ -405,15 +383,14 @@
{ }
virtual void work(unsigned int work_id) {
- assert(work_id < (unsigned int)_ref_processor.num_q(), "Index out-of-bounds");
+ assert(work_id < (unsigned int)_ref_processor.max_num_q(), "Index out-of-bounds");
// Simplest first cut: static partitioning.
int index = work_id;
// The increment on "index" must correspond to the maximum number of queues
// (n_queues) with which that ReferenceProcessor was created. That
// is because of the "clever" way the discovered references lists were
- // allocated and are indexed into. That number is ParallelGCThreads
- // currently. Assert that.
- assert(_n_queues == (int) ParallelGCThreads, "Different number not expected");
+ // allocated and are indexed into.
+ assert(_n_queues == (int) _ref_processor.max_num_q(), "Different number not expected");
for (int j = 0;
j < subclasses_of_ref;
j++, index += _n_queues) {
@@ -672,7 +649,7 @@
}
}
NOT_PRODUCT(
- if (PrintGCDetails && TraceReferenceGC) {
+ if (PrintGCDetails && TraceReferenceGC && (iter.processed() > 0)) {
gclog_or_tty->print_cr(" Dropped %d active Refs out of %d "
"Refs in discovered list " INTPTR_FORMAT,
iter.removed(), iter.processed(), (address)refs_list.head());
@@ -711,7 +688,7 @@
// Now close the newly reachable set
complete_gc->do_void();
NOT_PRODUCT(
- if (PrintGCDetails && TraceReferenceGC) {
+ if (PrintGCDetails && TraceReferenceGC && (iter.processed() > 0)) {
gclog_or_tty->print_cr(" Dropped %d active Refs out of %d "
"Refs in discovered list " INTPTR_FORMAT,
iter.removed(), iter.processed(), (address)refs_list.head());
@@ -951,7 +928,7 @@
}
if (PrintReferenceGC && PrintGCDetails) {
size_t total = 0;
- for (int i = 0; i < _num_q; ++i) {
+ for (int i = 0; i < _max_num_q; ++i) {
total += refs_lists[i].length();
}
gclog_or_tty->print(", %u refs", total);
@@ -967,7 +944,7 @@
RefProcPhase1Task phase1(*this, refs_lists, policy, true /*marks_oops_alive*/);
task_executor->execute(phase1);
} else {
- for (int i = 0; i < _num_q; i++) {
+ for (int i = 0; i < _max_num_q; i++) {
process_phase1(refs_lists[i], policy,
is_alive, keep_alive, complete_gc);
}
@@ -983,7 +960,7 @@
RefProcPhase2Task phase2(*this, refs_lists, !discovery_is_atomic() /*marks_oops_alive*/);
task_executor->execute(phase2);
} else {
- for (int i = 0; i < _num_q; i++) {
+ for (int i = 0; i < _max_num_q; i++) {
process_phase2(refs_lists[i], is_alive, keep_alive, complete_gc);
}
}
@@ -994,7 +971,7 @@
RefProcPhase3Task phase3(*this, refs_lists, clear_referent, true /*marks_oops_alive*/);
task_executor->execute(phase3);
} else {
- for (int i = 0; i < _num_q; i++) {
+ for (int i = 0; i < _max_num_q; i++) {
process_phase3(refs_lists[i], clear_referent,
is_alive, keep_alive, complete_gc);
}
@@ -1008,7 +985,7 @@
// for (int j = 0; j < _num_q; j++) {
// int index = i * _max_num_q + j;
for (int i = 0; i < _max_num_q * subclasses_of_ref; i++) {
- if (TraceReferenceGC && PrintGCDetails && ((i % _num_q) == 0)) {
+ if (TraceReferenceGC && PrintGCDetails && ((i % _max_num_q) == 0)) {
gclog_or_tty->print_cr(
"\nScrubbing %s discovered list of Null referents",
list_name(i));
@@ -1350,7 +1327,7 @@
{
TraceTime tt("Preclean WeakReferences", PrintGCDetails && PrintReferenceGC,
false, gclog_or_tty);
- for (int i = 0; i < _num_q; i++) {
+ for (int i = 0; i < _max_num_q; i++) {
if (yield->should_return()) {
return;
}
@@ -1363,7 +1340,7 @@
{
TraceTime tt("Preclean FinalReferences", PrintGCDetails && PrintReferenceGC,
false, gclog_or_tty);
- for (int i = 0; i < _num_q; i++) {
+ for (int i = 0; i < _max_num_q; i++) {
if (yield->should_return()) {
return;
}
@@ -1376,7 +1353,7 @@
{
TraceTime tt("Preclean PhantomReferences", PrintGCDetails && PrintReferenceGC,
false, gclog_or_tty);
- for (int i = 0; i < _num_q; i++) {
+ for (int i = 0; i < _max_num_q; i++) {
if (yield->should_return()) {
return;
}
@@ -1433,7 +1410,7 @@
complete_gc->do_void();
NOT_PRODUCT(
- if (PrintGCDetails && PrintReferenceGC) {
+ if (PrintGCDetails && PrintReferenceGC && (iter.processed() > 0)) {
gclog_or_tty->print_cr(" Dropped %d Refs out of %d "
"Refs in discovered list " INTPTR_FORMAT,
iter.removed(), iter.processed(), (address)refs_list.head());
--- a/hotspot/src/share/vm/memory/referenceProcessor.hpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/memory/referenceProcessor.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -71,7 +71,7 @@
bool _enqueuing_is_done; // true if all weak references enqueued
bool _processing_is_mt; // true during phases when
// reference processing is MT.
- int _next_id; // round-robin counter in
+ int _next_id; // round-robin mod _num_q counter in
// support of work distribution
// For collectors that do not keep GC marking information
@@ -103,7 +103,8 @@
public:
int num_q() { return _num_q; }
- void set_mt_degree(int v) { _num_q = v; }
+ int max_num_q() { return _max_num_q; }
+ void set_active_mt_degree(int v) { _num_q = v; }
DiscoveredList* discovered_soft_refs() { return _discoveredSoftRefs; }
static oop sentinel_ref() { return _sentinelRef; }
static oop* adr_sentinel_ref() { return &_sentinelRef; }
@@ -216,6 +217,7 @@
VoidClosure* complete_gc,
YieldClosure* yield);
+ // round-robin mod _num_q (not: _not_ mode _max_num_q)
int next_id() {
int id = _next_id;
if (++_next_id == _num_q) {
@@ -256,23 +258,15 @@
_max_num_q(0),
_processing_is_mt(false),
_next_id(0)
- {}
-
- ReferenceProcessor(MemRegion span, bool atomic_discovery,
- bool mt_discovery,
- int mt_degree = 1,
- bool mt_processing = false,
- bool discovered_list_needs_barrier = false);
+ { }
- // Allocates and initializes a reference processor.
- static ReferenceProcessor* create_ref_processor(
- MemRegion span,
- bool atomic_discovery,
- bool mt_discovery,
- BoolObjectClosure* is_alive_non_header = NULL,
- int parallel_gc_threads = 1,
- bool mt_processing = false,
- bool discovered_list_needs_barrier = false);
+ // Default parameters give you a vanilla reference processor.
+ ReferenceProcessor(MemRegion span,
+ bool mt_processing = false, int mt_processing_degree = 1,
+ bool mt_discovery = false, int mt_discovery_degree = 1,
+ bool atomic_discovery = true,
+ BoolObjectClosure* is_alive_non_header = NULL,
+ bool discovered_list_needs_barrier = false);
// RefDiscoveryPolicy values
enum DiscoveryPolicy {
@@ -397,20 +391,20 @@
// A utility class to temporarily change the MT'ness of
// reference discovery for the given ReferenceProcessor
// in the scope that contains it.
-class ReferenceProcessorMTMutator: StackObj {
+class ReferenceProcessorMTDiscoveryMutator: StackObj {
private:
ReferenceProcessor* _rp;
bool _saved_mt;
public:
- ReferenceProcessorMTMutator(ReferenceProcessor* rp,
- bool mt):
+ ReferenceProcessorMTDiscoveryMutator(ReferenceProcessor* rp,
+ bool mt):
_rp(rp) {
_saved_mt = _rp->discovery_is_mt();
_rp->set_mt_discovery(mt);
}
- ~ReferenceProcessorMTMutator() {
+ ~ReferenceProcessorMTDiscoveryMutator() {
_rp->set_mt_discovery(_saved_mt);
}
};
--- a/hotspot/src/share/vm/oops/constantPoolOop.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/oops/constantPoolOop.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -1175,8 +1175,15 @@
case JVM_CONSTANT_UnresolvedClass:
{
- Symbol* k = from_cp->unresolved_klass_at(from_i);
- to_cp->unresolved_klass_at_put(to_i, k);
+ // Can be resolved after checking tag, so check the slot first.
+ CPSlot entry = from_cp->slot_at(from_i);
+ if (entry.is_oop()) {
+ assert(entry.get_oop()->is_klass(), "must be");
+ // Already resolved
+ to_cp->klass_at_put(to_i, (klassOop)entry.get_oop());
+ } else {
+ to_cp->unresolved_klass_at_put(to_i, entry.get_symbol());
+ }
} break;
case JVM_CONSTANT_UnresolvedClassInError:
@@ -1189,8 +1196,14 @@
case JVM_CONSTANT_UnresolvedString:
{
- Symbol* s = from_cp->unresolved_string_at(from_i);
- to_cp->unresolved_string_at_put(to_i, s);
+ // Can be resolved after checking tag, so check the slot first.
+ CPSlot entry = from_cp->slot_at(from_i);
+ if (entry.is_oop()) {
+ // Already resolved (either string or pseudo-string)
+ to_cp->string_at_put(to_i, entry.get_oop());
+ } else {
+ to_cp->unresolved_string_at_put(to_i, entry.get_symbol());
+ }
} break;
case JVM_CONSTANT_Utf8:
--- a/hotspot/src/share/vm/oops/cpCacheOop.hpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/oops/cpCacheOop.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -190,7 +190,7 @@
);
void set_dynamic_call(
- Handle call_site, // Resolved java.dyn.CallSite (f1)
+ Handle call_site, // Resolved java.lang.invoke.CallSite (f1)
methodHandle signature_invoker // determines signature information
);
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -735,7 +735,12 @@
static int call_class_initializer_impl_counter = 0; // for debugging
methodOop instanceKlass::class_initializer() {
- return find_method(vmSymbols::class_initializer_name(), vmSymbols::void_method_signature());
+ methodOop clinit = find_method(
+ vmSymbols::class_initializer_name(), vmSymbols::void_method_signature());
+ if (clinit != NULL && clinit->has_valid_initializer_flags()) {
+ return clinit;
+ }
+ return NULL;
}
void instanceKlass::call_class_initializer_impl(instanceKlassHandle this_oop, TRAPS) {
@@ -2415,7 +2420,7 @@
st->cr();
} else if (as_klassOop() == SystemDictionary::MethodType_klass()) {
st->print(BULLET"signature: ");
- java_dyn_MethodType::print_signature(obj, st);
+ java_lang_invoke_MethodType::print_signature(obj, st);
st->cr();
}
}
@@ -2446,7 +2451,7 @@
}
} else if (as_klassOop() == SystemDictionary::MethodType_klass()) {
st->print(" = ");
- java_dyn_MethodType::print_signature(obj, st);
+ java_lang_invoke_MethodType::print_signature(obj, st);
} else if (java_lang_boxing_object::is_instance(obj)) {
st->print(" = ");
java_lang_boxing_object::print(obj, st);
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -193,8 +193,8 @@
typeArrayOop _inner_classes;
// Implementors of this interface (not valid if it overflows)
klassOop _implementors[implementors_limit];
- // invokedynamic bootstrap method (a java.dyn.MethodHandle)
- oop _bootstrap_method;
+ // invokedynamic bootstrap method (a java.lang.invoke.MethodHandle)
+ oop _bootstrap_method; // AllowTransitionalJSR292 ONLY
// Annotations for this class, or null if none.
typeArrayOop _class_annotations;
// Annotation objects (byte arrays) for fields, or null if no annotations.
@@ -529,7 +529,7 @@
_enclosing_method_method_index = method_index; }
// JSR 292 support
- oop bootstrap_method() const { return _bootstrap_method; }
+ oop bootstrap_method() const { return _bootstrap_method; } // AllowTransitionalJSR292 ONLY
void set_bootstrap_method(oop mh) { oop_store(&_bootstrap_method, mh); }
// jmethodID support
@@ -817,7 +817,7 @@
oop* adr_signers() const { return (oop*)&this->_signers;}
oop* adr_inner_classes() const { return (oop*)&this->_inner_classes;}
oop* adr_implementors() const { return (oop*)&this->_implementors[0];}
- oop* adr_bootstrap_method() const { return (oop*)&this->_bootstrap_method;}
+ oop* adr_bootstrap_method() const { return (oop*)&this->_bootstrap_method;} // AllowTransitionalJSR292 ONLY
oop* adr_methods_jmethod_ids() const { return (oop*)&this->_methods_jmethod_ids;}
oop* adr_methods_cached_itable_indices() const { return (oop*)&this->_methods_cached_itable_indices;}
oop* adr_class_annotations() const { return (oop*)&this->_class_annotations;}
--- a/hotspot/src/share/vm/oops/klassVtable.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/oops/klassVtable.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -883,7 +883,7 @@
int ime_num = 0;
// Skip first methodOop if it is a class initializer
- int i = ((methodOop)methods()->obj_at(0))->name() != vmSymbols::class_initializer_name() ? 0 : 1;
+ int i = ((methodOop)methods()->obj_at(0))->is_static_initializer() ? 1 : 0;
// m, method_name, method_signature, klass reset each loop so they
// don't need preserving across check_signature_loaders call
@@ -1121,7 +1121,7 @@
assert(index < methods->length(), "should find index for resolve_invoke");
}
// Adjust for <clinit>, which is left out of table if first method
- if (methods->length() > 0 && ((methodOop)methods->obj_at(0))->name() == vmSymbols::class_initializer_name()) {
+ if (methods->length() > 0 && ((methodOop)methods->obj_at(0))->is_static_initializer()) {
index--;
}
return index;
@@ -1135,7 +1135,7 @@
int index = itable_index;
// Adjust for <clinit>, which is left out of table if first method
- if (methods->length() > 0 && ((methodOop)methods->obj_at(0))->name() == vmSymbols::class_initializer_name()) {
+ if (methods->length() > 0 && ((methodOop)methods->obj_at(0))->is_static_initializer()) {
index++;
}
--- a/hotspot/src/share/vm/oops/methodDataOop.hpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/oops/methodDataOop.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -228,7 +228,7 @@
return byte_offset_of(DataLayout, _header._struct._bci);
}
static ByteSize cell_offset(int index) {
- return byte_offset_of(DataLayout, _cells[index]);
+ return byte_offset_of(DataLayout, _cells) + in_ByteSize(index * cell_size);
}
// Return a value which, when or-ed as a byte into _flags, sets the flag.
static int flag_number_to_byte_constant(int flag_number) {
--- a/hotspot/src/share/vm/oops/methodKlass.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/oops/methodKlass.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -103,6 +103,12 @@
m->backedge_counter()->init();
m->clear_number_of_breakpoints();
+#ifdef TIERED
+ m->set_rate(0);
+ m->set_prev_event_count(0);
+ m->set_prev_time(0);
+#endif
+
assert(m->is_parsable(), "must be parsable here.");
assert(m->size() == size, "wrong size for object");
// We should not publish an uprasable object's reference
--- a/hotspot/src/share/vm/oops/methodOop.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/oops/methodOop.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -466,7 +466,20 @@
bool methodOopDesc::is_initializer() const {
- return name() == vmSymbols::object_initializer_name() || name() == vmSymbols::class_initializer_name();
+ return name() == vmSymbols::object_initializer_name() || is_static_initializer();
+}
+
+bool methodOopDesc::has_valid_initializer_flags() const {
+ return (is_static() ||
+ instanceKlass::cast(method_holder())->major_version() < 51);
+}
+
+bool methodOopDesc::is_static_initializer() const {
+ // For classfiles version 51 or greater, ensure that the clinit method is
+ // static. Non-static methods with the name "<clinit>" are not static
+ // initializers. (older classfiles exempted for backward compatibility)
+ return name() == vmSymbols::class_initializer_name() &&
+ has_valid_initializer_flags();
}
@@ -842,7 +855,7 @@
case vmSymbols::VM_SYMBOL_ENUM_NAME(invokeGeneric_name):
return true;
}
- if (AllowTransitionalJSR292
+ if ((AllowTransitionalJSR292 || AllowInvokeForInvokeGeneric)
&& name_sid == vmSymbols::VM_SYMBOL_ENUM_NAME(invoke_name))
return true;
return false;
@@ -852,7 +865,7 @@
enum {
_imcp_invoke_name = 1, // utf8: 'invokeExact' or 'invokeGeneric'
_imcp_invoke_signature, // utf8: (variable Symbol*)
- _imcp_method_type_value, // string: (variable java/dyn/MethodType, sic)
+ _imcp_method_type_value, // string: (variable java/lang/invoke/MethodType, sic)
_imcp_limit
};
@@ -1078,7 +1091,8 @@
vmSymbols::SID name_id = vmSymbols::find_sid(name());
if (name_id == vmSymbols::NO_SID) return;
vmSymbols::SID sig_id = vmSymbols::find_sid(signature());
- if (klass_id != vmSymbols::VM_SYMBOL_ENUM_NAME(java_dyn_MethodHandle)
+ if (klass_id != vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_MethodHandle)
+ && !(klass_id == vmSymbols::VM_SYMBOL_ENUM_NAME(java_dyn_MethodHandle) && AllowTransitionalJSR292)
&& sig_id == vmSymbols::NO_SID) return;
jshort flags = access_flags().as_short();
@@ -1104,7 +1118,8 @@
break;
// Signature-polymorphic methods: MethodHandle.invoke*, InvokeDynamic.*.
- case vmSymbols::VM_SYMBOL_ENUM_NAME(java_dyn_MethodHandle):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(java_dyn_MethodHandle): // AllowTransitionalJSR292 ONLY
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_MethodHandle):
if (is_static() || !is_native()) break;
switch (name_id) {
case vmSymbols::VM_SYMBOL_ENUM_NAME(invokeGeneric_name):
@@ -1114,11 +1129,12 @@
id = vmIntrinsics::_invokeExact;
break;
case vmSymbols::VM_SYMBOL_ENUM_NAME(invoke_name):
- if (AllowTransitionalJSR292) id = vmIntrinsics::_invokeExact;
+ if (AllowInvokeForInvokeGeneric) id = vmIntrinsics::_invokeGeneric;
+ else if (AllowTransitionalJSR292) id = vmIntrinsics::_invokeExact;
break;
}
break;
- case vmSymbols::VM_SYMBOL_ENUM_NAME(java_dyn_InvokeDynamic):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_InvokeDynamic):
if (!is_static() || !is_native()) break;
id = vmIntrinsics::_invokeDynamic;
break;
--- a/hotspot/src/share/vm/oops/methodOop.hpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/oops/methodOop.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -84,6 +84,11 @@
// | invocation_counter |
// | backedge_counter |
// |------------------------------------------------------|
+// | prev_time (tiered only, 64 bit wide) |
+// | |
+// |------------------------------------------------------|
+// | rate (tiered) |
+// |------------------------------------------------------|
// | code (pointer) |
// | i2i (pointer) |
// | adapter (pointer) |
@@ -124,6 +129,11 @@
InvocationCounter _invocation_counter; // Incremented before each activation of the method - used to trigger frequency-based optimizations
InvocationCounter _backedge_counter; // Incremented before each backedge taken - used to trigger frequencey-based optimizations
+#ifdef TIERED
+ jlong _prev_time; // Previous time the rate was acquired
+ float _rate; // Events (invocation and backedge counter increments) per millisecond
+#endif
+
#ifndef PRODUCT
int _compiled_invocation_count; // Number of nmethod invocations so far (for perf. debugging)
#endif
@@ -304,6 +314,17 @@
InvocationCounter* invocation_counter() { return &_invocation_counter; }
InvocationCounter* backedge_counter() { return &_backedge_counter; }
+#ifdef TIERED
+ // We are reusing interpreter_invocation_count as a holder for the previous event count!
+ // We can do that since interpreter_invocation_count is not used in tiered.
+ int prev_event_count() const { return _interpreter_invocation_count; }
+ void set_prev_event_count(int count) { _interpreter_invocation_count = count; }
+ jlong prev_time() const { return _prev_time; }
+ void set_prev_time(jlong time) { _prev_time = time; }
+ float rate() const { return _rate; }
+ void set_rate(float rate) { _rate = rate; }
+#endif
+
int invocation_count();
int backedge_count();
@@ -497,6 +518,13 @@
// returns true if the method is an initializer (<init> or <clinit>).
bool is_initializer() const;
+ // returns true if the method is static OR if the classfile version < 51
+ bool has_valid_initializer_flags() const;
+
+ // returns true if the method name is <clinit> and the method has
+ // valid static initializer flags.
+ bool is_static_initializer() const;
+
// compiled code support
// NOTE: code() is inherently racy as deopt can be clearing code
// simultaneously. Use with caution.
--- a/hotspot/src/share/vm/opto/bytecodeInfo.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/opto/bytecodeInfo.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -487,7 +487,7 @@
if (caller_jvms->method()->is_method_handle_adapter())
new_depth_adjust -= 1; // don't count actions in MH or indy adapter frames
else if (callee_method->is_method_handle_invoke()) {
- new_depth_adjust -= 1; // don't count method handle calls from java.dyn implem
+ new_depth_adjust -= 1; // don't count method handle calls from java.lang.invoke implem
}
if (new_depth_adjust != 0 && PrintInlining) {
stringStream nm1; caller_jvms->method()->print_name(&nm1);
--- a/hotspot/src/share/vm/opto/callGenerator.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/opto/callGenerator.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -199,7 +199,7 @@
Node* call_site = kit.make_load(kit.control(), call_site_adr, TypeInstPtr::BOTTOM, T_OBJECT, Compile::AliasIdxRaw);
// Load the target MethodHandle from the CallSite object.
- Node* target_mh_adr = kit.basic_plus_adr(call_site, call_site, java_dyn_CallSite::target_offset_in_bytes());
+ Node* target_mh_adr = kit.basic_plus_adr(call_site, call_site, java_lang_invoke_CallSite::target_offset_in_bytes());
Node* target_mh = kit.make_load(kit.control(), target_mh_adr, TypeInstPtr::BOTTOM, T_OBJECT);
address resolve_stub = SharedRuntime::get_resolve_opt_virtual_call_stub();
@@ -725,7 +725,7 @@
Node* call_site = kit.make_load(kit.control(), call_site_adr, TypeInstPtr::BOTTOM, T_OBJECT, Compile::AliasIdxRaw);
// Load the target MethodHandle from the CallSite object.
- Node* target_adr = kit.basic_plus_adr(call_site, call_site, java_dyn_CallSite::target_offset_in_bytes());
+ Node* target_adr = kit.basic_plus_adr(call_site, call_site, java_lang_invoke_CallSite::target_offset_in_bytes());
Node* target_mh = kit.make_load(kit.control(), target_adr, TypeInstPtr::BOTTOM, T_OBJECT);
// Check if the MethodHandle is still the same.
--- a/hotspot/src/share/vm/opto/output.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/opto/output.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -1028,7 +1028,7 @@
// helper for Fill_buffer bailout logic
static void turn_off_compiler(Compile* C) {
- if (CodeCache::unallocated_capacity() >= CodeCacheMinimumFreeSpace*10) {
+ if (CodeCache::largest_free_block() >= CodeCacheMinimumFreeSpace*10) {
// Do not turn off compilation if a single giant method has
// blown the code cache size.
C->record_failure("excessive request to CodeCache");
--- a/hotspot/src/share/vm/opto/parse3.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/opto/parse3.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -143,8 +143,8 @@
return;
}
else {
- // final non-static field of a trusted class ({java,sun}.dyn
- // classes).
+ // final non-static field of a trusted class (classes in
+ // java.lang.invoke and sun.invoke packages and subpackages).
if (obj->is_Con()) {
const TypeOopPtr* oop_ptr = obj->bottom_type()->isa_oopptr();
ciObject* constant_oop = oop_ptr->const_oop();
--- a/hotspot/src/share/vm/opto/type.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/opto/type.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -3386,7 +3386,22 @@
instance_id = InstanceBot;
tary = TypeAry::make(Type::BOTTOM, tary->_size);
}
+ } else // Non integral arrays.
+ // Must fall to bottom if exact klasses in upper lattice
+ // are not equal or super klass is exact.
+ if ( above_centerline(ptr) && klass() != tap->klass() &&
+ // meet with top[] and bottom[] are processed further down:
+ tap ->_klass != NULL && this->_klass != NULL &&
+ // both are exact and not equal:
+ ((tap ->_klass_is_exact && this->_klass_is_exact) ||
+ // 'tap' is exact and super or unrelated:
+ (tap ->_klass_is_exact && !tap->klass()->is_subtype_of(klass())) ||
+ // 'this' is exact and super or unrelated:
+ (this->_klass_is_exact && !klass()->is_subtype_of(tap->klass())))) {
+ tary = TypeAry::make(Type::BOTTOM, tary->_size);
+ return make( NotNull, NULL, tary, lazy_klass, false, off, InstanceBot );
}
+
bool xk = false;
switch (tap->ptr()) {
case AnyNull:
@@ -3766,7 +3781,7 @@
// Oops, need to compute _klass and cache it
ciKlass* k_ary = compute_klass();
- if( this != TypeAryPtr::OOPS ) {
+ if( this != TypeAryPtr::OOPS && this->dual() != TypeAryPtr::OOPS ) {
// The _klass field acts as a cache of the underlying
// ciKlass for this array type. In order to set the field,
// we need to cast away const-ness.
--- a/hotspot/src/share/vm/prims/jvmtiImpl.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiImpl.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -919,15 +919,24 @@
nmethod* nm) {
JvmtiDeferredEvent event = JvmtiDeferredEvent(TYPE_COMPILED_METHOD_LOAD);
event._event_data.compiled_method_load = nm;
- nmethodLocker::lock_nmethod(nm); // will be unlocked when posted
+ // Keep the nmethod alive until the ServiceThread can process
+ // this deferred event.
+ nmethodLocker::lock_nmethod(nm);
return event;
}
JvmtiDeferredEvent JvmtiDeferredEvent::compiled_method_unload_event(
- jmethodID id, const void* code) {
+ nmethod* nm, jmethodID id, const void* code) {
JvmtiDeferredEvent event = JvmtiDeferredEvent(TYPE_COMPILED_METHOD_UNLOAD);
+ event._event_data.compiled_method_unload.nm = nm;
event._event_data.compiled_method_unload.method_id = id;
event._event_data.compiled_method_unload.code_begin = code;
+ // Keep the nmethod alive until the ServiceThread can process
+ // this deferred event. This will keep the memory for the
+ // generated code from being reused too early. We pass
+ // zombie_ok == true here so that our nmethod that was just
+ // made into a zombie can be locked.
+ nmethodLocker::lock_nmethod(nm, true /* zombie_ok */);
return event;
}
JvmtiDeferredEvent JvmtiDeferredEvent::dynamic_code_generated_event(
@@ -946,14 +955,19 @@
case TYPE_COMPILED_METHOD_LOAD: {
nmethod* nm = _event_data.compiled_method_load;
JvmtiExport::post_compiled_method_load(nm);
+ // done with the deferred event so unlock the nmethod
nmethodLocker::unlock_nmethod(nm);
break;
}
- case TYPE_COMPILED_METHOD_UNLOAD:
+ case TYPE_COMPILED_METHOD_UNLOAD: {
+ nmethod* nm = _event_data.compiled_method_unload.nm;
JvmtiExport::post_compiled_method_unload(
_event_data.compiled_method_unload.method_id,
_event_data.compiled_method_unload.code_begin);
+ // done with the deferred event so unlock the nmethod
+ nmethodLocker::unlock_nmethod(nm);
break;
+ }
case TYPE_DYNAMIC_CODE_GENERATED:
JvmtiExport::post_dynamic_code_generated_internal(
_event_data.dynamic_code_generated.name,
--- a/hotspot/src/share/vm/prims/jvmtiImpl.hpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiImpl.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -458,6 +458,7 @@
union {
nmethod* compiled_method_load;
struct {
+ nmethod* nm;
jmethodID method_id;
const void* code_begin;
} compiled_method_unload;
@@ -477,7 +478,7 @@
// Factory methods
static JvmtiDeferredEvent compiled_method_load_event(nmethod* nm)
KERNEL_RETURN_(JvmtiDeferredEvent());
- static JvmtiDeferredEvent compiled_method_unload_event(
+ static JvmtiDeferredEvent compiled_method_unload_event(nmethod* nm,
jmethodID id, const void* code) KERNEL_RETURN_(JvmtiDeferredEvent());
static JvmtiDeferredEvent dynamic_code_generated_event(
const char* name, const void* begin, const void* end)
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -1084,7 +1084,10 @@
jbyte old_tag = old_cp->tag_at(old_i).value();
switch (old_tag) {
case JVM_CONSTANT_Class:
+ case JVM_CONSTANT_UnresolvedClass:
// revert the copy to JVM_CONSTANT_UnresolvedClass
+ // May be resolving while calling this so do the same for
+ // JVM_CONSTANT_UnresolvedClass (klass_name_at() deals with transition)
(*merge_cp_p)->unresolved_klass_at_put(old_i,
old_cp->klass_name_at(old_i));
break;
--- a/hotspot/src/share/vm/prims/methodHandleWalk.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/prims/methodHandleWalk.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -36,7 +36,7 @@
// MethodHandleChain
void MethodHandleChain::set_method_handle(Handle mh, TRAPS) {
- if (!java_dyn_MethodHandle::is_instance(mh())) lose("bad method handle", CHECK);
+ if (!java_lang_invoke_MethodHandle::is_instance(mh())) lose("bad method handle", CHECK);
// set current method handle and unpack partially
_method_handle = mh;
@@ -47,21 +47,21 @@
_conversion = -1;
_last_invoke = Bytecodes::_nop; //arbitrary non-garbage
- if (sun_dyn_DirectMethodHandle::is_instance(mh())) {
+ if (java_lang_invoke_DirectMethodHandle::is_instance(mh())) {
set_last_method(mh(), THREAD);
return;
}
- if (sun_dyn_AdapterMethodHandle::is_instance(mh())) {
+ if (java_lang_invoke_AdapterMethodHandle::is_instance(mh())) {
_conversion = AdapterMethodHandle_conversion();
assert(_conversion != -1, "bad conv value");
- assert(sun_dyn_BoundMethodHandle::is_instance(mh()), "also BMH");
+ assert(java_lang_invoke_BoundMethodHandle::is_instance(mh()), "also BMH");
}
- if (sun_dyn_BoundMethodHandle::is_instance(mh())) {
+ if (java_lang_invoke_BoundMethodHandle::is_instance(mh())) {
if (!is_adapter()) // keep AMH and BMH separate in this model
_is_bound = true;
_arg_slot = BoundMethodHandle_vmargslot();
oop target = MethodHandle_vmtarget_oop();
- if (!is_bound() || java_dyn_MethodHandle::is_instance(target)) {
+ if (!is_bound() || java_lang_invoke_MethodHandle::is_instance(target)) {
_arg_type = compute_bound_arg_type(target, NULL, _arg_slot, CHECK);
} else if (target != NULL && target->is_method()) {
methodOop m = (methodOop) target;
@@ -100,13 +100,12 @@
BasicType MethodHandleChain::compute_bound_arg_type(oop target, methodOop m, int arg_slot, TRAPS) {
// There is no direct indication of whether the argument is primitive or not.
// It is implied by the _vmentry code, and by the MethodType of the target.
- // FIXME: Make it explicit MethodHandleImpl refactors out from MethodHandle
BasicType arg_type = T_VOID;
if (target != NULL) {
- oop mtype = java_dyn_MethodHandle::type(target);
+ oop mtype = java_lang_invoke_MethodHandle::type(target);
int arg_num = MethodHandles::argument_slot_to_argnum(mtype, arg_slot);
if (arg_num >= 0) {
- oop ptype = java_dyn_MethodType::ptype(mtype, arg_num);
+ oop ptype = java_lang_invoke_MethodType::ptype(mtype, arg_num);
arg_type = java_lang_Class::as_BasicType(ptype);
}
} else if (m != NULL) {
@@ -205,28 +204,28 @@
int arg_slot = chain().adapter_arg_slot();
SlotState* arg_state = slot_state(arg_slot);
if (arg_state == NULL
- && conv_op > sun_dyn_AdapterMethodHandle::OP_RETYPE_RAW) {
+ && conv_op > java_lang_invoke_AdapterMethodHandle::OP_RETYPE_RAW) {
lose("bad argument index", CHECK_(empty));
}
// perform the adapter action
switch (chain().adapter_conversion_op()) {
- case sun_dyn_AdapterMethodHandle::OP_RETYPE_ONLY:
+ case java_lang_invoke_AdapterMethodHandle::OP_RETYPE_ONLY:
// No changes to arguments; pass the bits through.
break;
- case sun_dyn_AdapterMethodHandle::OP_RETYPE_RAW: {
+ case java_lang_invoke_AdapterMethodHandle::OP_RETYPE_RAW: {
// To keep the verifier happy, emit bitwise ("raw") conversions as needed.
// See MethodHandles::same_basic_type_for_arguments for allowed conversions.
Handle incoming_mtype(THREAD, chain().method_type_oop());
oop outgoing_mh_oop = chain().vmtarget_oop();
- if (!java_dyn_MethodHandle::is_instance(outgoing_mh_oop))
+ if (!java_lang_invoke_MethodHandle::is_instance(outgoing_mh_oop))
lose("outgoing target not a MethodHandle", CHECK_(empty));
- Handle outgoing_mtype(THREAD, java_dyn_MethodHandle::type(outgoing_mh_oop));
+ Handle outgoing_mtype(THREAD, java_lang_invoke_MethodHandle::type(outgoing_mh_oop));
outgoing_mh_oop = NULL; // GC safety
- int nptypes = java_dyn_MethodType::ptype_count(outgoing_mtype());
- if (nptypes != java_dyn_MethodType::ptype_count(incoming_mtype()))
+ int nptypes = java_lang_invoke_MethodType::ptype_count(outgoing_mtype());
+ if (nptypes != java_lang_invoke_MethodType::ptype_count(incoming_mtype()))
lose("incoming and outgoing parameter count do not agree", CHECK_(empty));
for (int i = 0, slot = _outgoing.length() - 1; slot >= 0; slot--) {
@@ -236,8 +235,8 @@
klassOop in_klass = NULL;
klassOop out_klass = NULL;
- BasicType inpbt = java_lang_Class::as_BasicType(java_dyn_MethodType::ptype(incoming_mtype(), i), &in_klass);
- BasicType outpbt = java_lang_Class::as_BasicType(java_dyn_MethodType::ptype(outgoing_mtype(), i), &out_klass);
+ BasicType inpbt = java_lang_Class::as_BasicType(java_lang_invoke_MethodType::ptype(incoming_mtype(), i), &in_klass);
+ BasicType outpbt = java_lang_Class::as_BasicType(java_lang_invoke_MethodType::ptype(outgoing_mtype(), i), &out_klass);
assert(inpbt == arg.basic_type(), "sanity");
if (inpbt != outpbt) {
@@ -255,8 +254,8 @@
i++; // We need to skip void slots at the top of the loop.
}
- BasicType inrbt = java_lang_Class::as_BasicType(java_dyn_MethodType::rtype(incoming_mtype()));
- BasicType outrbt = java_lang_Class::as_BasicType(java_dyn_MethodType::rtype(outgoing_mtype()));
+ BasicType inrbt = java_lang_Class::as_BasicType(java_lang_invoke_MethodType::rtype(incoming_mtype()));
+ BasicType outrbt = java_lang_Class::as_BasicType(java_lang_invoke_MethodType::rtype(outgoing_mtype()));
if (inrbt != outrbt) {
if (inrbt == T_INT && outrbt == T_VOID) {
// See comments in MethodHandles::same_basic_type_for_arguments.
@@ -268,7 +267,7 @@
break;
}
- case sun_dyn_AdapterMethodHandle::OP_CHECK_CAST: {
+ case java_lang_invoke_AdapterMethodHandle::OP_CHECK_CAST: {
// checkcast the Nth outgoing argument in place
klassOop dest_klass = NULL;
BasicType dest = java_lang_Class::as_BasicType(chain().adapter_arg_oop(), &dest_klass);
@@ -281,7 +280,7 @@
break;
}
- case sun_dyn_AdapterMethodHandle::OP_PRIM_TO_PRIM: {
+ case java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_PRIM: {
// i2l, etc., on the Nth outgoing argument in place
BasicType src = chain().adapter_conversion_src_type(),
dest = chain().adapter_conversion_dest_type();
@@ -306,7 +305,7 @@
break;
}
- case sun_dyn_AdapterMethodHandle::OP_REF_TO_PRIM: {
+ case java_lang_invoke_AdapterMethodHandle::OP_REF_TO_PRIM: {
// checkcast to wrapper type & call intValue, etc.
BasicType dest = chain().adapter_conversion_dest_type();
ArgToken arg = arg_state->_arg;
@@ -324,7 +323,7 @@
break;
}
- case sun_dyn_AdapterMethodHandle::OP_PRIM_TO_REF: {
+ case java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_REF: {
// call wrapper type.valueOf
BasicType src = chain().adapter_conversion_src_type();
ArgToken arg = arg_state->_arg;
@@ -340,7 +339,7 @@
break;
}
- case sun_dyn_AdapterMethodHandle::OP_SWAP_ARGS: {
+ case java_lang_invoke_AdapterMethodHandle::OP_SWAP_ARGS: {
int dest_arg_slot = chain().adapter_conversion_vminfo();
if (!slot_has_argument(dest_arg_slot)) {
lose("bad swap index", CHECK_(empty));
@@ -353,7 +352,7 @@
break;
}
- case sun_dyn_AdapterMethodHandle::OP_ROT_ARGS: {
+ case java_lang_invoke_AdapterMethodHandle::OP_ROT_ARGS: {
int dest_arg_slot = chain().adapter_conversion_vminfo();
if (!slot_has_argument(dest_arg_slot) || arg_slot == dest_arg_slot) {
lose("bad rotate index", CHECK_(empty));
@@ -379,7 +378,7 @@
break;
}
- case sun_dyn_AdapterMethodHandle::OP_DUP_ARGS: {
+ case java_lang_invoke_AdapterMethodHandle::OP_DUP_ARGS: {
int dup_slots = chain().adapter_conversion_stack_pushes();
if (dup_slots <= 0) {
lose("bad dup count", CHECK_(empty));
@@ -393,7 +392,7 @@
break;
}
- case sun_dyn_AdapterMethodHandle::OP_DROP_ARGS: {
+ case java_lang_invoke_AdapterMethodHandle::OP_DROP_ARGS: {
int drop_slots = -chain().adapter_conversion_stack_pushes();
if (drop_slots <= 0) {
lose("bad drop count", CHECK_(empty));
@@ -407,12 +406,12 @@
break;
}
- case sun_dyn_AdapterMethodHandle::OP_COLLECT_ARGS: { //NYI, may GC
+ case java_lang_invoke_AdapterMethodHandle::OP_COLLECT_ARGS: { //NYI, may GC
lose("unimplemented", CHECK_(empty));
break;
}
- case sun_dyn_AdapterMethodHandle::OP_SPREAD_ARGS: {
+ case java_lang_invoke_AdapterMethodHandle::OP_SPREAD_ARGS: {
klassOop array_klass_oop = NULL;
BasicType array_type = java_lang_Class::as_BasicType(chain().adapter_arg_oop(),
&array_klass_oop);
@@ -470,8 +469,8 @@
break;
}
- case sun_dyn_AdapterMethodHandle::OP_FLYBY: //NYI, runs Java code
- case sun_dyn_AdapterMethodHandle::OP_RICOCHET: //NYI, runs Java code
+ case java_lang_invoke_AdapterMethodHandle::OP_FLYBY: //NYI, runs Java code
+ case java_lang_invoke_AdapterMethodHandle::OP_RICOCHET: //NYI, runs Java code
lose("unimplemented", CHECK_(empty));
break;
@@ -533,7 +532,7 @@
//
void MethodHandleWalker::walk_incoming_state(TRAPS) {
Handle mtype(THREAD, chain().method_type_oop());
- int nptypes = java_dyn_MethodType::ptype_count(mtype());
+ int nptypes = java_lang_invoke_MethodType::ptype_count(mtype());
_outgoing_argc = nptypes;
int argp = nptypes - 1;
if (argp >= 0) {
@@ -542,7 +541,7 @@
for (int i = 0; i < nptypes; i++) {
klassOop arg_type_klass = NULL;
BasicType arg_type = java_lang_Class::as_BasicType(
- java_dyn_MethodType::ptype(mtype(), i), &arg_type_klass);
+ java_lang_invoke_MethodType::ptype(mtype(), i), &arg_type_klass);
int index = new_local_index(arg_type);
ArgToken arg = make_parameter(arg_type, arg_type_klass, index, CHECK);
debug_only(arg_type_klass = (klassOop) NULL);
@@ -556,7 +555,7 @@
// call make_parameter at the end of the list for the return type
klassOop ret_type_klass = NULL;
BasicType ret_type = java_lang_Class::as_BasicType(
- java_dyn_MethodType::rtype(mtype()), &ret_type_klass);
+ java_lang_invoke_MethodType::rtype(mtype()), &ret_type_klass);
ArgToken ret = make_parameter(ret_type, ret_type_klass, -1, CHECK);
// ignore ret; client can catch it if needed
}
@@ -631,7 +630,7 @@
// Get return type klass.
Handle first_mtype(THREAD, chain().method_type_oop());
// _rklass is NULL for primitives.
- _rtype = java_lang_Class::as_BasicType(java_dyn_MethodType::rtype(first_mtype()), &_rklass);
+ _rtype = java_lang_Class::as_BasicType(java_lang_invoke_MethodType::rtype(first_mtype()), &_rklass);
if (_rtype == T_ARRAY) _rtype = T_OBJECT;
int params = _callee->size_of_parameters(); // Incoming arguments plus receiver.
@@ -960,6 +959,16 @@
if (m == NULL) {
// Get the intrinsic methodOop.
m = vmIntrinsics::method_for(iid);
+ if (m == NULL && iid == vmIntrinsics::_checkSpreadArgument && AllowTransitionalJSR292) {
+ m = vmIntrinsics::method_for(vmIntrinsics::_checkSpreadArgument_TRANS);
+ if (m == NULL)
+ // sun.dyn.MethodHandleImpl not found, look for java.dyn.MethodHandleNatives:
+ m = vmIntrinsics::method_for(vmIntrinsics::_checkSpreadArgument_TRANS2);
+ }
+ if (m == NULL) {
+ ArgToken zero;
+ lose(vmIntrinsics::name_at(iid), CHECK_(zero));
+ }
}
klassOop klass = m->method_holder();
@@ -1396,7 +1405,7 @@
void print_method_handle(oop mh) {
if (!mh->is_oop()) {
tty->print_cr("*** not a method handle: "INTPTR_FORMAT, (intptr_t)mh);
- } else if (java_dyn_MethodHandle::is_instance(mh)) {
+ } else if (java_lang_invoke_MethodHandle::is_instance(mh)) {
//MethodHandlePrinter::print(mh);
} else {
tty->print("*** not a method handle: ");
--- a/hotspot/src/share/vm/prims/methodHandleWalk.hpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/prims/methodHandleWalk.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -48,13 +48,13 @@
void set_last_method(oop target, TRAPS);
static BasicType compute_bound_arg_type(oop target, methodOop m, int arg_slot, TRAPS);
- oop MethodHandle_type_oop() { return java_dyn_MethodHandle::type(method_handle_oop()); }
- oop MethodHandle_vmtarget_oop() { return java_dyn_MethodHandle::vmtarget(method_handle_oop()); }
- int MethodHandle_vmslots() { return java_dyn_MethodHandle::vmslots(method_handle_oop()); }
- int DirectMethodHandle_vmindex() { return sun_dyn_DirectMethodHandle::vmindex(method_handle_oop()); }
- oop BoundMethodHandle_argument_oop() { return sun_dyn_BoundMethodHandle::argument(method_handle_oop()); }
- int BoundMethodHandle_vmargslot() { return sun_dyn_BoundMethodHandle::vmargslot(method_handle_oop()); }
- int AdapterMethodHandle_conversion() { return sun_dyn_AdapterMethodHandle::conversion(method_handle_oop()); }
+ oop MethodHandle_type_oop() { return java_lang_invoke_MethodHandle::type(method_handle_oop()); }
+ oop MethodHandle_vmtarget_oop() { return java_lang_invoke_MethodHandle::vmtarget(method_handle_oop()); }
+ int MethodHandle_vmslots() { return java_lang_invoke_MethodHandle::vmslots(method_handle_oop()); }
+ int DirectMethodHandle_vmindex() { return java_lang_invoke_DirectMethodHandle::vmindex(method_handle_oop()); }
+ oop BoundMethodHandle_argument_oop() { return java_lang_invoke_BoundMethodHandle::argument(method_handle_oop()); }
+ int BoundMethodHandle_vmargslot() { return java_lang_invoke_BoundMethodHandle::vmargslot(method_handle_oop()); }
+ int AdapterMethodHandle_conversion() { return java_lang_invoke_AdapterMethodHandle::conversion(method_handle_oop()); }
public:
MethodHandleChain(Handle root, TRAPS)
--- a/hotspot/src/share/vm/prims/methodHandles.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -163,9 +163,9 @@
// or it may use the klass/index form; both forms mean the same thing.
methodOop m = decode_methodOop(methodOop(vmtarget), decode_flags_result);
if ((decode_flags_result & _dmf_has_receiver) != 0
- && java_dyn_MethodType::is_instance(mtype)) {
+ && java_lang_invoke_MethodType::is_instance(mtype)) {
// Extract receiver type restriction from mtype.ptypes[0].
- objArrayOop ptypes = java_dyn_MethodType::ptypes(mtype);
+ objArrayOop ptypes = java_lang_invoke_MethodType::ptypes(mtype);
oop ptype0 = (ptypes == NULL || ptypes->length() < 1) ? oop(NULL) : ptypes->obj_at(0);
if (java_lang_Class::is_instance(ptype0))
receiver_limit_result = java_lang_Class::as_klassOop(ptype0);
@@ -199,18 +199,18 @@
// (MemberName is the non-operational name used for queries and setup.)
methodOop MethodHandles::decode_DirectMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) {
- oop vmtarget = sun_dyn_DirectMethodHandle::vmtarget(mh);
- int vmindex = sun_dyn_DirectMethodHandle::vmindex(mh);
- oop mtype = sun_dyn_DirectMethodHandle::type(mh);
+ oop vmtarget = java_lang_invoke_DirectMethodHandle::vmtarget(mh);
+ int vmindex = java_lang_invoke_DirectMethodHandle::vmindex(mh);
+ oop mtype = java_lang_invoke_DirectMethodHandle::type(mh);
return decode_vmtarget(vmtarget, vmindex, mtype, receiver_limit_result, decode_flags_result);
}
methodOop MethodHandles::decode_BoundMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) {
- assert(sun_dyn_BoundMethodHandle::is_instance(mh), "");
+ assert(java_lang_invoke_BoundMethodHandle::is_instance(mh), "");
assert(mh->klass() != SystemDictionary::AdapterMethodHandle_klass(), "");
for (oop bmh = mh;;) {
// Bound MHs can be stacked to bind several arguments.
- oop target = java_dyn_MethodHandle::vmtarget(bmh);
+ oop target = java_lang_invoke_MethodHandle::vmtarget(bmh);
if (target == NULL) return NULL;
decode_flags_result |= MethodHandles::_dmf_binds_argument;
klassOop tk = target->klass();
@@ -218,7 +218,7 @@
bmh = target;
continue;
} else {
- if (java_dyn_MethodHandle::is_subclass(tk)) {
+ if (java_lang_invoke_MethodHandle::is_subclass(tk)) {
//assert(tk == SystemDictionary::DirectMethodHandle_klass(), "end of BMH chain must be DMH");
return decode_MethodHandle(target, receiver_limit_result, decode_flags_result);
} else {
@@ -240,9 +240,9 @@
assert(mh->klass() == SystemDictionary::AdapterMethodHandle_klass(), "");
for (oop amh = mh;;) {
// Adapter MHs can be stacked to convert several arguments.
- int conv_op = adapter_conversion_op(sun_dyn_AdapterMethodHandle::conversion(amh));
+ int conv_op = adapter_conversion_op(java_lang_invoke_AdapterMethodHandle::conversion(amh));
decode_flags_result |= (_dmf_adapter_lsb << conv_op) & _DMF_ADAPTER_MASK;
- oop target = java_dyn_MethodHandle::vmtarget(amh);
+ oop target = java_lang_invoke_MethodHandle::vmtarget(amh);
if (target == NULL) return NULL;
klassOop tk = target->klass();
if (tk == SystemDictionary::AdapterMethodHandle_klass()) {
@@ -258,14 +258,14 @@
methodOop MethodHandles::decode_MethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) {
if (mh == NULL) return NULL;
klassOop mhk = mh->klass();
- assert(java_dyn_MethodHandle::is_subclass(mhk), "must be a MethodHandle");
+ assert(java_lang_invoke_MethodHandle::is_subclass(mhk), "must be a MethodHandle");
if (mhk == SystemDictionary::DirectMethodHandle_klass()) {
return decode_DirectMethodHandle(mh, receiver_limit_result, decode_flags_result);
} else if (mhk == SystemDictionary::BoundMethodHandle_klass()) {
return decode_BoundMethodHandle(mh, receiver_limit_result, decode_flags_result);
} else if (mhk == SystemDictionary::AdapterMethodHandle_klass()) {
return decode_AdapterMethodHandle(mh, receiver_limit_result, decode_flags_result);
- } else if (sun_dyn_BoundMethodHandle::is_subclass(mhk)) {
+ } else if (java_lang_invoke_BoundMethodHandle::is_subclass(mhk)) {
// could be a JavaMethodHandle (but not an adapter MH)
return decode_BoundMethodHandle(mh, receiver_limit_result, decode_flags_result);
} else {
@@ -308,7 +308,7 @@
} else if (xk == SystemDictionary::MemberName_klass()) {
// Note: This only works if the MemberName has already been resolved.
return decode_MemberName(x, receiver_limit_result, decode_flags_result);
- } else if (java_dyn_MethodHandle::is_subclass(xk)) {
+ } else if (java_lang_invoke_MethodHandle::is_subclass(xk)) {
return decode_MethodHandle(x, receiver_limit_result, decode_flags_result);
} else if (xk == SystemDictionary::reflect_Method_klass()) {
oop clazz = java_lang_reflect_Method::clazz(x);
@@ -327,7 +327,7 @@
} else {
// unrecognized object
assert(!x->is_method(), "already checked");
- assert(!sun_dyn_MemberName::is_instance(x), "already checked");
+ assert(!java_lang_invoke_MemberName::is_instance(x), "already checked");
}
return NULL;
}
@@ -336,15 +336,15 @@
int MethodHandles::decode_MethodHandle_stack_pushes(oop mh) {
if (mh->klass() == SystemDictionary::DirectMethodHandle_klass())
return 0; // no push/pop
- int this_vmslots = java_dyn_MethodHandle::vmslots(mh);
+ int this_vmslots = java_lang_invoke_MethodHandle::vmslots(mh);
int last_vmslots = 0;
oop last_mh = mh;
for (;;) {
- oop target = java_dyn_MethodHandle::vmtarget(last_mh);
+ oop target = java_lang_invoke_MethodHandle::vmtarget(last_mh);
if (target->klass() == SystemDictionary::DirectMethodHandle_klass()) {
- last_vmslots = java_dyn_MethodHandle::vmslots(target);
+ last_vmslots = java_lang_invoke_MethodHandle::vmslots(target);
break;
- } else if (!java_dyn_MethodHandle::is_instance(target)) {
+ } else if (!java_lang_invoke_MethodHandle::is_instance(target)) {
// might be klass or method
assert(target->is_method(), "must get here with a direct ref to method");
last_vmslots = methodOop(target)->size_of_parameters();
@@ -361,16 +361,16 @@
// MemberName support
-// import sun_dyn_MemberName.*
+// import java_lang_invoke_MemberName.*
enum {
- IS_METHOD = sun_dyn_MemberName::MN_IS_METHOD,
- IS_CONSTRUCTOR = sun_dyn_MemberName::MN_IS_CONSTRUCTOR,
- IS_FIELD = sun_dyn_MemberName::MN_IS_FIELD,
- IS_TYPE = sun_dyn_MemberName::MN_IS_TYPE,
- SEARCH_SUPERCLASSES = sun_dyn_MemberName::MN_SEARCH_SUPERCLASSES,
- SEARCH_INTERFACES = sun_dyn_MemberName::MN_SEARCH_INTERFACES,
+ IS_METHOD = java_lang_invoke_MemberName::MN_IS_METHOD,
+ IS_CONSTRUCTOR = java_lang_invoke_MemberName::MN_IS_CONSTRUCTOR,
+ IS_FIELD = java_lang_invoke_MemberName::MN_IS_FIELD,
+ IS_TYPE = java_lang_invoke_MemberName::MN_IS_TYPE,
+ SEARCH_SUPERCLASSES = java_lang_invoke_MemberName::MN_SEARCH_SUPERCLASSES,
+ SEARCH_INTERFACES = java_lang_invoke_MemberName::MN_SEARCH_INTERFACES,
ALL_KINDS = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE,
- VM_INDEX_UNINITIALIZED = sun_dyn_MemberName::VM_INDEX_UNINITIALIZED
+ VM_INDEX_UNINITIALIZED = java_lang_invoke_MemberName::VM_INDEX_UNINITIALIZED
};
Handle MethodHandles::new_MemberName(TRAPS) {
@@ -405,10 +405,10 @@
if (!do_dispatch || (flags & IS_CONSTRUCTOR) || m->can_be_statically_bound())
vmindex = methodOopDesc::nonvirtual_vtable_index; // implies never any dispatch
assert(vmindex != VM_INDEX_UNINITIALIZED, "Java sentinel value");
- sun_dyn_MemberName::set_vmtarget(mname_oop, vmtarget);
- sun_dyn_MemberName::set_vmindex(mname_oop, vmindex);
- sun_dyn_MemberName::set_flags(mname_oop, flags);
- sun_dyn_MemberName::set_clazz(mname_oop, Klass::cast(m->method_holder())->java_mirror());
+ java_lang_invoke_MemberName::set_vmtarget(mname_oop, vmtarget);
+ java_lang_invoke_MemberName::set_vmindex(mname_oop, vmindex);
+ java_lang_invoke_MemberName::set_flags(mname_oop, flags);
+ java_lang_invoke_MemberName::set_clazz(mname_oop, Klass::cast(m->method_holder())->java_mirror());
}
void MethodHandles::init_MemberName(oop mname_oop, klassOop field_holder, AccessFlags mods, int offset) {
@@ -416,21 +416,21 @@
oop vmtarget = field_holder;
int vmindex = offset; // determines the field uniquely when combined with static bit
assert(vmindex != VM_INDEX_UNINITIALIZED, "bad alias on vmindex");
- sun_dyn_MemberName::set_vmtarget(mname_oop, vmtarget);
- sun_dyn_MemberName::set_vmindex(mname_oop, vmindex);
- sun_dyn_MemberName::set_flags(mname_oop, flags);
- sun_dyn_MemberName::set_clazz(mname_oop, Klass::cast(field_holder)->java_mirror());
+ java_lang_invoke_MemberName::set_vmtarget(mname_oop, vmtarget);
+ java_lang_invoke_MemberName::set_vmindex(mname_oop, vmindex);
+ java_lang_invoke_MemberName::set_flags(mname_oop, flags);
+ java_lang_invoke_MemberName::set_clazz(mname_oop, Klass::cast(field_holder)->java_mirror());
}
methodOop MethodHandles::decode_MemberName(oop mname, klassOop& receiver_limit_result, int& decode_flags_result) {
- int flags = sun_dyn_MemberName::flags(mname);
+ int flags = java_lang_invoke_MemberName::flags(mname);
if ((flags & (IS_METHOD | IS_CONSTRUCTOR)) == 0) return NULL; // not invocable
- oop vmtarget = sun_dyn_MemberName::vmtarget(mname);
- int vmindex = sun_dyn_MemberName::vmindex(mname);
+ oop vmtarget = java_lang_invoke_MemberName::vmtarget(mname);
+ int vmindex = java_lang_invoke_MemberName::vmindex(mname);
if (vmindex == VM_INDEX_UNINITIALIZED) return NULL; // not resolved
methodOop m = decode_vmtarget(vmtarget, vmindex, NULL, receiver_limit_result, decode_flags_result);
- oop clazz = sun_dyn_MemberName::clazz(mname);
+ oop clazz = java_lang_invoke_MemberName::clazz(mname);
if (clazz != NULL && java_lang_Class::is_instance(clazz)) {
klassOop klass = java_lang_Class::as_klassOop(clazz);
if (klass != NULL) receiver_limit_result = klass;
@@ -442,8 +442,8 @@
Symbol* MethodHandles::convert_to_signature(oop type_str,
bool polymorphic,
TRAPS) {
- if (java_dyn_MethodType::is_instance(type_str)) {
- return java_dyn_MethodType::as_signature(type_str, polymorphic, CHECK_NULL);
+ if (java_lang_invoke_MethodType::is_instance(type_str)) {
+ return java_lang_invoke_MethodType::as_signature(type_str, polymorphic, CHECK_NULL);
} else if (java_lang_Class::is_instance(type_str)) {
return java_lang_Class::as_signature(type_str, false, CHECK_NULL);
} else if (java_lang_String::is_instance(type_str)) {
@@ -461,7 +461,7 @@
// Resolving it plants a vmtarget/vmindex in it,
// which refers dirctly to JVM internals.
void MethodHandles::resolve_MemberName(Handle mname, TRAPS) {
- assert(sun_dyn_MemberName::is_instance(mname()), "");
+ assert(java_lang_invoke_MemberName::is_instance(mname()), "");
#ifdef ASSERT
// If this assert throws, renegotiate the sentinel value used by the Java code,
// so that it is distinct from any valid vtable index value, and any special
@@ -472,12 +472,12 @@
const int sentinel_limit = methodOopDesc::highest_unused_vtable_index_value - sentinel_slop;
assert(VM_INDEX_UNINITIALIZED < sentinel_limit, "Java sentinel != JVM sentinels");
#endif
- if (sun_dyn_MemberName::vmindex(mname()) != VM_INDEX_UNINITIALIZED)
+ if (java_lang_invoke_MemberName::vmindex(mname()) != VM_INDEX_UNINITIALIZED)
return; // already resolved
- oop defc_oop = sun_dyn_MemberName::clazz(mname());
- oop name_str = sun_dyn_MemberName::name(mname());
- oop type_str = sun_dyn_MemberName::type(mname());
- int flags = sun_dyn_MemberName::flags(mname());
+ oop defc_oop = java_lang_invoke_MemberName::clazz(mname());
+ oop name_str = java_lang_invoke_MemberName::name(mname());
+ oop type_str = java_lang_invoke_MemberName::type(mname());
+ int flags = java_lang_invoke_MemberName::flags(mname());
if (defc_oop == NULL || name_str == NULL || type_str == NULL) {
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "nothing to resolve");
@@ -510,7 +510,7 @@
// convert the external string or reflective type to an internal signature
TempNewSymbol type = convert_to_signature(type_str, polymorphic_signature, CHECK);
- if (java_dyn_MethodType::is_instance(type_str) && polymorphic_signature) {
+ if (java_lang_invoke_MethodType::is_instance(type_str) && polymorphic_signature) {
polymorphic_method_type = Handle(THREAD, type_str); //preserve exactly
}
@@ -557,9 +557,9 @@
vmtarget = result.resolved_klass()->as_klassOop();
}
int mods = (m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS);
- sun_dyn_MemberName::set_vmtarget(mname(), vmtarget);
- sun_dyn_MemberName::set_vmindex(mname(), vmindex);
- sun_dyn_MemberName::set_modifiers(mname(), mods);
+ java_lang_invoke_MemberName::set_vmtarget(mname(), vmtarget);
+ java_lang_invoke_MemberName::set_vmindex(mname(), vmindex);
+ java_lang_invoke_MemberName::set_modifiers(mname(), mods);
DEBUG_ONLY(int junk; klassOop junk2);
assert(decode_MemberName(mname(), junk2, junk) == result.resolved_method()(),
"properly stored for later decoding");
@@ -586,9 +586,9 @@
oop vmtarget = m();
int vmindex = methodOopDesc::nonvirtual_vtable_index;
int mods = (m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS);
- sun_dyn_MemberName::set_vmtarget(mname(), vmtarget);
- sun_dyn_MemberName::set_vmindex(mname(), vmindex);
- sun_dyn_MemberName::set_modifiers(mname(), mods);
+ java_lang_invoke_MemberName::set_vmtarget(mname(), vmtarget);
+ java_lang_invoke_MemberName::set_vmindex(mname(), vmindex);
+ java_lang_invoke_MemberName::set_modifiers(mname(), mods);
DEBUG_ONLY(int junk; klassOop junk2);
assert(decode_MemberName(mname(), junk2, junk) == result.resolved_method()(),
"properly stored for later decoding");
@@ -605,9 +605,9 @@
int vmindex = fd.offset();
int mods = (fd.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS);
if (vmindex == VM_INDEX_UNINITIALIZED) break; // should not happen
- sun_dyn_MemberName::set_vmtarget(mname(), vmtarget);
- sun_dyn_MemberName::set_vmindex(mname(), vmindex);
- sun_dyn_MemberName::set_modifiers(mname(), mods);
+ java_lang_invoke_MemberName::set_vmtarget(mname(), vmtarget);
+ java_lang_invoke_MemberName::set_vmindex(mname(), vmindex);
+ java_lang_invoke_MemberName::set_modifiers(mname(), mods);
return;
}
default:
@@ -618,11 +618,11 @@
if (polymorphic_method_type.not_null()) {
// Look on a non-null class loader.
Handle cur_class_loader;
- const int nptypes = java_dyn_MethodType::ptype_count(polymorphic_method_type());
+ const int nptypes = java_lang_invoke_MethodType::ptype_count(polymorphic_method_type());
for (int i = 0; i <= nptypes; i++) {
oop type_mirror;
- if (i < nptypes) type_mirror = java_dyn_MethodType::ptype(polymorphic_method_type(), i);
- else type_mirror = java_dyn_MethodType::rtype(polymorphic_method_type());
+ if (i < nptypes) type_mirror = java_lang_invoke_MethodType::ptype(polymorphic_method_type(), i);
+ else type_mirror = java_lang_invoke_MethodType::rtype(polymorphic_method_type());
klassOop example_type = java_lang_Class::as_klassOop(type_mirror);
if (example_type == NULL) continue;
oop class_loader = Klass::cast(example_type)->class_loader();
@@ -639,9 +639,9 @@
}
if (m != NULL) {
int mods = (m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS);
- sun_dyn_MemberName::set_vmtarget(mname(), m);
- sun_dyn_MemberName::set_vmindex(mname(), m->vtable_index());
- sun_dyn_MemberName::set_modifiers(mname(), mods);
+ java_lang_invoke_MemberName::set_vmtarget(mname(), m);
+ java_lang_invoke_MemberName::set_vmindex(mname(), m->vtable_index());
+ java_lang_invoke_MemberName::set_modifiers(mname(), mods);
return;
}
}
@@ -653,17 +653,17 @@
// Resolving it plants a vmtarget/vmindex in it,
// which refers directly to JVM internals.
void MethodHandles::expand_MemberName(Handle mname, int suppress, TRAPS) {
- assert(sun_dyn_MemberName::is_instance(mname()), "");
- oop vmtarget = sun_dyn_MemberName::vmtarget(mname());
- int vmindex = sun_dyn_MemberName::vmindex(mname());
+ assert(java_lang_invoke_MemberName::is_instance(mname()), "");
+ oop vmtarget = java_lang_invoke_MemberName::vmtarget(mname());
+ int vmindex = java_lang_invoke_MemberName::vmindex(mname());
if (vmtarget == NULL || vmindex == VM_INDEX_UNINITIALIZED) {
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "nothing to expand");
}
- bool have_defc = (sun_dyn_MemberName::clazz(mname()) != NULL);
- bool have_name = (sun_dyn_MemberName::name(mname()) != NULL);
- bool have_type = (sun_dyn_MemberName::type(mname()) != NULL);
- int flags = sun_dyn_MemberName::flags(mname());
+ bool have_defc = (java_lang_invoke_MemberName::clazz(mname()) != NULL);
+ bool have_name = (java_lang_invoke_MemberName::name(mname()) != NULL);
+ bool have_type = (java_lang_invoke_MemberName::type(mname()) != NULL);
+ int flags = java_lang_invoke_MemberName::flags(mname());
if (suppress != 0) {
if (suppress & _suppress_defc) have_defc = true;
@@ -687,16 +687,16 @@
if (receiver_limit != NULL && receiver_limit != defc
&& Klass::cast(receiver_limit)->is_subtype_of(defc))
defc = receiver_limit;
- sun_dyn_MemberName::set_clazz(mname(), Klass::cast(defc)->java_mirror());
+ java_lang_invoke_MemberName::set_clazz(mname(), Klass::cast(defc)->java_mirror());
}
if (!have_name) {
//not java_lang_String::create_from_symbol; let's intern member names
Handle name = StringTable::intern(m->name(), CHECK);
- sun_dyn_MemberName::set_name(mname(), name());
+ java_lang_invoke_MemberName::set_name(mname(), name());
}
if (!have_type) {
Handle type = java_lang_String::create_from_symbol(m->signature(), CHECK);
- sun_dyn_MemberName::set_type(mname(), type());
+ java_lang_invoke_MemberName::set_type(mname(), type());
}
return;
}
@@ -711,16 +711,16 @@
if (!defc->find_field_from_offset(vmindex, is_static, &fd))
break; // cannot expand
if (!have_defc) {
- sun_dyn_MemberName::set_clazz(mname(), defc->java_mirror());
+ java_lang_invoke_MemberName::set_clazz(mname(), defc->java_mirror());
}
if (!have_name) {
//not java_lang_String::create_from_symbol; let's intern member names
Handle name = StringTable::intern(fd.name(), CHECK);
- sun_dyn_MemberName::set_name(mname(), name());
+ java_lang_invoke_MemberName::set_name(mname(), name());
}
if (!have_type) {
Handle type = java_lang_String::create_from_symbol(fd.signature(), CHECK);
- sun_dyn_MemberName::set_type(mname(), type());
+ java_lang_invoke_MemberName::set_type(mname(), type());
}
return;
}
@@ -775,7 +775,7 @@
--rskip;
} else if (rfill < rlimit) {
oop result = results->obj_at(rfill++);
- if (!sun_dyn_MemberName::is_instance(result))
+ if (!java_lang_invoke_MemberName::is_instance(result))
return -99; // caller bug!
MethodHandles::init_MemberName(result, st.klass()->as_klassOop(), st.access_flags(), st.offset());
} else if (++overflow >= overflow_limit) {
@@ -823,7 +823,7 @@
--rskip;
} else if (rfill < rlimit) {
oop result = results->obj_at(rfill++);
- if (!sun_dyn_MemberName::is_instance(result))
+ if (!java_lang_invoke_MemberName::is_instance(result))
return -99; // caller bug!
MethodHandles::init_MemberName(result, m, true);
} else if (++overflow >= overflow_limit) {
@@ -857,9 +857,9 @@
// Sanitize out methodOops, klassOops, and any other non-Java data.
// This is for debugging and reflection.
oop MethodHandles::encode_target(Handle mh, int format, TRAPS) {
- assert(java_dyn_MethodHandle::is_instance(mh()), "must be a MH");
+ assert(java_lang_invoke_MethodHandle::is_instance(mh()), "must be a MH");
if (format == ETF_HANDLE_OR_METHOD_NAME) {
- oop target = java_dyn_MethodHandle::vmtarget(mh());
+ oop target = java_lang_invoke_MethodHandle::vmtarget(mh());
if (target == NULL) {
return NULL; // unformed MH
}
@@ -874,10 +874,10 @@
if (target->klass() == SystemDictionary::DirectMethodHandle_klass()) {
return target;
}
- if (!java_dyn_MethodHandle::is_instance(target)){
+ if (!java_lang_invoke_MethodHandle::is_instance(target)){
return NULL; // unformed MH
}
- target = java_dyn_MethodHandle::vmtarget(target);
+ target = java_lang_invoke_MethodHandle::vmtarget(target);
}
}
// cases of metadata in MH.vmtarget:
@@ -904,7 +904,7 @@
instanceKlassHandle mname_klass(THREAD, SystemDictionary::MemberName_klass());
mname_klass->initialize(CHECK_NULL);
Handle mname = mname_klass->allocate_instance_handle(CHECK_NULL);
- sun_dyn_MemberName::set_vmindex(mname(), VM_INDEX_UNINITIALIZED);
+ java_lang_invoke_MemberName::set_vmindex(mname(), VM_INDEX_UNINITIALIZED);
bool do_dispatch = ((decode_flags & MethodHandles::_dmf_does_dispatch) != 0);
init_MemberName(mname(), m, do_dispatch);
expand_MemberName(mname, 0, CHECK_NULL);
@@ -923,6 +923,7 @@
"java/lang/Null",
//"java/lang/Nothing",
"sun/dyn/empty/Empty",
+ "sun/invoke/empty/Empty",
NULL
};
@@ -1025,7 +1026,7 @@
int first_ptype_pos,
KlassHandle insert_ptype,
TRAPS) {
- objArrayHandle ptypes(THREAD, java_dyn_MethodType::ptypes(mtype()));
+ objArrayHandle ptypes(THREAD, java_lang_invoke_MethodType::ptypes(mtype()));
int pnum = first_ptype_pos;
int pmax = ptypes->length();
int mnum = 0; // method argument
@@ -1036,7 +1037,7 @@
if (ss.at_return_type()) {
if (pnum != pmax)
{ err = "too many arguments"; break; }
- ptype_oop = java_dyn_MethodType::rtype(mtype());
+ ptype_oop = java_lang_invoke_MethodType::rtype(mtype());
} else {
if (pnum >= pmax)
{ err = "not enough arguments"; break; }
@@ -1111,7 +1112,7 @@
}
if (m_needs_receiver && err == NULL) {
- objArrayOop ptypes = java_dyn_MethodType::ptypes(mtype());
+ objArrayOop ptypes = java_lang_invoke_MethodType::ptypes(mtype());
if (ptypes->length() < first_ptype_pos)
{ err = "receiver argument is missing"; goto die; }
if (has_bound_recv)
@@ -1131,15 +1132,15 @@
void MethodHandles::verify_vmslots(Handle mh, TRAPS) {
// Verify vmslots.
- int check_slots = argument_slot_count(java_dyn_MethodHandle::type(mh()));
- if (java_dyn_MethodHandle::vmslots(mh()) != check_slots) {
+ int check_slots = argument_slot_count(java_lang_invoke_MethodHandle::type(mh()));
+ if (java_lang_invoke_MethodHandle::vmslots(mh()) != check_slots) {
THROW_MSG(vmSymbols::java_lang_InternalError(), "bad vmslots in BMH");
}
}
void MethodHandles::verify_vmargslot(Handle mh, int argnum, int argslot, TRAPS) {
// Verify that argslot points at the given argnum.
- int check_slot = argument_slot(java_dyn_MethodHandle::type(mh()), argnum);
+ int check_slot = argument_slot(java_lang_invoke_MethodHandle::type(mh()), argnum);
if (argslot != check_slot || argslot < 0) {
const char* fmt = "for argnum of %d, vmargslot is %d, should be %d";
size_t msglen = strlen(fmt) + 3*11 + 1;
@@ -1160,8 +1161,8 @@
int delete_argnum,
oop dst_mtype, int dst_beg, int dst_end,
bool raw) {
- objArrayOop src_ptypes = java_dyn_MethodType::ptypes(src_mtype);
- objArrayOop dst_ptypes = java_dyn_MethodType::ptypes(dst_mtype);
+ objArrayOop src_ptypes = java_lang_invoke_MethodType::ptypes(src_mtype);
+ objArrayOop dst_ptypes = java_lang_invoke_MethodType::ptypes(dst_mtype);
int src_max = src_ptypes->length();
int dst_max = dst_ptypes->length();
@@ -1224,8 +1225,8 @@
}
// Now compare return types also.
- oop src_rtype = java_dyn_MethodType::rtype(src_mtype);
- oop dst_rtype = java_dyn_MethodType::rtype(dst_mtype);
+ oop src_rtype = java_lang_invoke_MethodType::rtype(src_mtype);
+ oop dst_rtype = java_lang_invoke_MethodType::rtype(dst_mtype);
if (src_rtype != dst_rtype) {
err = check_return_type_change(dst_rtype, src_rtype, raw); // note reversal!
if (err != NULL) return err;
@@ -1314,7 +1315,7 @@
// then return a negative number. Otherwise, the result
// is in the range [0..vmslots] inclusive.
int MethodHandles::argument_slot(oop method_type, int arg) {
- objArrayOop ptypes = java_dyn_MethodType::ptypes(method_type);
+ objArrayOop ptypes = java_lang_invoke_MethodType::ptypes(method_type);
int argslot = 0;
int len = ptypes->length();
if (arg < -1 || arg >= len) return -99;
@@ -1328,7 +1329,7 @@
// Given a slot number, return the argument number.
int MethodHandles::argument_slot_to_argnum(oop method_type, int query_argslot) {
- objArrayOop ptypes = java_dyn_MethodType::ptypes(method_type);
+ objArrayOop ptypes = java_lang_invoke_MethodType::ptypes(method_type);
int argslot = 0;
int len = ptypes->length();
for (int i = len-1; i >= 0; i--) {
@@ -1394,11 +1395,11 @@
void MethodHandles::verify_DirectMethodHandle(Handle mh, methodHandle m, TRAPS) {
// Verify type.
- Handle mtype(THREAD, java_dyn_MethodHandle::type(mh()));
+ Handle mtype(THREAD, java_lang_invoke_MethodHandle::type(mh()));
verify_method_type(m, mtype, false, KlassHandle(), CHECK);
// Verify vmslots.
- if (java_dyn_MethodHandle::vmslots(mh()) != m->size_of_parameters()) {
+ if (java_lang_invoke_MethodHandle::vmslots(mh()) != m->size_of_parameters()) {
THROW_MSG(vmSymbols::java_lang_InternalError(), "bad vmslots in DMH");
}
}
@@ -1410,7 +1411,7 @@
THROW(vmSymbols::java_lang_InternalError());
}
- java_dyn_MethodHandle::init_vmslots(mh());
+ java_lang_invoke_MethodHandle::init_vmslots(mh());
if (VerifyMethodHandles) {
// The privileged code which invokes this routine should not make
@@ -1470,8 +1471,8 @@
if (me == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
- sun_dyn_DirectMethodHandle::set_vmtarget(mh(), vmtarget);
- sun_dyn_DirectMethodHandle::set_vmindex(mh(), vmindex);
+ java_lang_invoke_DirectMethodHandle::set_vmtarget(mh(), vmtarget);
+ java_lang_invoke_DirectMethodHandle::set_vmindex(mh(), vmindex);
DEBUG_ONLY(int flags; klassOop rlimit);
assert(MethodHandles::decode_method(mh(), rlimit, flags) == m(),
"properly stored for later decoding");
@@ -1482,15 +1483,15 @@
assert(decode_MethodHandle_stack_pushes(mh()) == 0, "DMH does not move stack");
// Done!
- java_dyn_MethodHandle::set_vmentry(mh(), me);
+ java_lang_invoke_MethodHandle::set_vmentry(mh(), me);
}
void MethodHandles::verify_BoundMethodHandle_with_receiver(Handle mh,
methodHandle m,
TRAPS) {
// Verify type.
- oop receiver = sun_dyn_BoundMethodHandle::argument(mh());
- Handle mtype(THREAD, java_dyn_MethodHandle::type(mh()));
+ oop receiver = java_lang_invoke_BoundMethodHandle::argument(mh());
+ Handle mtype(THREAD, java_lang_invoke_MethodHandle::type(mh()));
KlassHandle bound_recv_type;
if (receiver != NULL) bound_recv_type = KlassHandle(THREAD, receiver->klass());
verify_method_type(m, mtype, true, bound_recv_type, CHECK);
@@ -1498,11 +1499,11 @@
int receiver_pos = m->size_of_parameters() - 1;
// Verify MH.vmargslot, which should point at the bound receiver.
- verify_vmargslot(mh, -1, sun_dyn_BoundMethodHandle::vmargslot(mh()), CHECK);
+ verify_vmargslot(mh, -1, java_lang_invoke_BoundMethodHandle::vmargslot(mh()), CHECK);
//verify_vmslots(mh, CHECK);
// Verify vmslots.
- if (java_dyn_MethodHandle::vmslots(mh()) != receiver_pos) {
+ if (java_lang_invoke_MethodHandle::vmslots(mh()) != receiver_pos) {
THROW_MSG(vmSymbols::java_lang_InternalError(), "bad vmslots in BMH (receiver)");
}
}
@@ -1520,7 +1521,7 @@
KlassHandle receiver_klass;
{
- oop receiver_oop = sun_dyn_BoundMethodHandle::argument(mh());
+ oop receiver_oop = java_lang_invoke_BoundMethodHandle::argument(mh());
if (receiver_oop != NULL)
receiver_klass = KlassHandle(THREAD, receiver_oop->klass());
}
@@ -1531,31 +1532,31 @@
if (m.is_null()) { THROW(vmSymbols::java_lang_InternalError()); }
if (m->is_abstract()) { THROW(vmSymbols::java_lang_AbstractMethodError()); }
- java_dyn_MethodHandle::init_vmslots(mh());
+ java_lang_invoke_MethodHandle::init_vmslots(mh());
if (VerifyMethodHandles) {
verify_BoundMethodHandle_with_receiver(mh, m, CHECK);
}
- sun_dyn_BoundMethodHandle::set_vmtarget(mh(), m());
+ java_lang_invoke_BoundMethodHandle::set_vmtarget(mh(), m());
DEBUG_ONLY(int junk; klassOop junk2);
assert(MethodHandles::decode_method(mh(), junk2, junk) == m(), "properly stored for later decoding");
assert(decode_MethodHandle_stack_pushes(mh()) == 1, "BMH pushes one stack slot");
// Done!
- java_dyn_MethodHandle::set_vmentry(mh(), MethodHandles::entry(MethodHandles::_bound_ref_direct_mh));
+ java_lang_invoke_MethodHandle::set_vmentry(mh(), MethodHandles::entry(MethodHandles::_bound_ref_direct_mh));
}
void MethodHandles::verify_BoundMethodHandle(Handle mh, Handle target, int argnum,
bool direct_to_method, TRAPS) {
Handle ptype_handle(THREAD,
- java_dyn_MethodType::ptype(java_dyn_MethodHandle::type(target()), argnum));
+ java_lang_invoke_MethodType::ptype(java_lang_invoke_MethodHandle::type(target()), argnum));
KlassHandle ptype_klass;
BasicType ptype = java_lang_Class::as_BasicType(ptype_handle(), &ptype_klass);
int slots_pushed = type2size[ptype];
- oop argument = sun_dyn_BoundMethodHandle::argument(mh());
+ oop argument = java_lang_invoke_BoundMethodHandle::argument(mh());
const char* err = NULL;
@@ -1623,9 +1624,9 @@
if (err == NULL) {
// Verify the rest of the method type.
- err = check_method_type_insertion(java_dyn_MethodHandle::type(mh()),
+ err = check_method_type_insertion(java_lang_invoke_MethodHandle::type(mh()),
argnum, ptype_handle(),
- java_dyn_MethodHandle::type(target()));
+ java_lang_invoke_MethodHandle::type(target()));
}
if (err != NULL) {
@@ -1635,20 +1636,20 @@
void MethodHandles::init_BoundMethodHandle(Handle mh, Handle target, int argnum, TRAPS) {
// Check arguments.
- if (mh.is_null() || target.is_null() || !java_dyn_MethodHandle::is_instance(target())) {
+ if (mh.is_null() || target.is_null() || !java_lang_invoke_MethodHandle::is_instance(target())) {
THROW(vmSymbols::java_lang_InternalError());
}
- java_dyn_MethodHandle::init_vmslots(mh());
+ java_lang_invoke_MethodHandle::init_vmslots(mh());
if (VerifyMethodHandles) {
int insert_after = argnum - 1;
- verify_vmargslot(mh, insert_after, sun_dyn_BoundMethodHandle::vmargslot(mh()), CHECK);
+ verify_vmargslot(mh, insert_after, java_lang_invoke_BoundMethodHandle::vmargslot(mh()), CHECK);
verify_vmslots(mh, CHECK);
}
// Get bound type and required slots.
- oop ptype_oop = java_dyn_MethodType::ptype(java_dyn_MethodHandle::type(target()), argnum);
+ oop ptype_oop = java_lang_invoke_MethodType::ptype(java_lang_invoke_MethodHandle::type(target()), argnum);
BasicType ptype = java_lang_Class::as_BasicType(ptype_oop);
int slots_pushed = type2size[ptype];
@@ -1659,12 +1660,12 @@
bool direct_to_method = false;
if (OptimizeMethodHandles &&
target->klass() == SystemDictionary::DirectMethodHandle_klass() &&
- (argnum == 0 || sun_dyn_DirectMethodHandle::vmindex(target()) < 0)) {
+ (argnum == 0 || java_lang_invoke_DirectMethodHandle::vmindex(target()) < 0)) {
int decode_flags = 0; klassOop receiver_limit_oop = NULL;
methodHandle m(THREAD, decode_method(target(), receiver_limit_oop, decode_flags));
if (m.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "DMH failed to decode"); }
DEBUG_ONLY(int m_vmslots = m->size_of_parameters() - slots_pushed); // pos. of 1st arg.
- assert(sun_dyn_BoundMethodHandle::vmslots(mh()) == m_vmslots, "type w/ m sig");
+ assert(java_lang_invoke_BoundMethodHandle::vmslots(mh()) == m_vmslots, "type w/ m sig");
if (argnum == 0 && (decode_flags & _dmf_has_receiver) != 0) {
KlassHandle receiver_limit(THREAD, receiver_limit_oop);
init_BoundMethodHandle_with_receiver(mh, m,
@@ -1677,11 +1678,11 @@
// to bind another argument and still invoke the methodOop directly.
if (!(decode_flags & _dmf_does_dispatch)) {
direct_to_method = true;
- sun_dyn_BoundMethodHandle::set_vmtarget(mh(), m());
+ java_lang_invoke_BoundMethodHandle::set_vmtarget(mh(), m());
}
}
if (!direct_to_method)
- sun_dyn_BoundMethodHandle::set_vmtarget(mh(), target());
+ java_lang_invoke_BoundMethodHandle::set_vmtarget(mh(), target());
if (VerifyMethodHandles) {
verify_BoundMethodHandle(mh, target, argnum, direct_to_method, CHECK);
@@ -1703,7 +1704,7 @@
}
// Done!
- java_dyn_MethodHandle::set_vmentry(mh(), me);
+ java_lang_invoke_MethodHandle::set_vmentry(mh(), me);
}
static void throw_InternalError_for_bad_conversion(int conversion, const char* err, TRAPS) {
@@ -1713,8 +1714,8 @@
}
void MethodHandles::verify_AdapterMethodHandle(Handle mh, int argnum, TRAPS) {
- jint conversion = sun_dyn_AdapterMethodHandle::conversion(mh());
- int argslot = sun_dyn_AdapterMethodHandle::vmargslot(mh());
+ jint conversion = java_lang_invoke_AdapterMethodHandle::conversion(mh());
+ int argslot = java_lang_invoke_AdapterMethodHandle::vmargslot(mh());
verify_vmargslot(mh, argnum, argslot, CHECK);
verify_vmslots(mh, CHECK);
@@ -1731,10 +1732,10 @@
BasicType dest = adapter_conversion_dest_type(conversion);
int vminfo = adapter_conversion_vminfo(conversion); // should be zero
- Handle argument(THREAD, sun_dyn_AdapterMethodHandle::argument(mh()));
- Handle target(THREAD, sun_dyn_AdapterMethodHandle::vmtarget(mh()));
- Handle src_mtype(THREAD, java_dyn_MethodHandle::type(mh()));
- Handle dst_mtype(THREAD, java_dyn_MethodHandle::type(target()));
+ Handle argument(THREAD, java_lang_invoke_AdapterMethodHandle::argument(mh()));
+ Handle target(THREAD, java_lang_invoke_AdapterMethodHandle::vmtarget(mh()));
+ Handle src_mtype(THREAD, java_lang_invoke_MethodHandle::type(mh()));
+ Handle dst_mtype(THREAD, java_lang_invoke_MethodHandle::type(target()));
const char* err = NULL;
@@ -1760,7 +1761,7 @@
break;
case _adapter_flyby:
case _adapter_ricochet:
- if (!java_dyn_MethodHandle::is_instance(argument()))
+ if (!java_lang_invoke_MethodHandle::is_instance(argument()))
{ err = "MethodHandle adapter argument required"; break; }
break;
default:
@@ -1806,9 +1807,9 @@
err = "adapter requires src/dest conversion subfields for swap"; break;
}
int swap_size = type2size[src];
- oop src_mtype = sun_dyn_AdapterMethodHandle::type(mh());
- oop dest_mtype = sun_dyn_AdapterMethodHandle::type(target());
- int slot_limit = sun_dyn_AdapterMethodHandle::vmslots(target());
+ oop src_mtype = java_lang_invoke_AdapterMethodHandle::type(mh());
+ oop dest_mtype = java_lang_invoke_AdapterMethodHandle::type(target());
+ int slot_limit = java_lang_invoke_AdapterMethodHandle::vmslots(target());
int src_slot = argslot;
int dest_slot = vminfo;
bool rotate_up = (src_slot > dest_slot); // upward rotation
@@ -1821,8 +1822,8 @@
} else if (ek == _adapter_swap_args && !(src_slot > dest_slot)) {
err = "source of swap must be deeper in stack";
} else if (ek == _adapter_swap_args) {
- err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype, dest_arg),
- java_dyn_MethodType::ptype(dest_mtype, src_arg),
+ err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype, dest_arg),
+ java_lang_invoke_MethodType::ptype(dest_mtype, src_arg),
dest_arg);
} else if (ek == _adapter_rot_args) {
if (rotate_up) {
@@ -1830,8 +1831,8 @@
// rotate up: [dest_slot..src_slot-ss] --> [dest_slot+ss..src_slot]
// that is: [src_arg+1..dest_arg] --> [src_arg..dest_arg-1]
for (int i = src_arg+1; i <= dest_arg && err == NULL; i++) {
- err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype, i),
- java_dyn_MethodType::ptype(dest_mtype, i-1),
+ err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype, i),
+ java_lang_invoke_MethodType::ptype(dest_mtype, i-1),
i);
}
} else { // rotate down
@@ -1839,15 +1840,15 @@
// rotate down: [src_slot+ss..dest_slot] --> [src_slot..dest_slot-ss]
// that is: [dest_arg..src_arg-1] --> [dst_arg+1..src_arg]
for (int i = dest_arg; i <= src_arg-1 && err == NULL; i++) {
- err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype, i),
- java_dyn_MethodType::ptype(dest_mtype, i+1),
+ err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype, i),
+ java_lang_invoke_MethodType::ptype(dest_mtype, i+1),
i);
}
}
}
if (err == NULL)
- err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype, src_arg),
- java_dyn_MethodType::ptype(dest_mtype, dest_arg),
+ err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype, src_arg),
+ java_lang_invoke_MethodType::ptype(dest_mtype, dest_arg),
src_arg);
}
break;
@@ -1918,8 +1919,8 @@
if (err == NULL) {
// Make sure this adapter does not push too deeply.
int slots_pushed = stack_move / stack_move_unit();
- int this_vmslots = java_dyn_MethodHandle::vmslots(mh());
- int target_vmslots = java_dyn_MethodHandle::vmslots(target());
+ int this_vmslots = java_lang_invoke_MethodHandle::vmslots(mh());
+ int target_vmslots = java_lang_invoke_MethodHandle::vmslots(target());
if (slots_pushed != (target_vmslots - this_vmslots)) {
err = "stack_move inconsistent with previous and current MethodType vmslots";
} else if (slots_pushed > 0) {
@@ -1961,7 +1962,7 @@
case _adapter_check_cast:
{
// The actual value being checked must be a reference:
- err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype(), argnum),
+ err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), argnum),
object_java_mirror(), argnum);
if (err != NULL) break;
@@ -1985,9 +1986,9 @@
}
void MethodHandles::init_AdapterMethodHandle(Handle mh, Handle target, int argnum, TRAPS) {
- oop argument = sun_dyn_AdapterMethodHandle::argument(mh());
- int argslot = sun_dyn_AdapterMethodHandle::vmargslot(mh());
- jint conversion = sun_dyn_AdapterMethodHandle::conversion(mh());
+ oop argument = java_lang_invoke_AdapterMethodHandle::argument(mh());
+ int argslot = java_lang_invoke_AdapterMethodHandle::vmargslot(mh());
+ jint conversion = java_lang_invoke_AdapterMethodHandle::conversion(mh());
jint conv_op = adapter_conversion_op(conversion);
// adjust the adapter code to the internal EntryKind enumeration:
@@ -1995,11 +1996,11 @@
EntryKind ek_opt = ek_orig; // may be optimized
// Finalize the vmtarget field (Java initialized it to null).
- if (!java_dyn_MethodHandle::is_instance(target())) {
+ if (!java_lang_invoke_MethodHandle::is_instance(target())) {
throw_InternalError_for_bad_conversion(conversion, "bad target", THREAD);
return;
}
- sun_dyn_AdapterMethodHandle::set_vmtarget(mh(), target());
+ java_lang_invoke_AdapterMethodHandle::set_vmtarget(mh(), target());
if (VerifyMethodHandles) {
verify_AdapterMethodHandle(mh, argnum, CHECK);
@@ -2083,7 +2084,7 @@
case _adapter_rot_args:
{
int swap_slots = type2size[src];
- int slot_limit = sun_dyn_AdapterMethodHandle::vmslots(mh());
+ int slot_limit = java_lang_invoke_AdapterMethodHandle::vmslots(mh());
int src_slot = argslot;
int dest_slot = vminfo;
int rotate = (ek_orig == _adapter_swap_args) ? 0 : (src_slot > dest_slot) ? 1 : -1;
@@ -2147,10 +2148,10 @@
jint new_conversion = adapter_conversion(conv_op, src, dest, stack_move, vminfo);
// Finalize the conversion field. (Note that it is final to Java code.)
- sun_dyn_AdapterMethodHandle::set_conversion(mh(), new_conversion);
+ java_lang_invoke_AdapterMethodHandle::set_conversion(mh(), new_conversion);
// Done!
- java_dyn_MethodHandle::set_vmentry(mh(), entry(ek_opt));
+ java_lang_invoke_MethodHandle::set_vmentry(mh(), entry(ek_opt));
// There should be enough memory barriers on exit from native methods
// to ensure that the MH is fully initialized to all threads before
@@ -2158,7 +2159,7 @@
}
//
-// Here are the native methods on sun.dyn.MethodHandleImpl.
+// Here are the native methods on sun.invoke.MethodHandleImpl.
// They are the private interface between this JVM and the HotSpot-specific
// Java code that implements JSR 292 method handles.
//
@@ -2168,7 +2169,7 @@
// direct method handles for invokestatic or invokespecial
// void init(DirectMethodHandle self, MemberName ref, boolean doDispatch, Class<?> caller);
-JVM_ENTRY(void, MHI_init_DMH(JNIEnv *env, jobject igcls, jobject mh_jh,
+JVM_ENTRY(void, MHN_init_DMH(JNIEnv *env, jobject igcls, jobject mh_jh,
jobject target_jh, jboolean do_dispatch, jobject caller_jh)) {
ResourceMark rm; // for error messages
@@ -2177,13 +2178,13 @@
Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh));
// Early returns out of this method leave the DMH in an unfinished state.
- assert(java_dyn_MethodHandle::vmentry(mh()) == NULL, "must be safely null");
+ assert(java_lang_invoke_MethodHandle::vmentry(mh()) == NULL, "must be safely null");
// which method are we really talking about?
if (target_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
oop target_oop = JNIHandles::resolve_non_null(target_jh);
- if (sun_dyn_MemberName::is_instance(target_oop) &&
- sun_dyn_MemberName::vmindex(target_oop) == VM_INDEX_UNINITIALIZED) {
+ if (java_lang_invoke_MemberName::is_instance(target_oop) &&
+ java_lang_invoke_MemberName::vmindex(target_oop) == VM_INDEX_UNINITIALIZED) {
Handle mname(THREAD, target_oop);
MethodHandles::resolve_MemberName(mname, CHECK);
target_oop = mname(); // in case of GC
@@ -2232,7 +2233,7 @@
JVM_END
// bound method handles
-JVM_ENTRY(void, MHI_init_BMH(JNIEnv *env, jobject igcls, jobject mh_jh,
+JVM_ENTRY(void, MHN_init_BMH(JNIEnv *env, jobject igcls, jobject mh_jh,
jobject target_jh, int argnum)) {
ResourceMark rm; // for error messages
@@ -2241,12 +2242,12 @@
Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh));
// Early returns out of this method leave the BMH in an unfinished state.
- assert(java_dyn_MethodHandle::vmentry(mh()) == NULL, "must be safely null");
+ assert(java_lang_invoke_MethodHandle::vmentry(mh()) == NULL, "must be safely null");
if (target_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
Handle target(THREAD, JNIHandles::resolve_non_null(target_jh));
- if (!java_dyn_MethodHandle::is_instance(target())) {
+ if (!java_lang_invoke_MethodHandle::is_instance(target())) {
// Target object is a reflective method. (%%% Do we need this alternate path?)
Untested("init_BMH of non-MH");
if (argnum != 0) { THROW(vmSymbols::java_lang_InternalError()); }
@@ -2269,7 +2270,7 @@
JVM_END
// adapter method handles
-JVM_ENTRY(void, MHI_init_AMH(JNIEnv *env, jobject igcls, jobject mh_jh,
+JVM_ENTRY(void, MHN_init_AMH(JNIEnv *env, jobject igcls, jobject mh_jh,
jobject target_jh, int argnum)) {
// This is the guy we are initializing:
if (mh_jh == NULL || target_jh == NULL) {
@@ -2279,14 +2280,14 @@
Handle target(THREAD, JNIHandles::resolve_non_null(target_jh));
// Early returns out of this method leave the AMH in an unfinished state.
- assert(java_dyn_MethodHandle::vmentry(mh()) == NULL, "must be safely null");
+ assert(java_lang_invoke_MethodHandle::vmentry(mh()) == NULL, "must be safely null");
MethodHandles::init_AdapterMethodHandle(mh, target, argnum, CHECK);
}
JVM_END
// method type forms
-JVM_ENTRY(void, MHI_init_MT(JNIEnv *env, jobject igcls, jobject erased_jh)) {
+JVM_ENTRY(void, MHN_init_MT(JNIEnv *env, jobject igcls, jobject erased_jh)) {
if (erased_jh == NULL) return;
if (TraceMethodHandles) {
tty->print("creating MethodType form ");
@@ -2307,9 +2308,9 @@
JVM_END
// debugging and reflection
-JVM_ENTRY(jobject, MHI_getTarget(JNIEnv *env, jobject igcls, jobject mh_jh, jint format)) {
+JVM_ENTRY(jobject, MHN_getTarget(JNIEnv *env, jobject igcls, jobject mh_jh, jint format)) {
Handle mh(THREAD, JNIHandles::resolve(mh_jh));
- if (!java_dyn_MethodHandle::is_instance(mh())) {
+ if (!java_lang_invoke_MethodHandle::is_instance(mh())) {
THROW_NULL(vmSymbols::java_lang_IllegalArgumentException());
}
oop target = MethodHandles::encode_target(mh, format, CHECK_NULL);
@@ -2317,7 +2318,7 @@
}
JVM_END
-JVM_ENTRY(jint, MHI_getConstant(JNIEnv *env, jobject igcls, jint which)) {
+JVM_ENTRY(jint, MHN_getConstant(JNIEnv *env, jobject igcls, jint which)) {
switch (which) {
case MethodHandles::GC_JVM_PUSH_LIMIT:
guarantee(MethodHandlePushLimit >= 2 && MethodHandlePushLimit <= 0xFF,
@@ -2341,36 +2342,36 @@
template(MethodHandles,ETF_DIRECT_HANDLE) \
template(MethodHandles,ETF_METHOD_NAME) \
template(MethodHandles,ETF_REFLECT_METHOD) \
- template(sun_dyn_MemberName,MN_IS_METHOD) \
- template(sun_dyn_MemberName,MN_IS_CONSTRUCTOR) \
- template(sun_dyn_MemberName,MN_IS_FIELD) \
- template(sun_dyn_MemberName,MN_IS_TYPE) \
- template(sun_dyn_MemberName,MN_SEARCH_SUPERCLASSES) \
- template(sun_dyn_MemberName,MN_SEARCH_INTERFACES) \
- template(sun_dyn_MemberName,VM_INDEX_UNINITIALIZED) \
- template(sun_dyn_AdapterMethodHandle,OP_RETYPE_ONLY) \
- template(sun_dyn_AdapterMethodHandle,OP_RETYPE_RAW) \
- template(sun_dyn_AdapterMethodHandle,OP_CHECK_CAST) \
- template(sun_dyn_AdapterMethodHandle,OP_PRIM_TO_PRIM) \
- template(sun_dyn_AdapterMethodHandle,OP_REF_TO_PRIM) \
- template(sun_dyn_AdapterMethodHandle,OP_PRIM_TO_REF) \
- template(sun_dyn_AdapterMethodHandle,OP_SWAP_ARGS) \
- template(sun_dyn_AdapterMethodHandle,OP_ROT_ARGS) \
- template(sun_dyn_AdapterMethodHandle,OP_DUP_ARGS) \
- template(sun_dyn_AdapterMethodHandle,OP_DROP_ARGS) \
- template(sun_dyn_AdapterMethodHandle,OP_COLLECT_ARGS) \
- template(sun_dyn_AdapterMethodHandle,OP_SPREAD_ARGS) \
- template(sun_dyn_AdapterMethodHandle,OP_FLYBY) \
- template(sun_dyn_AdapterMethodHandle,OP_RICOCHET) \
- template(sun_dyn_AdapterMethodHandle,CONV_OP_LIMIT) \
- template(sun_dyn_AdapterMethodHandle,CONV_OP_MASK) \
- template(sun_dyn_AdapterMethodHandle,CONV_VMINFO_MASK) \
- template(sun_dyn_AdapterMethodHandle,CONV_VMINFO_SHIFT) \
- template(sun_dyn_AdapterMethodHandle,CONV_OP_SHIFT) \
- template(sun_dyn_AdapterMethodHandle,CONV_DEST_TYPE_SHIFT) \
- template(sun_dyn_AdapterMethodHandle,CONV_SRC_TYPE_SHIFT) \
- template(sun_dyn_AdapterMethodHandle,CONV_STACK_MOVE_SHIFT) \
- template(sun_dyn_AdapterMethodHandle,CONV_STACK_MOVE_MASK) \
+ template(java_lang_invoke_MemberName,MN_IS_METHOD) \
+ template(java_lang_invoke_MemberName,MN_IS_CONSTRUCTOR) \
+ template(java_lang_invoke_MemberName,MN_IS_FIELD) \
+ template(java_lang_invoke_MemberName,MN_IS_TYPE) \
+ template(java_lang_invoke_MemberName,MN_SEARCH_SUPERCLASSES) \
+ template(java_lang_invoke_MemberName,MN_SEARCH_INTERFACES) \
+ template(java_lang_invoke_MemberName,VM_INDEX_UNINITIALIZED) \
+ template(java_lang_invoke_AdapterMethodHandle,OP_RETYPE_ONLY) \
+ template(java_lang_invoke_AdapterMethodHandle,OP_RETYPE_RAW) \
+ template(java_lang_invoke_AdapterMethodHandle,OP_CHECK_CAST) \
+ template(java_lang_invoke_AdapterMethodHandle,OP_PRIM_TO_PRIM) \
+ template(java_lang_invoke_AdapterMethodHandle,OP_REF_TO_PRIM) \
+ template(java_lang_invoke_AdapterMethodHandle,OP_PRIM_TO_REF) \
+ template(java_lang_invoke_AdapterMethodHandle,OP_SWAP_ARGS) \
+ template(java_lang_invoke_AdapterMethodHandle,OP_ROT_ARGS) \
+ template(java_lang_invoke_AdapterMethodHandle,OP_DUP_ARGS) \
+ template(java_lang_invoke_AdapterMethodHandle,OP_DROP_ARGS) \
+ template(java_lang_invoke_AdapterMethodHandle,OP_COLLECT_ARGS) \
+ template(java_lang_invoke_AdapterMethodHandle,OP_SPREAD_ARGS) \
+ template(java_lang_invoke_AdapterMethodHandle,OP_FLYBY) \
+ template(java_lang_invoke_AdapterMethodHandle,OP_RICOCHET) \
+ template(java_lang_invoke_AdapterMethodHandle,CONV_OP_LIMIT) \
+ template(java_lang_invoke_AdapterMethodHandle,CONV_OP_MASK) \
+ template(java_lang_invoke_AdapterMethodHandle,CONV_VMINFO_MASK) \
+ template(java_lang_invoke_AdapterMethodHandle,CONV_VMINFO_SHIFT) \
+ template(java_lang_invoke_AdapterMethodHandle,CONV_OP_SHIFT) \
+ template(java_lang_invoke_AdapterMethodHandle,CONV_DEST_TYPE_SHIFT) \
+ template(java_lang_invoke_AdapterMethodHandle,CONV_SRC_TYPE_SHIFT) \
+ template(java_lang_invoke_AdapterMethodHandle,CONV_STACK_MOVE_SHIFT) \
+ template(java_lang_invoke_AdapterMethodHandle,CONV_STACK_MOVE_MASK) \
/*end*/
#define ONE_PLUS(scope,value) 1+
@@ -2386,7 +2387,7 @@
#undef EACH_NAMED_CON
#endif
-JVM_ENTRY(jint, MHI_getNamedCon(JNIEnv *env, jobject igcls, jint which, jobjectArray box_jh)) {
+JVM_ENTRY(jint, MHN_getNamedCon(JNIEnv *env, jobject igcls, jint which, jobjectArray box_jh)) {
#ifndef PRODUCT
if (which >= 0 && which < con_value_count) {
int con = con_values[which];
@@ -2406,7 +2407,7 @@
JVM_END
// void init(MemberName self, AccessibleObject ref)
-JVM_ENTRY(void, MHI_init_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jobject target_jh)) {
+JVM_ENTRY(void, MHN_init_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jobject target_jh)) {
if (mname_jh == NULL || target_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
oop target_oop = JNIHandles::resolve_non_null(target_jh);
@@ -2415,7 +2416,7 @@
JVM_END
// void expand(MemberName self)
-JVM_ENTRY(void, MHI_expand_Mem(JNIEnv *env, jobject igcls, jobject mname_jh)) {
+JVM_ENTRY(void, MHN_expand_Mem(JNIEnv *env, jobject igcls, jobject mname_jh)) {
if (mname_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
MethodHandles::expand_MemberName(mname, 0, CHECK);
@@ -2423,14 +2424,14 @@
JVM_END
// void resolve(MemberName self, Class<?> caller)
-JVM_ENTRY(void, MHI_resolve_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jclass caller_jh)) {
+JVM_ENTRY(void, MHN_resolve_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jclass caller_jh)) {
if (mname_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
// The trusted Java code that calls this method should already have performed
// access checks on behalf of the given caller. But, we can verify this.
if (VerifyMethodHandles && caller_jh != NULL) {
- klassOop reference_klass = java_lang_Class::as_klassOop(sun_dyn_MemberName::clazz(mname()));
+ klassOop reference_klass = java_lang_Class::as_klassOop(java_lang_invoke_MemberName::clazz(mname()));
if (reference_klass != NULL) {
// Emulate LinkResolver::check_klass_accessability.
klassOop caller = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(caller_jh));
@@ -2448,7 +2449,7 @@
// static native int getMembers(Class<?> defc, String matchName, String matchSig,
// int matchFlags, Class<?> caller, int skip, MemberName[] results);
-JVM_ENTRY(jint, MHI_getMembers(JNIEnv *env, jobject igcls,
+JVM_ENTRY(jint, MHN_getMembers(JNIEnv *env, jobject igcls,
jclass clazz_jh, jstring name_jh, jstring sig_jh,
int mflags, jclass caller_jh, jint skip, jobjectArray results_jh)) {
if (clazz_jh == NULL || results_jh == NULL) return -1;
@@ -2487,14 +2488,14 @@
}
JVM_END
-JVM_ENTRY(void, MHI_registerBootstrap(JNIEnv *env, jobject igcls, jclass caller_jh, jobject bsm_jh)) {
+JVM_ENTRY(void, MHN_registerBootstrap(JNIEnv *env, jobject igcls, jclass caller_jh, jobject bsm_jh)) {
instanceKlassHandle ik = MethodHandles::resolve_instance_klass(caller_jh, THREAD);
if (!AllowTransitionalJSR292) {
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
"registerBootstrapMethod is only supported in JSR 292 EDR");
}
ik->link_class(CHECK);
- if (!java_dyn_MethodHandle::is_instance(JNIHandles::resolve(bsm_jh))) {
+ if (!java_lang_invoke_MethodHandle::is_instance(JNIHandles::resolve(bsm_jh))) {
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "method handle");
}
const char* err = NULL;
@@ -2522,29 +2523,28 @@
}
JVM_END
-JVM_ENTRY(jobject, MHI_getBootstrap(JNIEnv *env, jobject igcls, jclass caller_jh)) {
+JVM_ENTRY(jobject, MHN_getBootstrap(JNIEnv *env, jobject igcls, jclass caller_jh)) {
+ if (!AllowTransitionalJSR292)
+ THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), "getBootstrap: transitional only");
instanceKlassHandle ik = MethodHandles::resolve_instance_klass(caller_jh, THREAD);
return JNIHandles::make_local(THREAD, ik->bootstrap_method());
}
JVM_END
-JVM_ENTRY(void, MHI_setCallSiteTarget(JNIEnv *env, jobject igcls, jobject site_jh, jobject target_jh)) {
- // No special action required, yet.
- oop site_oop = JNIHandles::resolve(site_jh);
- if (!java_dyn_CallSite::is_instance(site_oop))
- THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "not a CallSite");
- java_dyn_CallSite::set_target(site_oop, JNIHandles::resolve(target_jh));
+JVM_ENTRY(void, MHN_setCallSiteTarget(JNIEnv *env, jobject igcls, jobject site_jh, jobject target_jh)) {
+ if (!AllowTransitionalJSR292)
+ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "setCallSite: transitional only");
}
JVM_END
/// JVM_RegisterMethodHandleMethods
-#define ADR "J"
-
#define LANG "Ljava/lang/"
-#define JDYN "Ljava/dyn/"
-#define IDYN "Lsun/dyn/"
+#define JLINV "Ljava/lang/invoke/" /* standard package */
+#define JDYN "Ljava/dyn/" /* alternative package to JLINV if AllowTransitionalJSR292 */
+#define IDYN "Lsun/dyn/" /* alternative package to JDYN if AllowTransitionalJSR292 */
+// FIXME: After AllowTransitionalJSR292 is removed, replace JDYN and IDYN by JLINV.
#define OBJ LANG"Object;"
#define CLS LANG"Class;"
@@ -2552,7 +2552,6 @@
#define CST JDYN"CallSite;"
#define MT JDYN"MethodType;"
#define MH JDYN"MethodHandle;"
-#define MHI IDYN"MethodHandleImpl;"
#define MEM IDYN"MemberName;"
#define AMH IDYN"AdapterMethodHandle;"
#define BMH IDYN"BoundMethodHandle;"
@@ -2561,32 +2560,58 @@
#define CC (char*) /*cast a literal from (const char*)*/
#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
-// These are the native methods on sun.dyn.MethodHandleNatives.
+// These are the native methods on sun.invoke.MethodHandleNatives.
static JNINativeMethod methods[] = {
// void init(MemberName self, AccessibleObject ref)
- {CC"init", CC"("AMH""MH"I)V", FN_PTR(MHI_init_AMH)},
- {CC"init", CC"("BMH""OBJ"I)V", FN_PTR(MHI_init_BMH)},
- {CC"init", CC"("DMH""OBJ"Z"CLS")V", FN_PTR(MHI_init_DMH)},
- {CC"init", CC"("MT")V", FN_PTR(MHI_init_MT)},
- {CC"init", CC"("MEM""OBJ")V", FN_PTR(MHI_init_Mem)},
- {CC"expand", CC"("MEM")V", FN_PTR(MHI_expand_Mem)},
- {CC"resolve", CC"("MEM""CLS")V", FN_PTR(MHI_resolve_Mem)},
- {CC"getTarget", CC"("MH"I)"OBJ, FN_PTR(MHI_getTarget)},
- {CC"getConstant", CC"(I)I", FN_PTR(MHI_getConstant)},
+ {CC"init", CC"("AMH""MH"I)V", FN_PTR(MHN_init_AMH)},
+ {CC"init", CC"("BMH""OBJ"I)V", FN_PTR(MHN_init_BMH)},
+ {CC"init", CC"("DMH""OBJ"Z"CLS")V", FN_PTR(MHN_init_DMH)},
+ {CC"init", CC"("MT")V", FN_PTR(MHN_init_MT)},
+ {CC"init", CC"("MEM""OBJ")V", FN_PTR(MHN_init_Mem)},
+ {CC"expand", CC"("MEM")V", FN_PTR(MHN_expand_Mem)},
+ {CC"resolve", CC"("MEM""CLS")V", FN_PTR(MHN_resolve_Mem)},
+ {CC"getTarget", CC"("MH"I)"OBJ, FN_PTR(MHN_getTarget)},
+ {CC"getConstant", CC"(I)I", FN_PTR(MHN_getConstant)},
// static native int getNamedCon(int which, Object[] name)
- {CC"getNamedCon", CC"(I["OBJ")I", FN_PTR(MHI_getNamedCon)},
+ {CC"getNamedCon", CC"(I["OBJ")I", FN_PTR(MHN_getNamedCon)},
// static native int getMembers(Class<?> defc, String matchName, String matchSig,
// int matchFlags, Class<?> caller, int skip, MemberName[] results);
- {CC"getMembers", CC"("CLS""STRG""STRG"I"CLS"I["MEM")I", FN_PTR(MHI_getMembers)}
+ {CC"getMembers", CC"("CLS""STRG""STRG"I"CLS"I["MEM")I", FN_PTR(MHN_getMembers)}
};
// More entry points specifically for EnableInvokeDynamic.
+// FIXME: Remove methods2 after AllowTransitionalJSR292 is removed.
static JNINativeMethod methods2[] = {
- {CC"registerBootstrap", CC"("CLS MH")V", FN_PTR(MHI_registerBootstrap)},
- {CC"getBootstrap", CC"("CLS")"MH, FN_PTR(MHI_getBootstrap)},
- {CC"setCallSiteTarget", CC"("CST MH")V", FN_PTR(MHI_setCallSiteTarget)}
+ {CC"registerBootstrap", CC"("CLS MH")V", FN_PTR(MHN_registerBootstrap)},
+ {CC"getBootstrap", CC"("CLS")"MH, FN_PTR(MHN_getBootstrap)},
+ {CC"setCallSiteTarget", CC"("CST MH")V", FN_PTR(MHN_setCallSiteTarget)}
};
+static void hack_signatures(JNINativeMethod* methods, jint num_methods, const char* from_sig, const char* to_sig) {
+ for (int i = 0; i < num_methods; i++) {
+ const char* sig = methods[i].signature;
+ if (!strstr(sig, from_sig)) continue;
+ size_t buflen = strlen(sig) + 100;
+ char* buf = NEW_C_HEAP_ARRAY(char, buflen);
+ char* bufp = buf;
+ const char* sigp = sig;
+ size_t from_len = strlen(from_sig), to_len = strlen(to_sig);
+ while (*sigp != '\0') {
+ assert(bufp < buf + buflen - to_len - 1, "oob");
+ if (strncmp(sigp, from_sig, from_len) != 0) {
+ *bufp++ = *sigp++;
+ } else {
+ strcpy(bufp, to_sig);
+ bufp += to_len;
+ sigp += from_len;
+ }
+ }
+ *bufp = '\0';
+ methods[i].signature = buf; // replace with new signature
+ if (TraceMethodHandles)
+ tty->print_cr("MethodHandleNatives: %s: change signature %s => %s", methods[i].name, sig, buf);
+ }
+}
// This one function is exported, used by NativeLookup.
@@ -2600,45 +2625,78 @@
return; // bind nothing
}
+ if (SystemDictionary::MethodHandleNatives_klass() != NULL &&
+ SystemDictionary::MethodHandleNatives_klass() != java_lang_Class::as_klassOop(JNIHandles::resolve(MHN_class))) {
+ warning("multiple versions of MethodHandleNatives in boot classpath; consider using -XX:+PreferTransitionalJSR292");
+ THROW_MSG(vmSymbols::java_lang_InternalError(), "multiple versions of MethodHandleNatives in boot classpath; consider using -XX:+PreferTransitionalJSR292");
+ }
+
bool enable_MH = true;
- {
+ // Loop control. FIXME: Replace by dead reckoning after AllowTransitionalJSR292 is removed.
+ bool registered_natives = false;
+ bool try_plain = true, try_JDYN = true, try_IDYN = true;
+ for (;;) {
ThreadToNativeFromVM ttnfv(thread);
+ if (try_plain) { try_plain = false; }
+ else if (try_JDYN) { try_JDYN = false; hack_signatures(methods, sizeof(methods)/sizeof(JNINativeMethod), IDYN, JDYN); }
+ else if (try_IDYN) { try_IDYN = false; hack_signatures(methods, sizeof(methods)/sizeof(JNINativeMethod), JDYN, JLINV); }
+ else { break; }
int status = env->RegisterNatives(MHN_class, methods, sizeof(methods)/sizeof(JNINativeMethod));
if (env->ExceptionOccurred()) {
- MethodHandles::set_enabled(false);
- warning("JSR 292 method handle code is mismatched to this JVM. Disabling support.");
- enable_MH = false;
env->ExceptionClear();
+ // and try again...
+ } else {
+ registered_natives = true;
+ break;
}
}
+ if (!registered_natives) {
+ MethodHandles::set_enabled(false);
+ warning("JSR 292 method handle code is mismatched to this JVM. Disabling support.");
+ enable_MH = false;
+ }
if (enable_MH) {
+ bool found_raise_exception = false;
+ KlassHandle MHN_klass = SystemDictionaryHandles::MethodHandleNatives_klass();
KlassHandle MHI_klass = SystemDictionaryHandles::MethodHandleImpl_klass();
- if (MHI_klass.not_null()) {
+ // Loop control. FIXME: Replace by dead reckoning after AllowTransitionalJSR292 is removed.
+ bool try_MHN = true, try_MHI = AllowTransitionalJSR292;
+ for (;;) {
+ KlassHandle try_klass;
+ if (try_MHN) { try_MHN = false; try_klass = MHN_klass; }
+ else if (try_MHI) { try_MHI = false; try_klass = MHI_klass; }
+ else { break; }
+ if (try_klass.is_null()) continue;
TempNewSymbol raiseException_name = SymbolTable::new_symbol("raiseException", CHECK);
TempNewSymbol raiseException_sig = SymbolTable::new_symbol("(ILjava/lang/Object;Ljava/lang/Object;)V", CHECK);
- methodOop raiseException_method = instanceKlass::cast(MHI_klass->as_klassOop())
+ methodOop raiseException_method = instanceKlass::cast(try_klass->as_klassOop())
->find_method(raiseException_name, raiseException_sig);
if (raiseException_method != NULL && raiseException_method->is_static()) {
MethodHandles::set_raise_exception_method(raiseException_method);
- } else {
- warning("JSR 292 method handle code is mismatched to this JVM. Disabling support.");
- enable_MH = false;
+ found_raise_exception = true;
+ break;
}
- } else {
+ }
+ if (!found_raise_exception) {
+ warning("JSR 292 method handle code is mismatched to this JVM. Disabling support.");
enable_MH = false;
}
}
if (enable_MH) {
- // We need to link the MethodHandleImpl klass before we generate
- // the method handle adapters as the _raise_exception adapter uses
- // one of its methods (and its c2i-adapter).
- KlassHandle k = SystemDictionaryHandles::MethodHandleImpl_klass();
- instanceKlass* ik = instanceKlass::cast(k());
- ik->link_class(CHECK);
+ if (AllowTransitionalJSR292) {
+ // We need to link the MethodHandleImpl klass before we generate
+ // the method handle adapters as the _raise_exception adapter uses
+ // one of its methods (and its c2i-adapter).
+ klassOop k = SystemDictionary::MethodHandleImpl_klass();
+ if (k != NULL) {
+ instanceKlass* ik = instanceKlass::cast(k);
+ ik->link_class(CHECK);
+ }
+ }
MethodHandles::generate_adapters();
MethodHandles::set_enabled(true);
@@ -2649,16 +2707,14 @@
return; // bind nothing
}
- {
+ if (AllowTransitionalJSR292) {
ThreadToNativeFromVM ttnfv(thread);
int status = env->RegisterNatives(MHN_class, methods2, sizeof(methods2)/sizeof(JNINativeMethod));
if (env->ExceptionOccurred()) {
- MethodHandles::set_enabled(false);
- warning("JSR 292 method handle code is mismatched to this JVM. Disabling support.");
+ // Don't do this, since it's too late:
+ // MethodHandles::set_enabled(false)
env->ExceptionClear();
- } else {
- MethodHandles::set_enabled(true);
}
}
}
--- a/hotspot/src/share/vm/prims/methodHandles.hpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/prims/methodHandles.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -37,8 +37,8 @@
class MethodHandles: AllStatic {
// JVM support for MethodHandle, MethodType, and related types
- // in java.dyn and java.dyn.hotspot.
- // See also javaClasses for layouts java_dyn_Method{Handle,Type,Type::Form}.
+ // in java.lang.invoke and sun.invoke.
+ // See also javaClasses for layouts java_lang_invoke_Method{Handle,Type,Type::Form}.
public:
enum EntryKind {
_raise_exception, // stub for error generation from other stubs
@@ -54,21 +54,21 @@
_bound_long_direct_mh,
_adapter_mh_first, // adapter sequence goes here...
- _adapter_retype_only = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_RETYPE_ONLY,
- _adapter_retype_raw = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_RETYPE_RAW,
- _adapter_check_cast = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_CHECK_CAST,
- _adapter_prim_to_prim = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_PRIM_TO_PRIM,
- _adapter_ref_to_prim = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_REF_TO_PRIM,
- _adapter_prim_to_ref = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_PRIM_TO_REF,
- _adapter_swap_args = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_SWAP_ARGS,
- _adapter_rot_args = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_ROT_ARGS,
- _adapter_dup_args = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_DUP_ARGS,
- _adapter_drop_args = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_DROP_ARGS,
- _adapter_collect_args = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_COLLECT_ARGS,
- _adapter_spread_args = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_SPREAD_ARGS,
- _adapter_flyby = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_FLYBY,
- _adapter_ricochet = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_RICOCHET,
- _adapter_mh_last = _adapter_mh_first + sun_dyn_AdapterMethodHandle::CONV_OP_LIMIT - 1,
+ _adapter_retype_only = _adapter_mh_first + java_lang_invoke_AdapterMethodHandle::OP_RETYPE_ONLY,
+ _adapter_retype_raw = _adapter_mh_first + java_lang_invoke_AdapterMethodHandle::OP_RETYPE_RAW,
+ _adapter_check_cast = _adapter_mh_first + java_lang_invoke_AdapterMethodHandle::OP_CHECK_CAST,
+ _adapter_prim_to_prim = _adapter_mh_first + java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_PRIM,
+ _adapter_ref_to_prim = _adapter_mh_first + java_lang_invoke_AdapterMethodHandle::OP_REF_TO_PRIM,
+ _adapter_prim_to_ref = _adapter_mh_first + java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_REF,
+ _adapter_swap_args = _adapter_mh_first + java_lang_invoke_AdapterMethodHandle::OP_SWAP_ARGS,
+ _adapter_rot_args = _adapter_mh_first + java_lang_invoke_AdapterMethodHandle::OP_ROT_ARGS,
+ _adapter_dup_args = _adapter_mh_first + java_lang_invoke_AdapterMethodHandle::OP_DUP_ARGS,
+ _adapter_drop_args = _adapter_mh_first + java_lang_invoke_AdapterMethodHandle::OP_DROP_ARGS,
+ _adapter_collect_args = _adapter_mh_first + java_lang_invoke_AdapterMethodHandle::OP_COLLECT_ARGS,
+ _adapter_spread_args = _adapter_mh_first + java_lang_invoke_AdapterMethodHandle::OP_SPREAD_ARGS,
+ _adapter_flyby = _adapter_mh_first + java_lang_invoke_AdapterMethodHandle::OP_FLYBY,
+ _adapter_ricochet = _adapter_mh_first + java_lang_invoke_AdapterMethodHandle::OP_RICOCHET,
+ _adapter_mh_last = _adapter_mh_first + java_lang_invoke_AdapterMethodHandle::CONV_OP_LIMIT - 1,
// Optimized adapter types
@@ -107,16 +107,16 @@
static void set_enabled(bool z);
private:
- enum { // import sun_dyn_AdapterMethodHandle::CONV_OP_*
- CONV_OP_LIMIT = sun_dyn_AdapterMethodHandle::CONV_OP_LIMIT,
- CONV_OP_MASK = sun_dyn_AdapterMethodHandle::CONV_OP_MASK,
- CONV_VMINFO_MASK = sun_dyn_AdapterMethodHandle::CONV_VMINFO_MASK,
- CONV_VMINFO_SHIFT = sun_dyn_AdapterMethodHandle::CONV_VMINFO_SHIFT,
- CONV_OP_SHIFT = sun_dyn_AdapterMethodHandle::CONV_OP_SHIFT,
- CONV_DEST_TYPE_SHIFT = sun_dyn_AdapterMethodHandle::CONV_DEST_TYPE_SHIFT,
- CONV_SRC_TYPE_SHIFT = sun_dyn_AdapterMethodHandle::CONV_SRC_TYPE_SHIFT,
- CONV_STACK_MOVE_SHIFT = sun_dyn_AdapterMethodHandle::CONV_STACK_MOVE_SHIFT,
- CONV_STACK_MOVE_MASK = sun_dyn_AdapterMethodHandle::CONV_STACK_MOVE_MASK
+ enum { // import java_lang_invoke_AdapterMethodHandle::CONV_OP_*
+ CONV_OP_LIMIT = java_lang_invoke_AdapterMethodHandle::CONV_OP_LIMIT,
+ CONV_OP_MASK = java_lang_invoke_AdapterMethodHandle::CONV_OP_MASK,
+ CONV_VMINFO_MASK = java_lang_invoke_AdapterMethodHandle::CONV_VMINFO_MASK,
+ CONV_VMINFO_SHIFT = java_lang_invoke_AdapterMethodHandle::CONV_VMINFO_SHIFT,
+ CONV_OP_SHIFT = java_lang_invoke_AdapterMethodHandle::CONV_OP_SHIFT,
+ CONV_DEST_TYPE_SHIFT = java_lang_invoke_AdapterMethodHandle::CONV_DEST_TYPE_SHIFT,
+ CONV_SRC_TYPE_SHIFT = java_lang_invoke_AdapterMethodHandle::CONV_SRC_TYPE_SHIFT,
+ CONV_STACK_MOVE_SHIFT = java_lang_invoke_AdapterMethodHandle::CONV_STACK_MOVE_SHIFT,
+ CONV_STACK_MOVE_MASK = java_lang_invoke_AdapterMethodHandle::CONV_STACK_MOVE_MASK
};
static bool _enabled;
@@ -471,7 +471,7 @@
};
-// Access methods for the "entry" field of a java.dyn.MethodHandle.
+// Access methods for the "entry" field of a java.lang.invoke.MethodHandle.
// The field is primarily a jump target for compiled calls.
// However, we squirrel away some nice pointers for other uses,
// just before the jump target.
--- a/hotspot/src/share/vm/prims/nativeLookup.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/prims/nativeLookup.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -107,29 +107,30 @@
void JNICALL JVM_RegisterPerfMethods(JNIEnv *env, jclass perfclass);
}
+#define CC (char*) /* cast a literal from (const char*) */
+#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
+
+static JNINativeMethod lookup_special_native_methods[] = {
+ // Next two functions only exist for compatibility with 1.3.1 and earlier.
+ { CC"Java_java_io_ObjectOutputStream_getPrimitiveFieldValues", NULL, FN_PTR(JVM_GetPrimitiveFieldValues) }, // intercept ObjectOutputStream getPrimitiveFieldValues for faster serialization
+ { CC"Java_java_io_ObjectInputStream_setPrimitiveFieldValues", NULL, FN_PTR(JVM_SetPrimitiveFieldValues) }, // intercept ObjectInputStream setPrimitiveFieldValues for faster serialization
+
+ { CC"Java_sun_misc_Unsafe_registerNatives", NULL, FN_PTR(JVM_RegisterUnsafeMethods) },
+ { CC"Java_java_lang_invoke_MethodHandleNatives_registerNatives", NULL, FN_PTR(JVM_RegisterMethodHandleMethods) },
+ { CC"Java_sun_dyn_MethodHandleNatives_registerNatives", NULL, FN_PTR(JVM_RegisterMethodHandleMethods) }, // AllowTransitionalJSR292
+ { CC"Java_java_dyn_MethodHandleNatives_registerNatives", NULL, FN_PTR(JVM_RegisterMethodHandleMethods) }, // AllowTransitionalJSR292
+ { CC"Java_sun_misc_Perf_registerNatives", NULL, FN_PTR(JVM_RegisterPerfMethods) }
+};
+
static address lookup_special_native(char* jni_name) {
- // NB: To ignore the jni prefix and jni postfix strstr is used matching.
- if (!JDK_Version::is_gte_jdk14x_version()) {
- // These functions only exist for compatibility with 1.3.1 and earlier
- // Intercept ObjectOutputStream getPrimitiveFieldValues for faster serialization
- if (strstr(jni_name, "Java_java_io_ObjectOutputStream_getPrimitiveFieldValues") != NULL) {
- return CAST_FROM_FN_PTR(address, JVM_GetPrimitiveFieldValues);
- }
- // Intercept ObjectInputStream setPrimitiveFieldValues for faster serialization
- if (strstr(jni_name, "Java_java_io_ObjectInputStream_setPrimitiveFieldValues") != NULL) {
- return CAST_FROM_FN_PTR(address, JVM_SetPrimitiveFieldValues);
+ int i = !JDK_Version::is_gte_jdk14x_version() ? 0 : 2; // see comment in lookup_special_native_methods
+ int count = sizeof(lookup_special_native_methods) / sizeof(JNINativeMethod);
+ for (; i < count; i++) {
+ // NB: To ignore the jni prefix and jni postfix strstr is used matching.
+ if (strstr(jni_name, lookup_special_native_methods[i].name) != NULL) {
+ return CAST_FROM_FN_PTR(address, lookup_special_native_methods[i].fnPtr);
}
}
- if (strstr(jni_name, "Java_sun_misc_Unsafe_registerNatives") != NULL) {
- return CAST_FROM_FN_PTR(address, JVM_RegisterUnsafeMethods);
- }
- if (strstr(jni_name, "Java_sun_dyn_MethodHandleNatives_registerNatives") != NULL) {
- return CAST_FROM_FN_PTR(address, JVM_RegisterMethodHandleMethods);
- }
- if (strstr(jni_name, "Java_sun_misc_Perf_registerNatives") != NULL) {
- return CAST_FROM_FN_PTR(address, JVM_RegisterPerfMethods);
- }
-
return NULL;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -0,0 +1,450 @@
+/*
+* Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved.
+* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+*/
+
+#include "precompiled.hpp"
+#include "runtime/advancedThresholdPolicy.hpp"
+#include "runtime/simpleThresholdPolicy.inline.hpp"
+
+#ifdef TIERED
+// Print an event.
+void AdvancedThresholdPolicy::print_specific(EventType type, methodHandle mh, methodHandle imh,
+ int bci, CompLevel level) {
+ tty->print(" rate: ");
+ if (mh->prev_time() == 0) tty->print("n/a");
+ else tty->print("%f", mh->rate());
+
+ tty->print(" k: %.2lf,%.2lf", threshold_scale(CompLevel_full_profile, Tier3LoadFeedback),
+ threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback));
+
+}
+
+void AdvancedThresholdPolicy::initialize() {
+ // Turn on ergonomic compiler count selection
+ if (FLAG_IS_DEFAULT(CICompilerCountPerCPU) && FLAG_IS_DEFAULT(CICompilerCount)) {
+ FLAG_SET_DEFAULT(CICompilerCountPerCPU, true);
+ }
+ int count = CICompilerCount;
+ if (CICompilerCountPerCPU) {
+ // Simple log n seems to grow too slowly for tiered, try something faster: log n * log log n
+ int log_cpu = log2_intptr(os::active_processor_count());
+ int loglog_cpu = log2_intptr(MAX2(log_cpu, 1));
+ count = MAX2(log_cpu * loglog_cpu, 1) * 3 / 2;
+ }
+
+ set_c1_count(MAX2(count / 3, 1));
+ set_c2_count(MAX2(count - count / 3, 1));
+
+ // Some inlining tuning
+#ifdef X86
+ if (FLAG_IS_DEFAULT(InlineSmallCode)) {
+ FLAG_SET_DEFAULT(InlineSmallCode, 2000);
+ }
+#endif
+
+#ifdef SPARC
+ if (FLAG_IS_DEFAULT(InlineSmallCode)) {
+ FLAG_SET_DEFAULT(InlineSmallCode, 2500);
+ }
+#endif
+
+
+ set_start_time(os::javaTimeMillis());
+}
+
+// update_rate() is called from select_task() while holding a compile queue lock.
+void AdvancedThresholdPolicy::update_rate(jlong t, methodOop m) {
+ if (is_old(m)) {
+ // We don't remove old methods from the queue,
+ // so we can just zero the rate.
+ m->set_rate(0);
+ return;
+ }
+
+ // We don't update the rate if we've just came out of a safepoint.
+ // delta_s is the time since last safepoint in milliseconds.
+ jlong delta_s = t - SafepointSynchronize::end_of_last_safepoint();
+ jlong delta_t = t - (m->prev_time() != 0 ? m->prev_time() : start_time()); // milliseconds since the last measurement
+ // How many events were there since the last time?
+ int event_count = m->invocation_count() + m->backedge_count();
+ int delta_e = event_count - m->prev_event_count();
+
+ // We should be running for at least 1ms.
+ if (delta_s >= TieredRateUpdateMinTime) {
+ // And we must've taken the previous point at least 1ms before.
+ if (delta_t >= TieredRateUpdateMinTime && delta_e > 0) {
+ m->set_prev_time(t);
+ m->set_prev_event_count(event_count);
+ m->set_rate((float)delta_e / (float)delta_t); // Rate is events per millisecond
+ } else
+ if (delta_t > TieredRateUpdateMaxTime && delta_e == 0) {
+ // If nothing happened for 25ms, zero the rate. Don't modify prev values.
+ m->set_rate(0);
+ }
+ }
+}
+
+// Check if this method has been stale from a given number of milliseconds.
+// See select_task().
+bool AdvancedThresholdPolicy::is_stale(jlong t, jlong timeout, methodOop m) {
+ jlong delta_s = t - SafepointSynchronize::end_of_last_safepoint();
+ jlong delta_t = t - m->prev_time();
+ if (delta_t > timeout && delta_s > timeout) {
+ int event_count = m->invocation_count() + m->backedge_count();
+ int delta_e = event_count - m->prev_event_count();
+ // Return true if there were no events.
+ return delta_e == 0;
+ }
+ return false;
+}
+
+// We don't remove old methods from the compile queue even if they have
+// very low activity. See select_task().
+bool AdvancedThresholdPolicy::is_old(methodOop method) {
+ return method->invocation_count() > 50000 || method->backedge_count() > 500000;
+}
+
+double AdvancedThresholdPolicy::weight(methodOop method) {
+ return (method->rate() + 1) * ((method->invocation_count() + 1) * (method->backedge_count() + 1));
+}
+
+// Apply heuristics and return true if x should be compiled before y
+bool AdvancedThresholdPolicy::compare_methods(methodOop x, methodOop y) {
+ if (x->highest_comp_level() > y->highest_comp_level()) {
+ // recompilation after deopt
+ return true;
+ } else
+ if (x->highest_comp_level() == y->highest_comp_level()) {
+ if (weight(x) > weight(y)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// Is method profiled enough?
+bool AdvancedThresholdPolicy::is_method_profiled(methodOop method) {
+ methodDataOop mdo = method->method_data();
+ if (mdo != NULL) {
+ int i = mdo->invocation_count_delta();
+ int b = mdo->backedge_count_delta();
+ return call_predicate_helper<CompLevel_full_profile>(i, b, 1);
+ }
+ return false;
+}
+
+// Called with the queue locked and with at least one element
+CompileTask* AdvancedThresholdPolicy::select_task(CompileQueue* compile_queue) {
+ CompileTask *max_task = NULL;
+ methodOop max_method;
+ jlong t = os::javaTimeMillis();
+ // Iterate through the queue and find a method with a maximum rate.
+ for (CompileTask* task = compile_queue->first(); task != NULL;) {
+ CompileTask* next_task = task->next();
+ methodOop method = (methodOop)JNIHandles::resolve(task->method_handle());
+ methodDataOop mdo = method->method_data();
+ update_rate(t, method);
+ if (max_task == NULL) {
+ max_task = task;
+ max_method = method;
+ } else {
+ // If a method has been stale for some time, remove it from the queue.
+ if (is_stale(t, TieredCompileTaskTimeout, method) && !is_old(method)) {
+ if (PrintTieredEvents) {
+ print_event(KILL, method, method, task->osr_bci(), (CompLevel)task->comp_level());
+ }
+ CompileTaskWrapper ctw(task); // Frees the task
+ compile_queue->remove(task);
+ method->clear_queued_for_compilation();
+ task = next_task;
+ continue;
+ }
+
+ // Select a method with a higher rate
+ if (compare_methods(method, max_method)) {
+ max_task = task;
+ max_method = method;
+ }
+ }
+ task = next_task;
+ }
+
+ if (max_task->comp_level() == CompLevel_full_profile && is_method_profiled(max_method)) {
+ max_task->set_comp_level(CompLevel_limited_profile);
+ if (PrintTieredEvents) {
+ print_event(UPDATE, max_method, max_method, max_task->osr_bci(), (CompLevel)max_task->comp_level());
+ }
+ }
+
+ return max_task;
+}
+
+double AdvancedThresholdPolicy::threshold_scale(CompLevel level, int feedback_k) {
+ double queue_size = CompileBroker::queue_size(level);
+ int comp_count = compiler_count(level);
+ double k = queue_size / (feedback_k * comp_count) + 1;
+ return k;
+}
+
+// Call and loop predicates determine whether a transition to a higher
+// compilation level should be performed (pointers to predicate functions
+// are passed to common()).
+// Tier?LoadFeedback is basically a coefficient that determines of
+// how many methods per compiler thread can be in the queue before
+// the threshold values double.
+bool AdvancedThresholdPolicy::loop_predicate(int i, int b, CompLevel cur_level) {
+ switch(cur_level) {
+ case CompLevel_none:
+ case CompLevel_limited_profile: {
+ double k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback);
+ return loop_predicate_helper<CompLevel_none>(i, b, k);
+ }
+ case CompLevel_full_profile: {
+ double k = threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback);
+ return loop_predicate_helper<CompLevel_full_profile>(i, b, k);
+ }
+ default:
+ return true;
+ }
+}
+
+bool AdvancedThresholdPolicy::call_predicate(int i, int b, CompLevel cur_level) {
+ switch(cur_level) {
+ case CompLevel_none:
+ case CompLevel_limited_profile: {
+ double k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback);
+ return call_predicate_helper<CompLevel_none>(i, b, k);
+ }
+ case CompLevel_full_profile: {
+ double k = threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback);
+ return call_predicate_helper<CompLevel_full_profile>(i, b, k);
+ }
+ default:
+ return true;
+ }
+}
+
+// If a method is old enough and is still in the interpreter we would want to
+// start profiling without waiting for the compiled method to arrive.
+// We also take the load on compilers into the account.
+bool AdvancedThresholdPolicy::should_create_mdo(methodOop method, CompLevel cur_level) {
+ if (cur_level == CompLevel_none &&
+ CompileBroker::queue_size(CompLevel_full_optimization) <=
+ Tier3DelayOn * compiler_count(CompLevel_full_optimization)) {
+ int i = method->invocation_count();
+ int b = method->backedge_count();
+ double k = Tier0ProfilingStartPercentage / 100.0;
+ return call_predicate_helper<CompLevel_none>(i, b, k) || loop_predicate_helper<CompLevel_none>(i, b, k);
+ }
+ return false;
+}
+
+// Create MDO if necessary.
+void AdvancedThresholdPolicy::create_mdo(methodHandle mh, TRAPS) {
+ if (mh->is_native() || mh->is_abstract() || mh->is_accessor()) return;
+ if (mh->method_data() == NULL) {
+ methodOopDesc::build_interpreter_method_data(mh, THREAD);
+ if (HAS_PENDING_EXCEPTION) {
+ CLEAR_PENDING_EXCEPTION;
+ }
+ }
+}
+
+
+/*
+ * Method states:
+ * 0 - interpreter (CompLevel_none)
+ * 1 - pure C1 (CompLevel_simple)
+ * 2 - C1 with invocation and backedge counting (CompLevel_limited_profile)
+ * 3 - C1 with full profiling (CompLevel_full_profile)
+ * 4 - C2 (CompLevel_full_optimization)
+ *
+ * Common state transition patterns:
+ * a. 0 -> 3 -> 4.
+ * The most common path. But note that even in this straightforward case
+ * profiling can start at level 0 and finish at level 3.
+ *
+ * b. 0 -> 2 -> 3 -> 4.
+ * This case occures when the load on C2 is deemed too high. So, instead of transitioning
+ * into state 3 directly and over-profiling while a method is in the C2 queue we transition to
+ * level 2 and wait until the load on C2 decreases. This path is disabled for OSRs.
+ *
+ * c. 0 -> (3->2) -> 4.
+ * In this case we enqueue a method for compilation at level 3, but the C1 queue is long enough
+ * to enable the profiling to fully occur at level 0. In this case we change the compilation level
+ * of the method to 2, because it'll allow it to run much faster without full profiling while c2
+ * is compiling.
+ *
+ * d. 0 -> 3 -> 1 or 0 -> 2 -> 1.
+ * After a method was once compiled with C1 it can be identified as trivial and be compiled to
+ * level 1. These transition can also occur if a method can't be compiled with C2 but can with C1.
+ *
+ * e. 0 -> 4.
+ * This can happen if a method fails C1 compilation (it will still be profiled in the interpreter)
+ * or because of a deopt that didn't require reprofiling (compilation won't happen in this case because
+ * the compiled version already exists).
+ *
+ * Note that since state 0 can be reached from any other state via deoptimization different loops
+ * are possible.
+ *
+ */
+
+// Common transition function. Given a predicate determines if a method should transition to another level.
+CompLevel AdvancedThresholdPolicy::common(Predicate p, methodOop method, CompLevel cur_level) {
+ if (is_trivial(method)) return CompLevel_simple;
+
+ CompLevel next_level = cur_level;
+ int i = method->invocation_count();
+ int b = method->backedge_count();
+
+ switch(cur_level) {
+ case CompLevel_none:
+ // If we were at full profile level, would we switch to full opt?
+ if (common(p, method, CompLevel_full_profile) == CompLevel_full_optimization) {
+ next_level = CompLevel_full_optimization;
+ } else if ((this->*p)(i, b, cur_level)) {
+ // C1-generated fully profiled code is about 30% slower than the limited profile
+ // code that has only invocation and backedge counters. The observation is that
+ // if C2 queue is large enough we can spend too much time in the fully profiled code
+ // while waiting for C2 to pick the method from the queue. To alleviate this problem
+ // we introduce a feedback on the C2 queue size. If the C2 queue is sufficiently long
+ // we choose to compile a limited profiled version and then recompile with full profiling
+ // when the load on C2 goes down.
+ if (CompileBroker::queue_size(CompLevel_full_optimization) >
+ Tier3DelayOn * compiler_count(CompLevel_full_optimization)) {
+ next_level = CompLevel_limited_profile;
+ } else {
+ next_level = CompLevel_full_profile;
+ }
+ }
+ break;
+ case CompLevel_limited_profile:
+ if (is_method_profiled(method)) {
+ // Special case: we got here because this method was fully profiled in the interpreter.
+ next_level = CompLevel_full_optimization;
+ } else {
+ methodDataOop mdo = method->method_data();
+ if (mdo != NULL) {
+ if (mdo->would_profile()) {
+ if (CompileBroker::queue_size(CompLevel_full_optimization) <=
+ Tier3DelayOff * compiler_count(CompLevel_full_optimization) &&
+ (this->*p)(i, b, cur_level)) {
+ next_level = CompLevel_full_profile;
+ }
+ } else {
+ next_level = CompLevel_full_optimization;
+ }
+ }
+ }
+ break;
+ case CompLevel_full_profile:
+ {
+ methodDataOop mdo = method->method_data();
+ if (mdo != NULL) {
+ if (mdo->would_profile()) {
+ int mdo_i = mdo->invocation_count_delta();
+ int mdo_b = mdo->backedge_count_delta();
+ if ((this->*p)(mdo_i, mdo_b, cur_level)) {
+ next_level = CompLevel_full_optimization;
+ }
+ } else {
+ next_level = CompLevel_full_optimization;
+ }
+ }
+ }
+ break;
+ }
+ return next_level;
+}
+
+// Determine if a method should be compiled with a normal entry point at a different level.
+CompLevel AdvancedThresholdPolicy::call_event(methodOop method, CompLevel cur_level) {
+ CompLevel osr_level = (CompLevel) method->highest_osr_comp_level();
+ CompLevel next_level = common(&AdvancedThresholdPolicy::call_predicate, method, cur_level);
+
+ // If OSR method level is greater than the regular method level, the levels should be
+ // equalized by raising the regular method level in order to avoid OSRs during each
+ // invocation of the method.
+ if (osr_level == CompLevel_full_optimization && cur_level == CompLevel_full_profile) {
+ methodDataOop mdo = method->method_data();
+ guarantee(mdo != NULL, "MDO should not be NULL");
+ if (mdo->invocation_count() >= 1) {
+ next_level = CompLevel_full_optimization;
+ }
+ } else {
+ next_level = MAX2(osr_level, next_level);
+ }
+
+ return next_level;
+}
+
+// Determine if we should do an OSR compilation of a given method.
+CompLevel AdvancedThresholdPolicy::loop_event(methodOop method, CompLevel cur_level) {
+ if (cur_level == CompLevel_none) {
+ // If there is a live OSR method that means that we deopted to the interpreter
+ // for the transition.
+ CompLevel osr_level = (CompLevel)method->highest_osr_comp_level();
+ if (osr_level > CompLevel_none) {
+ return osr_level;
+ }
+ }
+ return common(&AdvancedThresholdPolicy::loop_predicate, method, cur_level);
+}
+
+// Update the rate and submit compile
+void AdvancedThresholdPolicy::submit_compile(methodHandle mh, int bci, CompLevel level, TRAPS) {
+ int hot_count = (bci == InvocationEntryBci) ? mh->invocation_count() : mh->backedge_count();
+ update_rate(os::javaTimeMillis(), mh());
+ CompileBroker::compile_method(mh, bci, level, mh, hot_count, "tiered", THREAD);
+}
+
+
+// Handle the invocation event.
+void AdvancedThresholdPolicy::method_invocation_event(methodHandle mh, methodHandle imh,
+ CompLevel level, TRAPS) {
+ if (should_create_mdo(mh(), level)) {
+ create_mdo(mh, THREAD);
+ }
+ if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh, InvocationEntryBci)) {
+ CompLevel next_level = call_event(mh(), level);
+ if (next_level != level) {
+ compile(mh, InvocationEntryBci, next_level, THREAD);
+ }
+ }
+}
+
+// Handle the back branch event. Notice that we can compile the method
+// with a regular entry from here.
+void AdvancedThresholdPolicy::method_back_branch_event(methodHandle mh, methodHandle imh,
+ int bci, CompLevel level, TRAPS) {
+ if (should_create_mdo(mh(), level)) {
+ create_mdo(mh, THREAD);
+ }
+
+ // If the method is already compiling, quickly bail out.
+ if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh, bci)) {
+ // Use loop event as an opportinity to also check there's been
+ // enough calls.
+ CompLevel cur_level = comp_level(mh());
+ CompLevel next_level = call_event(mh(), cur_level);
+ CompLevel next_osr_level = loop_event(mh(), level);
+ if (next_osr_level == CompLevel_limited_profile) {
+ next_osr_level = CompLevel_full_profile; // OSRs are supposed to be for very hot methods.
+ }
+ next_level = MAX2(next_level,
+ next_osr_level < CompLevel_full_optimization ? next_osr_level : cur_level);
+ bool is_compiling = false;
+ if (next_level != cur_level) {
+ compile(mh, InvocationEntryBci, next_level, THREAD);
+ is_compiling = true;
+ }
+
+ // Do the OSR version
+ if (!is_compiling && next_osr_level != level) {
+ compile(mh, bci, next_osr_level, THREAD);
+ }
+ }
+}
+
+#endif // TIERED
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -0,0 +1,207 @@
+/*
+* Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved.
+* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+*/
+
+#ifndef SHARE_VM_RUNTIME_ADVANCEDTHRESHOLDPOLICY_HPP
+#define SHARE_VM_RUNTIME_ADVANCEDTHRESHOLDPOLICY_HPP
+
+#include "runtime/simpleThresholdPolicy.hpp"
+
+#ifdef TIERED
+class CompileTask;
+class CompileQueue;
+
+/*
+ * The system supports 5 execution levels:
+ * * level 0 - interpreter
+ * * level 1 - C1 with full optimization (no profiling)
+ * * level 2 - C1 with invocation and backedge counters
+ * * level 3 - C1 with full profiling (level 2 + MDO)
+ * * level 4 - C2
+ *
+ * Levels 0, 2 and 3 periodically notify the runtime about the current value of the counters
+ * (invocation counters and backedge counters). The frequency of these notifications is
+ * different at each level. These notifications are used by the policy to decide what transition
+ * to make.
+ *
+ * Execution starts at level 0 (interpreter), then the policy can decide either to compile the
+ * method at level 3 or level 2. The decision is based on the following factors:
+ * 1. The length of the C2 queue determines the next level. The observation is that level 2
+ * is generally faster than level 3 by about 30%, therefore we would want to minimize the time
+ * a method spends at level 3. We should only spend the time at level 3 that is necessary to get
+ * adequate profiling. So, if the C2 queue is long enough it is more beneficial to go first to
+ * level 2, because if we transitioned to level 3 we would be stuck there until our C2 compile
+ * request makes its way through the long queue. When the load on C2 recedes we are going to
+ * recompile at level 3 and start gathering profiling information.
+ * 2. The length of C1 queue is used to dynamically adjust the thresholds, so as to introduce
+ * additional filtering if the compiler is overloaded. The rationale is that by the time a
+ * method gets compiled it can become unused, so it doesn't make sense to put too much onto the
+ * queue.
+ *
+ * After profiling is completed at level 3 the transition is made to level 4. Again, the length
+ * of the C2 queue is used as a feedback to adjust the thresholds.
+ *
+ * After the first C1 compile some basic information is determined about the code like the number
+ * of the blocks and the number of the loops. Based on that it can be decided that a method
+ * is trivial and compiling it with C1 will yield the same code. In this case the method is
+ * compiled at level 1 instead of 4.
+ *
+ * We also support profiling at level 0. If C1 is slow enough to produce the level 3 version of
+ * the code and the C2 queue is sufficiently small we can decide to start profiling in the
+ * interpreter (and continue profiling in the compiled code once the level 3 version arrives).
+ * If the profiling at level 0 is fully completed before level 3 version is produced, a level 2
+ * version is compiled instead in order to run faster waiting for a level 4 version.
+ *
+ * Compile queues are implemented as priority queues - for each method in the queue we compute
+ * the event rate (the number of invocation and backedge counter increments per unit of time).
+ * When getting an element off the queue we pick the one with the largest rate. Maintaining the
+ * rate also allows us to remove stale methods (the ones that got on the queue but stopped
+ * being used shortly after that).
+*/
+
+/* Command line options:
+ * - Tier?InvokeNotifyFreqLog and Tier?BackedgeNotifyFreqLog control the frequency of method
+ * invocation and backedge notifications. Basically every n-th invocation or backedge a mutator thread
+ * makes a call into the runtime.
+ *
+ * - Tier?CompileThreshold, Tier?BackEdgeThreshold, Tier?MinInvocationThreshold control
+ * compilation thresholds.
+ * Level 2 thresholds are not used and are provided for option-compatibility and potential future use.
+ * Other thresholds work as follows:
+ *
+ * Transition from interpreter (level 0) to C1 with full profiling (level 3) happens when
+ * the following predicate is true (X is the level):
+ *
+ * i > TierXInvocationThreshold * s || (i > TierXMinInvocationThreshold * s && i + b > TierXCompileThreshold * s),
+ *
+ * where $i$ is the number of method invocations, $b$ number of backedges and $s$ is the scaling
+ * coefficient that will be discussed further.
+ * The intuition is to equalize the time that is spend profiling each method.
+ * The same predicate is used to control the transition from level 3 to level 4 (C2). It should be
+ * noted though that the thresholds are relative. Moreover i and b for the 0->3 transition come
+ * from methodOop and for 3->4 transition they come from MDO (since profiled invocations are
+ * counted separately).
+ *
+ * OSR transitions are controlled simply with b > TierXBackEdgeThreshold * s predicates.
+ *
+ * - Tier?LoadFeedback options are used to automatically scale the predicates described above depending
+ * on the compiler load. The scaling coefficients are computed as follows:
+ *
+ * s = queue_size_X / (TierXLoadFeedback * compiler_count_X) + 1,
+ *
+ * where queue_size_X is the current size of the compiler queue of level X, and compiler_count_X
+ * is the number of level X compiler threads.
+ *
+ * Basically these parameters describe how many methods should be in the compile queue
+ * per compiler thread before the scaling coefficient increases by one.
+ *
+ * This feedback provides the mechanism to automatically control the flow of compilation requests
+ * depending on the machine speed, mutator load and other external factors.
+ *
+ * - Tier3DelayOn and Tier3DelayOff parameters control another important feedback loop.
+ * Consider the following observation: a method compiled with full profiling (level 3)
+ * is about 30% slower than a method at level 2 (just invocation and backedge counters, no MDO).
+ * Normally, the following transitions will occur: 0->3->4. The problem arises when the C2 queue
+ * gets congested and the 3->4 transition is delayed. While the method is the C2 queue it continues
+ * executing at level 3 for much longer time than is required by the predicate and at suboptimal speed.
+ * The idea is to dynamically change the behavior of the system in such a way that if a substantial
+ * load on C2 is detected we would first do the 0->2 transition allowing a method to run faster.
+ * And then when the load decreases to allow 2->3 transitions.
+ *
+ * Tier3Delay* parameters control this switching mechanism.
+ * Tier3DelayOn is the number of methods in the C2 queue per compiler thread after which the policy
+ * no longer does 0->3 transitions but does 0->2 transitions instead.
+ * Tier3DelayOff switches the original behavior back when the number of methods in the C2 queue
+ * per compiler thread falls below the specified amount.
+ * The hysteresis is necessary to avoid jitter.
+ *
+ * - TieredCompileTaskTimeout is the amount of time an idle method can spend in the compile queue.
+ * Basically, since we use the event rate d(i + b)/dt as a value of priority when selecting a method to
+ * compile from the compile queue, we also can detect stale methods for which the rate has been
+ * 0 for some time in the same iteration. Stale methods can appear in the queue when an application
+ * abruptly changes its behavior.
+ *
+ * - TieredStopAtLevel, is used mostly for testing. It allows to bypass the policy logic and stick
+ * to a given level. For example it's useful to set TieredStopAtLevel = 1 in order to compile everything
+ * with pure c1.
+ *
+ * - Tier0ProfilingStartPercentage allows the interpreter to start profiling when the inequalities in the
+ * 0->3 predicate are already exceeded by the given percentage but the level 3 version of the
+ * method is still not ready. We can even go directly from level 0 to 4 if c1 doesn't produce a compiled
+ * version in time. This reduces the overall transition to level 4 and decreases the startup time.
+ * Note that this behavior is also guarded by the Tier3Delay mechanism: when the c2 queue is too long
+ * these is not reason to start profiling prematurely.
+ *
+ * - TieredRateUpdateMinTime and TieredRateUpdateMaxTime are parameters of the rate computation.
+ * Basically, the rate is not computed more frequently than TieredRateUpdateMinTime and is considered
+ * to be zero if no events occurred in TieredRateUpdateMaxTime.
+ */
+
+
+class AdvancedThresholdPolicy : public SimpleThresholdPolicy {
+ jlong _start_time;
+
+ // Call and loop predicates determine whether a transition to a higher compilation
+ // level should be performed (pointers to predicate functions are passed to common().
+ // Predicates also take compiler load into account.
+ typedef bool (AdvancedThresholdPolicy::*Predicate)(int i, int b, CompLevel cur_level);
+ bool call_predicate(int i, int b, CompLevel cur_level);
+ bool loop_predicate(int i, int b, CompLevel cur_level);
+ // Common transition function. Given a predicate determines if a method should transition to another level.
+ CompLevel common(Predicate p, methodOop method, CompLevel cur_level);
+ // Transition functions.
+ // call_event determines if a method should be compiled at a different
+ // level with a regular invocation entry.
+ CompLevel call_event(methodOop method, CompLevel cur_level);
+ // loop_event checks if a method should be OSR compiled at a different
+ // level.
+ CompLevel loop_event(methodOop method, CompLevel cur_level);
+ // Has a method been long around?
+ // We don't remove old methods from the compile queue even if they have
+ // very low activity (see select_task()).
+ inline bool is_old(methodOop method);
+ // Was a given method inactive for a given number of milliseconds.
+ // If it is, we would remove it from the queue (see select_task()).
+ inline bool is_stale(jlong t, jlong timeout, methodOop m);
+ // Compute the weight of the method for the compilation scheduling
+ inline double weight(methodOop method);
+ // Apply heuristics and return true if x should be compiled before y
+ inline bool compare_methods(methodOop x, methodOop y);
+ // Compute event rate for a given method. The rate is the number of event (invocations + backedges)
+ // per millisecond.
+ inline void update_rate(jlong t, methodOop m);
+ // Compute threshold scaling coefficient
+ inline double threshold_scale(CompLevel level, int feedback_k);
+ // If a method is old enough and is still in the interpreter we would want to
+ // start profiling without waiting for the compiled method to arrive. This function
+ // determines whether we should do that.
+ inline bool should_create_mdo(methodOop method, CompLevel cur_level);
+ // Create MDO if necessary.
+ void create_mdo(methodHandle mh, TRAPS);
+ // Is method profiled enough?
+ bool is_method_profiled(methodOop method);
+
+protected:
+ void print_specific(EventType type, methodHandle mh, methodHandle imh, int bci, CompLevel level);
+
+ void set_start_time(jlong t) { _start_time = t; }
+ jlong start_time() const { return _start_time; }
+
+ // Submit a given method for compilation (and update the rate).
+ virtual void submit_compile(methodHandle mh, int bci, CompLevel level, TRAPS);
+ // event() from SimpleThresholdPolicy would call these.
+ virtual void method_invocation_event(methodHandle method, methodHandle inlinee,
+ CompLevel level, TRAPS);
+ virtual void method_back_branch_event(methodHandle method, methodHandle inlinee,
+ int bci, CompLevel level, TRAPS);
+public:
+ AdvancedThresholdPolicy() : _start_time(0) { }
+ // Select task is called by CompileBroker. We should return a task or NULL.
+ virtual CompileTask* select_task(CompileQueue* compile_queue);
+ virtual void initialize();
+};
+
+#endif // TIERED
+
+#endif // SHARE_VM_RUNTIME_ADVANCEDTHRESHOLDPOLICY_HPP
--- a/hotspot/src/share/vm/runtime/arguments.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -242,6 +242,7 @@
JDK_Version::jdk_update(6,24), JDK_Version::jdk(8) },
{ "MaxLiveObjectEvacuationRatio",
JDK_Version::jdk_update(6,24), JDK_Version::jdk(8) },
+ { "ForceSharedSpaces", JDK_Version::jdk_update(6,25), JDK_Version::jdk(8) },
{ NULL, JDK_Version(0), JDK_Version(0) }
};
@@ -1003,31 +1004,10 @@
}
}
-void Arguments::check_compressed_oops_compat() {
-#ifdef _LP64
- assert(UseCompressedOops, "Precondition");
- // Is it on by default or set on ergonomically
- bool is_on_by_default = FLAG_IS_DEFAULT(UseCompressedOops) || FLAG_IS_ERGO(UseCompressedOops);
-
- // If dumping an archive or forcing its use, disable compressed oops if possible
- if (DumpSharedSpaces || RequireSharedSpaces) {
- if (is_on_by_default) {
- FLAG_SET_DEFAULT(UseCompressedOops, false);
- return;
- } else {
- vm_exit_during_initialization(
- "Class Data Sharing is not supported with compressed oops yet", NULL);
- }
- } else if (UseSharedSpaces) {
- // UseSharedSpaces is on by default. With compressed oops, we turn it off.
- FLAG_SET_DEFAULT(UseSharedSpaces, false);
- }
-#endif
-}
-
void Arguments::set_tiered_flags() {
+ // With tiered, set default policy to AdvancedThresholdPolicy, which is 3.
if (FLAG_IS_DEFAULT(CompilationPolicyChoice)) {
- FLAG_SET_DEFAULT(CompilationPolicyChoice, 2);
+ FLAG_SET_DEFAULT(CompilationPolicyChoice, 3);
}
if (CompilationPolicyChoice < 2) {
vm_exit_during_initialization(
@@ -1122,40 +1102,28 @@
set_parnew_gc_flags();
}
+ // MaxHeapSize is aligned down in collectorPolicy
+ size_t max_heap = align_size_down(MaxHeapSize,
+ CardTableRS::ct_max_alignment_constraint());
+
// Now make adjustments for CMS
- size_t young_gen_per_worker;
- intx new_ratio;
- size_t min_new_default;
- intx tenuring_default;
- if (CMSUseOldDefaults) { // old defaults: "old" as of 6.0
- if FLAG_IS_DEFAULT(CMSYoungGenPerWorker) {
- FLAG_SET_ERGO(intx, CMSYoungGenPerWorker, 4*M);
- }
- young_gen_per_worker = 4*M;
- new_ratio = (intx)15;
- min_new_default = 4*M;
- tenuring_default = (intx)0;
- } else { // new defaults: "new" as of 6.0
- young_gen_per_worker = CMSYoungGenPerWorker;
- new_ratio = (intx)7;
- min_new_default = 16*M;
- tenuring_default = (intx)4;
- }
-
- // Preferred young gen size for "short" pauses
+ intx tenuring_default = (intx)6;
+ size_t young_gen_per_worker = CMSYoungGenPerWorker;
+
+ // Preferred young gen size for "short" pauses:
+ // upper bound depends on # of threads and NewRatio.
const uintx parallel_gc_threads =
(ParallelGCThreads == 0 ? 1 : ParallelGCThreads);
const size_t preferred_max_new_size_unaligned =
- ScaleForWordSize(young_gen_per_worker * parallel_gc_threads);
- const size_t preferred_max_new_size =
+ MIN2(max_heap/(NewRatio+1), ScaleForWordSize(young_gen_per_worker * parallel_gc_threads));
+ size_t preferred_max_new_size =
align_size_up(preferred_max_new_size_unaligned, os::vm_page_size());
// Unless explicitly requested otherwise, size young gen
- // for "short" pauses ~ 4M*ParallelGCThreads
+ // for "short" pauses ~ CMSYoungGenPerWorker*ParallelGCThreads
// If either MaxNewSize or NewRatio is set on the command line,
// assume the user is trying to set the size of the young gen.
-
if (FLAG_IS_DEFAULT(MaxNewSize) && FLAG_IS_DEFAULT(NewRatio)) {
// Set MaxNewSize to our calculated preferred_max_new_size unless
@@ -1168,49 +1136,13 @@
}
if (PrintGCDetails && Verbose) {
// Too early to use gclog_or_tty
- tty->print_cr("Ergo set MaxNewSize: " SIZE_FORMAT, MaxNewSize);
+ tty->print_cr("CMS ergo set MaxNewSize: " SIZE_FORMAT, MaxNewSize);
}
- // Unless explicitly requested otherwise, prefer a large
- // Old to Young gen size so as to shift the collection load
- // to the old generation concurrent collector
-
- // If this is only guarded by FLAG_IS_DEFAULT(NewRatio)
- // then NewSize and OldSize may be calculated. That would
- // generally lead to some differences with ParNewGC for which
- // there was no obvious reason. Also limit to the case where
- // MaxNewSize has not been set.
-
- FLAG_SET_ERGO(intx, NewRatio, MAX2(NewRatio, new_ratio));
-
// Code along this path potentially sets NewSize and OldSize
- // Calculate the desired minimum size of the young gen but if
- // NewSize has been set on the command line, use it here since
- // it should be the final value.
- size_t min_new;
- if (FLAG_IS_DEFAULT(NewSize)) {
- min_new = align_size_up(ScaleForWordSize(min_new_default),
- os::vm_page_size());
- } else {
- min_new = NewSize;
- }
- size_t prev_initial_size = InitialHeapSize;
- if (prev_initial_size != 0 && prev_initial_size < min_new + OldSize) {
- FLAG_SET_ERGO(uintx, InitialHeapSize, min_new + OldSize);
- // Currently minimum size and the initial heap sizes are the same.
- set_min_heap_size(InitialHeapSize);
- if (PrintGCDetails && Verbose) {
- warning("Initial heap size increased to " SIZE_FORMAT " M from "
- SIZE_FORMAT " M; use -XX:NewSize=... for finer control.",
- InitialHeapSize/M, prev_initial_size/M);
- }
- }
-
- // MaxHeapSize is aligned down in collectorPolicy
- size_t max_heap =
- align_size_down(MaxHeapSize,
- CardTableRS::ct_max_alignment_constraint());
+ assert(max_heap >= InitialHeapSize, "Error");
+ assert(max_heap >= NewSize, "Error");
if (PrintGCDetails && Verbose) {
// Too early to use gclog_or_tty
@@ -1219,7 +1151,11 @@
" max_heap: " SIZE_FORMAT,
min_heap_size(), InitialHeapSize, max_heap);
}
- if (max_heap > min_new) {
+ size_t min_new = preferred_max_new_size;
+ if (FLAG_IS_CMDLINE(NewSize)) {
+ min_new = NewSize;
+ }
+ if (max_heap > min_new && min_heap_size() > min_new) {
// Unless explicitly requested otherwise, make young gen
// at least min_new, and at most preferred_max_new_size.
if (FLAG_IS_DEFAULT(NewSize)) {
@@ -1227,18 +1163,17 @@
FLAG_SET_ERGO(uintx, NewSize, MIN2(preferred_max_new_size, NewSize));
if (PrintGCDetails && Verbose) {
// Too early to use gclog_or_tty
- tty->print_cr("Ergo set NewSize: " SIZE_FORMAT, NewSize);
+ tty->print_cr("CMS ergo set NewSize: " SIZE_FORMAT, NewSize);
}
}
// Unless explicitly requested otherwise, size old gen
- // so that it's at least 3X of NewSize to begin with;
- // later NewRatio will decide how it grows; see above.
+ // so it's NewRatio x of NewSize.
if (FLAG_IS_DEFAULT(OldSize)) {
if (max_heap > NewSize) {
- FLAG_SET_ERGO(uintx, OldSize, MIN2(3*NewSize, max_heap - NewSize));
+ FLAG_SET_ERGO(uintx, OldSize, MIN2(NewRatio*NewSize, max_heap - NewSize));
if (PrintGCDetails && Verbose) {
// Too early to use gclog_or_tty
- tty->print_cr("Ergo set OldSize: " SIZE_FORMAT, OldSize);
+ tty->print_cr("CMS ergo set OldSize: " SIZE_FORMAT, OldSize);
}
}
}
@@ -1382,7 +1317,7 @@
void Arguments::set_ergonomics_flags() {
// Parallel GC is not compatible with sharing. If one specifies
// that they want sharing explicitly, do not set ergonomics flags.
- if (DumpSharedSpaces || ForceSharedSpaces) {
+ if (DumpSharedSpaces || RequireSharedSpaces) {
return;
}
@@ -1689,13 +1624,13 @@
}
bool Arguments::verify_min_value(intx val, intx min, const char* name) {
- // Returns true if given value is greater than specified min threshold
+ // Returns true if given value is at least specified min threshold
// false, otherwise.
if (val >= min ) {
return true;
}
jio_fprintf(defaultStream::error_stream(),
- "%s of " INTX_FORMAT " is invalid; must be greater than " INTX_FORMAT "\n",
+ "%s of " INTX_FORMAT " is invalid; must be at least " INTX_FORMAT "\n",
name, val, min);
return false;
}
@@ -1845,33 +1780,6 @@
status = status && verify_percentage(GCHeapFreeLimit, "GCHeapFreeLimit");
- // Check whether user-specified sharing option conflicts with GC or page size.
- // Both sharing and large pages are enabled by default on some platforms;
- // large pages override sharing only if explicitly set on the command line.
- const bool cannot_share = UseConcMarkSweepGC || CMSIncrementalMode ||
- UseG1GC || UseParNewGC || UseParallelGC || UseParallelOldGC ||
- UseLargePages && FLAG_IS_CMDLINE(UseLargePages);
- if (cannot_share) {
- // Either force sharing on by forcing the other options off, or
- // force sharing off.
- if (DumpSharedSpaces || ForceSharedSpaces) {
- jio_fprintf(defaultStream::error_stream(),
- "Using Serial GC and default page size because of %s\n",
- ForceSharedSpaces ? "-Xshare:on" : "-Xshare:dump");
- force_serial_gc();
- FLAG_SET_DEFAULT(UseLargePages, false);
- } else {
- if (UseSharedSpaces && Verbose) {
- jio_fprintf(defaultStream::error_stream(),
- "Turning off use of shared archive because of "
- "choice of garbage collector or large pages\n");
- }
- no_shared_spaces();
- }
- } else if (UseLargePages && (UseSharedSpaces || DumpSharedSpaces)) {
- FLAG_SET_DEFAULT(UseLargePages, false);
- }
-
status = status && check_gc_consistency();
status = status && check_stack_pages();
@@ -1949,6 +1857,8 @@
status = false;
}
+ status = status && verify_min_value(ParGCArrayScanChunk, 1, "ParGCArrayScanChunk");
+
#ifndef SERIALGC
if (UseG1GC) {
status = status && verify_percentage(InitiatingHeapOccupancyPercent,
@@ -2412,9 +2322,6 @@
} else if (match_option(option, "-Xshare:on", &tail)) {
FLAG_SET_CMDLINE(bool, UseSharedSpaces, true);
FLAG_SET_CMDLINE(bool, RequireSharedSpaces, true);
-#ifdef TIERED
- FLAG_SET_CMDLINE(bool, ForceSharedSpaces, true);
-#endif // TIERED
// -Xshare:auto
} else if (match_option(option, "-Xshare:auto", &tail)) {
FLAG_SET_CMDLINE(bool, UseSharedSpaces, true);
@@ -2911,6 +2818,36 @@
return JNI_OK;
}
+void Arguments::set_shared_spaces_flags() {
+ // Check whether class data sharing settings conflict with GC, compressed oops
+ // or page size, and fix them up. Explicit sharing options override other
+ // settings.
+ const bool cannot_share = UseConcMarkSweepGC || CMSIncrementalMode ||
+ UseG1GC || UseParNewGC || UseParallelGC || UseParallelOldGC ||
+ UseCompressedOops || UseLargePages && FLAG_IS_CMDLINE(UseLargePages);
+ const bool must_share = DumpSharedSpaces || RequireSharedSpaces;
+ const bool might_share = must_share || UseSharedSpaces;
+ if (cannot_share) {
+ if (must_share) {
+ warning("selecting serial gc and disabling large pages %s"
+ "because of %s", "" LP64_ONLY("and compressed oops "),
+ DumpSharedSpaces ? "-Xshare:dump" : "-Xshare:on");
+ force_serial_gc();
+ FLAG_SET_CMDLINE(bool, UseLargePages, false);
+ LP64_ONLY(FLAG_SET_CMDLINE(bool, UseCompressedOops, false));
+ } else {
+ if (UseSharedSpaces && Verbose) {
+ warning("turning off use of shared archive because of "
+ "choice of garbage collector or large pages");
+ }
+ no_shared_spaces();
+ }
+ } else if (UseLargePages && might_share) {
+ // Disable large pages to allow shared spaces. This is sub-optimal, since
+ // there may not even be a shared archive to use.
+ FLAG_SET_DEFAULT(UseLargePages, false);
+ }
+}
// Parse entry point called from JNI_CreateJavaVM
@@ -3058,9 +2995,7 @@
// Set flags based on ergonomics.
set_ergonomics_flags();
- if (UseCompressedOops) {
- check_compressed_oops_compat();
- }
+ set_shared_spaces_flags();
// Check the GC selections again.
if (!check_gc_consistency()) {
@@ -3078,22 +3013,17 @@
}
#ifndef KERNEL
- if (UseConcMarkSweepGC) {
- // Set flags for CMS and ParNew. Check UseConcMarkSweep first
- // to ensure that when both UseConcMarkSweepGC and UseParNewGC
- // are true, we don't call set_parnew_gc_flags() as well.
+ // Set heap size based on available physical memory
+ set_heap_size();
+ // Set per-collector flags
+ if (UseParallelGC || UseParallelOldGC) {
+ set_parallel_gc_flags();
+ } else if (UseConcMarkSweepGC) { // should be done before ParNew check below
set_cms_and_parnew_gc_flags();
- } else {
- // Set heap size based on available physical memory
- set_heap_size();
- // Set per-collector flags
- if (UseParallelGC || UseParallelOldGC) {
- set_parallel_gc_flags();
- } else if (UseParNewGC) {
- set_parnew_gc_flags();
- } else if (UseG1GC) {
- set_g1_gc_flags();
- }
+ } else if (UseParNewGC) { // skipped if CMS is set above
+ set_parnew_gc_flags();
+ } else if (UseG1GC) {
+ set_g1_gc_flags();
}
#endif // KERNEL
@@ -3110,7 +3040,11 @@
// Turn off biased locking for locking debug mode flags,
// which are subtlely different from each other but neither works with
// biased locking.
- if (!UseFastLocking || UseHeavyMonitors) {
+ if (UseHeavyMonitors
+#ifdef COMPILER1
+ || !UseFastLocking
+#endif // COMPILER1
+ ) {
if (!FLAG_IS_DEFAULT(UseBiasedLocking) && UseBiasedLocking) {
// flag set to true on command line; warn the user that they
// can't enable biased locking here
--- a/hotspot/src/share/vm/runtime/arguments.hpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -301,8 +301,6 @@
// Tiered
static void set_tiered_flags();
- // Check compressed oops compatibility with other flags
- static void check_compressed_oops_compat();
// CMS/ParNew garbage collectors
static void set_parnew_gc_flags();
static void set_cms_and_parnew_gc_flags();
@@ -312,6 +310,7 @@
static void set_g1_gc_flags();
// GC ergonomics
static void set_ergonomics_flags();
+ static void set_shared_spaces_flags();
// Setup heap size
static void set_heap_size();
// Based on automatic selection criteria, should the
--- a/hotspot/src/share/vm/runtime/compilationPolicy.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/runtime/compilationPolicy.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -32,6 +32,7 @@
#include "oops/methodOop.hpp"
#include "oops/oop.inline.hpp"
#include "prims/nativeLookup.hpp"
+#include "runtime/advancedThresholdPolicy.hpp"
#include "runtime/compilationPolicy.hpp"
#include "runtime/frame.hpp"
#include "runtime/handles.inline.hpp"
@@ -72,8 +73,15 @@
Unimplemented();
#endif
break;
+ case 3:
+#ifdef TIERED
+ CompilationPolicy::set_policy(new AdvancedThresholdPolicy());
+#else
+ Unimplemented();
+#endif
+ break;
default:
- fatal("CompilationPolicyChoice must be in the range: [0-2]");
+ fatal("CompilationPolicyChoice must be in the range: [0-3]");
}
CompilationPolicy::policy()->initialize();
}
--- a/hotspot/src/share/vm/runtime/deoptimization.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/runtime/deoptimization.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -101,9 +101,9 @@
_frame_pcs = frame_pcs;
_register_block = NEW_C_HEAP_ARRAY(intptr_t, RegisterMap::reg_count * 2);
_return_type = return_type;
+ _initial_fp = 0;
// PD (x86 only)
_counter_temp = 0;
- _initial_fp = 0;
_unpack_kind = 0;
_sender_sp_temp = 0;
@@ -459,18 +459,9 @@
frame_sizes,
frame_pcs,
return_type);
-#if defined(IA32) || defined(AMD64)
- // We need a way to pass fp to the unpacking code so the skeletal frames
- // come out correct. This is only needed for x86 because of c2 using ebp
- // as an allocatable register. So this update is useless (and harmless)
- // on the other platforms. It would be nice to do this in a different
- // way but even the old style deoptimization had a problem with deriving
- // this value. NEEDS_CLEANUP
- // Note: now that c1 is using c2's deopt blob we must do this on all
- // x86 based platforms
- intptr_t** fp_addr = (intptr_t**) (((address)info) + info->initial_fp_offset_in_bytes());
- *fp_addr = array->sender().fp(); // was adapter_caller
-#endif /* IA32 || AMD64 */
+ // On some platforms, we need a way to pass fp to the unpacking code
+ // so the skeletal frames come out correct.
+ info->set_initial_fp((intptr_t) array->sender().fp());
if (array->frames() > 1) {
if (VerifyStack && TraceDeoptimization) {
--- a/hotspot/src/share/vm/runtime/deoptimization.hpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/runtime/deoptimization.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -136,12 +136,12 @@
address* _frame_pcs; // Array of frame pc's, in bytes, for unrolling the stack
intptr_t* _register_block; // Block for storing callee-saved registers.
BasicType _return_type; // Tells if we have to restore double or long return value
+ intptr_t _initial_fp; // FP of the sender frame
// The following fields are used as temps during the unpacking phase
// (which is tight on registers, especially on x86). They really ought
// to be PD variables but that involves moving this class into its own
// file to use the pd include mechanism. Maybe in a later cleanup ...
intptr_t _counter_temp; // SHOULD BE PD VARIABLE (x86 frame count temp)
- intptr_t _initial_fp; // SHOULD BE PD VARIABLE (x86/c2 initial ebp)
intptr_t _unpack_kind; // SHOULD BE PD VARIABLE (x86 unpack kind)
intptr_t _sender_sp_temp; // SHOULD BE PD VARIABLE (x86 sender_sp)
public:
@@ -165,6 +165,8 @@
// Returns the total size of frames
int size_of_frames() const;
+ void set_initial_fp(intptr_t fp) { _initial_fp = fp; }
+
// Accessors used by the code generator for the unpack stub.
static int size_of_deoptimized_frame_offset_in_bytes() { return offset_of(UnrollBlock, _size_of_deoptimized_frame); }
static int caller_adjustment_offset_in_bytes() { return offset_of(UnrollBlock, _caller_adjustment); }
--- a/hotspot/src/share/vm/runtime/globals.hpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/runtime/globals.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -1540,12 +1540,8 @@
product(bool, AlwaysPreTouch, false, \
"It forces all freshly committed pages to be pre-touched.") \
\
- product(bool, CMSUseOldDefaults, false, \
- "A flag temporarily introduced to allow reverting to some " \
- "older default settings; older as of 6.0") \
- \
- product(intx, CMSYoungGenPerWorker, 16*M, \
- "The amount of young gen chosen by default per GC worker " \
+ product_pd(intx, CMSYoungGenPerWorker, \
+ "The maximum size of young gen chosen by default per GC worker " \
"thread available") \
\
product(bool, GCOverheadReporting, false, \
@@ -3653,9 +3649,6 @@
product(bool, RequireSharedSpaces, false, \
"Require shared spaces in the permanent generation") \
\
- product(bool, ForceSharedSpaces, false, \
- "Require shared spaces in the permanent generation") \
- \
product(bool, DumpSharedSpaces, false, \
"Special mode: JVM reads a class list, loads classes, builds " \
"shared spaces, and dumps the shared spaces to a file to be " \
@@ -3719,6 +3712,13 @@
experimental(bool, AllowTransitionalJSR292, true, \
"recognize pre-PFD formats of invokedynamic") \
\
+ experimental(bool, PreferTransitionalJSR292, false, \
+ "prefer pre-PFD APIs on boot class path, if they exist") \
+ \
+ experimental(bool, AllowInvokeForInvokeGeneric, false, \
+ "accept MethodHandle.invoke and MethodHandle.invokeGeneric " \
+ "as equivalent methods") \
+ \
develop(bool, TraceInvokeDynamic, false, \
"trace internal invoke dynamic operations") \
\
--- a/hotspot/src/share/vm/runtime/os.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/runtime/os.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -633,10 +633,10 @@
*q = (u_char)freeBlockPad;
}
if (PrintMalloc && tty != NULL)
- fprintf(stderr, "os::free " SIZE_FORMAT " bytes --> " PTR_FORMAT "\n", size, memblock);
+ fprintf(stderr, "os::free " SIZE_FORMAT " bytes --> " PTR_FORMAT "\n", size, (uintptr_t)memblock);
} else if (PrintMalloc && tty != NULL) {
// tty->print_cr("os::free %p", memblock);
- fprintf(stderr, "os::free " PTR_FORMAT "\n", memblock);
+ fprintf(stderr, "os::free " PTR_FORMAT "\n", (uintptr_t)memblock);
}
#endif
::free((char*)memblock - space_before);
--- a/hotspot/src/share/vm/runtime/serviceThread.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/runtime/serviceThread.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -70,11 +70,10 @@
java_lang_Thread::set_priority(thread_oop(), NearMaxPriority);
java_lang_Thread::set_daemon(thread_oop());
thread->set_threadObj(thread_oop());
+ _instance = thread;
Threads::add(thread);
Thread::start(thread);
-
- _instance = thread;
}
}
--- a/hotspot/src/share/vm/runtime/sweeper.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/runtime/sweeper.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -426,9 +426,7 @@
tty->vprint(format, ap);
va_end(ap);
}
- tty->print_cr(" total_blobs='" UINT32_FORMAT "' nmethods='" UINT32_FORMAT "'"
- " adapters='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'",
- CodeCache::nof_blobs(), CodeCache::nof_nmethods(), CodeCache::nof_adapters(), CodeCache::unallocated_capacity());
+ CodeCache::log_state(tty); tty->cr();
}
if (LogCompilation && (xtty != NULL)) {
@@ -440,9 +438,7 @@
xtty->vprint(format, ap);
va_end(ap);
}
- xtty->print(" total_blobs='" UINT32_FORMAT "' nmethods='" UINT32_FORMAT "'"
- " adapters='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'",
- CodeCache::nof_blobs(), CodeCache::nof_nmethods(), CodeCache::nof_adapters(), CodeCache::unallocated_capacity());
+ CodeCache::log_state(xtty);
xtty->stamp();
xtty->end_elem();
}
--- a/hotspot/src/share/vm/utilities/debug.hpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/utilities/debug.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -25,6 +25,7 @@
#ifndef SHARE_VM_UTILITIES_DEBUG_HPP
#define SHARE_VM_UTILITIES_DEBUG_HPP
+#include "prims/jvm.h"
#include "utilities/globalDefinitions.hpp"
#include <stdarg.h>
@@ -48,7 +49,7 @@
FormatBuffer<bufsz>::FormatBuffer(const char * format, ...) {
va_list argp;
va_start(argp, format);
- vsnprintf(_buf, bufsz, format, argp);
+ jio_vsnprintf(_buf, bufsz, format, argp);
va_end(argp);
}
@@ -61,7 +62,7 @@
va_list argp;
va_start(argp, format);
- vsnprintf(buf_end, bufsz - len, format, argp);
+ jio_vsnprintf(buf_end, bufsz - len, format, argp);
va_end(argp);
}
--- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -1185,7 +1185,7 @@
// '%d' formats to indicate a 64-bit quantity; commonly "l" (in LP64) or "ll"
// (in ILP32).
-#define BOOL_TO_STR(__b) (__b) ? "true" : "false"
+#define BOOL_TO_STR(_b_) ((_b_) ? "true" : "false")
// Format 32-bit quantities.
#define INT32_FORMAT "%d"
--- a/hotspot/src/share/vm/utilities/workgroup.cpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/utilities/workgroup.cpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -156,7 +156,7 @@
tty->print_cr("/nFinished work gang %s: %d/%d sequence %d",
name(), finished_workers(), total_workers(),
_sequence_number);
- }
+ }
}
void AbstractWorkGang::stop() {
--- a/hotspot/src/share/vm/utilities/workgroup.hpp Tue Mar 22 12:12:31 2011 -0700
+++ b/hotspot/src/share/vm/utilities/workgroup.hpp Wed Jul 05 17:38:16 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -36,6 +36,20 @@
# include "thread_windows.inline.hpp"
#endif
+// Task class hierarchy:
+// AbstractGangTask
+// AbstractGangTaskWOopQueues
+//
+// Gang/Group class hierarchy:
+// AbstractWorkGang
+// WorkGang
+// FlexibleWorkGang
+// YieldingFlexibleWorkGang (defined in another file)
+//
+// Worker class hierarchy:
+// GangWorker (subclass of WorkerThread)
+// YieldingFlexibleGangWorker (defined in another file)
+
// Forward declarations of classes defined here
class WorkGang;