mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-16 05:15:22 +00:00
Merge
This commit is contained in:
commit
232ec9607b
3
.hgtags
3
.hgtags
@ -108,3 +108,6 @@ a36beda9b9de91231d92a2c529f21cc218fcf8d5 jdk7-b130
|
||||
d8af56da89bc0fc02a6b6ad78f51157a46d665ab jdk7-b131
|
||||
d61280d36755d1941fb487f554e8b7a6d0bca6a1 jdk7-b132
|
||||
fd444c61e7ed3d92b2a730da7c737b02191b682f jdk7-b133
|
||||
def8e16dd237a47fc067d66d4c616d7baaec6001 jdk7-b134
|
||||
f75a1efb141210901aabe00a834e0fc32bb8b337 jdk7-b135
|
||||
46acf76a533954cfd594bb88fdea79938abfbe20 jdk7-b136
|
||||
|
||||
@ -109,3 +109,5 @@ cc58c11af15411042719e9c82707fdbef60a9e0f jdk7-b130
|
||||
0f62a65fb666b337caa585015ab6ea2e60e709ca jdk7-b132
|
||||
c6f380693342feadccc5fe2c5adf500e861361aa jdk7-b133
|
||||
ddc2fcb3682ffd27f44354db666128827be7e3c3 jdk7-b134
|
||||
783bd02b4ab4596059c74b10a1793d7bd2f1c157 jdk7-b135
|
||||
2fe76e73adaa5133ac559f0b3c2c0707eca04580 jdk7-b136
|
||||
|
||||
9
README
9
README
@ -29,13 +29,14 @@ Simple Build Instructions:
|
||||
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.
|
||||
|
||||
@ -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>
|
||||
@ -1649,6 +1763,12 @@
|
||||
Where each of these directories contain the import JDK image
|
||||
for that platform.
|
||||
</dd>
|
||||
<dt><a name="ALT_OPENWIN_HOME"><tt>ALT_OPENWIN_HOME</tt></a></dt>
|
||||
<dd>
|
||||
The top-level directory of the libraries and include files for the platform's
|
||||
graphical programming environment. The default location is platform specific.
|
||||
For example, on Linux it defaults to <tt>/usr/X11R6/</tt>.
|
||||
</dd>
|
||||
<dt><strong>Windows specific:</strong></dt>
|
||||
<dd>
|
||||
<dl>
|
||||
@ -1659,9 +1779,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>
|
||||
@ -1678,10 +1797,160 @@
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt><strong>Cross-Compilation Support:</strong></dt>
|
||||
<dd>
|
||||
<dl>
|
||||
<dt><a name="CROSS_COMPILE_ARCH"><tt>CROSS_COMPILE_ARCH</tt></a> </dt>
|
||||
<dd>
|
||||
Set to the target architecture of a cross-compilation build. If set, this
|
||||
variable is used to signify that we are cross-compiling. The expectation
|
||||
is that <a href="#ALT_COMPILER_PATH"><tt>ALT_COMPILER_PATH</tt></a> is set
|
||||
to point to the cross-compiler and that any cross-compilation specific flags
|
||||
are passed using <a href="#EXTRA_CFLAGS"><tt>EXTRA_CFLAGS</tt></a>.
|
||||
The <a href="#ALT_OPENWIN_HOME"><tt>ALT_OPENWIN_HOME</tt></a> variable should
|
||||
also be set to point to the graphical header files (e.g. X11) provided with
|
||||
the cross-compiler.
|
||||
When cross-compiling we skip execution of any demos etc that may be built, and
|
||||
also skip binary-file verification.
|
||||
</dd>
|
||||
<dt><tt><a name="EXTRA_CFLAGS">EXTRA_CFLAGS</a></tt> </dt>
|
||||
<dd>
|
||||
Used to pass cross-compilation options to the cross-compiler.
|
||||
These are added to the <tt>CFLAGS</tt> and <tt>CXXFLAGS</tt> variables.
|
||||
</dd>
|
||||
<dt><tt><a name="USE_ONLY_BOOTDIR_TOOLS">USE_ONLY_BOOTDIR_TOOLS</a></tt> </dt>
|
||||
<dd>
|
||||
Used primarily for cross-compilation builds (and always set in that case)
|
||||
this variable indicates that tools from the boot JDK should be used during
|
||||
the build process, not the tools (<tt>javac</tt>, <tt>javah</tt>, <tt>jar</tt>)
|
||||
just built (which can't execute on the build host).
|
||||
</dd>
|
||||
<dt><tt><a name="HOST_CC">HOST_CC</a></tt> </dt>
|
||||
<dd>
|
||||
The location of the C compiler to generate programs to run on the build host.
|
||||
Some parts of the build generate programs that are then compiled and executed
|
||||
to produce other parts of the build. Normally the primary C compiler is used
|
||||
to do this, but when cross-compiling that would be the cross-compiler and the
|
||||
resulting program could not be executed.
|
||||
On Linux this defaults to <tt>/usr/bin/gcc</tt>; on other platforms it must be
|
||||
set explicitly.
|
||||
</dd>
|
||||
</dl>
|
||||
<dt><strong>Specialized Build Options:</strong></dt>
|
||||
<dd>
|
||||
Some build variables exist to support specialized build environments and/or specialized
|
||||
build products. Their use is only supported in those contexts:
|
||||
<dl>
|
||||
<dt><tt><a name="BUILD_CLIENT_ONLY">BUILD_CLIENT_ONLY</a></tt> </dt>
|
||||
<dd>
|
||||
Indicates this build will only contain the Hotspot client VM. In addition to
|
||||
controlling the Hotspot build target, it ensures that we don't try to copy
|
||||
any server VM files/directories, and defines a default <tt>jvm.cfg</tt> file
|
||||
suitable for a client-only environment. Using this in a 64-bit build will
|
||||
generate a sanity warning as 64-bit client builds are not directly supported.
|
||||
</dd>
|
||||
<dt><tt><a name="BUILD_HEADLESS_ONLY"></a>BUILD_HEADLESS_ONLY</tt> </dt>
|
||||
<dd>
|
||||
Used when the build environment has no graphical capabilities at all. This
|
||||
excludes building anything that requires graphical libraries to be available.
|
||||
</dd>
|
||||
<dt><tt><a name="JAVASE_EMBEDDED"></a>JAVASE_EMBEDDED</tt> </dt>
|
||||
<dd>
|
||||
Used to indicate this is a build of the Oracle Java SE Embedded product.
|
||||
This will enable the directives included in the SE-Embedded specific build
|
||||
files.
|
||||
</dd>
|
||||
<dt><tt><a name="LIBZIP_CAN_USE_MMAP">LIBZIP_CAN_USE_MMAP</a></tt> </dt>
|
||||
<dd>
|
||||
If set to false, disables the use of mmap by the zip utility. Otherwise,
|
||||
mmap will be used.
|
||||
</dd>
|
||||
<dt><tt><a name="COMPRESS_JARS"></a>COMPRESS_JARS</tt> </dt>
|
||||
<dd>
|
||||
If set to true, causes certain jar files that would otherwise be built without
|
||||
compression, to use compression.
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</blockquote>
|
||||
<!-- ------------------------------------------------------ -->
|
||||
<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.
|
||||
@ -1706,6 +1975,19 @@
|
||||
Some of the more common problems with builds are briefly described
|
||||
below, with suggestions for remedies.
|
||||
<ul>
|
||||
<li>
|
||||
<b>Corrupted Bundles on Windows:</b>
|
||||
<blockquote>
|
||||
Some virus scanning software has been known to corrupt the
|
||||
downloading of zip bundles.
|
||||
It may be necessary to disable the 'on access' or 'real time'
|
||||
virus scanning features to prevent this corruption.
|
||||
This type of "real time" virus scanning can also slow down the
|
||||
build process significantly.
|
||||
Temporarily disabling the feature, or excluding the build
|
||||
output directory may be necessary to get correct and faster builds.
|
||||
</blockquote>
|
||||
</li>
|
||||
<li>
|
||||
<b>Slow Builds:</b>
|
||||
<blockquote>
|
||||
@ -1801,7 +2083,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 +2096,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>
|
||||
|
||||
@ -108,3 +108,6 @@ d7532bcd3742f1576dd07ff9fbb535c9c9a276e9 jdk7-b126
|
||||
9d6dd2cdfcb92612dbd836ecded87770d52b49db jdk7-b131
|
||||
1b1e75e8f476e5c07f0d2b035993895e2603e1f0 jdk7-b132
|
||||
671fe2e623ffefb4b7c312be919fc71eb48c1df1 jdk7-b133
|
||||
918003855fa0dba5acf4bf1fe36526d2fc4c1ba8 jdk7-b134
|
||||
e0b72ae5dc5e824b342801c8d1d336a55eb54e2c jdk7-b135
|
||||
48ef0c712e7cbf272f47f9224db92a3c6a9e2612 jdk7-b136
|
||||
|
||||
@ -154,3 +154,9 @@ e9aa2ca89ad6c53420623d579765f9706ec523d7 hs21-b02
|
||||
0e531ab5ba04967a0e9aa6aef65e6eb3a0dcf632 jdk7-b132
|
||||
a8d643a4db47c7b58e0bcb49c77b5c3610de86a8 hs21-b03
|
||||
1b3a350709e4325d759bb453ff3fb6a463270488 jdk7-b133
|
||||
447e6faab4a8755d4860c2366630729dbaec111c jdk7-b134
|
||||
3c76374706ea8a77e15aec8310e831e5734f8775 hs21-b04
|
||||
b898f0fc3cedc972d884d31a751afd75969531cf jdk7-b135
|
||||
b898f0fc3cedc972d884d31a751afd75969531cf hs21-b05
|
||||
bd586e392d93b7ed7a1636dcc8da2b6a4203a102 jdk7-b136
|
||||
bd586e392d93b7ed7a1636dcc8da2b6a4203a102 hs21-b06
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2003, 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
|
||||
@ -27,7 +27,7 @@ package sun.jvm.hotspot.jdi;
|
||||
import com.sun.jdi.*;
|
||||
import sun.jvm.hotspot.oops.Instance;
|
||||
import sun.jvm.hotspot.oops.Klass;
|
||||
import sun.jvm.hotspot.oops.OopUtilities;
|
||||
import sun.jvm.hotspot.oops.java_lang_Class;
|
||||
|
||||
public class ClassObjectReferenceImpl extends ObjectReferenceImpl
|
||||
implements ClassObjectReference {
|
||||
@ -39,7 +39,7 @@ public class ClassObjectReferenceImpl extends ObjectReferenceImpl
|
||||
|
||||
public ReferenceType reflectedType() {
|
||||
if (reflectedType == null) {
|
||||
Klass k = OopUtilities.classOopToKlass(ref());
|
||||
Klass k = java_lang_Class.asKlass(ref());
|
||||
reflectedType = vm.referenceType(k);
|
||||
}
|
||||
return reflectedType;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2003, 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
|
||||
@ -62,7 +62,7 @@ public class FieldImpl extends TypeComponentImpl implements Field {
|
||||
|
||||
// get the value of static field
|
||||
ValueImpl getValue() {
|
||||
return getValue(saField.getFieldHolder());
|
||||
return getValue(saField.getFieldHolder().getJavaMirror());
|
||||
}
|
||||
|
||||
// get the value of this Field from a specific Oop
|
||||
|
||||
@ -44,12 +44,10 @@ public class StringTable extends sun.jvm.hotspot.utilities.Hashtable {
|
||||
private static synchronized void initialize(TypeDataBase db) {
|
||||
Type type = db.lookupType("StringTable");
|
||||
theTableField = type.getAddressField("_the_table");
|
||||
stringTableSize = db.lookupIntConstant("StringTable::string_table_size").intValue();
|
||||
}
|
||||
|
||||
// Fields
|
||||
private static AddressField theTableField;
|
||||
private static int stringTableSize;
|
||||
|
||||
// Accessors
|
||||
public static StringTable getTheTable() {
|
||||
@ -57,10 +55,6 @@ public class StringTable extends sun.jvm.hotspot.utilities.Hashtable {
|
||||
return (StringTable) VMObjectFactory.newObject(StringTable.class, tmp);
|
||||
}
|
||||
|
||||
public static int getStringTableSize() {
|
||||
return stringTableSize;
|
||||
}
|
||||
|
||||
public StringTable(Address addr) {
|
||||
super(addr);
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2008, 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
|
||||
@ -64,7 +64,7 @@ public class Instance extends Oop {
|
||||
|
||||
public void iterateFields(OopVisitor visitor, boolean doVMFields) {
|
||||
super.iterateFields(visitor, doVMFields);
|
||||
((InstanceKlass) getKlass()).iterateNonStaticFields(visitor);
|
||||
((InstanceKlass) getKlass()).iterateNonStaticFields(visitor, this);
|
||||
}
|
||||
|
||||
public void printValueOn(PrintStream tty) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2008, 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
|
||||
@ -87,7 +87,7 @@ public class InstanceKlass extends Klass {
|
||||
innerClasses = new OopField(type.getOopField("_inner_classes"), Oop.getHeaderSize());
|
||||
nonstaticFieldSize = new CIntField(type.getCIntegerField("_nonstatic_field_size"), Oop.getHeaderSize());
|
||||
staticFieldSize = new CIntField(type.getCIntegerField("_static_field_size"), Oop.getHeaderSize());
|
||||
staticOopFieldSize = new CIntField(type.getCIntegerField("_static_oop_field_size"), Oop.getHeaderSize());
|
||||
staticOopFieldCount = new CIntField(type.getCIntegerField("_static_oop_field_count"), Oop.getHeaderSize());
|
||||
nonstaticOopMapSize = new CIntField(type.getCIntegerField("_nonstatic_oop_map_size"), Oop.getHeaderSize());
|
||||
isMarkedDependent = new CIntField(type.getCIntegerField("_is_marked_dependent"), Oop.getHeaderSize());
|
||||
initState = new CIntField(type.getCIntegerField("_init_state"), Oop.getHeaderSize());
|
||||
@ -140,7 +140,7 @@ public class InstanceKlass extends Klass {
|
||||
private static OopField innerClasses;
|
||||
private static CIntField nonstaticFieldSize;
|
||||
private static CIntField staticFieldSize;
|
||||
private static CIntField staticOopFieldSize;
|
||||
private static CIntField staticOopFieldCount;
|
||||
private static CIntField nonstaticOopMapSize;
|
||||
private static CIntField isMarkedDependent;
|
||||
private static CIntField initState;
|
||||
@ -241,6 +241,10 @@ public class InstanceKlass extends Klass {
|
||||
// Byteside of the header
|
||||
private static long headerSize;
|
||||
|
||||
public long getObjectSize(Oop object) {
|
||||
return getSizeHelper() * VM.getVM().getAddressSize();
|
||||
}
|
||||
|
||||
public static long getHeaderSize() { return headerSize; }
|
||||
|
||||
// Accessors for declared fields
|
||||
@ -261,8 +265,7 @@ public class InstanceKlass extends Klass {
|
||||
public Symbol getSourceDebugExtension(){ return getSymbol(sourceDebugExtension); }
|
||||
public TypeArray getInnerClasses() { return (TypeArray) innerClasses.getValue(this); }
|
||||
public long getNonstaticFieldSize() { return nonstaticFieldSize.getValue(this); }
|
||||
public long getStaticFieldSize() { return staticFieldSize.getValue(this); }
|
||||
public long getStaticOopFieldSize() { return staticOopFieldSize.getValue(this); }
|
||||
public long getStaticOopFieldCount() { return staticOopFieldCount.getValue(this); }
|
||||
public long getNonstaticOopMapSize() { return nonstaticOopMapSize.getValue(this); }
|
||||
public boolean getIsMarkedDependent() { return isMarkedDependent.getValue(this) != 0; }
|
||||
public long getVtableLen() { return vtableLen.getValue(this); }
|
||||
@ -453,14 +456,29 @@ public class InstanceKlass extends Klass {
|
||||
visitor.doOop(innerClasses, true);
|
||||
visitor.doCInt(nonstaticFieldSize, true);
|
||||
visitor.doCInt(staticFieldSize, true);
|
||||
visitor.doCInt(staticOopFieldSize, true);
|
||||
visitor.doCInt(staticOopFieldCount, true);
|
||||
visitor.doCInt(nonstaticOopMapSize, true);
|
||||
visitor.doCInt(isMarkedDependent, true);
|
||||
visitor.doCInt(initState, true);
|
||||
visitor.doCInt(vtableLen, true);
|
||||
visitor.doCInt(itableLen, true);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Visit the static fields of this InstanceKlass with the obj of
|
||||
* the visitor set to the oop holding the fields, which is
|
||||
* currently the java mirror.
|
||||
*/
|
||||
public void iterateStaticFields(OopVisitor visitor) {
|
||||
visitor.setObj(getJavaMirror());
|
||||
visitor.prologue();
|
||||
iterateStaticFieldsInternal(visitor);
|
||||
visitor.epilogue();
|
||||
|
||||
}
|
||||
|
||||
void iterateStaticFieldsInternal(OopVisitor visitor) {
|
||||
TypeArray fields = getFields();
|
||||
int length = (int) fields.getLength();
|
||||
for (int index = 0; index < length; index += NEXT_OFFSET) {
|
||||
@ -478,9 +496,9 @@ public class InstanceKlass extends Klass {
|
||||
return getSuper();
|
||||
}
|
||||
|
||||
public void iterateNonStaticFields(OopVisitor visitor) {
|
||||
public void iterateNonStaticFields(OopVisitor visitor, Oop obj) {
|
||||
if (getSuper() != null) {
|
||||
((InstanceKlass) getSuper()).iterateNonStaticFields(visitor);
|
||||
((InstanceKlass) getSuper()).iterateNonStaticFields(visitor, obj);
|
||||
}
|
||||
TypeArray fields = getFields();
|
||||
|
||||
@ -692,7 +710,7 @@ public class InstanceKlass extends Klass {
|
||||
public long getObjectSize() {
|
||||
long bodySize = alignObjectOffset(getVtableLen() * getHeap().getOopSize())
|
||||
+ alignObjectOffset(getItableLen() * getHeap().getOopSize())
|
||||
+ (getStaticFieldSize() + getNonstaticOopMapSize()) * getHeap().getOopSize();
|
||||
+ (getNonstaticOopMapSize()) * getHeap().getOopSize();
|
||||
return alignObjectSize(headerSize + bodySize);
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.jvm.hotspot.oops;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import sun.jvm.hotspot.debugger.*;
|
||||
import sun.jvm.hotspot.memory.*;
|
||||
import sun.jvm.hotspot.runtime.*;
|
||||
import sun.jvm.hotspot.types.*;
|
||||
import sun.jvm.hotspot.utilities.*;
|
||||
|
||||
// An InstanceKlass is the VM level representation of a Java class.
|
||||
|
||||
public class InstanceMirrorKlass extends InstanceKlass {
|
||||
static {
|
||||
VM.registerVMInitializedObserver(new Observer() {
|
||||
public void update(Observable o, Object data) {
|
||||
initialize(VM.getVM().getTypeDataBase());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
|
||||
// Just make sure it's there for now
|
||||
Type type = db.lookupType("instanceMirrorKlass");
|
||||
}
|
||||
|
||||
InstanceMirrorKlass(OopHandle handle, ObjectHeap heap) {
|
||||
super(handle, heap);
|
||||
}
|
||||
|
||||
public long getObjectSize(Oop o) {
|
||||
return java_lang_Class.getOopSize(o) * VM.getVM().getAddressSize();
|
||||
}
|
||||
|
||||
public void iterateNonStaticFields(OopVisitor visitor, Oop obj) {
|
||||
super.iterateNonStaticFields(visitor, obj);
|
||||
// Fetch the real klass from the mirror object
|
||||
Klass klass = java_lang_Class.asKlass(obj);
|
||||
if (klass instanceof InstanceKlass) {
|
||||
((InstanceKlass)klass).iterateStaticFields(visitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 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
|
||||
@ -40,7 +40,12 @@ public class IntField extends Field {
|
||||
super(holder, fieldArrayIndex);
|
||||
}
|
||||
|
||||
public int getValue(Oop obj) { return obj.getHandle().getJIntAt(getOffset()); }
|
||||
public int getValue(Oop obj) {
|
||||
if (!isVMField() && !obj.isInstance() && !obj.isArray()) {
|
||||
throw new InternalError(obj.toString());
|
||||
}
|
||||
return obj.getHandle().getJIntAt(getOffset());
|
||||
}
|
||||
public void setValue(Oop obj, int value) throws MutationException {
|
||||
// Fix this: setJIntAt is missing in Address
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2008, 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
|
||||
@ -362,7 +362,16 @@ public class ObjectHeap {
|
||||
if (klass.equals(compiledICHolderKlassHandle)) return new CompiledICHolder(handle, this);
|
||||
if (klass.equals(methodDataKlassHandle)) return new MethodData(handle, this);
|
||||
}
|
||||
if (klass.equals(instanceKlassKlassHandle)) return new InstanceKlass(handle, this);
|
||||
if (klass.equals(instanceKlassKlassHandle)) {
|
||||
InstanceKlass ik = new InstanceKlass(handle, this);
|
||||
if (ik.getName().asString().equals("java/lang/Class")) {
|
||||
// We would normally do this using the vtable style
|
||||
// lookup but since it's not used for these currently
|
||||
// it's simpler to just check for the name.
|
||||
return new InstanceMirrorKlass(handle, this);
|
||||
}
|
||||
return ik;
|
||||
}
|
||||
if (klass.equals(objArrayKlassKlassHandle)) return new ObjArrayKlass(handle, this);
|
||||
if (klass.equals(typeArrayKlassKlassHandle)) return new TypeArrayKlass(handle, this);
|
||||
|
||||
|
||||
@ -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
|
||||
@ -103,12 +103,8 @@ public class Oop {
|
||||
// Returns the byte size of this object
|
||||
public long getObjectSize() {
|
||||
Klass k = getKlass();
|
||||
if (k instanceof InstanceKlass) {
|
||||
return ((InstanceKlass)k).getSizeHelper()
|
||||
* VM.getVM().getAddressSize();
|
||||
}
|
||||
// If it is not an instance, this method should be replaced.
|
||||
return getHeaderSize();
|
||||
// All other types should be overriding getObjectSize directly
|
||||
return ((InstanceKlass)k).getObjectSize(this);
|
||||
}
|
||||
|
||||
// Type test operations
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2002, 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
|
||||
@ -41,11 +41,17 @@ public class OopField extends Field {
|
||||
}
|
||||
|
||||
public Oop getValue(Oop obj) {
|
||||
if (!isVMField() && !obj.isInstance() && !obj.isArray()) {
|
||||
throw new InternalError();
|
||||
}
|
||||
return obj.getHeap().newOop(getValueAsOopHandle(obj));
|
||||
}
|
||||
|
||||
/** Debugging support */
|
||||
public OopHandle getValueAsOopHandle(Oop obj) {
|
||||
if (!isVMField() && !obj.isInstance() && !obj.isArray()) {
|
||||
throw new InternalError(obj.toString());
|
||||
}
|
||||
return obj.getHandle().getOopHandleAt(getOffset());
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2008, 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
|
||||
@ -74,9 +74,6 @@ public class OopUtilities implements /* imports */ JVMTIThreadState {
|
||||
private static int THREAD_STATUS_TERMINATED;
|
||||
*/
|
||||
|
||||
// java.lang.Class fields
|
||||
private static OopField hcKlassField;
|
||||
|
||||
// java.util.concurrent.locks.AbstractOwnableSynchronizer fields
|
||||
private static OopField absOwnSyncOwnerThreadField;
|
||||
|
||||
@ -268,33 +265,6 @@ public class OopUtilities implements /* imports */ JVMTIThreadState {
|
||||
return null;
|
||||
}
|
||||
|
||||
// initialize fields for java.lang.Class
|
||||
private static void initClassFields() {
|
||||
if (hcKlassField == null) {
|
||||
// hc_klass is a HotSpot magic field and hence we can't
|
||||
// find it from InstanceKlass for java.lang.Class.
|
||||
TypeDataBase db = VM.getVM().getTypeDataBase();
|
||||
int hcKlassOffset = (int) Instance.getHeaderSize();
|
||||
try {
|
||||
hcKlassOffset += (db.lookupIntConstant("java_lang_Class::hc_klass_offset").intValue() *
|
||||
VM.getVM().getHeapOopSize());
|
||||
} catch (RuntimeException re) {
|
||||
// ignore, currently java_lang_Class::hc_klass_offset is zero
|
||||
}
|
||||
if (VM.getVM().isCompressedOopsEnabled()) {
|
||||
hcKlassField = new NarrowOopField(new NamedFieldIdentifier("hc_klass"), hcKlassOffset, true);
|
||||
} else {
|
||||
hcKlassField = new OopField(new NamedFieldIdentifier("hc_klass"), hcKlassOffset, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** get klassOop field at offset hc_klass_offset from a java.lang.Class object */
|
||||
public static Klass classOopToKlass(Oop aClass) {
|
||||
initClassFields();
|
||||
return (Klass) hcKlassField.getValue(aClass);
|
||||
}
|
||||
|
||||
// initialize fields for j.u.c.l AbstractOwnableSynchornizer class
|
||||
private static void initAbsOwnSyncFields() {
|
||||
if (absOwnSyncOwnerThreadField == null) {
|
||||
|
||||
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.jvm.hotspot.oops;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import sun.jvm.hotspot.debugger.*;
|
||||
import sun.jvm.hotspot.memory.*;
|
||||
import sun.jvm.hotspot.runtime.*;
|
||||
import sun.jvm.hotspot.types.Type;
|
||||
import sun.jvm.hotspot.types.TypeDataBase;
|
||||
import sun.jvm.hotspot.utilities.*;
|
||||
import sun.jvm.hotspot.jdi.JVMTIThreadState;
|
||||
|
||||
/** A utility class encapsulating useful oop operations */
|
||||
|
||||
// initialize fields for java.lang.Class
|
||||
public class java_lang_Class {
|
||||
|
||||
// java.lang.Class fields
|
||||
static OopField klassField;
|
||||
static IntField oopSizeField;
|
||||
|
||||
static {
|
||||
VM.registerVMInitializedObserver(new Observer() {
|
||||
public void update(Observable o, Object data) {
|
||||
initialize(VM.getVM().getTypeDataBase());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static synchronized void initialize(TypeDataBase db) {
|
||||
// klass and oop_size are HotSpot magic fields and hence we can't
|
||||
// find them from InstanceKlass for java.lang.Class.
|
||||
Type jlc = db.lookupType("java_lang_Class");
|
||||
int klassOffset = (int) jlc.getCIntegerField("klass_offset").getValue();
|
||||
if (VM.getVM().isCompressedOopsEnabled()) {
|
||||
klassField = new NarrowOopField(new NamedFieldIdentifier("klass"), klassOffset, true);
|
||||
} else {
|
||||
klassField = new OopField(new NamedFieldIdentifier("klass"), klassOffset, true);
|
||||
}
|
||||
int oopSizeOffset = (int) jlc.getCIntegerField("oop_size_offset").getValue();
|
||||
oopSizeField = new IntField(new NamedFieldIdentifier("oop_size"), oopSizeOffset, true);
|
||||
}
|
||||
|
||||
/** get klassOop field at offset hc_klass_offset from a java.lang.Class object */
|
||||
public static Klass asKlass(Oop aClass) {
|
||||
return (Klass) java_lang_Class.klassField.getValue(aClass);
|
||||
}
|
||||
|
||||
/** get oop_size field at offset oop_size_offset from a java.lang.Class object */
|
||||
public static long getOopSize(Oop aClass) {
|
||||
return java_lang_Class.oopSizeField.getValue(aClass);
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
@ -839,20 +839,18 @@ public class VM {
|
||||
}
|
||||
|
||||
private void readSystemProperties() {
|
||||
InstanceKlass systemKls = getSystemDictionary().getSystemKlass();
|
||||
systemKls.iterate(new DefaultOopVisitor() {
|
||||
ObjectReader objReader = new ObjectReader();
|
||||
public void doOop(sun.jvm.hotspot.oops.OopField field, boolean isVMField) {
|
||||
if (field.getID().getName().equals("props")) {
|
||||
try {
|
||||
sysProps = (Properties) objReader.readObject(field.getValue(getObj()));
|
||||
} catch (Exception e) {
|
||||
if (Assert.ASSERTS_ENABLED) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, false);
|
||||
final InstanceKlass systemKls = getSystemDictionary().getSystemKlass();
|
||||
systemKls.iterateStaticFields(new DefaultOopVisitor() {
|
||||
ObjectReader objReader = new ObjectReader();
|
||||
public void doOop(sun.jvm.hotspot.oops.OopField field, boolean isVMField) {
|
||||
if (field.getID().getName().equals("props")) {
|
||||
try {
|
||||
sysProps = (Properties) objReader.readObject(field.getValue(getObj()));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2004, 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
|
||||
@ -64,16 +64,16 @@ public class FinalizerInfo extends Tool {
|
||||
*/
|
||||
InstanceKlass ik =
|
||||
SystemDictionaryHelper.findInstanceKlass("java.lang.ref.Finalizer");
|
||||
final OopField queueField[] = new OopField[1];
|
||||
ik.iterateFields(new DefaultOopVisitor() {
|
||||
final Oop[] queueref = new Oop[1];
|
||||
ik.iterateStaticFields(new DefaultOopVisitor() {
|
||||
public void doOop(OopField field, boolean isVMField) {
|
||||
String name = field.getID().getName();
|
||||
if (name.equals("queue")) {
|
||||
queueField[0] = field;
|
||||
}
|
||||
String name = field.getID().getName();
|
||||
if (name.equals("queue")) {
|
||||
queueref[0] = field.getValue(getObj());
|
||||
}
|
||||
}
|
||||
}, false);
|
||||
Oop queue = queueField[0].getValue(ik);
|
||||
});
|
||||
Oop queue = queueref[0];
|
||||
|
||||
InstanceKlass k = (InstanceKlass) queue.getKlass();
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2004, 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
|
||||
@ -164,7 +164,7 @@ public class HeapGXLWriter extends AbstractHeapGraphWriter {
|
||||
|
||||
protected void writeClass(Instance instance) throws IOException {
|
||||
writeObjectHeader(instance);
|
||||
Klass reflectedType = OopUtilities.classOopToKlass(instance);
|
||||
Klass reflectedType = java_lang_Class.asKlass(instance);
|
||||
boolean isInstanceKlass = (reflectedType instanceof InstanceKlass);
|
||||
// reflectedType is null for primitive types (int.class etc).
|
||||
if (reflectedType != null) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2004, 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
|
||||
@ -455,7 +455,7 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
|
||||
}
|
||||
|
||||
protected void writeClass(Instance instance) throws IOException {
|
||||
Klass reflectedKlass = OopUtilities.classOopToKlass(instance);
|
||||
Klass reflectedKlass = java_lang_Class.asKlass(instance);
|
||||
// dump instance record only for primitive type Class objects.
|
||||
// all other Class objects are covered by writeClassDumpRecords.
|
||||
if (reflectedKlass == null) {
|
||||
@ -746,7 +746,7 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
|
||||
out.writeByte((byte)kind);
|
||||
if (ik != null) {
|
||||
// static field
|
||||
writeField(field, ik);
|
||||
writeField(field, ik.getJavaMirror());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2008, 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
|
||||
@ -117,10 +117,10 @@ public class ReversePtrsAnalysis {
|
||||
public boolean doObj(Oop obj) {
|
||||
if (obj instanceof InstanceKlass) {
|
||||
final InstanceKlass ik = (InstanceKlass) obj;
|
||||
ik.iterateFields(
|
||||
ik.iterateStaticFields(
|
||||
new DefaultOopVisitor() {
|
||||
public void doOop(OopField field, boolean isVMField) {
|
||||
Oop next = field.getValue(ik);
|
||||
Oop next = field.getValue(getObj());
|
||||
LivenessPathElement lp = new LivenessPathElement(null,
|
||||
new NamedFieldIdentifier("Static field \"" +
|
||||
field.getID().getName() +
|
||||
@ -142,8 +142,7 @@ public class ReversePtrsAnalysis {
|
||||
System.err.println();
|
||||
}
|
||||
}
|
||||
},
|
||||
false);
|
||||
});
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2004, 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
|
||||
@ -158,7 +158,7 @@ public class JSJavaFactoryImpl implements JSJavaFactory {
|
||||
} else if (className.equals(javaLangThread())) {
|
||||
res = new JSJavaThread(instance, this);
|
||||
} else if (className.equals(javaLangClass())) {
|
||||
Klass reflectedType = OopUtilities.classOopToKlass(instance);
|
||||
Klass reflectedType = java_lang_Class.asKlass(instance);
|
||||
if (reflectedType != null) {
|
||||
JSJavaKlass jk = newJSJavaKlass(reflectedType);
|
||||
// we don't support mirrors of VM internal Klasses
|
||||
|
||||
@ -43,6 +43,7 @@ if [ "$1" == "-help" ]; then
|
||||
fi
|
||||
|
||||
jdk=$1
|
||||
shift
|
||||
OS=`uname`
|
||||
|
||||
if [ "$OS" != "Linux" ]; then
|
||||
@ -68,7 +69,7 @@ fi
|
||||
|
||||
tmp=/tmp/sagsetup
|
||||
rm -f $tmp
|
||||
$jdk/bin/java sagtarg > $tmp &
|
||||
$jdk/bin/java $* sagtarg > $tmp &
|
||||
pid=$!
|
||||
while [ ! -s $tmp ] ; do
|
||||
# Kludge alert!
|
||||
|
||||
@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2011
|
||||
|
||||
HS_MAJOR_VER=21
|
||||
HS_MINOR_VER=0
|
||||
HS_BUILD_NUMBER=04
|
||||
HS_BUILD_NUMBER=07
|
||||
|
||||
JDK_MAJOR_VER=1
|
||||
JDK_MINOR_VER=7
|
||||
|
||||
@ -102,7 +102,7 @@ all: $(EXEC)
|
||||
|
||||
$(EXEC) : $(OBJECTS)
|
||||
@echo Making adlc
|
||||
$(QUIETLY) $(LINK_NOPROF.CC) -o $(EXEC) $(OBJECTS)
|
||||
$(QUIETLY) $(HOST.LINK_NOPROF.CC) -o $(EXEC) $(OBJECTS)
|
||||
|
||||
# Random dependencies:
|
||||
$(OBJECTS): opcodes.hpp classes.hpp adlc.hpp adlcVMDeps.hpp adlparse.hpp archDesc.hpp arena.hpp dict2.hpp filebuff.hpp forms.hpp formsopt.hpp formssel.hpp
|
||||
@ -204,14 +204,14 @@ PROCESS_AD_FILES = awk '{ \
|
||||
$(OUTDIR)/%.o: %.cpp
|
||||
@echo Compiling $<
|
||||
$(QUIETLY) $(REMOVE_TARGET)
|
||||
$(QUIETLY) $(COMPILE.CC) -o $@ $< $(COMPILE_DONE)
|
||||
$(QUIETLY) $(HOST.COMPILE.CC) -o $@ $< $(COMPILE_DONE)
|
||||
|
||||
# Some object files are given a prefix, to disambiguate
|
||||
# them from objects of the same name built for the VM.
|
||||
$(OUTDIR)/adlc-%.o: %.cpp
|
||||
@echo Compiling $<
|
||||
$(QUIETLY) $(REMOVE_TARGET)
|
||||
$(QUIETLY) $(COMPILE.CC) -o $@ $< $(COMPILE_DONE)
|
||||
$(QUIETLY) $(HOST.COMPILE.CC) -o $@ $< $(COMPILE_DONE)
|
||||
|
||||
# #########################################################################
|
||||
|
||||
|
||||
@ -30,9 +30,13 @@
|
||||
ifdef CROSS_COMPILE_ARCH
|
||||
CPP = $(ALT_COMPILER_PATH)/g++
|
||||
CC = $(ALT_COMPILER_PATH)/gcc
|
||||
HOSTCPP = g++
|
||||
HOSTCC = gcc
|
||||
else
|
||||
CPP = g++
|
||||
CC = gcc
|
||||
HOSTCPP = $(CPP)
|
||||
HOSTCC = $(CC)
|
||||
endif
|
||||
|
||||
AS = $(CC) -c
|
||||
|
||||
@ -55,6 +55,14 @@ LINK_NOPROF.CC = $(CCC) $(LFLAGS) $(AOUT_FLAGS)
|
||||
LINK_LIB.CC = $(CCC) $(LFLAGS) $(SHARED_FLAG)
|
||||
PREPROCESS.CC = $(CC_COMPILE) -E
|
||||
|
||||
# cross compiling the jvm with c2 requires host compilers to build
|
||||
# adlc tool
|
||||
|
||||
HOST.CC_COMPILE = $(HOSTCPP) $(CPPFLAGS) $(CFLAGS)
|
||||
HOST.COMPILE.CC = $(HOST.CC_COMPILE) -c
|
||||
HOST.LINK_NOPROF.CC = $(HOSTCPP) $(LFLAGS) $(AOUT_FLAGS)
|
||||
|
||||
|
||||
# Effect of REMOVE_TARGET is to delete out-of-date files during "gnumake -k".
|
||||
REMOVE_TARGET = rm -f $@
|
||||
|
||||
|
||||
@ -29,6 +29,9 @@ CPP = CC
|
||||
CC = cc
|
||||
AS = $(CC) -c
|
||||
|
||||
HOSTCPP = $(CPP)
|
||||
HOSTCC = $(CC)
|
||||
|
||||
ARCHFLAG = $(ARCHFLAG/$(BUILDARCH))
|
||||
ARCHFLAG/i486 = -m32
|
||||
ARCHFLAG/amd64 = -m64
|
||||
|
||||
@ -93,16 +93,15 @@ if "%MSC_VER%" == "1500" (
|
||||
echo Will generate VC9 {Visual Studio 2008}
|
||||
) else (
|
||||
if "%MSC_VER%" == "1600" (
|
||||
echo Detected Visual Studio 2010, but
|
||||
echo will generate VC9 {Visual Studio 2008}
|
||||
echo Use conversion wizard in VS 2010.
|
||||
echo Will generate VC10 {Visual Studio 2010}
|
||||
set ProjectFile=%HotSpotBuildSpace%\jvm.vcxproj
|
||||
) else (
|
||||
echo Will generate VC7 project {Visual Studio 2003 .NET}
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
echo %ProjectFile%
|
||||
echo %ProjectFile%
|
||||
echo **************************************************************
|
||||
|
||||
REM Test all variables to see whether the directories they
|
||||
|
||||
@ -27,10 +27,6 @@
|
||||
# This is used externally by both batch and IDE builds, so can't
|
||||
# reference any of the HOTSPOTWORKSPACE, HOTSPOTBUILDSPACE,
|
||||
# HOTSPOTRELEASEBINDEST, or HOTSPOTDEBUGBINDEST environment variables.
|
||||
#
|
||||
# NOTE: unfortunately the ProjectCreatorSources list must be kept
|
||||
# synchronized between this and the Solaris version
|
||||
# (make/solaris/makefiles/projectcreator.make).
|
||||
|
||||
ProjectCreatorSources=\
|
||||
$(WorkSpace)\src\share\tools\ProjectCreator\DirectoryTree.java \
|
||||
@ -42,6 +38,7 @@ ProjectCreatorSources=\
|
||||
$(WorkSpace)\src\share\tools\ProjectCreator\WinGammaPlatformVC7.java \
|
||||
$(WorkSpace)\src\share\tools\ProjectCreator\WinGammaPlatformVC8.java \
|
||||
$(WorkSpace)\src\share\tools\ProjectCreator\WinGammaPlatformVC9.java \
|
||||
$(WorkSpace)\src\share\tools\ProjectCreator\WinGammaPlatformVC10.java \
|
||||
$(WorkSpace)\src\share\tools\ProjectCreator\Util.java \
|
||||
$(WorkSpace)\src\share\tools\ProjectCreator\BuildConfig.java \
|
||||
$(WorkSpace)\src\share\tools\ProjectCreator\ArgsParser.java
|
||||
|
||||
@ -65,8 +65,8 @@ VcVersion=VC9
|
||||
|
||||
!elseif "$(MSC_VER)" == "1600"
|
||||
|
||||
# for compatibility - we don't yet have a ProjectCreator for VC10
|
||||
VcVersion=VC9
|
||||
VcVersion=VC10
|
||||
ProjectFile=jvm.vcxproj
|
||||
|
||||
!else
|
||||
|
||||
|
||||
@ -3179,7 +3179,7 @@ void MacroAssembler::check_method_handle_type(Register mtype_reg, Register mh_re
|
||||
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 @@ void MacroAssembler::load_method_handle_vmslots(Register vmslots_reg, Register m
|
||||
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 @@ void MacroAssembler::jump_to_method_handle_entry(Register mh_reg, Register temp_
|
||||
|
||||
// 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);
|
||||
|
||||
@ -301,7 +301,8 @@ void PatchingStub::emit_code(LIR_Assembler* ce) {
|
||||
// thread.
|
||||
assert(_obj != noreg, "must be a valid register");
|
||||
assert(_oop_index >= 0, "must have oop index");
|
||||
__ ld_ptr(_obj, instanceKlass::init_thread_offset_in_bytes() + sizeof(klassOopDesc), G3);
|
||||
__ load_heap_oop(_obj, java_lang_Class::klass_offset_in_bytes(), G3);
|
||||
__ ld_ptr(G3, instanceKlass::init_thread_offset_in_bytes() + sizeof(klassOopDesc), G3);
|
||||
__ cmp(G2_thread, G3);
|
||||
__ br(Assembler::notEqual, false, Assembler::pn, call_patch);
|
||||
__ delayed()->nop();
|
||||
|
||||
@ -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,8 +1188,8 @@ void CppInterpreterGenerator::generate_compute_interpreter_state(const Register
|
||||
__ 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
|
||||
//6815692//if (EnableMethodHandles)
|
||||
guarantee(!EnableInvokeDynamic, "no support yet for java.lang.invoke.MethodHandle"); //6815692
|
||||
//6815692//if (EnableInvokeDynamic)
|
||||
//6815692// __ inc(O3, methodOopDesc::extra_stack_entries());
|
||||
__ sll(O3, LogBytesPerWord, O3);
|
||||
__ sub(O2, O3, O3);
|
||||
|
||||
@ -80,13 +80,19 @@ void CompactingPermGenGen::generate_vtable_methods(void** vtbl_list,
|
||||
for (int j = 0; j < num_virtuals; ++j) {
|
||||
dummy_vtable[num_virtuals * i + j] = (void*)masm->pc();
|
||||
__ save(SP, -256, SP);
|
||||
int offset = (i << 8) + j;
|
||||
Register src = G0;
|
||||
if (!Assembler::is_simm13(offset)) {
|
||||
__ sethi(offset, L0);
|
||||
src = L0;
|
||||
offset = offset & ((1 << 10) - 1);
|
||||
}
|
||||
__ brx(Assembler::always, false, Assembler::pt, common_code);
|
||||
|
||||
// Load L0 with a value indicating vtable/offset pair.
|
||||
// -- bits[ 7..0] (8 bits) which virtual method in table?
|
||||
// -- bits[12..8] (5 bits) which virtual method table?
|
||||
// -- must fit in 13-bit instruction immediate field.
|
||||
__ delayed()->set((i << 8) + j, L0);
|
||||
// -- bits[13..8] (6 bits) which virtual method table?
|
||||
__ delayed()->or3(src, offset, L0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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, CodeEntryAlignment, 32);
|
||||
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, RewriteFrequentPairs, true);
|
||||
|
||||
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
|
||||
|
||||
@ -743,12 +743,12 @@ void InterpreterMacroAssembler::get_cache_index_at_bcp(Register cache, Register
|
||||
if (index_size == sizeof(u2)) {
|
||||
get_2_byte_integer_at_bcp(bcp_offset, cache, tmp, Unsigned);
|
||||
} else if (index_size == sizeof(u4)) {
|
||||
assert(EnableInvokeDynamic, "giant index used only for EnableInvokeDynamic");
|
||||
assert(EnableInvokeDynamic, "giant index used only for JSR 292");
|
||||
get_4_byte_integer_at_bcp(bcp_offset, cache, tmp);
|
||||
assert(constantPoolCacheOopDesc::decode_secondary_index(~123) == 123, "else change next line");
|
||||
xor3(tmp, -1, tmp); // convert to plain index
|
||||
} else if (index_size == sizeof(u1)) {
|
||||
assert(EnableMethodHandles, "tiny index used only for EnableMethodHandles");
|
||||
assert(EnableInvokeDynamic, "tiny index used only for JSR 292");
|
||||
ldub(Lbcp, bcp_offset, tmp);
|
||||
} else {
|
||||
ShouldNotReachHere();
|
||||
|
||||
@ -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,9 +260,9 @@ address InterpreterGenerator::generate_abstract_entry(void) {
|
||||
|
||||
|
||||
// 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) {
|
||||
if (!EnableInvokeDynamic) {
|
||||
return generate_abstract_entry();
|
||||
}
|
||||
|
||||
|
||||
@ -112,8 +112,8 @@ address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler*
|
||||
}
|
||||
|
||||
// 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 @@ address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler*
|
||||
// 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 @@ void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adapt
|
||||
|
||||
// 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 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
|
||||
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 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
|
||||
__ 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);
|
||||
@ -775,9 +775,13 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
|
||||
switch (ek) {
|
||||
case _adapter_opt_i2l:
|
||||
{
|
||||
__ ldsw(arg_lsw, O2_scratch); // Load LSW
|
||||
NOT_LP64(__ srlx(O2_scratch, BitsPerInt, O3_scratch)); // Move high bits to lower bits for std
|
||||
__ st_long(O2_scratch, arg_msw); // Uses O2/O3 on !_LP64
|
||||
#ifdef _LP64
|
||||
__ ldsw(arg_lsw, O2_scratch); // Load LSW sign-extended
|
||||
#else
|
||||
__ ldsw(arg_lsw, O3_scratch); // Load LSW sign-extended
|
||||
__ srlx(O3_scratch, BitsPerInt, O2_scratch); // Move MSW value to lower 32-bits for std
|
||||
#endif
|
||||
__ st_long(O2_scratch, arg_msw); // Uses O2/O3 on !_LP64
|
||||
}
|
||||
break;
|
||||
case _adapter_opt_unboxl:
|
||||
|
||||
@ -52,6 +52,22 @@ void NativeInstruction::set_data64_sethi(address instaddr, intptr_t x) {
|
||||
ICache::invalidate_range(instaddr, 7 * BytesPerInstWord);
|
||||
}
|
||||
|
||||
void NativeInstruction::verify_data64_sethi(address instaddr, intptr_t x) {
|
||||
ResourceMark rm;
|
||||
unsigned char buffer[10 * BytesPerInstWord];
|
||||
CodeBuffer buf(buffer, 10 * BytesPerInstWord);
|
||||
MacroAssembler masm(&buf);
|
||||
|
||||
Register destreg = inv_rd(*(unsigned int *)instaddr);
|
||||
// Generate the proper sequence into a temporary buffer and compare
|
||||
// it with the original sequence.
|
||||
masm.patchable_sethi(x, destreg);
|
||||
int len = buffer - masm.pc();
|
||||
for (int i = 0; i < len; i++) {
|
||||
assert(instaddr[i] == buffer[i], "instructions must match");
|
||||
}
|
||||
}
|
||||
|
||||
void NativeInstruction::verify() {
|
||||
// make sure code pattern is actually an instruction address
|
||||
address addr = addr_at(0);
|
||||
|
||||
@ -254,6 +254,7 @@ class NativeInstruction VALUE_OBJ_CLASS_SPEC {
|
||||
// sethi. This only does the sethi. The disp field (bottom 10 bits)
|
||||
// must be handled separately.
|
||||
static void set_data64_sethi(address instaddr, intptr_t x);
|
||||
static void verify_data64_sethi(address instaddr, intptr_t x);
|
||||
|
||||
// combine the fields of a sethi/simm13 pair (simm13 = or, add, jmpl, ld/st)
|
||||
static int data32(int sethi_insn, int arith_insn) {
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "runtime/safepoint.hpp"
|
||||
|
||||
void Relocation::pd_set_data_value(address x, intptr_t o) {
|
||||
void Relocation::pd_set_data_value(address x, intptr_t o, bool verify_only) {
|
||||
NativeInstruction* ip = nativeInstruction_at(addr());
|
||||
jint inst = ip->long_at(0);
|
||||
assert(inst != NativeInstruction::illegal_instruction(), "no breakpoint");
|
||||
@ -83,7 +83,11 @@ void Relocation::pd_set_data_value(address x, intptr_t o) {
|
||||
guarantee(Assembler::is_simm13(simm13), "offset can't overflow simm13");
|
||||
inst &= ~Assembler::simm( -1, 13);
|
||||
inst |= Assembler::simm(simm13, 13);
|
||||
ip->set_long_at(0, inst);
|
||||
if (verify_only) {
|
||||
assert(ip->long_at(0) == inst, "instructions must match");
|
||||
} else {
|
||||
ip->set_long_at(0, inst);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -97,19 +101,36 @@ void Relocation::pd_set_data_value(address x, intptr_t o) {
|
||||
jint np = oopDesc::encode_heap_oop((oop)x);
|
||||
inst &= ~Assembler::hi22(-1);
|
||||
inst |= Assembler::hi22((intptr_t)np);
|
||||
ip->set_long_at(0, inst);
|
||||
if (verify_only) {
|
||||
assert(ip->long_at(0) == inst, "instructions must match");
|
||||
} else {
|
||||
ip->set_long_at(0, inst);
|
||||
}
|
||||
inst2 = ip->long_at( NativeInstruction::nop_instruction_size );
|
||||
guarantee(Assembler::inv_op(inst2)==Assembler::arith_op, "arith op");
|
||||
ip->set_long_at(NativeInstruction::nop_instruction_size, ip->set_data32_simm13( inst2, (intptr_t)np));
|
||||
if (verify_only) {
|
||||
assert(ip->long_at(NativeInstruction::nop_instruction_size) == NativeInstruction::set_data32_simm13( inst2, (intptr_t)np),
|
||||
"instructions must match");
|
||||
} else {
|
||||
ip->set_long_at(NativeInstruction::nop_instruction_size, NativeInstruction::set_data32_simm13( inst2, (intptr_t)np));
|
||||
}
|
||||
break;
|
||||
}
|
||||
ip->set_data64_sethi( ip->addr_at(0), (intptr_t)x );
|
||||
if (verify_only) {
|
||||
ip->verify_data64_sethi( ip->addr_at(0), (intptr_t)x );
|
||||
} else {
|
||||
ip->set_data64_sethi( ip->addr_at(0), (intptr_t)x );
|
||||
}
|
||||
#else
|
||||
guarantee(Assembler::inv_op2(inst)==Assembler::sethi_op2, "must be sethi");
|
||||
inst &= ~Assembler::hi22( -1);
|
||||
inst |= Assembler::hi22((intptr_t)x);
|
||||
// (ignore offset; it doesn't play into the sethi)
|
||||
ip->set_long_at(0, inst);
|
||||
if (verify_only) {
|
||||
assert(ip->long_at(0) == inst, "instructions must match");
|
||||
} else {
|
||||
ip->set_long_at(0, inst);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
@ -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
|
||||
@ -1769,6 +1769,7 @@ static void create_inner_frame(MacroAssembler* masm, bool* already_created) {
|
||||
// returns.
|
||||
nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
||||
methodHandle method,
|
||||
int compile_id,
|
||||
int total_in_args,
|
||||
int comp_args_on_stack, // in VMRegStackSlots
|
||||
BasicType *in_sig_bt,
|
||||
@ -2462,6 +2463,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
||||
__ flush();
|
||||
|
||||
nmethod *nm = nmethod::new_native_nmethod(method,
|
||||
compile_id,
|
||||
masm->code(),
|
||||
vep_offset,
|
||||
frame_complete,
|
||||
|
||||
@ -1843,6 +1843,10 @@ const int Matcher::init_array_short_size = 8 * BytesPerLong;
|
||||
// registers? True for Intel but false for most RISCs
|
||||
const bool Matcher::clone_shift_expressions = false;
|
||||
|
||||
// Do we need to mask the count passed to shift instructions or does
|
||||
// the cpu only look at the lower 5/6 bits anyway?
|
||||
const bool Matcher::need_masked_shift_count = false;
|
||||
|
||||
bool Matcher::narrow_oop_use_complex_address() {
|
||||
NOT_LP64(ShouldNotCallThis());
|
||||
assert(UseCompressedOops, "only for compressed oops code");
|
||||
|
||||
@ -334,8 +334,8 @@ void TemplateTable::ldc(bool wide) {
|
||||
void TemplateTable::fast_aldc(bool wide) {
|
||||
transition(vtos, atos);
|
||||
|
||||
if (!EnableMethodHandles) {
|
||||
// We should not encounter this bytecode if !EnableMethodHandles.
|
||||
if (!EnableInvokeDynamic) {
|
||||
// We should not encounter this bytecode if !EnableInvokeDynamic.
|
||||
// The verifier will stop it. However, if we get past the verifier,
|
||||
// this will stop the thread in a reasonable way, without crashing the JVM.
|
||||
__ call_VM(noreg, CAST_FROM_FN_PTR(address,
|
||||
@ -3303,7 +3303,7 @@ void TemplateTable::invokedynamic(int byte_no) {
|
||||
__ 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
|
||||
|
||||
@ -3510,7 +3510,6 @@ bool Assembler::reachable(AddressLiteral adr) {
|
||||
// anywhere in the codeCache then we are always reachable.
|
||||
// This would have to change if we ever save/restore shared code
|
||||
// to be more pessimistic.
|
||||
|
||||
disp = (int64_t)adr._target - ((int64_t)CodeCache::low_bound() + sizeof(int));
|
||||
if (!is_simm32(disp)) return false;
|
||||
disp = (int64_t)adr._target - ((int64_t)CodeCache::high_bound() + sizeof(int));
|
||||
@ -3534,6 +3533,14 @@ bool Assembler::reachable(AddressLiteral adr) {
|
||||
return is_simm32(disp);
|
||||
}
|
||||
|
||||
// Check if the polling page is not reachable from the code cache using rip-relative
|
||||
// addressing.
|
||||
bool Assembler::is_polling_page_far() {
|
||||
intptr_t addr = (intptr_t)os::get_polling_page();
|
||||
return !is_simm32(addr - (intptr_t)CodeCache::low_bound()) ||
|
||||
!is_simm32(addr - (intptr_t)CodeCache::high_bound());
|
||||
}
|
||||
|
||||
void Assembler::emit_data64(jlong data,
|
||||
relocInfo::relocType rtype,
|
||||
int format) {
|
||||
@ -6886,6 +6893,11 @@ void MacroAssembler::sign_extend_short(Register reg) {
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::testl(Register dst, AddressLiteral src) {
|
||||
assert(reachable(src), "Address should be reachable");
|
||||
testl(dst, as_Address(src));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef SERIALGC
|
||||
|
||||
@ -7121,17 +7133,6 @@ void MacroAssembler::subptr(Register dst, Register src) {
|
||||
LP64_ONLY(subq(dst, src)) NOT_LP64(subl(dst, src));
|
||||
}
|
||||
|
||||
void MacroAssembler::test32(Register src1, AddressLiteral src2) {
|
||||
// src2 must be rval
|
||||
|
||||
if (reachable(src2)) {
|
||||
testl(src1, as_Address(src2));
|
||||
} else {
|
||||
lea(rscratch1, src2);
|
||||
testl(src1, Address(rscratch1, 0));
|
||||
}
|
||||
}
|
||||
|
||||
// C++ bool manipulation
|
||||
void MacroAssembler::testbool(Register dst) {
|
||||
if(sizeof(bool) == 1)
|
||||
@ -7768,6 +7769,28 @@ void MacroAssembler::xorps(XMMRegister dst, AddressLiteral src) {
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::cmov32(Condition cc, Register dst, Address src) {
|
||||
if (VM_Version::supports_cmov()) {
|
||||
cmovl(cc, dst, src);
|
||||
} else {
|
||||
Label L;
|
||||
jccb(negate_condition(cc), L);
|
||||
movl(dst, src);
|
||||
bind(L);
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::cmov32(Condition cc, Register dst, Register src) {
|
||||
if (VM_Version::supports_cmov()) {
|
||||
cmovl(cc, dst, src);
|
||||
} else {
|
||||
Label L;
|
||||
jccb(negate_condition(cc), L);
|
||||
movl(dst, src);
|
||||
bind(L);
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::verify_oop(Register reg, const char* s) {
|
||||
if (!VerifyOops) return;
|
||||
|
||||
@ -7831,7 +7854,7 @@ RegisterOrConstant MacroAssembler::delayed_value_impl(intptr_t* delayed_value_ad
|
||||
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 +7874,14 @@ void MacroAssembler::load_method_handle_vmslots(Register vmslots_reg, Register m
|
||||
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 +7896,7 @@ void MacroAssembler::jump_to_method_handle_entry(Register mh_reg, Register temp_
|
||||
|
||||
// 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()));
|
||||
@ -9018,14 +9041,7 @@ void MacroAssembler::string_compare(Register str1, Register str2,
|
||||
movl(result, cnt1);
|
||||
subl(cnt1, cnt2);
|
||||
push(cnt1);
|
||||
if (VM_Version::supports_cmov()) {
|
||||
cmovl(Assembler::lessEqual, cnt2, result);
|
||||
} else {
|
||||
Label GT_LABEL;
|
||||
jccb(Assembler::greater, GT_LABEL);
|
||||
movl(cnt2, result);
|
||||
bind(GT_LABEL);
|
||||
}
|
||||
cmov32(Assembler::lessEqual, cnt2, result);
|
||||
|
||||
// Is the minimum length zero?
|
||||
testl(cnt2, cnt2);
|
||||
|
||||
@ -580,7 +580,6 @@ private:
|
||||
void emit_data64(jlong data, relocInfo::relocType rtype, int format = 0);
|
||||
void emit_data64(jlong data, RelocationHolder const& rspec, int format = 0);
|
||||
|
||||
|
||||
bool reachable(AddressLiteral adr) NOT_LP64({ return true;});
|
||||
|
||||
// These are all easily abused and hence protected
|
||||
@ -683,6 +682,8 @@ private:
|
||||
static bool is_simm32(int32_t x) { return true; }
|
||||
#endif // _LP64
|
||||
|
||||
static bool is_polling_page_far() NOT_LP64({ return false;});
|
||||
|
||||
// Generic instructions
|
||||
// Does 32bit or 64bit as needed for the platform. In some sense these
|
||||
// belong in macro assembler but there is no need for both varieties to exist
|
||||
@ -2094,7 +2095,10 @@ class MacroAssembler: public Assembler {
|
||||
|
||||
void leal32(Register dst, Address src) { leal(dst, src); }
|
||||
|
||||
void test32(Register src1, AddressLiteral src2);
|
||||
// Import other testl() methods from the parent class or else
|
||||
// they will be hidden by the following overriding declaration.
|
||||
using Assembler::testl;
|
||||
void testl(Register dst, AddressLiteral src);
|
||||
|
||||
void orptr(Register dst, Address src) { LP64_ONLY(orq(dst, src)) NOT_LP64(orl(dst, src)); }
|
||||
void orptr(Register dst, Register src) { LP64_ONLY(orq(dst, src)) NOT_LP64(orl(dst, src)); }
|
||||
@ -2240,10 +2244,13 @@ public:
|
||||
|
||||
// Data
|
||||
|
||||
void cmov(Condition cc, Register dst, Register src) { LP64_ONLY(cmovq(cc, dst, src)) NOT_LP64(cmovl(cc, dst, src)); }
|
||||
void cmov32( Condition cc, Register dst, Address src);
|
||||
void cmov32( Condition cc, Register dst, Register src);
|
||||
|
||||
void cmovptr(Condition cc, Register dst, Address src) { LP64_ONLY(cmovq(cc, dst, src)) NOT_LP64(cmovl(cc, dst, src)); }
|
||||
void cmovptr(Condition cc, Register dst, Register src) { LP64_ONLY(cmovq(cc, dst, src)) NOT_LP64(cmovl(cc, dst, src)); }
|
||||
void cmov( Condition cc, Register dst, Register src) { cmovptr(cc, dst, src); }
|
||||
|
||||
void cmovptr(Condition cc, Register dst, Address src) { LP64_ONLY(cmovq(cc, dst, src)) NOT_LP64(cmov32(cc, dst, src)); }
|
||||
void cmovptr(Condition cc, Register dst, Register src) { LP64_ONLY(cmovq(cc, dst, src)) NOT_LP64(cmov32(cc, dst, src)); }
|
||||
|
||||
void movoop(Register dst, jobject obj);
|
||||
void movoop(Address dst, jobject obj);
|
||||
|
||||
@ -313,10 +313,13 @@ void PatchingStub::emit_code(LIR_Assembler* ce) {
|
||||
}
|
||||
assert(_obj != noreg, "must be a valid register");
|
||||
Register tmp = rax;
|
||||
if (_obj == tmp) tmp = rbx;
|
||||
Register tmp2 = rbx;
|
||||
__ push(tmp);
|
||||
__ push(tmp2);
|
||||
__ load_heap_oop(tmp2, Address(_obj, java_lang_Class::klass_offset_in_bytes()));
|
||||
__ get_thread(tmp);
|
||||
__ cmpptr(tmp, Address(_obj, instanceKlass::init_thread_offset_in_bytes() + sizeof(klassOopDesc)));
|
||||
__ cmpptr(tmp, Address(tmp2, instanceKlass::init_thread_offset_in_bytes() + sizeof(klassOopDesc)));
|
||||
__ pop(tmp2);
|
||||
__ pop(tmp);
|
||||
__ jcc(Assembler::notEqual, call_patch);
|
||||
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "asm/assembler.hpp"
|
||||
#include "c1/c1_Compilation.hpp"
|
||||
#include "c1/c1_LIRAssembler.hpp"
|
||||
#include "c1/c1_MacroAssembler.hpp"
|
||||
@ -569,24 +570,13 @@ void LIR_Assembler::emit_string_compare(LIR_Opr arg0, LIR_Opr arg1, LIR_Opr dst,
|
||||
__ lea (rdi, Address(rdi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
|
||||
|
||||
// compute minimum length (in rax) and difference of lengths (on top of stack)
|
||||
if (VM_Version::supports_cmov()) {
|
||||
__ movl (rbx, Address(rbx, java_lang_String::count_offset_in_bytes()));
|
||||
__ movl (rax, Address(rax, java_lang_String::count_offset_in_bytes()));
|
||||
__ mov (rcx, rbx);
|
||||
__ subptr (rbx, rax); // subtract lengths
|
||||
__ push (rbx); // result
|
||||
__ cmov (Assembler::lessEqual, rax, rcx);
|
||||
} else {
|
||||
Label L;
|
||||
__ movl (rbx, Address(rbx, java_lang_String::count_offset_in_bytes()));
|
||||
__ movl (rcx, Address(rax, java_lang_String::count_offset_in_bytes()));
|
||||
__ mov (rax, rbx);
|
||||
__ subptr (rbx, rcx);
|
||||
__ push (rbx);
|
||||
__ jcc (Assembler::lessEqual, L);
|
||||
__ mov (rax, rcx);
|
||||
__ bind (L);
|
||||
}
|
||||
__ movl (rbx, Address(rbx, java_lang_String::count_offset_in_bytes()));
|
||||
__ movl (rax, Address(rax, java_lang_String::count_offset_in_bytes()));
|
||||
__ mov (rcx, rbx);
|
||||
__ subptr(rbx, rax); // subtract lengths
|
||||
__ push (rbx); // result
|
||||
__ cmov (Assembler::lessEqual, rax, rcx);
|
||||
|
||||
// is minimum length 0?
|
||||
Label noLoop, haveResult;
|
||||
__ testptr (rax, rax);
|
||||
@ -648,12 +638,13 @@ void LIR_Assembler::return_op(LIR_Opr result) {
|
||||
AddressLiteral polling_page(os::get_polling_page() + (SafepointPollOffset % os::vm_page_size()),
|
||||
relocInfo::poll_return_type);
|
||||
|
||||
// NOTE: the requires that the polling page be reachable else the reloc
|
||||
// goes to the movq that loads the address and not the faulting instruction
|
||||
// which breaks the signal handler code
|
||||
|
||||
__ test32(rax, polling_page);
|
||||
|
||||
if (Assembler::is_polling_page_far()) {
|
||||
__ lea(rscratch1, polling_page);
|
||||
__ relocate(relocInfo::poll_return_type);
|
||||
__ testl(rax, Address(rscratch1, 0));
|
||||
} else {
|
||||
__ testl(rax, polling_page);
|
||||
}
|
||||
__ ret(0);
|
||||
}
|
||||
|
||||
@ -661,20 +652,17 @@ void LIR_Assembler::return_op(LIR_Opr result) {
|
||||
int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) {
|
||||
AddressLiteral polling_page(os::get_polling_page() + (SafepointPollOffset % os::vm_page_size()),
|
||||
relocInfo::poll_type);
|
||||
|
||||
if (info != NULL) {
|
||||
add_debug_info_for_branch(info);
|
||||
} else {
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
|
||||
guarantee(info != NULL, "Shouldn't be NULL");
|
||||
int offset = __ offset();
|
||||
|
||||
// NOTE: the requires that the polling page be reachable else the reloc
|
||||
// goes to the movq that loads the address and not the faulting instruction
|
||||
// which breaks the signal handler code
|
||||
|
||||
__ test32(rax, polling_page);
|
||||
if (Assembler::is_polling_page_far()) {
|
||||
__ lea(rscratch1, polling_page);
|
||||
offset = __ offset();
|
||||
add_debug_info_for_branch(info);
|
||||
__ testl(rax, Address(rscratch1, 0));
|
||||
} else {
|
||||
add_debug_info_for_branch(info);
|
||||
__ testl(rax, polling_page);
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "asm/assembler.hpp"
|
||||
#include "c1/c1_Defs.hpp"
|
||||
#include "c1/c1_MacroAssembler.hpp"
|
||||
#include "c1/c1_Runtime1.hpp"
|
||||
|
||||
@ -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
|
||||
@ -125,7 +125,7 @@
|
||||
// Entry frames
|
||||
#ifdef AMD64
|
||||
#ifdef _WIN64
|
||||
entry_frame_after_call_words = 8,
|
||||
entry_frame_after_call_words = 28,
|
||||
entry_frame_call_wrapper_offset = 2,
|
||||
|
||||
arg_reg_save_area_bytes = 32, // Register argument save area
|
||||
|
||||
@ -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, RewriteFrequentPairs, true);
|
||||
|
||||
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
|
||||
|
||||
@ -215,7 +215,7 @@ void InterpreterMacroAssembler::get_cache_index_at_bcp(Register reg, int bcp_off
|
||||
if (index_size == sizeof(u2)) {
|
||||
load_unsigned_short(reg, Address(rsi, bcp_offset));
|
||||
} else if (index_size == sizeof(u4)) {
|
||||
assert(EnableInvokeDynamic, "giant index used only for EnableInvokeDynamic");
|
||||
assert(EnableInvokeDynamic, "giant index used only for JSR 292");
|
||||
movl(reg, Address(rsi, bcp_offset));
|
||||
// Check if the secondary index definition is still ~x, otherwise
|
||||
// we have to change the following assembler code to calculate the
|
||||
@ -223,7 +223,7 @@ void InterpreterMacroAssembler::get_cache_index_at_bcp(Register reg, int bcp_off
|
||||
assert(constantPoolCacheOopDesc::decode_secondary_index(~123) == 123, "else change next line");
|
||||
notl(reg); // convert to plain index
|
||||
} else if (index_size == sizeof(u1)) {
|
||||
assert(EnableMethodHandles, "tiny index used only for EnableMethodHandles");
|
||||
assert(EnableInvokeDynamic, "tiny index used only for JSR 292");
|
||||
load_unsigned_byte(reg, Address(rsi, bcp_offset));
|
||||
} else {
|
||||
ShouldNotReachHere();
|
||||
|
||||
@ -213,7 +213,7 @@ void InterpreterMacroAssembler::get_cache_index_at_bcp(Register index,
|
||||
if (index_size == sizeof(u2)) {
|
||||
load_unsigned_short(index, Address(r13, bcp_offset));
|
||||
} else if (index_size == sizeof(u4)) {
|
||||
assert(EnableInvokeDynamic, "giant index used only for EnableInvokeDynamic");
|
||||
assert(EnableInvokeDynamic, "giant index used only for JSR 292");
|
||||
movl(index, Address(r13, bcp_offset));
|
||||
// Check if the secondary index definition is still ~x, otherwise
|
||||
// we have to change the following assembler code to calculate the
|
||||
@ -221,7 +221,7 @@ void InterpreterMacroAssembler::get_cache_index_at_bcp(Register index,
|
||||
assert(constantPoolCacheOopDesc::decode_secondary_index(~123) == 123, "else change next line");
|
||||
notl(index); // convert to plain index
|
||||
} else if (index_size == sizeof(u1)) {
|
||||
assert(EnableMethodHandles, "tiny index used only for EnableMethodHandles");
|
||||
assert(EnableInvokeDynamic, "tiny index used only for JSR 292");
|
||||
load_unsigned_byte(index, Address(r13, bcp_offset));
|
||||
} else {
|
||||
ShouldNotReachHere();
|
||||
|
||||
@ -231,9 +231,9 @@ address InterpreterGenerator::generate_abstract_entry(void) {
|
||||
|
||||
|
||||
// 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) {
|
||||
if (!EnableInvokeDynamic) {
|
||||
return generate_abstract_entry();
|
||||
}
|
||||
|
||||
|
||||
@ -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,9 +318,9 @@ address InterpreterGenerator::generate_abstract_entry(void) {
|
||||
|
||||
|
||||
// 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) {
|
||||
if (!EnableInvokeDynamic) {
|
||||
return generate_abstract_entry();
|
||||
}
|
||||
|
||||
|
||||
@ -125,9 +125,9 @@ address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler*
|
||||
}
|
||||
|
||||
// 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 @@ address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler*
|
||||
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 @@ void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adapt
|
||||
|
||||
// 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 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
|
||||
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 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
|
||||
|
||||
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);
|
||||
|
||||
@ -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
|
||||
@ -519,7 +519,11 @@ class NativeReturnX: public NativeInstruction {
|
||||
class NativeTstRegMem: public NativeInstruction {
|
||||
public:
|
||||
enum Intel_specific_constants {
|
||||
instruction_code_memXregl = 0x85
|
||||
instruction_rex_prefix_mask = 0xF0,
|
||||
instruction_rex_prefix = Assembler::REX,
|
||||
instruction_code_memXregl = 0x85,
|
||||
modrm_mask = 0x38, // select reg from the ModRM byte
|
||||
modrm_reg = 0x00 // rax
|
||||
};
|
||||
};
|
||||
|
||||
@ -533,12 +537,25 @@ inline bool NativeInstruction::is_cond_jump() { return (int_at(0) & 0xF0FF) =
|
||||
(ubyte_at(0) & 0xF0) == 0x70; /* short jump */ }
|
||||
inline bool NativeInstruction::is_safepoint_poll() {
|
||||
#ifdef AMD64
|
||||
if ( ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl &&
|
||||
ubyte_at(1) == 0x05 ) { // 00 rax 101
|
||||
address fault = addr_at(6) + int_at(2);
|
||||
return os::is_poll_address(fault);
|
||||
if (Assembler::is_polling_page_far()) {
|
||||
// two cases, depending on the choice of the base register in the address.
|
||||
if (((ubyte_at(0) & NativeTstRegMem::instruction_rex_prefix_mask) == NativeTstRegMem::instruction_rex_prefix &&
|
||||
ubyte_at(1) == NativeTstRegMem::instruction_code_memXregl &&
|
||||
(ubyte_at(2) & NativeTstRegMem::modrm_mask) == NativeTstRegMem::modrm_reg) ||
|
||||
ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl &&
|
||||
(ubyte_at(1) & NativeTstRegMem::modrm_mask) == NativeTstRegMem::modrm_reg) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
if (ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl &&
|
||||
ubyte_at(1) == 0x05) { // 00 rax 101
|
||||
address fault = addr_at(6) + int_at(2);
|
||||
return os::is_poll_address(fault);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#else
|
||||
return ( ubyte_at(0) == NativeMovRegMem::instruction_code_mem2reg ||
|
||||
|
||||
@ -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
|
||||
@ -31,7 +31,7 @@
|
||||
#include "runtime/safepoint.hpp"
|
||||
|
||||
|
||||
void Relocation::pd_set_data_value(address x, intptr_t o) {
|
||||
void Relocation::pd_set_data_value(address x, intptr_t o, bool verify_only) {
|
||||
#ifdef AMD64
|
||||
x += o;
|
||||
typedef Assembler::WhichOperand WhichOperand;
|
||||
@ -40,19 +40,35 @@ void Relocation::pd_set_data_value(address x, intptr_t o) {
|
||||
which == Assembler::narrow_oop_operand ||
|
||||
which == Assembler::imm_operand, "format unpacks ok");
|
||||
if (which == Assembler::imm_operand) {
|
||||
*pd_address_in_code() = x;
|
||||
if (verify_only) {
|
||||
assert(*pd_address_in_code() == x, "instructions must match");
|
||||
} else {
|
||||
*pd_address_in_code() = x;
|
||||
}
|
||||
} else if (which == Assembler::narrow_oop_operand) {
|
||||
address disp = Assembler::locate_operand(addr(), which);
|
||||
*(int32_t*) disp = oopDesc::encode_heap_oop((oop)x);
|
||||
if (verify_only) {
|
||||
assert(*(uint32_t*) disp == oopDesc::encode_heap_oop((oop)x), "instructions must match");
|
||||
} else {
|
||||
*(int32_t*) disp = oopDesc::encode_heap_oop((oop)x);
|
||||
}
|
||||
} else {
|
||||
// Note: Use runtime_call_type relocations for call32_operand.
|
||||
address ip = addr();
|
||||
address disp = Assembler::locate_operand(ip, which);
|
||||
address next_ip = Assembler::locate_next_instruction(ip);
|
||||
*(int32_t*) disp = x - next_ip;
|
||||
if (verify_only) {
|
||||
assert(*(int32_t*) disp == (x - next_ip), "instructions must match");
|
||||
} else {
|
||||
*(int32_t*) disp = x - next_ip;
|
||||
}
|
||||
}
|
||||
#else
|
||||
*pd_address_in_code() = x + o;
|
||||
if (verify_only) {
|
||||
assert(*pd_address_in_code() == (x + o), "instructions must match");
|
||||
} else {
|
||||
*pd_address_in_code() = x + o;
|
||||
}
|
||||
#endif // AMD64
|
||||
}
|
||||
|
||||
@ -182,41 +198,44 @@ void Relocation::pd_swap_out_breakpoint(address x, short* instrs, int instrlen)
|
||||
|
||||
void poll_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
|
||||
#ifdef _LP64
|
||||
typedef Assembler::WhichOperand WhichOperand;
|
||||
WhichOperand which = (WhichOperand) format();
|
||||
// This format is imm but it is really disp32
|
||||
which = Assembler::disp32_operand;
|
||||
address orig_addr = old_addr_for(addr(), src, dest);
|
||||
NativeInstruction* oni = nativeInstruction_at(orig_addr);
|
||||
int32_t* orig_disp = (int32_t*) Assembler::locate_operand(orig_addr, which);
|
||||
// This poll_addr is incorrect by the size of the instruction it is irrelevant
|
||||
intptr_t poll_addr = (intptr_t)oni + *orig_disp;
|
||||
if (!Assembler::is_polling_page_far()) {
|
||||
typedef Assembler::WhichOperand WhichOperand;
|
||||
WhichOperand which = (WhichOperand) format();
|
||||
// This format is imm but it is really disp32
|
||||
which = Assembler::disp32_operand;
|
||||
address orig_addr = old_addr_for(addr(), src, dest);
|
||||
NativeInstruction* oni = nativeInstruction_at(orig_addr);
|
||||
int32_t* orig_disp = (int32_t*) Assembler::locate_operand(orig_addr, which);
|
||||
// This poll_addr is incorrect by the size of the instruction it is irrelevant
|
||||
intptr_t poll_addr = (intptr_t)oni + *orig_disp;
|
||||
|
||||
NativeInstruction* ni = nativeInstruction_at(addr());
|
||||
intptr_t new_disp = poll_addr - (intptr_t) ni;
|
||||
|
||||
int32_t* disp = (int32_t*) Assembler::locate_operand(addr(), which);
|
||||
* disp = (int32_t)new_disp;
|
||||
NativeInstruction* ni = nativeInstruction_at(addr());
|
||||
intptr_t new_disp = poll_addr - (intptr_t) ni;
|
||||
|
||||
int32_t* disp = (int32_t*) Assembler::locate_operand(addr(), which);
|
||||
* disp = (int32_t)new_disp;
|
||||
}
|
||||
#endif // _LP64
|
||||
}
|
||||
|
||||
void poll_return_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
|
||||
#ifdef _LP64
|
||||
typedef Assembler::WhichOperand WhichOperand;
|
||||
WhichOperand which = (WhichOperand) format();
|
||||
// This format is imm but it is really disp32
|
||||
which = Assembler::disp32_operand;
|
||||
address orig_addr = old_addr_for(addr(), src, dest);
|
||||
NativeInstruction* oni = nativeInstruction_at(orig_addr);
|
||||
int32_t* orig_disp = (int32_t*) Assembler::locate_operand(orig_addr, which);
|
||||
// This poll_addr is incorrect by the size of the instruction it is irrelevant
|
||||
intptr_t poll_addr = (intptr_t)oni + *orig_disp;
|
||||
if (!Assembler::is_polling_page_far()) {
|
||||
typedef Assembler::WhichOperand WhichOperand;
|
||||
WhichOperand which = (WhichOperand) format();
|
||||
// This format is imm but it is really disp32
|
||||
which = Assembler::disp32_operand;
|
||||
address orig_addr = old_addr_for(addr(), src, dest);
|
||||
NativeInstruction* oni = nativeInstruction_at(orig_addr);
|
||||
int32_t* orig_disp = (int32_t*) Assembler::locate_operand(orig_addr, which);
|
||||
// This poll_addr is incorrect by the size of the instruction it is irrelevant
|
||||
intptr_t poll_addr = (intptr_t)oni + *orig_disp;
|
||||
|
||||
NativeInstruction* ni = nativeInstruction_at(addr());
|
||||
intptr_t new_disp = poll_addr - (intptr_t) ni;
|
||||
NativeInstruction* ni = nativeInstruction_at(addr());
|
||||
intptr_t new_disp = poll_addr - (intptr_t) ni;
|
||||
|
||||
int32_t* disp = (int32_t*) Assembler::locate_operand(addr(), which);
|
||||
* disp = (int32_t)new_disp;
|
||||
int32_t* disp = (int32_t*) Assembler::locate_operand(addr(), which);
|
||||
* disp = (int32_t)new_disp;
|
||||
}
|
||||
#endif // _LP64
|
||||
}
|
||||
|
||||
@ -1111,6 +1111,7 @@ void SharedRuntime::restore_native_result(MacroAssembler *masm, BasicType ret_ty
|
||||
// returns.
|
||||
nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
|
||||
methodHandle method,
|
||||
int compile_id,
|
||||
int total_in_args,
|
||||
int comp_args_on_stack,
|
||||
BasicType *in_sig_bt,
|
||||
@ -1854,6 +1855,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
|
||||
__ flush();
|
||||
|
||||
nmethod *nm = nmethod::new_native_nmethod(method,
|
||||
compile_id,
|
||||
masm->code(),
|
||||
vep_offset,
|
||||
frame_complete,
|
||||
|
||||
@ -1174,6 +1174,7 @@ static void restore_args(MacroAssembler *masm, int arg_count, int first_arg, VMR
|
||||
// returns.
|
||||
nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
|
||||
methodHandle method,
|
||||
int compile_id,
|
||||
int total_in_args,
|
||||
int comp_args_on_stack,
|
||||
BasicType *in_sig_bt,
|
||||
@ -1881,6 +1882,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
|
||||
__ flush();
|
||||
|
||||
nmethod *nm = nmethod::new_native_nmethod(method,
|
||||
compile_id,
|
||||
masm->code(),
|
||||
vep_offset,
|
||||
frame_complete,
|
||||
|
||||
@ -144,8 +144,11 @@ class StubGenerator: public StubCodeGenerator {
|
||||
// [ return_from_Java ] <--- rsp
|
||||
// [ argument word n ]
|
||||
// ...
|
||||
// -8 [ argument word 1 ]
|
||||
// -7 [ saved r15 ] <--- rsp_after_call
|
||||
// -28 [ argument word 1 ]
|
||||
// -27 [ saved xmm15 ] <--- rsp_after_call
|
||||
// [ saved xmm7-xmm14 ]
|
||||
// -9 [ saved xmm6 ] (each xmm register takes 2 slots)
|
||||
// -7 [ saved r15 ]
|
||||
// -6 [ saved r14 ]
|
||||
// -5 [ saved r13 ]
|
||||
// -4 [ saved r12 ]
|
||||
@ -169,8 +172,11 @@ class StubGenerator: public StubCodeGenerator {
|
||||
// Call stub stack layout word offsets from rbp
|
||||
enum call_stub_layout {
|
||||
#ifdef _WIN64
|
||||
rsp_after_call_off = -7,
|
||||
r15_off = rsp_after_call_off,
|
||||
xmm_save_first = 6, // save from xmm6
|
||||
xmm_save_last = 15, // to xmm15
|
||||
xmm_save_base = -9,
|
||||
rsp_after_call_off = xmm_save_base - 2 * (xmm_save_last - xmm_save_first), // -27
|
||||
r15_off = -7,
|
||||
r14_off = -6,
|
||||
r13_off = -5,
|
||||
r12_off = -4,
|
||||
@ -208,6 +214,13 @@ class StubGenerator: public StubCodeGenerator {
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef _WIN64
|
||||
Address xmm_save(int reg) {
|
||||
assert(reg >= xmm_save_first && reg <= xmm_save_last, "XMM register number out of range");
|
||||
return Address(rbp, (xmm_save_base - (reg - xmm_save_first) * 2) * wordSize);
|
||||
}
|
||||
#endif
|
||||
|
||||
address generate_call_stub(address& return_address) {
|
||||
assert((int)frame::entry_frame_after_call_words == -(int)rsp_after_call_off + 1 &&
|
||||
(int)frame::entry_frame_call_wrapper_offset == (int)call_wrapper_off,
|
||||
@ -256,8 +269,11 @@ class StubGenerator: public StubCodeGenerator {
|
||||
__ movptr(r13_save, r13);
|
||||
__ movptr(r14_save, r14);
|
||||
__ movptr(r15_save, r15);
|
||||
|
||||
#ifdef _WIN64
|
||||
for (int i = 6; i <= 15; i++) {
|
||||
__ movdqu(xmm_save(i), as_XMMRegister(i));
|
||||
}
|
||||
|
||||
const Address rdi_save(rbp, rdi_off * wordSize);
|
||||
const Address rsi_save(rbp, rsi_off * wordSize);
|
||||
|
||||
@ -360,6 +376,11 @@ class StubGenerator: public StubCodeGenerator {
|
||||
#endif
|
||||
|
||||
// restore regs belonging to calling function
|
||||
#ifdef _WIN64
|
||||
for (int i = 15; i >= 6; i--) {
|
||||
__ movdqu(as_XMMRegister(i), xmm_save(i));
|
||||
}
|
||||
#endif
|
||||
__ movptr(r15, r15_save);
|
||||
__ movptr(r14, r14_save);
|
||||
__ movptr(r13, r13_save);
|
||||
@ -2428,8 +2449,8 @@ class StubGenerator: public StubCodeGenerator {
|
||||
//
|
||||
address generate_generic_copy(const char *name,
|
||||
address byte_copy_entry, address short_copy_entry,
|
||||
address int_copy_entry, address long_copy_entry,
|
||||
address oop_copy_entry, address checkcast_copy_entry) {
|
||||
address int_copy_entry, address oop_copy_entry,
|
||||
address long_copy_entry, address checkcast_copy_entry) {
|
||||
|
||||
Label L_failed, L_failed_0, L_objArray;
|
||||
Label L_copy_bytes, L_copy_shorts, L_copy_ints, L_copy_longs;
|
||||
|
||||
@ -1527,7 +1527,7 @@ int AbstractInterpreter::layout_activation(methodOop method,
|
||||
|
||||
if (interpreter_frame != NULL) {
|
||||
#ifdef ASSERT
|
||||
if (!EnableMethodHandles)
|
||||
if (!EnableInvokeDynamic)
|
||||
// @@@ FIXME: Should we correct interpreter_frame_sender_sp in the calling sequences?
|
||||
// Probably, since deoptimization doesn't work yet.
|
||||
assert(caller->unextended_sp() == interpreter_frame->interpreter_frame_sender_sp(), "Frame not properly walkable");
|
||||
|
||||
@ -1541,7 +1541,7 @@ int AbstractInterpreter::layout_activation(methodOop method,
|
||||
tempcount* Interpreter::stackElementWords + popframe_extra_args;
|
||||
if (interpreter_frame != NULL) {
|
||||
#ifdef ASSERT
|
||||
if (!EnableMethodHandles)
|
||||
if (!EnableInvokeDynamic)
|
||||
// @@@ FIXME: Should we correct interpreter_frame_sender_sp in the calling sequences?
|
||||
// Probably, since deoptimization doesn't work yet.
|
||||
assert(caller->unextended_sp() == interpreter_frame->interpreter_frame_sender_sp(), "Frame not properly walkable");
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "asm/assembler.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "interpreter/interpreterRuntime.hpp"
|
||||
#include "interpreter/templateTable.hpp"
|
||||
@ -391,8 +392,8 @@ void TemplateTable::ldc(bool wide) {
|
||||
void TemplateTable::fast_aldc(bool wide) {
|
||||
transition(vtos, atos);
|
||||
|
||||
if (!EnableMethodHandles) {
|
||||
// We should not encounter this bytecode if !EnableMethodHandles.
|
||||
if (!EnableInvokeDynamic) {
|
||||
// We should not encounter this bytecode if !EnableInvokeDynamic.
|
||||
// The verifier will stop it. However, if we get past the verifier,
|
||||
// this will stop the thread in a reasonable way, without crashing the JVM.
|
||||
__ call_VM(noreg, CAST_FROM_FN_PTR(address,
|
||||
@ -1939,18 +1940,10 @@ void TemplateTable::fast_binaryswitch() {
|
||||
__ movl(temp, Address(array, h, Address::times_8, 0*wordSize));
|
||||
__ bswapl(temp);
|
||||
__ cmpl(key, temp);
|
||||
if (VM_Version::supports_cmov()) {
|
||||
__ cmovl(Assembler::less , j, h); // j = h if (key < array[h].fast_match())
|
||||
__ cmovl(Assembler::greaterEqual, i, h); // i = h if (key >= array[h].fast_match())
|
||||
} else {
|
||||
Label set_i, end_of_if;
|
||||
__ jccb(Assembler::greaterEqual, set_i); // {
|
||||
__ mov(j, h); // j = h;
|
||||
__ jmp(end_of_if); // }
|
||||
__ bind(set_i); // else {
|
||||
__ mov(i, h); // i = h;
|
||||
__ bind(end_of_if); // }
|
||||
}
|
||||
// j = h if (key < array[h].fast_match())
|
||||
__ cmov32(Assembler::less , j, h);
|
||||
// i = h if (key >= array[h].fast_match())
|
||||
__ cmov32(Assembler::greaterEqual, i, h);
|
||||
// while (i+1 < j)
|
||||
__ bind(entry);
|
||||
__ leal(h, Address(i, 1)); // i+1
|
||||
@ -3110,7 +3103,7 @@ void TemplateTable::invokedynamic(int byte_no) {
|
||||
__ 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);
|
||||
@ -3478,22 +3471,14 @@ void TemplateTable::monitorenter() {
|
||||
|
||||
// find a free slot in the monitor block (result in rdx)
|
||||
{ Label entry, loop, exit;
|
||||
__ movptr(rcx, monitor_block_top); // points to current entry, starting with top-most entry
|
||||
__ lea(rbx, monitor_block_bot); // points to word before bottom of monitor block
|
||||
__ movptr(rcx, monitor_block_top); // points to current entry, starting with top-most entry
|
||||
|
||||
__ lea(rbx, monitor_block_bot); // points to word before bottom of monitor block
|
||||
__ jmpb(entry);
|
||||
|
||||
__ bind(loop);
|
||||
__ cmpptr(Address(rcx, BasicObjectLock::obj_offset_in_bytes()), (int32_t)NULL_WORD); // check if current entry is used
|
||||
|
||||
// TODO - need new func here - kbt
|
||||
if (VM_Version::supports_cmov()) {
|
||||
__ cmov(Assembler::equal, rdx, rcx); // if not used then remember entry in rdx
|
||||
} else {
|
||||
Label L;
|
||||
__ jccb(Assembler::notEqual, L);
|
||||
__ mov(rdx, rcx); // if not used then remember entry in rdx
|
||||
__ bind(L);
|
||||
}
|
||||
__ cmovptr(Assembler::equal, rdx, rcx); // if not used then remember entry in rdx
|
||||
__ cmpptr(rax, Address(rcx, BasicObjectLock::obj_offset_in_bytes())); // check if current entry is for same object
|
||||
__ jccb(Assembler::equal, exit); // if same object then stop searching
|
||||
__ addptr(rcx, entry_size); // otherwise advance to next entry
|
||||
|
||||
@ -405,8 +405,8 @@ void TemplateTable::ldc(bool wide) {
|
||||
void TemplateTable::fast_aldc(bool wide) {
|
||||
transition(vtos, atos);
|
||||
|
||||
if (!EnableMethodHandles) {
|
||||
// We should not encounter this bytecode if !EnableMethodHandles.
|
||||
if (!EnableInvokeDynamic) {
|
||||
// We should not encounter this bytecode if !EnableInvokeDynamic.
|
||||
// The verifier will stop it. However, if we get past the verifier,
|
||||
// this will stop the thread in a reasonable way, without crashing the JVM.
|
||||
__ call_VM(noreg, CAST_FROM_FN_PTR(address,
|
||||
@ -3145,7 +3145,7 @@ void TemplateTable::invokedynamic(int byte_no) {
|
||||
__ 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);
|
||||
|
||||
@ -429,6 +429,11 @@ void VM_Version::get_processor_features() {
|
||||
UseXmmI2D = false;
|
||||
}
|
||||
}
|
||||
if( FLAG_IS_DEFAULT(UseSSE42Intrinsics) ) {
|
||||
if( supports_sse4_2() && UseSSE >= 4 ) {
|
||||
UseSSE42Intrinsics = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Use count leading zeros count instruction if available.
|
||||
if (supports_lzcnt()) {
|
||||
@ -436,6 +441,13 @@ void VM_Version::get_processor_features() {
|
||||
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
|
||||
|
||||
@ -1393,6 +1393,10 @@ const int Matcher::init_array_short_size = 8 * BytesPerLong;
|
||||
// registers? True for Intel but false for most RISCs
|
||||
const bool Matcher::clone_shift_expressions = true;
|
||||
|
||||
// Do we need to mask the count passed to shift instructions or does
|
||||
// the cpu only look at the lower 5/6 bits anyway?
|
||||
const bool Matcher::need_masked_shift_count = false;
|
||||
|
||||
bool Matcher::narrow_oop_use_complex_address() {
|
||||
ShouldNotCallThis();
|
||||
return true;
|
||||
|
||||
@ -574,12 +574,11 @@ int MachCallDynamicJavaNode::ret_addr_offset()
|
||||
// In os_cpu .ad file
|
||||
// int MachCallRuntimeNode::ret_addr_offset()
|
||||
|
||||
// Indicate if the safepoint node needs the polling page as an input.
|
||||
// Since amd64 does not have absolute addressing but RIP-relative
|
||||
// addressing and the polling page is within 2G, it doesn't.
|
||||
// Indicate if the safepoint node needs the polling page as an input,
|
||||
// it does if the polling page is more than disp32 away.
|
||||
bool SafePointNode::needs_polling_address_input()
|
||||
{
|
||||
return false;
|
||||
return Assembler::is_polling_page_far();
|
||||
}
|
||||
|
||||
//
|
||||
@ -992,15 +991,21 @@ void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const
|
||||
framesize -= 2*wordSize;
|
||||
|
||||
if (framesize) {
|
||||
st->print_cr("addq\trsp, %d\t# Destroy frame", framesize);
|
||||
st->print_cr("addq rsp, %d\t# Destroy frame", framesize);
|
||||
st->print("\t");
|
||||
}
|
||||
|
||||
st->print_cr("popq\trbp");
|
||||
st->print_cr("popq rbp");
|
||||
if (do_polling() && C->is_method_compilation()) {
|
||||
st->print_cr("\ttestl\trax, [rip + #offset_to_poll_page]\t"
|
||||
"# Safepoint: poll for GC");
|
||||
st->print("\t");
|
||||
if (Assembler::is_polling_page_far()) {
|
||||
st->print_cr("movq rscratch1, #polling_page_address\n\t"
|
||||
"testl rax, [rscratch1]\t"
|
||||
"# Safepoint: poll for GC");
|
||||
} else {
|
||||
st->print_cr("testl rax, [rip + #offset_to_poll_page]\t"
|
||||
"# Safepoint: poll for GC");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -1033,45 +1038,22 @@ void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
|
||||
emit_opcode(cbuf, 0x58 | RBP_enc);
|
||||
|
||||
if (do_polling() && C->is_method_compilation()) {
|
||||
// testl %rax, off(%rip) // Opcode + ModRM + Disp32 == 6 bytes
|
||||
// XXX reg_mem doesn't support RIP-relative addressing yet
|
||||
cbuf.set_insts_mark();
|
||||
cbuf.relocate(cbuf.insts_mark(), relocInfo::poll_return_type, 0); // XXX
|
||||
emit_opcode(cbuf, 0x85); // testl
|
||||
emit_rm(cbuf, 0x0, RAX_enc, 0x5); // 00 rax 101 == 0x5
|
||||
// cbuf.insts_mark() is beginning of instruction
|
||||
emit_d32_reloc(cbuf, os::get_polling_page());
|
||||
// relocInfo::poll_return_type,
|
||||
MacroAssembler _masm(&cbuf);
|
||||
AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type);
|
||||
if (Assembler::is_polling_page_far()) {
|
||||
__ lea(rscratch1, polling_page);
|
||||
__ relocate(relocInfo::poll_return_type);
|
||||
__ testl(rax, Address(rscratch1, 0));
|
||||
} else {
|
||||
__ testl(rax, polling_page);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint MachEpilogNode::size(PhaseRegAlloc* ra_) const
|
||||
{
|
||||
Compile* C = ra_->C;
|
||||
int framesize = C->frame_slots() << LogBytesPerInt;
|
||||
assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
|
||||
// Remove word for return adr already pushed
|
||||
// and RBP
|
||||
framesize -= 2*wordSize;
|
||||
|
||||
uint size = 0;
|
||||
|
||||
if (do_polling() && C->is_method_compilation()) {
|
||||
size += 6;
|
||||
}
|
||||
|
||||
// count popq rbp
|
||||
size++;
|
||||
|
||||
if (framesize) {
|
||||
if (framesize < 0x80) {
|
||||
size += 4;
|
||||
} else if (framesize) {
|
||||
size += 7;
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
return MachNode::size(ra_); // too many variables; just compute it
|
||||
// the hard way
|
||||
}
|
||||
|
||||
int MachEpilogNode::reloc() const
|
||||
@ -2000,6 +1982,10 @@ const int Matcher::init_array_short_size = 8 * BytesPerLong;
|
||||
// into registers? True for Intel but false for most RISCs
|
||||
const bool Matcher::clone_shift_expressions = true;
|
||||
|
||||
// Do we need to mask the count passed to shift instructions or does
|
||||
// the cpu only look at the lower 5/6 bits anyway?
|
||||
const bool Matcher::need_masked_shift_count = false;
|
||||
|
||||
bool Matcher::narrow_oop_use_complex_address() {
|
||||
assert(UseCompressedOops, "only for compressed oops code");
|
||||
return (LogMinObjAlignmentInBytes <= 3);
|
||||
@ -3406,8 +3392,8 @@ encode %{
|
||||
}
|
||||
if (EmitSync & 1) {
|
||||
// Without cast to int32_t a movptr will destroy r10 which is typically obj
|
||||
masm.movptr (Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ;
|
||||
masm.cmpptr(rsp, (int32_t)NULL_WORD) ;
|
||||
masm.movptr (Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ;
|
||||
masm.cmpptr(rsp, (int32_t)NULL_WORD) ;
|
||||
} else
|
||||
if (EmitSync & 2) {
|
||||
Label DONE_LABEL;
|
||||
@ -3435,10 +3421,10 @@ encode %{
|
||||
} else {
|
||||
Label DONE_LABEL, IsInflated, Egress;
|
||||
|
||||
masm.movptr(tmpReg, Address(objReg, 0)) ;
|
||||
masm.movptr(tmpReg, Address(objReg, 0)) ;
|
||||
masm.testl (tmpReg, 0x02) ; // inflated vs stack-locked|neutral|biased
|
||||
masm.jcc (Assembler::notZero, IsInflated) ;
|
||||
|
||||
masm.jcc (Assembler::notZero, IsInflated) ;
|
||||
|
||||
// it's stack-locked, biased or neutral
|
||||
// TODO: optimize markword triage order to reduce the number of
|
||||
// conditional branches in the most common cases.
|
||||
@ -3452,9 +3438,9 @@ encode %{
|
||||
}
|
||||
|
||||
// was q will it destroy high?
|
||||
masm.orl (tmpReg, 1) ;
|
||||
masm.movptr(Address(boxReg, 0), tmpReg) ;
|
||||
if (os::is_MP()) { masm.lock(); }
|
||||
masm.orl (tmpReg, 1) ;
|
||||
masm.movptr(Address(boxReg, 0), tmpReg) ;
|
||||
if (os::is_MP()) { masm.lock(); }
|
||||
masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg
|
||||
if (_counters != NULL) {
|
||||
masm.cond_inc32(Assembler::equal,
|
||||
@ -3481,16 +3467,16 @@ encode %{
|
||||
// fetched _owner. If the CAS is successful we may
|
||||
// avoid an RTO->RTS upgrade on the $line.
|
||||
// Without cast to int32_t a movptr will destroy r10 which is typically obj
|
||||
masm.movptr(Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ;
|
||||
masm.movptr(Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ;
|
||||
|
||||
masm.mov (boxReg, tmpReg) ;
|
||||
masm.movptr (tmpReg, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
|
||||
masm.testptr(tmpReg, tmpReg) ;
|
||||
masm.jcc (Assembler::notZero, DONE_LABEL) ;
|
||||
masm.mov (boxReg, tmpReg) ;
|
||||
masm.movptr (tmpReg, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
|
||||
masm.testptr(tmpReg, tmpReg) ;
|
||||
masm.jcc (Assembler::notZero, DONE_LABEL) ;
|
||||
|
||||
// It's inflated and appears unlocked
|
||||
if (os::is_MP()) { masm.lock(); }
|
||||
masm.cmpxchgptr(r15_thread, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
|
||||
if (os::is_MP()) { masm.lock(); }
|
||||
masm.cmpxchgptr(r15_thread, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
|
||||
// Intentional fall-through into DONE_LABEL ...
|
||||
|
||||
masm.bind (DONE_LABEL) ;
|
||||
@ -3509,8 +3495,8 @@ encode %{
|
||||
Register tmpReg = as_Register($tmp$$reg);
|
||||
MacroAssembler masm(&cbuf);
|
||||
|
||||
if (EmitSync & 4) {
|
||||
masm.cmpptr(rsp, 0) ;
|
||||
if (EmitSync & 4) {
|
||||
masm.cmpptr(rsp, 0) ;
|
||||
} else
|
||||
if (EmitSync & 8) {
|
||||
Label DONE_LABEL;
|
||||
@ -3537,25 +3523,25 @@ encode %{
|
||||
if (UseBiasedLocking && !UseOptoBiasInlining) {
|
||||
masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL);
|
||||
}
|
||||
|
||||
masm.movptr(tmpReg, Address(objReg, 0)) ;
|
||||
masm.cmpptr(Address(boxReg, 0), (int32_t)NULL_WORD) ;
|
||||
masm.jcc (Assembler::zero, DONE_LABEL) ;
|
||||
masm.testl (tmpReg, 0x02) ;
|
||||
masm.jcc (Assembler::zero, Stacked) ;
|
||||
|
||||
|
||||
masm.movptr(tmpReg, Address(objReg, 0)) ;
|
||||
masm.cmpptr(Address(boxReg, 0), (int32_t)NULL_WORD) ;
|
||||
masm.jcc (Assembler::zero, DONE_LABEL) ;
|
||||
masm.testl (tmpReg, 0x02) ;
|
||||
masm.jcc (Assembler::zero, Stacked) ;
|
||||
|
||||
// It's inflated
|
||||
masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
|
||||
masm.xorptr(boxReg, r15_thread) ;
|
||||
masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ;
|
||||
masm.jcc (Assembler::notZero, DONE_LABEL) ;
|
||||
masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ;
|
||||
masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ;
|
||||
masm.jcc (Assembler::notZero, CheckSucc) ;
|
||||
masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
|
||||
masm.jmp (DONE_LABEL) ;
|
||||
|
||||
if ((EmitSync & 65536) == 0) {
|
||||
masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
|
||||
masm.xorptr(boxReg, r15_thread) ;
|
||||
masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ;
|
||||
masm.jcc (Assembler::notZero, DONE_LABEL) ;
|
||||
masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ;
|
||||
masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ;
|
||||
masm.jcc (Assembler::notZero, CheckSucc) ;
|
||||
masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
|
||||
masm.jmp (DONE_LABEL) ;
|
||||
|
||||
if ((EmitSync & 65536) == 0) {
|
||||
Label LSuccess, LGoSlowPath ;
|
||||
masm.bind (CheckSucc) ;
|
||||
masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
|
||||
@ -3587,9 +3573,9 @@ encode %{
|
||||
masm.jmp (DONE_LABEL) ;
|
||||
}
|
||||
|
||||
masm.bind (Stacked) ;
|
||||
masm.bind (Stacked) ;
|
||||
masm.movptr(tmpReg, Address (boxReg, 0)) ; // re-fetch
|
||||
if (os::is_MP()) { masm.lock(); }
|
||||
if (os::is_MP()) { masm.lock(); }
|
||||
masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box
|
||||
|
||||
if (EmitSync & 65536) {
|
||||
@ -3910,22 +3896,6 @@ encode %{
|
||||
|
||||
// done:
|
||||
%}
|
||||
|
||||
// Safepoint Poll. This polls the safepoint page, and causes an
|
||||
// exception if it is not readable. Unfortunately, it kills
|
||||
// RFLAGS in the process.
|
||||
enc_class enc_safepoint_poll
|
||||
%{
|
||||
// testl %rax, off(%rip) // Opcode + ModRM + Disp32 == 6 bytes
|
||||
// XXX reg_mem doesn't support RIP-relative addressing yet
|
||||
cbuf.set_insts_mark();
|
||||
cbuf.relocate(cbuf.insts_mark(), relocInfo::poll_type, 0); // XXX
|
||||
emit_opcode(cbuf, 0x85); // testl
|
||||
emit_rm(cbuf, 0x0, RAX_enc, 0x5); // 00 rax 101 == 0x5
|
||||
// cbuf.insts_mark() is beginning of instruction
|
||||
emit_d32_reloc(cbuf, os::get_polling_page());
|
||||
// relocInfo::poll_type,
|
||||
%}
|
||||
%}
|
||||
|
||||
|
||||
@ -4229,6 +4199,15 @@ operand immP0()
|
||||
interface(CONST_INTER);
|
||||
%}
|
||||
|
||||
operand immP_poll() %{
|
||||
predicate(n->get_ptr() != 0 && n->get_ptr() == (intptr_t)os::get_polling_page());
|
||||
match(ConP);
|
||||
|
||||
// formats are generated automatically for constants and base registers
|
||||
format %{ %}
|
||||
interface(CONST_INTER);
|
||||
%}
|
||||
|
||||
// Pointer Immediate
|
||||
operand immN() %{
|
||||
match(ConN);
|
||||
@ -4836,7 +4815,7 @@ operand regF()
|
||||
%}
|
||||
|
||||
// Double register operands
|
||||
operand regD()
|
||||
operand regD()
|
||||
%{
|
||||
constraint(ALLOC_IN_RC(double_reg));
|
||||
match(RegD);
|
||||
@ -6564,6 +6543,16 @@ instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr)
|
||||
ins_pipe(ialu_reg);
|
||||
%}
|
||||
|
||||
instruct loadConP_poll(rRegP dst, immP_poll src) %{
|
||||
match(Set dst src);
|
||||
format %{ "movq $dst, $src\t!ptr" %}
|
||||
ins_encode %{
|
||||
AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_type);
|
||||
__ lea($dst$$Register, polling_page);
|
||||
%}
|
||||
ins_pipe(ialu_reg_fat);
|
||||
%}
|
||||
|
||||
instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr)
|
||||
%{
|
||||
match(Set dst src);
|
||||
@ -7237,11 +7226,11 @@ instruct bytes_reverse_long(rRegL dst) %{
|
||||
instruct bytes_reverse_unsigned_short(rRegI dst) %{
|
||||
match(Set dst (ReverseBytesUS dst));
|
||||
|
||||
format %{ "bswapl $dst\n\t"
|
||||
format %{ "bswapl $dst\n\t"
|
||||
"shrl $dst,16\n\t" %}
|
||||
ins_encode %{
|
||||
__ bswapl($dst$$Register);
|
||||
__ shrl($dst$$Register, 16);
|
||||
__ shrl($dst$$Register, 16);
|
||||
%}
|
||||
ins_pipe( ialu_reg );
|
||||
%}
|
||||
@ -7249,11 +7238,11 @@ instruct bytes_reverse_unsigned_short(rRegI dst) %{
|
||||
instruct bytes_reverse_short(rRegI dst) %{
|
||||
match(Set dst (ReverseBytesS dst));
|
||||
|
||||
format %{ "bswapl $dst\n\t"
|
||||
format %{ "bswapl $dst\n\t"
|
||||
"sar $dst,16\n\t" %}
|
||||
ins_encode %{
|
||||
__ bswapl($dst$$Register);
|
||||
__ sarl($dst$$Register, 16);
|
||||
__ sarl($dst$$Register, 16);
|
||||
%}
|
||||
ins_pipe( ialu_reg );
|
||||
%}
|
||||
@ -7476,7 +7465,7 @@ instruct membar_volatile(rFlagsReg cr) %{
|
||||
effect(KILL cr);
|
||||
ins_cost(400);
|
||||
|
||||
format %{
|
||||
format %{
|
||||
$$template
|
||||
if (os::is_MP()) {
|
||||
$$emit$$"lock addl [rsp + #0], 0\t! membar_volatile"
|
||||
@ -8287,7 +8276,7 @@ instruct storePConditional(memory heap_top_ptr,
|
||||
rFlagsReg cr)
|
||||
%{
|
||||
match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval)));
|
||||
|
||||
|
||||
format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) "
|
||||
"If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %}
|
||||
opcode(0x0F, 0xB1);
|
||||
@ -9850,9 +9839,9 @@ instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
|
||||
|
||||
// Xor Register with Immediate -1
|
||||
instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{
|
||||
match(Set dst (XorI dst imm));
|
||||
match(Set dst (XorI dst imm));
|
||||
|
||||
format %{ "not $dst" %}
|
||||
format %{ "not $dst" %}
|
||||
ins_encode %{
|
||||
__ notl($dst$$Register);
|
||||
%}
|
||||
@ -10093,9 +10082,9 @@ instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
|
||||
|
||||
// Xor Register with Immediate -1
|
||||
instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{
|
||||
match(Set dst (XorL dst imm));
|
||||
match(Set dst (XorL dst imm));
|
||||
|
||||
format %{ "notq $dst" %}
|
||||
format %{ "notq $dst" %}
|
||||
ins_encode %{
|
||||
__ notq($dst$$Register);
|
||||
%}
|
||||
@ -12469,14 +12458,33 @@ instruct cmpFastUnlock(rFlagsReg cr,
|
||||
// Safepoint Instructions
|
||||
instruct safePoint_poll(rFlagsReg cr)
|
||||
%{
|
||||
predicate(!Assembler::is_polling_page_far());
|
||||
match(SafePoint);
|
||||
effect(KILL cr);
|
||||
|
||||
format %{ "testl rax, [rip + #offset_to_poll_page]\t"
|
||||
format %{ "testl rax, [rip + #offset_to_poll_page]\t"
|
||||
"# Safepoint: poll for GC" %}
|
||||
size(6); // Opcode + ModRM + Disp32 == 6 bytes
|
||||
ins_cost(125);
|
||||
ins_encode(enc_safepoint_poll);
|
||||
ins_encode %{
|
||||
AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type);
|
||||
__ testl(rax, addr);
|
||||
%}
|
||||
ins_pipe(ialu_reg_mem);
|
||||
%}
|
||||
|
||||
instruct safePoint_poll_far(rFlagsReg cr, rRegP poll)
|
||||
%{
|
||||
predicate(Assembler::is_polling_page_far());
|
||||
match(SafePoint poll);
|
||||
effect(KILL cr, USE poll);
|
||||
|
||||
format %{ "testl rax, [$poll]\t"
|
||||
"# Safepoint: poll for GC" %}
|
||||
ins_cost(125);
|
||||
ins_encode %{
|
||||
__ relocate(relocInfo::poll_type);
|
||||
__ testl(rax, Address($poll$$Register, 0));
|
||||
%}
|
||||
ins_pipe(ialu_reg_mem);
|
||||
%}
|
||||
|
||||
|
||||
@ -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.
|
||||
* Copyright 2007, 2008, 2009, 2010 Red Hat, Inc.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -281,7 +281,7 @@ int CppInterpreter::native_entry(methodOop method, intptr_t UNUSED, TRAPS) {
|
||||
|
||||
if (method->is_static()) {
|
||||
istate->set_oop_temp(
|
||||
method->constants()->pool_holder()->klass_part()->java_mirror());
|
||||
method->constants()->pool_holder()->java_mirror());
|
||||
mirror = istate->oop_temp_addr();
|
||||
*(dst++) = &mirror;
|
||||
}
|
||||
@ -667,7 +667,7 @@ InterpreterFrame *InterpreterFrame::build(const methodOop method, TRAPS) {
|
||||
(BasicObjectLock *) stack->alloc(monitor_words * wordSize);
|
||||
oop object;
|
||||
if (method->is_static())
|
||||
object = method->constants()->pool_holder()->klass_part()->java_mirror();
|
||||
object = method->constants()->pool_holder()->java_mirror();
|
||||
else
|
||||
object = (oop) locals[0];
|
||||
monitor->set_obj(object);
|
||||
|
||||
@ -524,6 +524,8 @@ name_for_methodOop(jvm_agent_t* J, uint64_t methodOopPtr, char * result, size_t
|
||||
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 @@ name_for_methodOop(jvm_agent_t* J, uint64_t methodOopPtr, char * result, size_t
|
||||
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);
|
||||
|
||||
@ -3297,9 +3297,14 @@ bool os::is_interrupted(Thread* thread, bool clear_interrupted) {
|
||||
"possibility of dangling Thread pointer");
|
||||
|
||||
OSThread* osthread = thread->osthread();
|
||||
bool interrupted;
|
||||
interrupted = osthread->interrupted();
|
||||
if (clear_interrupted == true) {
|
||||
bool interrupted = osthread->interrupted();
|
||||
// There is no synchronization between the setting of the interrupt
|
||||
// and it being cleared here. It is critical - see 6535709 - that
|
||||
// we only clear the interrupt state, and reset the interrupt event,
|
||||
// if we are going to report that we were indeed interrupted - else
|
||||
// an interrupt can be "lost", leading to spurious wakeups or lost wakeups
|
||||
// depending on the timing
|
||||
if (interrupted && clear_interrupted) {
|
||||
osthread->set_interrupted(false);
|
||||
ResetEvent(osthread->interrupt_event());
|
||||
} // Otherwise leave the interrupted state alone
|
||||
|
||||
@ -47,18 +47,6 @@ public class Util {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
static String join(String padder, String v[]) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
for (int i=0; i<v.length; i++) {
|
||||
sb.append(v[i]);
|
||||
if (i < (v.length - 1)) sb.append(padder);
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
static String prefixed_join(String padder, Vector v, boolean quoted) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
@ -587,7 +587,6 @@ public abstract class WinGammaPlatform {
|
||||
Vector allConfigs = new Vector();
|
||||
|
||||
allConfigs.add(new C1DebugConfig());
|
||||
|
||||
allConfigs.add(new C1FastDebugConfig());
|
||||
allConfigs.add(new C1ProductConfig());
|
||||
|
||||
@ -655,6 +654,10 @@ public abstract class WinGammaPlatform {
|
||||
boolean isHeader() {
|
||||
return attr.shortName.endsWith(".h") || attr.shortName.endsWith(".hpp");
|
||||
}
|
||||
|
||||
boolean isCpp() {
|
||||
return attr.shortName.endsWith(".cpp");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -708,7 +711,7 @@ public abstract class WinGammaPlatform {
|
||||
PrintWriter printWriter;
|
||||
|
||||
public void writeProjectFile(String projectFileName, String projectName,
|
||||
Vector allConfigs) throws IOException {
|
||||
Vector<BuildConfig> allConfigs) throws IOException {
|
||||
throw new RuntimeException("use compiler version specific version");
|
||||
}
|
||||
}
|
||||
|
||||
545
hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java
Normal file
545
hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java
Normal file
@ -0,0 +1,545 @@
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Iterator;
|
||||
import java.util.TreeSet;
|
||||
import java.util.UUID;
|
||||
import java.util.Vector;
|
||||
|
||||
public class WinGammaPlatformVC10 extends WinGammaPlatformVC7 {
|
||||
|
||||
@Override
|
||||
protected String getProjectExt() {
|
||||
return ".vcxproj";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeProjectFile(String projectFileName, String projectName,
|
||||
Vector<BuildConfig> allConfigs) throws IOException {
|
||||
System.out.println();
|
||||
System.out.print(" Writing .vcxproj file: " + projectFileName);
|
||||
|
||||
String projDir = Util.normalize(new File(projectFileName).getParent());
|
||||
|
||||
printWriter = new PrintWriter(projectFileName, "UTF-8");
|
||||
printWriter.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
|
||||
startTag("Project",
|
||||
"DefaultTargets", "Build",
|
||||
"ToolsVersion", "4.0",
|
||||
"xmlns", "http://schemas.microsoft.com/developer/msbuild/2003");
|
||||
startTag("ItemGroup",
|
||||
"Label", "ProjectConfigurations");
|
||||
for (BuildConfig cfg : allConfigs) {
|
||||
startTag("ProjectConfiguration",
|
||||
"Include", cfg.get("Name"));
|
||||
tagData("Configuration", cfg.get("Id"));
|
||||
tagData("Platform", cfg.get("PlatformName"));
|
||||
endTag("ProjectConfiguration");
|
||||
}
|
||||
endTag("ItemGroup");
|
||||
|
||||
startTag("PropertyGroup", "Label", "Globals");
|
||||
tagData("ProjectGuid", "{8822CB5C-1C41-41C2-8493-9F6E1994338B}");
|
||||
tag("SccProjectName");
|
||||
tag("SccLocalPath");
|
||||
endTag("PropertyGroup");
|
||||
|
||||
tag("Import", "Project", "$(VCTargetsPath)\\Microsoft.Cpp.Default.props");
|
||||
|
||||
for (BuildConfig cfg : allConfigs) {
|
||||
startTag(cfg, "PropertyGroup", "Label", "Configuration");
|
||||
tagData("ConfigurationType", "DynamicLibrary");
|
||||
tagData("UseOfMfc", "false");
|
||||
endTag("PropertyGroup");
|
||||
}
|
||||
|
||||
tag("Import", "Project", "$(VCTargetsPath)\\Microsoft.Cpp.props");
|
||||
startTag("ImportGroup", "Label", "ExtensionSettings");
|
||||
endTag("ImportGroup");
|
||||
for (BuildConfig cfg : allConfigs) {
|
||||
startTag(cfg, "ImportGroup", "Label", "PropertySheets");
|
||||
tag("Import",
|
||||
"Project", "$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props",
|
||||
"Condition", "exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')",
|
||||
"Label", "LocalAppDataPlatform");
|
||||
endTag("ImportGroup");
|
||||
}
|
||||
|
||||
tag("PropertyGroup", "Label", "UserMacros");
|
||||
|
||||
startTag("PropertyGroup");
|
||||
tagData("_ProjectFileVersion", "10.0.30319.1");
|
||||
for (BuildConfig cfg : allConfigs) {
|
||||
tagData(cfg, "OutDir", cfg.get("OutputDir") + Util.sep);
|
||||
tagData(cfg, "IntDir", cfg.get("OutputDir") + Util.sep);
|
||||
tagData(cfg, "LinkIncremental", "false");
|
||||
}
|
||||
for (BuildConfig cfg : allConfigs) {
|
||||
tagData(cfg, "CodeAnalysisRuleSet", "AllRules.ruleset");
|
||||
tag(cfg, "CodeAnalysisRules");
|
||||
tag(cfg, "CodeAnalysisRuleAssemblies");
|
||||
}
|
||||
endTag("PropertyGroup");
|
||||
|
||||
for (BuildConfig cfg : allConfigs) {
|
||||
startTag(cfg, "ItemDefinitionGroup");
|
||||
startTag("ClCompile");
|
||||
tagV(cfg.getV("CompilerFlags"));
|
||||
endTag("ClCompile");
|
||||
|
||||
startTag("Link");
|
||||
tagV(cfg.getV("LinkerFlags"));
|
||||
endTag("Link");
|
||||
|
||||
startTag("PostBuildEvent");
|
||||
tagData("Message", BuildConfig.getFieldString(null, "PostbuildDescription"));
|
||||
tagData("Command", cfg.expandFormat(BuildConfig.getFieldString(null, "PostbuildCommand").replace("\t", "\r\n")));
|
||||
endTag("PostBuildEvent");
|
||||
|
||||
startTag("PreLinkEvent");
|
||||
tagData("Message", BuildConfig.getFieldString(null, "PrelinkDescription"));
|
||||
tagData("Command", cfg.expandFormat(BuildConfig.getFieldString(null, "PrelinkCommand").replace("\t", "\r\n")));
|
||||
endTag("PreLinkEvent");
|
||||
|
||||
endTag("ItemDefinitionGroup");
|
||||
}
|
||||
|
||||
writeFiles(allConfigs, projDir);
|
||||
|
||||
tag("Import", "Project", "$(VCTargetsPath)\\Microsoft.Cpp.targets");
|
||||
startTag("ImportGroup", "Label", "ExtensionTargets");
|
||||
endTag("ImportGroup");
|
||||
|
||||
endTag("Project");
|
||||
printWriter.close();
|
||||
System.out.println(" Done.");
|
||||
|
||||
writeFilterFile(projectFileName, projectName, allConfigs, projDir);
|
||||
writeUserFile(projectFileName, allConfigs);
|
||||
}
|
||||
|
||||
|
||||
private void writeUserFile(String projectFileName, Vector<BuildConfig> allConfigs) throws FileNotFoundException, UnsupportedEncodingException {
|
||||
String userFileName = projectFileName + ".user";
|
||||
if (new File(userFileName).exists()) {
|
||||
return;
|
||||
}
|
||||
System.out.print(" Writing .vcxproj.user file: " + userFileName);
|
||||
printWriter = new PrintWriter(userFileName, "UTF-8");
|
||||
|
||||
printWriter.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
|
||||
startTag("Project",
|
||||
"ToolsVersion", "4.0",
|
||||
"xmlns", "http://schemas.microsoft.com/developer/msbuild/2003");
|
||||
|
||||
for (BuildConfig cfg : allConfigs) {
|
||||
startTag(cfg, "PropertyGroup");
|
||||
tagData("LocalDebuggerCommand", "$(TargetDir)/hotspot.exe");
|
||||
endTag("PropertyGroup");
|
||||
}
|
||||
|
||||
endTag("Project");
|
||||
printWriter.close();
|
||||
System.out.println(" Done.");
|
||||
}
|
||||
|
||||
private void writeFilterFile(String projectFileName, String projectName,
|
||||
Vector<BuildConfig> allConfigs, String base) throws FileNotFoundException, UnsupportedEncodingException {
|
||||
String filterFileName = projectFileName + ".filters";
|
||||
System.out.print(" Writing .vcxproj.filters file: " + filterFileName);
|
||||
printWriter = new PrintWriter(filterFileName, "UTF-8");
|
||||
|
||||
printWriter.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
|
||||
startTag("Project",
|
||||
"ToolsVersion", "4.0",
|
||||
"xmlns", "http://schemas.microsoft.com/developer/msbuild/2003");
|
||||
|
||||
Hashtable<String, FileAttribute> allFiles = computeAttributedFiles(allConfigs);
|
||||
TreeSet<FileInfo> sortedFiles = sortFiles(allFiles);
|
||||
Vector<NameFilter> filters = makeFilters(sortedFiles);
|
||||
|
||||
// first all filters
|
||||
startTag("ItemGroup");
|
||||
for (NameFilter filter : filters) {
|
||||
doWriteFilter(filter, "");
|
||||
}
|
||||
startTag("Filter", "Include", "Resource Files");
|
||||
UUID uuid = UUID.randomUUID();
|
||||
tagData("UniqueIdentifier", "{" + uuid.toString() + "}");
|
||||
tagData("Extensions", "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe");
|
||||
endTag("Filter");
|
||||
endTag("ItemGroup");
|
||||
|
||||
// then all cpp files
|
||||
startTag("ItemGroup");
|
||||
for (NameFilter filter : filters) {
|
||||
doWriteFiles(sortedFiles, filter, "", "ClCompile", new Evaluator() {
|
||||
public boolean pick(FileInfo fi) {
|
||||
return fi.isCpp();
|
||||
}
|
||||
}, base);
|
||||
}
|
||||
endTag("ItemGroup");
|
||||
|
||||
// then all header files
|
||||
startTag("ItemGroup");
|
||||
for (NameFilter filter : filters) {
|
||||
doWriteFiles(sortedFiles, filter, "", "ClInclude", new Evaluator() {
|
||||
public boolean pick(FileInfo fi) {
|
||||
return fi.isHeader();
|
||||
}
|
||||
}, base);
|
||||
}
|
||||
endTag("ItemGroup");
|
||||
|
||||
// then all other files
|
||||
startTag("ItemGroup");
|
||||
for (NameFilter filter : filters) {
|
||||
doWriteFiles(sortedFiles, filter, "", "None", new Evaluator() {
|
||||
public boolean pick(FileInfo fi) {
|
||||
return true;
|
||||
}
|
||||
}, base);
|
||||
}
|
||||
endTag("ItemGroup");
|
||||
|
||||
endTag("Project");
|
||||
printWriter.close();
|
||||
System.out.println(" Done.");
|
||||
}
|
||||
|
||||
|
||||
private void doWriteFilter(NameFilter filter, String start) {
|
||||
startTag("Filter", "Include", start + filter.fname);
|
||||
UUID uuid = UUID.randomUUID();
|
||||
tagData("UniqueIdentifier", "{" + uuid.toString() + "}");
|
||||
endTag("Filter");
|
||||
if (filter instanceof ContainerFilter) {
|
||||
Iterator i = ((ContainerFilter)filter).babies();
|
||||
while (i.hasNext()) {
|
||||
doWriteFilter((NameFilter)i.next(), start + filter.fname + "\\");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface Evaluator {
|
||||
boolean pick(FileInfo fi);
|
||||
}
|
||||
|
||||
private void doWriteFiles(TreeSet<FileInfo> allFiles, NameFilter filter, String start, String tool, Evaluator eval, String base) {
|
||||
if (filter instanceof ContainerFilter) {
|
||||
Iterator i = ((ContainerFilter)filter).babies();
|
||||
while (i.hasNext()) {
|
||||
doWriteFiles(allFiles, (NameFilter)i.next(), start + filter.fname + "\\", tool, eval, base);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Iterator i = allFiles.iterator();
|
||||
while (i.hasNext()) {
|
||||
FileInfo fi = (FileInfo)i.next();
|
||||
|
||||
if (!filter.match(fi)) {
|
||||
continue;
|
||||
}
|
||||
if (eval.pick(fi)) {
|
||||
startTag(tool, "Include", rel(fi.full, base));
|
||||
tagData("Filter", start + filter.fname);
|
||||
endTag(tool);
|
||||
|
||||
// we not gonna look at this file anymore (sic!)
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void writeFiles(Vector<BuildConfig> allConfigs, String projDir) {
|
||||
Hashtable<String, FileAttribute> allFiles = computeAttributedFiles(allConfigs);
|
||||
TreeSet<FileInfo> sortedFiles = sortFiles(allFiles);
|
||||
|
||||
// first cpp-files
|
||||
startTag("ItemGroup");
|
||||
for (FileInfo fi : sortedFiles) {
|
||||
if (!fi.isCpp()) {
|
||||
continue;
|
||||
}
|
||||
writeFile("ClCompile", allConfigs, fi, projDir);
|
||||
}
|
||||
endTag("ItemGroup");
|
||||
|
||||
// then header-files
|
||||
startTag("ItemGroup");
|
||||
for (FileInfo fi : sortedFiles) {
|
||||
if (!fi.isHeader()) {
|
||||
continue;
|
||||
}
|
||||
writeFile("ClInclude", allConfigs, fi, projDir);
|
||||
}
|
||||
endTag("ItemGroup");
|
||||
|
||||
// then others
|
||||
startTag("ItemGroup");
|
||||
for (FileInfo fi : sortedFiles) {
|
||||
if (fi.isHeader() || fi.isCpp()) {
|
||||
continue;
|
||||
}
|
||||
writeFile("None", allConfigs, fi, projDir);
|
||||
}
|
||||
endTag("ItemGroup");
|
||||
}
|
||||
|
||||
/**
|
||||
* Make "path" into a relative path using "base" as the base.
|
||||
*
|
||||
* path and base are assumed to be normalized with / as the file separator.
|
||||
* returned path uses "\\" as file separator
|
||||
*/
|
||||
private String rel(String path, String base)
|
||||
{
|
||||
if(!base.endsWith("/")) {
|
||||
base += "/";
|
||||
}
|
||||
String[] pathTok = path.split("/");
|
||||
String[] baseTok = base.split("/");
|
||||
int pi = 0;
|
||||
int bi = 0;
|
||||
StringBuilder newPath = new StringBuilder();
|
||||
|
||||
// first step past all path components that are the same
|
||||
while (pi < pathTok.length &&
|
||||
bi < baseTok.length &&
|
||||
pathTok[pi].equals(baseTok[bi])) {
|
||||
pi++;
|
||||
bi++;
|
||||
}
|
||||
|
||||
// for each path component left in base, add "../"
|
||||
while (bi < baseTok.length) {
|
||||
bi++;
|
||||
newPath.append("..\\");
|
||||
}
|
||||
|
||||
// now add everything left in path
|
||||
while (pi < pathTok.length) {
|
||||
newPath.append(pathTok[pi]);
|
||||
pi++;
|
||||
if (pi != pathTok.length) {
|
||||
newPath.append("\\");
|
||||
}
|
||||
}
|
||||
return newPath.toString();
|
||||
}
|
||||
|
||||
private void writeFile(String tool, Vector<BuildConfig> allConfigs, FileInfo fi, String base) {
|
||||
if (fi.attr.configs == null && fi.attr.pchRoot == false && fi.attr.noPch == false) {
|
||||
tag(tool, "Include", rel(fi.full, base));
|
||||
}
|
||||
else {
|
||||
startTag(tool, "Include", rel(fi.full, base));
|
||||
for (BuildConfig cfg : allConfigs) {
|
||||
if (fi.attr.configs != null && !fi.attr.configs.contains(cfg.get("Name"))) {
|
||||
tagData(cfg, "ExcludedFromBuild", "true");
|
||||
}
|
||||
if (fi.attr.pchRoot) {
|
||||
tagData(cfg, "PrecompiledHeader", "Create");
|
||||
}
|
||||
if (fi.attr.noPch) {
|
||||
startTag(cfg, "PrecompiledHeader");
|
||||
endTag("PrecompiledHeader");
|
||||
}
|
||||
}
|
||||
endTag(tool);
|
||||
}
|
||||
}
|
||||
|
||||
String buildCond(BuildConfig cfg) {
|
||||
return "'$(Configuration)|$(Platform)'=='"+cfg.get("Name")+"'";
|
||||
}
|
||||
|
||||
|
||||
void tagV(Vector<String> v) {
|
||||
Iterator<String> i = v.iterator();
|
||||
while(i.hasNext()) {
|
||||
String name = i.next();
|
||||
String data = i.next();
|
||||
tagData(name, data);
|
||||
}
|
||||
}
|
||||
|
||||
void tagData(BuildConfig cfg, String name, String data) {
|
||||
tagData(name, data, "Condition", buildCond(cfg));
|
||||
}
|
||||
|
||||
void tag(BuildConfig cfg, String name, String... attrs) {
|
||||
String[] ss = new String[attrs.length + 2];
|
||||
ss[0] = "Condition";
|
||||
ss[1] = buildCond(cfg);
|
||||
System.arraycopy(attrs, 0, ss, 2, attrs.length);
|
||||
|
||||
tag(name, ss);
|
||||
}
|
||||
|
||||
void startTag(BuildConfig cfg, String name, String... attrs) {
|
||||
String[] ss = new String[attrs.length + 2];
|
||||
ss[0] = "Condition";
|
||||
ss[1] = buildCond(cfg);
|
||||
System.arraycopy(attrs, 0, ss, 2, attrs.length);
|
||||
|
||||
startTag(name, ss);
|
||||
}
|
||||
}
|
||||
|
||||
class CompilerInterfaceVC10 extends CompilerInterface {
|
||||
|
||||
@Override
|
||||
Vector getBaseCompilerFlags(Vector defines, Vector includes, String outDir) {
|
||||
Vector rv = new Vector();
|
||||
|
||||
addAttr(rv, "AdditionalIncludeDirectories", Util.join(";", includes));
|
||||
addAttr(rv, "PreprocessorDefinitions",
|
||||
Util.join(";", defines).replace("\\\"", "\""));
|
||||
addAttr(rv, "PrecompiledHeaderFile", "precompiled.hpp");
|
||||
addAttr(rv, "PrecompiledHeaderOutputFile", outDir+Util.sep+"vm.pch");
|
||||
addAttr(rv, "AssemblerListingLocation", outDir);
|
||||
addAttr(rv, "ObjectFileName", outDir+Util.sep);
|
||||
addAttr(rv, "ProgramDataBaseFileName", outDir+Util.sep+"jvm.pdb");
|
||||
// Set /nologo option
|
||||
addAttr(rv, "SuppressStartupBanner", "true");
|
||||
// Surpass the default /Tc or /Tp.
|
||||
addAttr(rv, "CompileAs", "Default");
|
||||
// Set /W3 option.
|
||||
addAttr(rv, "WarningLevel", "Level3");
|
||||
// Set /WX option,
|
||||
addAttr(rv, "TreatWarningAsError", "true");
|
||||
// Set /GS option
|
||||
addAttr(rv, "BufferSecurityCheck", "false");
|
||||
// Set /Zi option.
|
||||
addAttr(rv, "DebugInformationFormat", "ProgramDatabase");
|
||||
// Set /Yu option.
|
||||
addAttr(rv, "PrecompiledHeader", "Use");
|
||||
// Set /EHsc- option
|
||||
addAttr(rv, "ExceptionHandling", "");
|
||||
|
||||
addAttr(rv, "MultiProcessorCompilation", "true");
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@Override
|
||||
Vector getDebugCompilerFlags(String opt) {
|
||||
Vector rv = new Vector();
|
||||
|
||||
// Set /On option
|
||||
addAttr(rv, "Optimization", opt);
|
||||
// Set /FR option.
|
||||
addAttr(rv, "BrowseInformation", "true");
|
||||
addAttr(rv, "BrowseInformationFile", "$(IntDir)");
|
||||
// Set /MD option.
|
||||
addAttr(rv, "RuntimeLibrary", "MultiThreadedDLL");
|
||||
// Set /Oy- option
|
||||
addAttr(rv, "OmitFramePointers", "false");
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@Override
|
||||
Vector getProductCompilerFlags() {
|
||||
Vector rv = new Vector();
|
||||
|
||||
// Set /O2 option.
|
||||
addAttr(rv, "Optimization", "MaxSpeed");
|
||||
// Set /Oy- option
|
||||
addAttr(rv, "OmitFramePointers", "false");
|
||||
// Set /Ob option. 1 is expandOnlyInline
|
||||
addAttr(rv, "InlineFunctionExpansion", "OnlyExplicitInline");
|
||||
// Set /GF option.
|
||||
addAttr(rv, "StringPooling", "true");
|
||||
// Set /MD option. 2 is rtMultiThreadedDLL
|
||||
addAttr(rv, "RuntimeLibrary", "MultiThreadedDLL");
|
||||
// Set /Gy option
|
||||
addAttr(rv, "FunctionLevelLinking", "true");
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@Override
|
||||
Vector getBaseLinkerFlags(String outDir, String outDll, String platformName) {
|
||||
Vector rv = new Vector();
|
||||
|
||||
addAttr(rv, "AdditionalOptions",
|
||||
"/export:JNI_GetDefaultJavaVMInitArgs " +
|
||||
"/export:JNI_CreateJavaVM " +
|
||||
"/export:JVM_FindClassFromBootLoader "+
|
||||
"/export:JNI_GetCreatedJavaVMs "+
|
||||
"/export:jio_snprintf /export:jio_printf "+
|
||||
"/export:jio_fprintf /export:jio_vfprintf "+
|
||||
"/export:jio_vsnprintf "+
|
||||
"/export:JVM_GetVersionInfo "+
|
||||
"/export:JVM_GetThreadStateNames "+
|
||||
"/export:JVM_GetThreadStateValues "+
|
||||
"/export:JVM_InitAgentProperties");
|
||||
addAttr(rv, "AdditionalDependencies", "kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;Wsock32.lib;winmm.lib");
|
||||
addAttr(rv, "OutputFile", outDll);
|
||||
addAttr(rv, "SuppressStartupBanner", "true");
|
||||
addAttr(rv, "ModuleDefinitionFile", outDir+Util.sep+"vm.def");
|
||||
addAttr(rv, "ProgramDatabaseFile", outDir+Util.sep+"jvm.pdb");
|
||||
addAttr(rv, "SubSystem", "Windows");
|
||||
addAttr(rv, "BaseAddress", "0x8000000");
|
||||
addAttr(rv, "ImportLibrary", outDir+Util.sep+"jvm.lib");
|
||||
|
||||
if(platformName.equals("Win32")) {
|
||||
addAttr(rv, "TargetMachine", "MachineX86");
|
||||
} else {
|
||||
addAttr(rv, "TargetMachine", "MachineX64");
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@Override
|
||||
Vector getDebugLinkerFlags() {
|
||||
Vector rv = new Vector();
|
||||
|
||||
// /DEBUG option
|
||||
addAttr(rv, "GenerateDebugInformation", "true");
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@Override
|
||||
Vector getProductLinkerFlags() {
|
||||
Vector rv = new Vector();
|
||||
|
||||
// Set /OPT:REF option.
|
||||
addAttr(rv, "OptimizeReferences", "true");
|
||||
// Set /OPT:ICF option.
|
||||
addAttr(rv, "EnableCOMDATFolding", "true");
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@Override
|
||||
void getAdditionalNonKernelLinkerFlags(Vector rv) {
|
||||
extAttr(rv, "AdditionalOptions", " /export:AsyncGetCallTrace");
|
||||
}
|
||||
|
||||
@Override
|
||||
String getOptFlag() {
|
||||
return "MaxSpeed";
|
||||
}
|
||||
|
||||
@Override
|
||||
String getNoOptFlag() {
|
||||
return "Disabled";
|
||||
}
|
||||
|
||||
@Override
|
||||
String makeCfgName(String flavourBuild, String platform) {
|
||||
return flavourBuild + "|" + platform;
|
||||
}
|
||||
|
||||
}
|
||||
@ -35,7 +35,7 @@ public class WinGammaPlatformVC7 extends WinGammaPlatform {
|
||||
String projectVersion() {return "7.10";};
|
||||
|
||||
public void writeProjectFile(String projectFileName, String projectName,
|
||||
Vector allConfigs) throws IOException {
|
||||
Vector<BuildConfig> allConfigs) throws IOException {
|
||||
System.out.println();
|
||||
System.out.println(" Writing .vcproj file: "+projectFileName);
|
||||
// If we got this far without an error, we're safe to actually
|
||||
@ -54,11 +54,11 @@ public class WinGammaPlatformVC7 extends WinGammaPlatform {
|
||||
"SccLocalPath", ""
|
||||
}
|
||||
);
|
||||
startTag("Platforms", null);
|
||||
startTag("Platforms");
|
||||
tag("Platform", new String[] {"Name", (String) BuildConfig.getField(null, "PlatformName")});
|
||||
endTag("Platforms");
|
||||
|
||||
startTag("Configurations", null);
|
||||
startTag("Configurations");
|
||||
|
||||
for (Iterator i = allConfigs.iterator(); i.hasNext(); ) {
|
||||
writeConfiguration((BuildConfig)i.next());
|
||||
@ -66,11 +66,11 @@ public class WinGammaPlatformVC7 extends WinGammaPlatform {
|
||||
|
||||
endTag("Configurations");
|
||||
|
||||
tag("References", null);
|
||||
tag("References");
|
||||
|
||||
writeFiles(allConfigs);
|
||||
|
||||
tag("Globals", null);
|
||||
tag("Globals");
|
||||
|
||||
endTag("VisualStudioProject");
|
||||
printWriter.close();
|
||||
@ -190,28 +190,6 @@ public class WinGammaPlatformVC7 extends WinGammaPlatform {
|
||||
}
|
||||
}
|
||||
|
||||
class TypeFilter extends NameFilter {
|
||||
String[] exts;
|
||||
|
||||
TypeFilter(String fname, String[] exts) {
|
||||
this.fname = fname;
|
||||
this.exts = exts;
|
||||
}
|
||||
|
||||
boolean match(FileInfo fi) {
|
||||
for (int i=0; i<exts.length; i++) {
|
||||
if (fi.full.endsWith(exts[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
String filterString() {
|
||||
return Util.join(";", exts);
|
||||
}
|
||||
}
|
||||
|
||||
class TerminatorFilter extends NameFilter {
|
||||
TerminatorFilter(String fname) {
|
||||
this.fname = fname;
|
||||
@ -299,8 +277,8 @@ public class WinGammaPlatformVC7 extends WinGammaPlatform {
|
||||
// - container filter just provides a container to group together real filters
|
||||
// - real filter can select elements from the set according to some rule, put it into XML
|
||||
// and remove from the list
|
||||
Vector makeFilters(TreeSet<FileInfo> files) {
|
||||
Vector rv = new Vector();
|
||||
Vector<NameFilter> makeFilters(TreeSet<FileInfo> files) {
|
||||
Vector<NameFilter> rv = new Vector<NameFilter>();
|
||||
String sbase = Util.normalize(BuildConfig.getFieldString(null, "SourceBase")+"/src/");
|
||||
|
||||
String currentDir = "";
|
||||
@ -370,13 +348,12 @@ public class WinGammaPlatformVC7 extends WinGammaPlatform {
|
||||
rv.add(new SpecificNameFilter("Precompiled Header", new String[] {"precompiled.hpp"}));
|
||||
|
||||
// this one is to catch files not caught by other filters
|
||||
//rv.add(new TypeFilter("Header Files", new String[] {"h", "hpp", "hxx", "hm", "inl", "fi", "fd"}));
|
||||
rv.add(new TerminatorFilter("Source Files"));
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void writeFiles(Vector allConfigs) {
|
||||
void writeFiles(Vector<BuildConfig> allConfigs) {
|
||||
|
||||
Hashtable allFiles = computeAttributedFiles(allConfigs);
|
||||
|
||||
@ -387,7 +364,7 @@ public class WinGammaPlatformVC7 extends WinGammaPlatform {
|
||||
|
||||
TreeSet sortedFiles = sortFiles(allFiles);
|
||||
|
||||
startTag("Files", null);
|
||||
startTag("Files");
|
||||
|
||||
for (Iterator i = makeFilters(sortedFiles).iterator(); i.hasNext(); ) {
|
||||
doWriteFiles(sortedFiles, allConfigNames, (NameFilter)i.next());
|
||||
@ -555,35 +532,40 @@ public class WinGammaPlatformVC7 extends WinGammaPlatform {
|
||||
|
||||
int indent;
|
||||
|
||||
private void startTagPrim(String name,
|
||||
String[] attrs,
|
||||
boolean close) {
|
||||
startTagPrim(name, attrs, close, true);
|
||||
}
|
||||
|
||||
private void startTagPrim(String name,
|
||||
String[] attrs,
|
||||
boolean close) {
|
||||
boolean close,
|
||||
boolean newline) {
|
||||
doIndent();
|
||||
printWriter.print("<"+name);
|
||||
indent++;
|
||||
|
||||
if (attrs != null) {
|
||||
printWriter.println();
|
||||
if (attrs != null && attrs.length > 0) {
|
||||
for (int i=0; i<attrs.length; i+=2) {
|
||||
doIndent();
|
||||
printWriter.print(" " + attrs[i]+"=\""+attrs[i+1]+"\"");
|
||||
if (i < attrs.length - 2) {
|
||||
printWriter.println();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (close) {
|
||||
indent--;
|
||||
//doIndent();
|
||||
printWriter.println("/>");
|
||||
printWriter.print(" />");
|
||||
} else {
|
||||
//doIndent();
|
||||
printWriter.println(">");
|
||||
printWriter.print(">");
|
||||
}
|
||||
if(newline) {
|
||||
printWriter.println();
|
||||
}
|
||||
}
|
||||
|
||||
void startTag(String name, String[] attrs) {
|
||||
void startTag(String name, String... attrs) {
|
||||
startTagPrim(name, attrs, false);
|
||||
}
|
||||
|
||||
@ -601,11 +583,25 @@ public class WinGammaPlatformVC7 extends WinGammaPlatform {
|
||||
printWriter.println("</"+name+">");
|
||||
}
|
||||
|
||||
void tag(String name, String[] attrs) {
|
||||
void tag(String name, String... attrs) {
|
||||
startTagPrim(name, attrs, true);
|
||||
}
|
||||
|
||||
void tagV(String name, Vector attrs) {
|
||||
void tagData(String name, String data) {
|
||||
doIndent();
|
||||
printWriter.print("<"+name+">");
|
||||
printWriter.print(data);
|
||||
printWriter.println("</"+name+">");
|
||||
}
|
||||
|
||||
void tagData(String name, String data, String... attrs) {
|
||||
startTagPrim(name, attrs, false, false);
|
||||
printWriter.print(data);
|
||||
printWriter.println("</"+name+">");
|
||||
indent--;
|
||||
}
|
||||
|
||||
void tagV(String name, Vector attrs) {
|
||||
String s[] = new String [attrs.size()];
|
||||
for (int i=0; i<attrs.size(); i++) {
|
||||
s[i] = (String)attrs.elementAt(i);
|
||||
@ -616,7 +612,7 @@ public class WinGammaPlatformVC7 extends WinGammaPlatform {
|
||||
|
||||
void doIndent() {
|
||||
for (int i=0; i<indent; i++) {
|
||||
printWriter.print(" ");
|
||||
printWriter.print(" ");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -239,6 +239,11 @@ int main(int argc, char *argv[])
|
||||
AD.addInclude(AD._CPP_file, "assembler_sparc.inline.hpp");
|
||||
AD.addInclude(AD._CPP_file, "nativeInst_sparc.hpp");
|
||||
AD.addInclude(AD._CPP_file, "vmreg_sparc.inline.hpp");
|
||||
#endif
|
||||
#ifdef TARGET_ARCH_arm
|
||||
AD.addInclude(AD._CPP_file, "assembler_arm.inline.hpp");
|
||||
AD.addInclude(AD._CPP_file, "nativeInst_arm.hpp");
|
||||
AD.addInclude(AD._CPP_file, "vmreg_arm.inline.hpp");
|
||||
#endif
|
||||
AD.addInclude(AD._HPP_file, "memory/allocation.hpp");
|
||||
AD.addInclude(AD._HPP_file, "opto/machnode.hpp");
|
||||
|
||||
@ -209,7 +209,7 @@ void Canonicalizer::do_StoreField (StoreField* x) {
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
#include "c1/c1_InstructionPrinter.hpp"
|
||||
#include "ci/ciField.hpp"
|
||||
#include "ci/ciKlass.hpp"
|
||||
#include "compiler/compileBroker.hpp"
|
||||
#include "interpreter/bytecode.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "utilities/bitMap.inline.hpp"
|
||||
@ -1456,12 +1457,12 @@ void GraphBuilder::access_field(Bytecodes::Code code) {
|
||||
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,20 +1470,16 @@ void GraphBuilder::access_field(Bytecodes::Code code) {
|
||||
|
||||
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);
|
||||
obj = new Constant(new InstanceConstant(holder->java_mirror()), state_before);
|
||||
} else {
|
||||
obj = new Constant(new ClassConstant(holder));
|
||||
obj = new Constant(new InstanceConstant(holder->java_mirror()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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 +1506,7 @@ void GraphBuilder::access_field(Bytecodes::Code code) {
|
||||
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 +1515,7 @@ void GraphBuilder::access_field(Bytecodes::Code code) {
|
||||
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 +1523,8 @@ void GraphBuilder::access_field(Bytecodes::Code code) {
|
||||
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 +1539,8 @@ void GraphBuilder::access_field(Bytecodes::Code code) {
|
||||
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);
|
||||
}
|
||||
@ -3779,24 +3776,7 @@ void GraphBuilder::append_unsafe_CAS(ciMethod* callee) {
|
||||
|
||||
#ifndef PRODUCT
|
||||
void GraphBuilder::print_inline_result(ciMethod* callee, bool res) {
|
||||
const char sync_char = callee->is_synchronized() ? 's' : ' ';
|
||||
const char exception_char = callee->has_exception_handlers() ? '!' : ' ';
|
||||
const char monitors_char = callee->has_monitor_bytecodes() ? 'm' : ' ';
|
||||
tty->print(" %c%c%c ", sync_char, exception_char, monitors_char);
|
||||
for (int i = 0; i < scope()->level(); i++) tty->print(" ");
|
||||
if (res) {
|
||||
tty->print(" ");
|
||||
} else {
|
||||
tty->print("- ");
|
||||
}
|
||||
tty->print("@ %d ", bci());
|
||||
callee->print_short_name();
|
||||
tty->print(" (%d bytes)", callee->code_size());
|
||||
if (_inline_bailout_msg) {
|
||||
tty->print(" %s", _inline_bailout_msg);
|
||||
}
|
||||
tty->cr();
|
||||
|
||||
CompileTask::print_inlining(callee, scope()->level(), bci(), _inline_bailout_msg);
|
||||
if (res && CIPrintMethodCodes) {
|
||||
callee->print_codes();
|
||||
}
|
||||
|
||||
@ -323,8 +323,6 @@ class Instruction: public CompilationResourceObj {
|
||||
CanTrapFlag,
|
||||
DirectCompareFlag,
|
||||
IsEliminatedFlag,
|
||||
IsInitializedFlag,
|
||||
IsLoadedFlag,
|
||||
IsSafepointFlag,
|
||||
IsStaticFlag,
|
||||
IsStrictfpFlag,
|
||||
@ -693,7 +691,7 @@ BASE(AccessField, Instruction)
|
||||
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 @@ BASE(AccessField, Instruction)
|
||||
, _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 @@ BASE(AccessField, Instruction)
|
||||
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 @@ LEAF(LoadField, AccessField)
|
||||
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 @@ LEAF(StoreField, AccessField)
|
||||
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());
|
||||
|
||||
@ -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 @@ class LIR_OpJavaCall: public LIR_OpCall {
|
||||
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()));
|
||||
}
|
||||
|
||||
|
||||
@ -1559,9 +1559,7 @@ void LIRGenerator::do_StoreField(StoreField* x) {
|
||||
(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 @@ void LIRGenerator::do_LoadField(LoadField* x) {
|
||||
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 @@ void LIRGenerator::do_Invoke(Invoke* x) {
|
||||
__ 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(),
|
||||
|
||||
@ -2703,7 +2703,7 @@ int LinearScan::append_scope_value_for_operand(LIR_Opr opr, GrowableArray<ScopeV
|
||||
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 @@ int LinearScan::append_scope_value_for_operand(LIR_Opr opr, GrowableArray<ScopeV
|
||||
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;
|
||||
|
||||
@ -808,7 +808,7 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* thread, Runtime1::StubID stub_i
|
||||
{ klassOop klass = resolve_field_return_klass(caller_method, bci, CHECK);
|
||||
// Save a reference to the class that has to be checked for initialization
|
||||
init_klass = KlassHandle(THREAD, klass);
|
||||
k = klass;
|
||||
k = klass->java_mirror();
|
||||
}
|
||||
break;
|
||||
case Bytecodes::_new:
|
||||
|
||||
@ -141,7 +141,8 @@ class ValueNumberingVisitor: public InstructionVisitor {
|
||||
|
||||
// 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 @@ class ValueNumberingVisitor: public InstructionVisitor {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
@ -46,8 +46,7 @@ size_t ciCPCache::get_f1_offset(int index) {
|
||||
// ciCPCache::is_f1_null_at
|
||||
bool ciCPCache::is_f1_null_at(int index) {
|
||||
VM_ENTRY_MARK;
|
||||
oop f1 = entry_at(index)->f1();
|
||||
return (f1 == NULL);
|
||||
return entry_at(index)->is_f1_null();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
|
||||
@ -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) {}
|
||||
|
||||
@ -177,7 +177,7 @@ static bool trust_final_non_static_fields(ciInstanceKlass* holder) {
|
||||
// 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 @@ void ciField::initialize_from(fieldDescriptor* fd) {
|
||||
// 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;
|
||||
@ -212,7 +213,7 @@ void ciField::initialize_from(fieldDescriptor* fd) {
|
||||
// may change. The three examples are java.lang.System.in,
|
||||
// java.lang.System.out, and java.lang.System.err.
|
||||
|
||||
Handle k = _holder->get_klassOop();
|
||||
KlassHandle k = _holder->get_klassOop();
|
||||
assert( SystemDictionary::System_klass() != NULL, "Check once per vm");
|
||||
if( k() == SystemDictionary::System_klass() ) {
|
||||
// Check offsets for case 2: System.in, System.out, or System.err
|
||||
@ -224,36 +225,38 @@ void ciField::initialize_from(fieldDescriptor* fd) {
|
||||
}
|
||||
}
|
||||
|
||||
Handle mirror = k->java_mirror();
|
||||
|
||||
_is_constant = true;
|
||||
switch(type()->basic_type()) {
|
||||
case T_BYTE:
|
||||
_constant_value = ciConstant(type()->basic_type(), k->byte_field(_offset));
|
||||
_constant_value = ciConstant(type()->basic_type(), mirror->byte_field(_offset));
|
||||
break;
|
||||
case T_CHAR:
|
||||
_constant_value = ciConstant(type()->basic_type(), k->char_field(_offset));
|
||||
_constant_value = ciConstant(type()->basic_type(), mirror->char_field(_offset));
|
||||
break;
|
||||
case T_SHORT:
|
||||
_constant_value = ciConstant(type()->basic_type(), k->short_field(_offset));
|
||||
_constant_value = ciConstant(type()->basic_type(), mirror->short_field(_offset));
|
||||
break;
|
||||
case T_BOOLEAN:
|
||||
_constant_value = ciConstant(type()->basic_type(), k->bool_field(_offset));
|
||||
_constant_value = ciConstant(type()->basic_type(), mirror->bool_field(_offset));
|
||||
break;
|
||||
case T_INT:
|
||||
_constant_value = ciConstant(type()->basic_type(), k->int_field(_offset));
|
||||
_constant_value = ciConstant(type()->basic_type(), mirror->int_field(_offset));
|
||||
break;
|
||||
case T_FLOAT:
|
||||
_constant_value = ciConstant(k->float_field(_offset));
|
||||
_constant_value = ciConstant(mirror->float_field(_offset));
|
||||
break;
|
||||
case T_DOUBLE:
|
||||
_constant_value = ciConstant(k->double_field(_offset));
|
||||
_constant_value = ciConstant(mirror->double_field(_offset));
|
||||
break;
|
||||
case T_LONG:
|
||||
_constant_value = ciConstant(k->long_field(_offset));
|
||||
_constant_value = ciConstant(mirror->long_field(_offset));
|
||||
break;
|
||||
case T_OBJECT:
|
||||
case T_ARRAY:
|
||||
{
|
||||
oop o = k->obj_field(_offset);
|
||||
oop o = mirror->obj_field(_offset);
|
||||
|
||||
// A field will be "constant" if it is known always to be
|
||||
// a non-null reference to an instance of a particular class,
|
||||
|
||||
@ -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
|
||||
@ -138,3 +138,9 @@ void ciInstance::print_impl(outputStream* st) {
|
||||
st->print(" type=");
|
||||
klass()->print(st);
|
||||
}
|
||||
|
||||
|
||||
ciKlass* ciInstance::java_lang_Class_klass() {
|
||||
VM_ENTRY_MARK;
|
||||
return CURRENT_ENV->get_object(java_lang_Class::as_klassOop(get_oop()))->as_klass();
|
||||
}
|
||||
|
||||
@ -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
|
||||
@ -64,6 +64,8 @@ public:
|
||||
|
||||
// Constant value of a field at the specified offset.
|
||||
ciConstant field_value_by_offset(int field_offset);
|
||||
|
||||
ciKlass* java_lang_Class_klass();
|
||||
};
|
||||
|
||||
#endif // SHARE_VM_CI_CIINSTANCE_HPP
|
||||
|
||||
@ -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
|
||||
@ -85,7 +85,6 @@ ciInstanceKlass::ciInstanceKlass(KlassHandle h_k) :
|
||||
if (h_k() != SystemDictionary::Object_klass()) {
|
||||
super();
|
||||
}
|
||||
java_mirror();
|
||||
//compute_nonstatic_fields(); // done outside of constructor
|
||||
}
|
||||
|
||||
@ -320,6 +319,9 @@ ciInstanceKlass* ciInstanceKlass::super() {
|
||||
// Get the instance of java.lang.Class corresponding to this klass.
|
||||
// Cache it on this->_java_mirror.
|
||||
ciInstance* ciInstanceKlass::java_mirror() {
|
||||
if (is_shared()) {
|
||||
return ciKlass::java_mirror();
|
||||
}
|
||||
if (_java_mirror == NULL) {
|
||||
_java_mirror = ciKlass::java_mirror();
|
||||
}
|
||||
|
||||
@ -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 @@ int ciMethod::scale_count(int count, float prof_factor) {
|
||||
// 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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 @@ ciObject* ciObjectFactory::create_new_object(oop o) {
|
||||
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);
|
||||
@ -663,7 +663,7 @@ ciObjectFactory::NonPermObject* &ciObjectFactory::find_non_perm(oop key) {
|
||||
if (key->is_perm() && _non_perm_count == 0) {
|
||||
return emptyBucket;
|
||||
} else if (key->is_instance()) {
|
||||
if (key->klass() == SystemDictionary::Class_klass()) {
|
||||
if (key->klass() == SystemDictionary::Class_klass() && JavaObjectsInPerm) {
|
||||
// class mirror instances are always perm
|
||||
return emptyBucket;
|
||||
}
|
||||
|
||||
@ -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 @@ ciKlass* ciBytecodeStream::get_declared_method_holder() {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@ -1871,7 +1871,8 @@ void ciTypeFlow::Block::print_value_on(outputStream* st) const {
|
||||
// ------------------------------------------------------------------
|
||||
// ciTypeFlow::Block::print_on
|
||||
void ciTypeFlow::Block::print_on(outputStream* st) const {
|
||||
if ((Verbose || WizardMode)) {
|
||||
if ((Verbose || WizardMode) && (limit() >= 0)) {
|
||||
// Don't print 'dummy' blocks (i.e. blocks with limit() '-1')
|
||||
outer()->method()->print_codes_on(start(), limit(), st);
|
||||
}
|
||||
st->print_cr(" ==================================================== ");
|
||||
|
||||
@ -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
|
||||
@ -37,6 +37,7 @@
|
||||
#include "memory/universe.inline.hpp"
|
||||
#include "oops/constantPoolOop.hpp"
|
||||
#include "oops/instanceKlass.hpp"
|
||||
#include "oops/instanceMirrorKlass.hpp"
|
||||
#include "oops/klass.inline.hpp"
|
||||
#include "oops/klassOop.hpp"
|
||||
#include "oops/klassVtable.hpp"
|
||||
@ -146,12 +147,14 @@ void ClassFileParser::parse_constant_pool_entries(constantPoolHandle cp, int len
|
||||
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 (!EnableInvokeDynamic) {
|
||||
classfile_parse_error(
|
||||
"This JVM does not support constant tag %u in class file %s",
|
||||
tag, CHECK);
|
||||
}
|
||||
if (tag == JVM_CONSTANT_MethodHandle) {
|
||||
@ -170,12 +173,14 @@ void ClassFileParser::parse_constant_pool_entries(constantPoolHandle cp, int len
|
||||
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
|
||||
@ -255,7 +260,7 @@ void ClassFileParser::parse_constant_pool_entries(constantPoolHandle cp, int len
|
||||
verify_legal_utf8((unsigned char*)utf8_buffer, utf8_length, CHECK);
|
||||
}
|
||||
|
||||
if (AnonymousClasses && has_cp_patch_at(index)) {
|
||||
if (EnableInvokeDynamic && has_cp_patch_at(index)) {
|
||||
Handle patch = clear_cp_patch_at(index);
|
||||
guarantee_property(java_lang_String::is_instance(patch()),
|
||||
"Illegal utf8 patch at %d in class file %s",
|
||||
@ -438,7 +443,7 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
|
||||
int ref_index = cp->method_handle_index_at(index);
|
||||
check_property(
|
||||
valid_cp_range(ref_index, length) &&
|
||||
EnableMethodHandles,
|
||||
EnableInvokeDynamic,
|
||||
"Invalid constant pool index %u in class file %s",
|
||||
ref_index, CHECK_(nullHandle));
|
||||
constantTag tag = cp->tag_at(ref_index);
|
||||
@ -482,7 +487,7 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
|
||||
check_property(
|
||||
valid_cp_range(ref_index, length) &&
|
||||
cp->tag_at(ref_index).is_utf8() &&
|
||||
EnableMethodHandles,
|
||||
EnableInvokeDynamic,
|
||||
"Invalid constant pool index %u in class file %s",
|
||||
ref_index, CHECK_(nullHandle));
|
||||
}
|
||||
@ -517,7 +522,7 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
|
||||
|
||||
if (_cp_patches != NULL) {
|
||||
// need to treat this_class specially...
|
||||
assert(AnonymousClasses, "");
|
||||
assert(EnableInvokeDynamic, "");
|
||||
int this_class_index;
|
||||
{
|
||||
cfs->guarantee_more(8, CHECK_(nullHandle)); // flags, this_class, super_class, infs_len
|
||||
@ -672,7 +677,7 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
|
||||
|
||||
|
||||
void ClassFileParser::patch_constant_pool(constantPoolHandle cp, int index, Handle patch, TRAPS) {
|
||||
assert(AnonymousClasses, "");
|
||||
assert(EnableInvokeDynamic, "");
|
||||
BasicType patch_type = T_VOID;
|
||||
switch (cp->tag_at(index).value()) {
|
||||
|
||||
@ -1616,8 +1621,13 @@ methodHandle ClassFileParser::parse_method(constantPoolHandle cp, bool is_interf
|
||||
|
||||
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));
|
||||
}
|
||||
@ -2093,7 +2103,7 @@ methodHandle ClassFileParser::parse_method(constantPoolHandle cp, bool is_interf
|
||||
_has_vanilla_constructor = true;
|
||||
}
|
||||
|
||||
if (EnableMethodHandles && (m->is_method_handle_invoke() ||
|
||||
if (EnableInvokeDynamic && (m->is_method_handle_invoke() ||
|
||||
m->is_method_handle_adapter())) {
|
||||
THROW_MSG_(vmSymbols::java_lang_VirtualMachineError(),
|
||||
"Method handle invokers must be defined internally to the VM", nullHandle);
|
||||
@ -2597,54 +2607,6 @@ typeArrayHandle ClassFileParser::assemble_annotations(u1* runtime_visible_annota
|
||||
}
|
||||
|
||||
|
||||
static void initialize_static_field(fieldDescriptor* fd, TRAPS) {
|
||||
KlassHandle h_k (THREAD, fd->field_holder());
|
||||
assert(h_k.not_null() && fd->is_static(), "just checking");
|
||||
if (fd->has_initial_value()) {
|
||||
BasicType t = fd->field_type();
|
||||
switch (t) {
|
||||
case T_BYTE:
|
||||
h_k()->byte_field_put(fd->offset(), fd->int_initial_value());
|
||||
break;
|
||||
case T_BOOLEAN:
|
||||
h_k()->bool_field_put(fd->offset(), fd->int_initial_value());
|
||||
break;
|
||||
case T_CHAR:
|
||||
h_k()->char_field_put(fd->offset(), fd->int_initial_value());
|
||||
break;
|
||||
case T_SHORT:
|
||||
h_k()->short_field_put(fd->offset(), fd->int_initial_value());
|
||||
break;
|
||||
case T_INT:
|
||||
h_k()->int_field_put(fd->offset(), fd->int_initial_value());
|
||||
break;
|
||||
case T_FLOAT:
|
||||
h_k()->float_field_put(fd->offset(), fd->float_initial_value());
|
||||
break;
|
||||
case T_DOUBLE:
|
||||
h_k()->double_field_put(fd->offset(), fd->double_initial_value());
|
||||
break;
|
||||
case T_LONG:
|
||||
h_k()->long_field_put(fd->offset(), fd->long_initial_value());
|
||||
break;
|
||||
case T_OBJECT:
|
||||
{
|
||||
#ifdef ASSERT
|
||||
TempNewSymbol sym = SymbolTable::new_symbol("Ljava/lang/String;", CHECK);
|
||||
assert(fd->signature() == sym, "just checking");
|
||||
#endif
|
||||
oop string = fd->string_initial_value(CHECK);
|
||||
h_k()->obj_field_put(fd->offset(), string);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
THROW_MSG(vmSymbols::java_lang_ClassFormatError(),
|
||||
"Illegal ConstantValue attribute in class file");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ClassFileParser::java_lang_ref_Reference_fix_pre(typeArrayHandle* fields_ptr,
|
||||
constantPoolHandle cp, FieldAllocationCount *fac_ptr, TRAPS) {
|
||||
// This code is for compatibility with earlier jdk's that do not
|
||||
@ -2760,8 +2722,8 @@ void ClassFileParser::java_lang_ref_Reference_fix_pre(typeArrayHandle* fields_pt
|
||||
}
|
||||
|
||||
|
||||
void ClassFileParser::java_lang_Class_fix_pre(objArrayHandle* methods_ptr,
|
||||
FieldAllocationCount *fac_ptr, TRAPS) {
|
||||
void ClassFileParser::java_lang_Class_fix_pre(int* nonstatic_field_size,
|
||||
FieldAllocationCount *fac_ptr) {
|
||||
// Add fake fields for java.lang.Class instances
|
||||
//
|
||||
// This is not particularly nice. We should consider adding a
|
||||
@ -2778,10 +2740,13 @@ void ClassFileParser::java_lang_Class_fix_pre(objArrayHandle* methods_ptr,
|
||||
// versions because when the offsets are computed at bootstrap
|
||||
// time we don't know yet which version of the JDK we're running in.
|
||||
|
||||
// The values below are fake but will force two non-static oop fields and
|
||||
// The values below are fake but will force three non-static oop fields and
|
||||
// a corresponding non-static oop map block to be allocated.
|
||||
const int extra = java_lang_Class::number_of_fake_oop_fields;
|
||||
fac_ptr->nonstatic_oop_count += extra;
|
||||
|
||||
// Reserve some leading space for fake ints
|
||||
*nonstatic_field_size += align_size_up(java_lang_Class::hc_number_of_fake_int_fields * BytesPerInt, heapOopSize) / heapOopSize;
|
||||
}
|
||||
|
||||
|
||||
@ -2797,16 +2762,16 @@ void ClassFileParser::java_lang_Class_fix_post(int* next_nonstatic_oop_offset_pt
|
||||
|
||||
// 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.
|
||||
|
||||
if (!EnableMethodHandles) return;
|
||||
if (!EnableInvokeDynamic) return;
|
||||
|
||||
int word_sig_index = 0;
|
||||
const int cp_size = cp->length();
|
||||
@ -2818,9 +2783,10 @@ void ClassFileParser::java_dyn_MethodHandle_fix_pre(constantPoolHandle cp,
|
||||
}
|
||||
}
|
||||
|
||||
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 +2823,10 @@ void ClassFileParser::java_dyn_MethodHandle_fix_pre(constantPoolHandle cp,
|
||||
}
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
|
||||
@ -3194,9 +3161,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
||||
int next_nonstatic_field_offset;
|
||||
|
||||
// Calculate the starting byte offsets
|
||||
next_static_oop_offset = (instanceKlass::header_size() +
|
||||
align_object_offset(vtable_size) +
|
||||
align_object_offset(itable_size)) * wordSize;
|
||||
next_static_oop_offset = instanceMirrorKlass::offset_of_static_fields();
|
||||
next_static_double_offset = next_static_oop_offset +
|
||||
(fac.static_oop_count * heapOopSize);
|
||||
if ( fac.static_double_count &&
|
||||
@ -3215,18 +3180,28 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
||||
fac.static_byte_count ), wordSize );
|
||||
static_field_size = (next_static_type_offset -
|
||||
next_static_oop_offset) / wordSize;
|
||||
|
||||
// Add fake fields for java.lang.Class instances (also see below)
|
||||
if (class_name == vmSymbols::java_lang_Class() && class_loader.is_null()) {
|
||||
java_lang_Class_fix_pre(&nonstatic_field_size, &fac);
|
||||
}
|
||||
|
||||
first_nonstatic_field_offset = instanceOopDesc::base_offset_in_bytes() +
|
||||
nonstatic_field_size * heapOopSize;
|
||||
next_nonstatic_field_offset = first_nonstatic_field_offset;
|
||||
|
||||
// Add fake fields for java.lang.Class instances (also see below)
|
||||
if (class_name == vmSymbols::java_lang_Class() && class_loader.is_null()) {
|
||||
java_lang_Class_fix_pre(&methods, &fac, CHECK_(nullHandle));
|
||||
// adjust the vmentry field declaration in java.lang.invoke.MethodHandle
|
||||
if (EnableInvokeDynamic && class_name == vmSymbols::java_lang_invoke_MethodHandle() && class_loader.is_null()) {
|
||||
java_lang_invoke_MethodHandle_fix_pre(cp, fields, &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));
|
||||
if (AllowTransitionalJSR292 &&
|
||||
EnableInvokeDynamic && class_name == vmSymbols::java_dyn_MethodHandle() && class_loader.is_null()) {
|
||||
java_lang_invoke_MethodHandle_fix_pre(cp, fields, &fac, CHECK_(nullHandle));
|
||||
}
|
||||
if (AllowTransitionalJSR292 &&
|
||||
EnableInvokeDynamic && 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
|
||||
@ -3546,7 +3521,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
||||
}
|
||||
|
||||
// We can now create the basic klassOop for this klass
|
||||
klassOop ik = oopFactory::new_instanceKlass(vtable_size, itable_size,
|
||||
klassOop ik = oopFactory::new_instanceKlass(name, vtable_size, itable_size,
|
||||
static_field_size,
|
||||
total_oop_map_count,
|
||||
rt, CHECK_(nullHandle));
|
||||
@ -3568,7 +3543,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
||||
this_klass->set_class_loader(class_loader());
|
||||
this_klass->set_nonstatic_field_size(nonstatic_field_size);
|
||||
this_klass->set_has_nonstatic_fields(has_nonstatic_fields);
|
||||
this_klass->set_static_oop_field_size(fac.static_oop_count);
|
||||
this_klass->set_static_oop_field_count(fac.static_oop_count);
|
||||
cp->set_pool_holder(this_klass());
|
||||
error_handler.set_in_error(false); // turn off error handler for cp
|
||||
this_klass->set_constants(cp());
|
||||
@ -3629,9 +3604,6 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
||||
// Make sure this is the end of class file stream
|
||||
guarantee_property(cfs->at_eos(), "Extra bytes at the end of class file %s", CHECK_(nullHandle));
|
||||
|
||||
// Initialize static fields
|
||||
this_klass->do_local_static_fields(&initialize_static_field, CHECK_(nullHandle));
|
||||
|
||||
// VerifyOops believes that once this has been set, the object is completely loaded.
|
||||
// Compute transitive closure of interfaces this class implements
|
||||
this_klass->set_transitive_interfaces(transitive_interfaces());
|
||||
@ -3665,6 +3637,9 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
||||
check_illegal_static_method(this_klass, CHECK_(nullHandle));
|
||||
}
|
||||
|
||||
// Allocate mirror and initialize static fields
|
||||
java_lang_Class::create_mirror(this_klass, CHECK_(nullHandle));
|
||||
|
||||
ClassLoadingService::notify_class_loaded(instanceKlass::cast(this_klass()),
|
||||
false /* not shared class */);
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user