Merge
This commit is contained in:
commit
c6c70af568
3
.hgtags
3
.hgtags
@ -44,3 +44,6 @@ d22867c5f1b295a0a2b3b4bc8999a2676f6e20c3 jdk7-b64
|
||||
eb24af1404aec8aa140c4cd4d13d2839b150dd41 jdk7-b67
|
||||
bca2225b66d78c4bf4d9801f54cac7715a598650 jdk7-b68
|
||||
1b662b1ed14eb4ae31d5138a36c433b13d941dc5 jdk7-b69
|
||||
207f694795c448c17753eff1a2f50363106960c2 jdk7-b70
|
||||
c5d39b6be65cba0effb5f466ea48fe43764d0e0c jdk7-b71
|
||||
df4bcd06e1d0ab306efa5a44f24a409dc0c0c742 jdk7-b72
|
||||
|
@ -44,3 +44,6 @@ e01380cd1de4ce048b87d059d238e5ab5e341947 jdk7-b65
|
||||
c4523c6f82048f420bf0d57c4cd47976753b7d2c jdk7-b67
|
||||
e1b972ff53cd58f825791f8ed9b2deffd16e768c jdk7-b68
|
||||
82e6c820c51ac27882b77755d42efefdbf1dcda0 jdk7-b69
|
||||
175cb3fe615998d1004c6d3fd96e6d2e86b6772d jdk7-b70
|
||||
4c36e9853dda27bdac5ef4839a610509fbe31d34 jdk7-b71
|
||||
0d7e03b426df27c21dcc44ffb9178eacd1b04f10 jdk7-b72
|
||||
|
@ -38,12 +38,17 @@
|
||||
<ul>
|
||||
<li><a href="#introduction">Introduction</a></li>
|
||||
<li><a href="#MBE">Minimum Build Environments</a></li>
|
||||
<li><a href="#SDBE">Specific Developer Build Environments</a></li>
|
||||
<li><a href="#SDBE">Specific Developer Build Environments</a>
|
||||
<ul>
|
||||
<li><a href="#fedora">Fedora Linux</a> </li>
|
||||
<li><a href="#centos">CentOS Linux</a> </li>
|
||||
<li><a href="#ubuntu">Ubuntu Linux</a> </li>
|
||||
<li><a href="#debian">Debian GNU/Linux</a></li>
|
||||
<li><a href="#ubuntu">Ubuntu Linux</a> </li>
|
||||
<li><a href="#opensuse">OpenSUSE</a></li>
|
||||
<li><a href="#mandriva">Mandriva</a></li>
|
||||
<li><a href="#opensolaris">OpenSolaris</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#directories">Source Directory Structure</a> </li>
|
||||
<li><a href="#building">Build Information</a>
|
||||
<ul>
|
||||
@ -68,7 +73,6 @@
|
||||
</li>
|
||||
<li><a href="#zip">Zip and Unzip</a> </li>
|
||||
<li><a href="#freetype">FreeType2 Fonts</a> </li>
|
||||
<li><a href="#jibx">JIBX Libraries</a> </li>
|
||||
<li>Linux and Solaris:
|
||||
<ul>
|
||||
<li><a href="#cups">CUPS Include files</a> </li>
|
||||
@ -210,24 +214,59 @@
|
||||
we will try to provide what information we have available to us.
|
||||
</blockquote>
|
||||
<!-- ------------------------------------------------------ -->
|
||||
<h3><a name="fedora">Fedora 9</a></h3>
|
||||
<h3><a name="fedora">Fedora</a></h3>
|
||||
<blockquote>
|
||||
After installing
|
||||
<a href="http://www.fedoraproject.org/">Fedora 9</a>
|
||||
you need to make sure you have
|
||||
the "Software Development" bundle installed, plus the
|
||||
following packages:
|
||||
<blockquote>
|
||||
<ul>
|
||||
<li>cups devel: Cups Development Package</li>
|
||||
<li>freetype 2.3+ devel: Freetype 2.3 Development Package</li>
|
||||
<li>hg: Mercurial, if you need to clone or manage source repositories</li>
|
||||
<li>ksh: May be needed when using <tt>webrev</tt></li>
|
||||
</ul>
|
||||
<h4>Fedora 9</h4>
|
||||
<p>
|
||||
<blockquote>
|
||||
After installing <a href="http://fedoraproject.org">Fedora</a> 9
|
||||
you need to install several build dependencies. The simplest
|
||||
way to do it is to execute the following commands as user
|
||||
<tt>root</tt>:
|
||||
<p/>
|
||||
<code>yum-builddep java-openjdk</code>
|
||||
<p/>
|
||||
<code>yum install gcc gcc-c++</code>
|
||||
<p/>
|
||||
In addition, it's necessary to set a few environment variables for the build:
|
||||
|
||||
<p/>
|
||||
<code>export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-openjdk</code>
|
||||
</blockquote>
|
||||
<p>
|
||||
Always a good idea to do a complete Software Update/Refresh
|
||||
after you get all the packages installed.
|
||||
<h4>Fedora 10</h4>
|
||||
<p>
|
||||
<blockquote>
|
||||
After installing <a href="http://fedoraproject.org">Fedora</a> 10
|
||||
you need to install several build dependencies. The simplest
|
||||
way to do it is to execute the following commands as user
|
||||
<tt>root</tt>:
|
||||
<p/>
|
||||
<code>yum-builddep java-1.6.0-openjdk</code>
|
||||
<p/>
|
||||
<code>yum install gcc gcc-c++</code>
|
||||
<p/>
|
||||
In addition, it's necessary to set a few environment variables for the build:
|
||||
|
||||
<p/>
|
||||
<code>export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-openjdk</code>
|
||||
</blockquote>
|
||||
<h4>Fedora 11</h4>
|
||||
<p>
|
||||
<blockquote>
|
||||
After installing <a href="http://fedoraproject.org">Fedora</a> 11
|
||||
you need to install several build dependencies. The simplest
|
||||
way to do it is to execute the following commands as user
|
||||
<tt>root</tt>:
|
||||
<p/>
|
||||
<code>yum-builddep java-1.6.0-openjdk</code>
|
||||
<p/>
|
||||
<code>yum install gcc gcc-c++</code>
|
||||
<p/>
|
||||
In addition, it's necessary to set a few environment variables for the build:
|
||||
|
||||
<p/>
|
||||
<code>export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-openjdk</code>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
<!-- ------------------------------------------------------ -->
|
||||
<h3><a name="centos">CentOS 5.2</a></h3>
|
||||
@ -270,145 +309,146 @@
|
||||
it's needed.
|
||||
</blockquote>
|
||||
<!-- ------------------------------------------------------ -->
|
||||
<h3><a name="ubuntu">Ubuntu</a></h3>
|
||||
<h3><a name="debian">Debian</a></h3>
|
||||
<blockquote>
|
||||
In addition to needing the Bootstrap JDK and the Binary Plugs,
|
||||
when building on Ubuntu you will need to
|
||||
make sure certain packages are installed.
|
||||
In particular, certain X11 packages, make, m4, gawk, gcc 4,
|
||||
binutils, cups, freetype
|
||||
and alsa.
|
||||
<!-- ------------------------------------------------------ -->
|
||||
<h4>Ubuntu 6.06</h4>
|
||||
<h4>Debian 5.0 (Lenny)</h4>
|
||||
<p>
|
||||
The following list of packages for Ubuntu 6.06 is a working set that
|
||||
does appear to work.
|
||||
<p>
|
||||
<b>Note that it's quite possible that some of these
|
||||
packages are not required, so anyone discovering that some of the
|
||||
packages listed below are NOT required,
|
||||
please let the
|
||||
OpenJDK
|
||||
team know.</b>
|
||||
<p>
|
||||
All the packages below can be installed with the
|
||||
Synaptic Package manager provided with the base Ubuntu 6.06 release.
|
||||
<blockquote>
|
||||
<ul>
|
||||
<li>binutils (2.16.1cvs20060117-1ubuntu2.1)</li>
|
||||
<li>cpp (4:4.0.3-1)</li>
|
||||
<li>cpp-4.0 (4.0.3-1ubuntu5)</li>
|
||||
<li>libfreetype6-dev</li>
|
||||
<li>g++ (4:4.0.3-1)</li>
|
||||
<li>g++-4.0 (4.0.3-1ubuntu5)</li>
|
||||
<li>gawk (1:3.1.5-2build1)</li>
|
||||
<li>gcc (4:4.0.3-1)</li>
|
||||
<li>gcc-4.0 (4.0.3-1ubuntu5)</li>
|
||||
<li>libasound2-dev (1.0.10-2ubuntu4)</li>
|
||||
<li>libc6 (2.3.6-0ubuntu20) to 2.3.6-0ubuntu20.4</li>
|
||||
<li>libc6-dev (2.3.6-0ubuntu20.4)</li>
|
||||
<li>libc6-i686 (2.3.6-0ubuntu20) to 2.3.6-0ubuntu20.4</li>
|
||||
<li>libcupsys2-dev (1.2.2-0ubuntu0.6.06)</li>
|
||||
<li>libgcrypt11-dev (1.2.2-1)</li>
|
||||
<li>libgnutls-dev (1.2.9-2ubuntu1.1)</li>
|
||||
<li>libgnutls12 (1.2.9-2ubuntu1) to 1.2.9-2ubuntu1.1</li>
|
||||
<li>libgpg-error-dev (1.1-4)</li>
|
||||
<li>libice-dev (2:1.0.0-0ubuntu2)</li>
|
||||
<li>liblockfile1 (1.06.1)</li>
|
||||
<li>libopencdk8-dev (0.5.7-2)</li>
|
||||
<li>libpopt-dev (1.7-5)</li>
|
||||
<li>libsm-dev (2:1.0.0-0ubuntu2)</li>
|
||||
<li>libstdc++6-4.0-dev (4.0.3-1ubuntu5)</li>
|
||||
<li>libtasn1-2-dev (0.2.17-1ubuntu1)</li>
|
||||
<li>libx11-dev (2:1.0.0-0ubuntu9)</li>
|
||||
<li>libxau-dev (1:1.0.0-0ubuntu4)</li>
|
||||
<li>libxaw-headers (2:1.0.1-0ubuntu3)</li>
|
||||
<li>libxaw7-dev (2:1.0.1-0ubuntu3)</li>
|
||||
<li>libxdmcp-dev (1:1.0.0-0ubuntu2)</li>
|
||||
<li>libxext-dev (2:1.0.0-0ubuntu4)</li>
|
||||
<li>libxi-dev (2:1.0.0-0ubuntu3) </li>
|
||||
<li>libxmu-dev (2:1.0.0-0ubuntu3)</li>
|
||||
<li>libxmu-headers (2:1.0.0-0ubuntu3)</li>
|
||||
<li>libxmuu-dev (2:1.0.0-0ubuntu3)</li>
|
||||
<li>libxp-dev (6.8.2-11ubuntu2)</li>
|
||||
<li>libxpm-dev (1:3.5.4.2-0ubuntu3)</li>
|
||||
<li>libxrandr-dev (1:1.1.0.2-0ubuntu4)</li>
|
||||
<li>libxt-dev (1:1.0.0-0ubuntu3)</li>
|
||||
<li>libxtrap-dev (2:1.0.0-0ubuntu2)</li>
|
||||
<li>libxtst-dev (2:1.0.1-0ubuntu2)</li>
|
||||
<li>libxv-dev (2:1.0.1-0ubuntu3)</li>
|
||||
<li>linux-kernel-headers (2.6.11.2-0ubuntu18)</li>
|
||||
<li>m4 (1.4.4-1)</li>
|
||||
<li>make (3.80+3.81.b4-1)</li>
|
||||
<li>ssl-cert (1.0.13)</li>
|
||||
<li>x-dev (7.0.4-0ubuntu2)</li>
|
||||
<li>x11proto-core-dev (7.0.4-0ubuntu2)</li>
|
||||
<li>x11proto-input-dev (1.3.2-0ubuntu2)</li>
|
||||
<li>x11proto-kb-dev (1.0.2-0ubuntu2)</li>
|
||||
<li>x11proto-randr-dev (1.1.2-0ubuntu2)</li>
|
||||
<li>x11proto-record-dev (1.13.2-0ubuntu2)</li>
|
||||
<li>x11proto-trap-dev (3.4.3-0ubuntu2)</li>
|
||||
<li>x11proto-video-dev (2.2.2-0ubuntu2)</li>
|
||||
<li>x11proto-xext-dev (7.0.2-0ubuntu2)</li>
|
||||
<li>xlibs-dev (7.0.0-0ubuntu45)</li>
|
||||
<li>zlib1g-dev (1:1.2.3-6ubuntu4)</li>
|
||||
</ul>
|
||||
</blockquote>
|
||||
<!-- ------------------------------------------------------ -->
|
||||
<h4>Ubuntu 7.04</h4>
|
||||
<p>
|
||||
Using the Synaptic Package Manager, download the following
|
||||
packages (double indented packages are automatically aquired
|
||||
due to package dependencies):
|
||||
<blockquote>
|
||||
<ul>
|
||||
<li>build-essential</li>
|
||||
<ul>
|
||||
<li>dpkg-dev</li>
|
||||
<li>g++</li>
|
||||
<li>g++-4.1</li>
|
||||
<li>libc6-dev</li>
|
||||
<li>libstdc++6.4.1-dev</li>
|
||||
<li>linux-libc-dev</li>
|
||||
</ul>
|
||||
<li>gawk</li>
|
||||
<li>m4</li>
|
||||
<li>libasound2-dev</li>
|
||||
<li>libcupsys2-dev</li>
|
||||
<ul>
|
||||
<li>libgcrypt11-dev</li>
|
||||
<li>lgnutls-dev</li>
|
||||
<li>libgpg-error-dev</li>
|
||||
<li>liblzo-dev</li>
|
||||
<li>libopencdk8-dev</li>
|
||||
<li>libpopt-dev</li>
|
||||
<li>libtasn1-3-dev</li>
|
||||
<li>zlib1g-dev</li>
|
||||
</ul>
|
||||
<li>sun-java6-jdk</li>
|
||||
<ul>
|
||||
<li>java-common</li>
|
||||
<li>libltdl3</li>
|
||||
<li>odbcinst1debian1</li>
|
||||
<li>sun-java6-bin</li>
|
||||
<li>sun-java6-jre</li>
|
||||
<li>unixodbc</li>
|
||||
</ul>
|
||||
<li>xlibs-dev</li>
|
||||
<ul>
|
||||
<li>(many)</li>
|
||||
</ul>
|
||||
<li>x11proto-print-dev</li>
|
||||
<li>libxaw7-dev</li>
|
||||
<ul>
|
||||
<li>libxaw-headers</li>
|
||||
</ul>
|
||||
<li>libxp-dev</li>
|
||||
<li>libfreetype6-dev</li>
|
||||
</ul>
|
||||
</blockquote>
|
||||
<blockquote>
|
||||
After installing <a href="http://debian.org">Debian</a> 5
|
||||
you need to install several build dependencies.
|
||||
The simplest way to install the build dependencies is to
|
||||
execute the following commands as user <tt>root</tt>:
|
||||
<p/>
|
||||
<code>aptitude build-dep openjdk-6</code>
|
||||
<p/>
|
||||
<code>aptitude install openjdk-6-jdk libmotif-dev</code>
|
||||
<p/>
|
||||
In addition, it's necessary to set a few environment variables for the build:
|
||||
<p/>
|
||||
<code>export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-6-openjdk</code>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
<!-- ------------------------------------------------------ -->
|
||||
<!-- ====================================================== -->
|
||||
<h3><a name="ubuntu">Ubuntu</a></h3>
|
||||
<blockquote>
|
||||
<h4>Ubuntu 8.04</h4>
|
||||
<p>
|
||||
<blockquote>
|
||||
After installing <a href="http://ubuntu.org">Ubuntu</a> 8.04
|
||||
you need to install several build dependencies.
|
||||
<p/>
|
||||
First, you need to enable the universe repository in the
|
||||
Software Sources application and reload the repository
|
||||
information. The Software Sources application is available
|
||||
under the System/Administration menu.
|
||||
<p/>
|
||||
The simplest way to install the build dependencies is to
|
||||
execute the following commands:
|
||||
<p/>
|
||||
<code>sudo aptitude build-dep openjdk-6</code>
|
||||
<p/>
|
||||
<code>sudo aptitude install openjdk-6-jdk</code>
|
||||
<p/>
|
||||
In addition, it's necessary to set a few environment variables for the build:
|
||||
<p/>
|
||||
<code>export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-6-openjdk</code>
|
||||
</blockquote>
|
||||
<h4>Ubuntu 8.10</h4>
|
||||
<p>
|
||||
<blockquote>
|
||||
After installing <a href="http://ubuntu.org">Ubuntu</a> 8.10
|
||||
you need to install several build dependencies. The simplest
|
||||
way to do it is to execute the following commands:
|
||||
<p/>
|
||||
<code>sudo aptitude build-dep openjdk-6</code>
|
||||
<p/>
|
||||
<code>sudo aptitude install openjdk-6-jdk</code>
|
||||
<p/>
|
||||
In addition, it's necessary to set a few environment variables for the build:
|
||||
<p/>
|
||||
<code>export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-6-openjdk</code>
|
||||
</blockquote>
|
||||
<h4>Ubuntu 9.04</h4>
|
||||
<p>
|
||||
<blockquote>
|
||||
After installing <a href="http://ubuntu.org">Ubuntu</a> 9.04
|
||||
you need to install several build dependencies. The simplest
|
||||
way to do it is to execute the following commands:
|
||||
<p/>
|
||||
<code>sudo aptitude build-dep openjdk-6</code>
|
||||
<p/>
|
||||
<code>sudo aptitude install openjdk-6-jdk</code>
|
||||
<p/>
|
||||
In addition, it's necessary to set a few environment variables for the build:
|
||||
<p/>
|
||||
<code>export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-6-openjdk</code>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
<!-- ====================================================== -->
|
||||
<h3><a name="opensuse">OpenSUSE</a></h3>
|
||||
<blockquote>
|
||||
<h4>OpenSUSE 11.1</h4>
|
||||
<p>
|
||||
<blockquote>
|
||||
After installing <a href="http://opensuse.org">OpenSUSE</a> 11.1
|
||||
you need to install several build dependencies.
|
||||
The simplest way to install the build dependencies is to
|
||||
execute the following commands:
|
||||
<p/>
|
||||
<code>sudo zypper source-install -d java-1_6_0-openjdk</code>
|
||||
<p/>
|
||||
<code>sudo zypper install make</code>
|
||||
<p/>
|
||||
In addition, it is necessary to set a few environment variables for the build:
|
||||
<p/>
|
||||
<code>export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-1.6.0-openjdk</code>
|
||||
<p/>
|
||||
Finally, you need to unset the <code>JAVA_HOME</code> environment variable:
|
||||
<p/>
|
||||
<code>export -n JAVA_HOME</code>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
<!-- ====================================================== -->
|
||||
<h3><a name="mandriva">Mandriva</a></h3>
|
||||
<blockquote>
|
||||
<h4>Mandriva Linux One 2009 Spring</h4>
|
||||
<p>
|
||||
<blockquote>
|
||||
After installing <a href="http://mandriva.org">Mandriva</a> Linux One 2009 Spring
|
||||
you need to install several build dependencies.
|
||||
The simplest way to install the build dependencies is to
|
||||
execute the following commands as user <tt>root</tt>:
|
||||
<p/>
|
||||
<code>urpmi java-1.6.0-openjdk-devel ant make gcc gcc-c++ freetype-devel zip unzip libcups2-devel libxrender1-devel libalsa2-devel libstc++-static-devel libxtst6-devel libxi-devel</code>
|
||||
<p/>
|
||||
In addition, it is necessary to set a few environment variables for the build:
|
||||
<p/>
|
||||
<code>export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-1.6.0-openjdk</code>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
<!-- ====================================================== -->
|
||||
<h3><a name="opensolaris">OpenSolaris</a></h3>
|
||||
<blockquote>
|
||||
<h4>OpenSolaris 2009.06</h4>
|
||||
<p>
|
||||
<blockquote>
|
||||
After installing <a href="http://opensolaris.org">OpenSolaris</a> 2009.06
|
||||
you need to install several build dependencies.
|
||||
The simplest way to install the build dependencies is to
|
||||
execute the following commands:
|
||||
<p/>
|
||||
<code>pfexec pkg install SUNWgmake SUNWj6dev SUNWant sunstudioexpress SUNWcups SUNWzip SUNWunzip SUNWxwhl SUNWxorg-headers SUNWaudh SUNWfreetype2</code>
|
||||
<p/>
|
||||
In addition, it is necessary to set a few environment variables for the build:
|
||||
<p/>
|
||||
<code>export LANG=C ALT_COMPILER_PATH=/opt/SunStudioExpress/bin/ ALT_CUPS_HEADERS_PATH=/usr/include/</code>
|
||||
<p/>
|
||||
Finally, you need to make sure that the build process can find the Sun Studio compilers:
|
||||
<p/>
|
||||
<code>export PATH=$PATH:/opt/SunStudioExpress/bin/</code>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
<!-- ------------------------------------------------------ -->
|
||||
<hr>
|
||||
<h2><a name="directories">Source Directory Structure</a></h2>
|
||||
<blockquote>
|
||||
@ -596,11 +636,6 @@
|
||||
Install or upgrade the <a href="#freetype">FreeType development
|
||||
package</a>.
|
||||
</li>
|
||||
<li>
|
||||
Install the
|
||||
<a href="#jibx">JIBX Libraries</a>, set
|
||||
<tt><a href="#ALT_JIBX_LIBS_PATH">ALT_JIBX_LIBS_PATH</a></tt>.
|
||||
</li>
|
||||
<li>
|
||||
Install
|
||||
<a href="#ant">Ant</a>,
|
||||
@ -669,11 +704,6 @@
|
||||
<li>
|
||||
Install the <a href="#xrender">XRender Include files</a>.
|
||||
</li>
|
||||
<li>
|
||||
Install the
|
||||
<a href="#jibx">JIBX Libraries</a>, set
|
||||
<tt><a href="#ALT_JIBX_LIBS_PATH">ALT_JIBX_LIBS_PATH</a></tt>.
|
||||
</li>
|
||||
<li>
|
||||
Install
|
||||
<a href="#ant">Ant</a>,
|
||||
@ -769,11 +799,6 @@
|
||||
Install
|
||||
<a href="#dxsdk">Microsoft DirectX SDK</a>.
|
||||
</li>
|
||||
<li>
|
||||
Install the
|
||||
<a href="#jibx">JIBX Libraries</a>, set
|
||||
<tt><a href="#ALT_JIBX_LIBS_PATH">ALT_JIBX_LIBS_PATH</a></tt>.
|
||||
</li>
|
||||
<li>
|
||||
Install
|
||||
<a href="#ant">Ant</a>,
|
||||
@ -903,27 +928,6 @@
|
||||
fine for most JDK developers.
|
||||
</blockquote>
|
||||
<!-- ------------------------------------------------------ -->
|
||||
<h4><a name="jibx">JIBX</a></h4>
|
||||
<blockquote>
|
||||
JIBX libraries version 1.1.5 is required for building the OpenJDK.
|
||||
Namely, the following JAR files from the JIBX distribution package
|
||||
are required:
|
||||
<ul>
|
||||
<li>bcel.jar
|
||||
<li>jibx-bind.jar
|
||||
<li>jibx-run.jar
|
||||
<li>xpp3.jar
|
||||
</ul>
|
||||
<p>
|
||||
You can download the package from the
|
||||
<a href="http://jibx.sourceforge.net" target="_blank">JIBX site</a>.
|
||||
<p>
|
||||
You will need to set the
|
||||
<tt><a href="#ALT_JIBX_LIBS_PATH">ALT_JIBX_LIBS_PATH</a></tt>
|
||||
environment variable to refer to place where the JAR files,
|
||||
above, are located.
|
||||
</blockquote>
|
||||
<!-- ------------------------------------------------------ -->
|
||||
<h4><a name="compilers">Compilers</a></h4>
|
||||
<blockquote>
|
||||
<strong><a name="gcc">Linux gcc/binutils</a></strong>
|
||||
@ -1496,12 +1500,6 @@
|
||||
The default will refer to
|
||||
<tt>jdk/src/share/lib/security/cacerts</tt>.
|
||||
</dd>
|
||||
<dt><tt><a name="ALT_JIBX_LIBS_PATH">ALT_JIBX_LIBS_PATH</a></tt></dt>
|
||||
<dd>
|
||||
The location of the <a href="#jibx">JIBX libraries</a> file.
|
||||
The default value is
|
||||
<tt>$(ALT_SLASH_JAVA)/devtools/share/jibx/lib</tt>.
|
||||
</dd>
|
||||
<dt><a name="ALT_CUPS_HEADERS_PATH"><tt>ALT_CUPS_HEADERS_PATH</tt></a> </dt>
|
||||
<dd>
|
||||
The location of the CUPS header files.
|
||||
|
@ -44,3 +44,6 @@ a821e059a961bcb02830280d51f6dd030425c066 jdk7-b66
|
||||
a12ea7c7b497b4ba7830550095ef633bd6f43971 jdk7-b67
|
||||
5182bcc9c60cac429d1f7988676cec7320752be3 jdk7-b68
|
||||
8120d308ec4e805c5588b8d9372844d781c4112d jdk7-b69
|
||||
175bd68779546078dbdb6dacd7f0aced79ed22b1 jdk7-b70
|
||||
3f1ef7f899ea2aec189c4fb67e5c8fa374437c50 jdk7-b71
|
||||
c793a31209263fbb867c23c752599d85c21abb73 jdk7-b72
|
||||
|
@ -141,12 +141,12 @@ $(CLASSES_JAR):
|
||||
|
||||
#----- src.zip
|
||||
|
||||
SRC_ZIP_FILES = $(shell $(FIND) $(SRC_CLASSES_DIR) \( -name SCCS -o -name \*-template \) -prune -o -type f -print )
|
||||
SRC_ZIP_FILES = $(shell $(FIND) $(SRC_CLASSES_DIR) \( -name \*-template \) -prune -o -type f -print )
|
||||
|
||||
SRC_ZIP = $(LIB_DIR)/src.zip
|
||||
$(SRC_ZIP): $(SRC_ZIP_FILES)
|
||||
abs_src_zip=`cd $(@D) ; pwd`/$(@F) ; \
|
||||
( cd $(SRC_CLASSES_DIR) ; $(FIND) . \( -name SCCS -o -name \*-template \) -prune -o -type f -print | $(ZIP) -q $$abs_src_zip -@ ) ; \
|
||||
( cd $(SRC_CLASSES_DIR) ; $(FIND) . \( -name \*-template \) -prune -o -type f -print | $(ZIP) -q $$abs_src_zip -@ ) ; \
|
||||
( cd $(GENSRC_DIR) ; $(FIND) . -type f -print | $(ZIP) -q $$abs_src_zip -@ ) ;
|
||||
|
||||
#----- bin.zip
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 1998-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,22 +24,29 @@
|
||||
#
|
||||
|
||||
# Input: BUILDDIR PACKAGE PKGDIR PROGRAM BUILDTOOL_SOURCE_ROOT BUILDTOOL_MAIN
|
||||
|
||||
|
||||
# All subdirectories under the package root for the tool (max depth 4)
|
||||
_WC_DIRS = * */* */*/* */*/*/*
|
||||
|
||||
BUILDTOOL_MAIN_SOURCE_FILE = $(BUILDTOOL_SOURCE_ROOT)/$(BUILDTOOL_MAIN)
|
||||
BUILDTOOL_MANIFEST_FILE = $(BUILDTOOLCLASSDIR)/$(PROGRAM)_manifest.mf
|
||||
BUILDTOOL_JAR_FILE = $(BUILDTOOLJARDIR)/$(PROGRAM).jar
|
||||
BUILDTOOL_ALL_FILES := $(shell $(CD) $(BUILDTOOL_SOURCE_ROOT) \
|
||||
&& $(FIND) $(PKGDIR) $(SCM_DIRS_prune) -o -type f -print)
|
||||
BUILTTOOL_MAINCLASS = $(subst /,.,$(BUILDTOOL_MAIN:%.java=%))
|
||||
BUILTTOOL_MAINCLASS = $(subst /,.,$(BUILDTOOL_MAIN:%.java=%))
|
||||
|
||||
all build: $(BUILDTOOL_JAR_FILE) tool_info
|
||||
# Wildcard patterns that find all the sources for this build tool
|
||||
BUILDTOOL_WC_PATTERNS = $(BUILDTOOL_SOURCE_ROOT)/$(PKGDIR)/*.java \
|
||||
$(patsubst %, $(BUILDTOOL_SOURCE_ROOT)/$(PKGDIR)/%/*.java, $(_WC_DIRS))
|
||||
|
||||
# Wildcard expansion that finds all the files
|
||||
BUILDTOOL_SRC_FILES := $(wildcard $(BUILDTOOL_WC_PATTERNS))
|
||||
|
||||
all build: $(BUILDTOOL_JAR_FILE)
|
||||
|
||||
$(BUILDTOOL_MANIFEST_FILE): $(BUILDTOOL_MAIN_SOURCE_FILE)
|
||||
@$(prep-target)
|
||||
$(ECHO) "Main-Class: $(BUILTTOOL_MAINCLASS)" > $@
|
||||
|
||||
$(BUILDTOOL_JAR_FILE): $(BUILDTOOL_MANIFEST_FILE) \
|
||||
$(BUILDTOOL_ALL_FILES:%=$(BUILDTOOL_SOURCE_ROOT)/%)
|
||||
$(BUILDTOOL_JAR_FILE): $(BUILDTOOL_MANIFEST_FILE) $(BUILDTOOL_SRC_FILES)
|
||||
@$(prep-target)
|
||||
@$(MKDIR) -p $(BUILDTOOLCLASSDIR)
|
||||
$(BOOT_JAVAC_CMD) -d $(BUILDTOOLCLASSDIR) \
|
||||
@ -49,23 +56,8 @@ $(BUILDTOOL_JAR_FILE): $(BUILDTOOL_MANIFEST_FILE) \
|
||||
$(JAR_JFLAGS) || $(RM) $@
|
||||
@$(java-vm-cleanup)
|
||||
|
||||
# Printing out a build tool information line
|
||||
define printBuildToolSetting
|
||||
if [ "$2" != "" ] ; then $(PRINTF) "%-25s %s\n" "$1:" "$2"; fi
|
||||
endef
|
||||
|
||||
# Print out the build tool information
|
||||
tool_info:
|
||||
@$(ECHO) "========================================================="
|
||||
@$(call printBuildToolSetting,BUILDTOOL,$(PROGRAM))
|
||||
@$(call printBuildToolSetting,PACKAGE,$(PACKAGE))
|
||||
@$(call printBuildToolSetting,BUILDTOOL_SOURCE_ROOT,$(BUILDTOOL_SOURCE_ROOT))
|
||||
@$(call printBuildToolSetting,BUILTTOOL_MAINCLASS,$(BUILTTOOL_MAINCLASS))
|
||||
@$(call printBuildToolSetting,BUILDTOOL_JAR_FILE,$(BUILDTOOL_JAR_FILE))
|
||||
@$(ECHO) "========================================================="
|
||||
|
||||
clean clobber::
|
||||
$(RM) -r $(BUILDTOOLCLASSDIR)/$(PKGDIR)
|
||||
$(RM) $(BUILDTOOL_MANIFEST_FILE)
|
||||
$(RM) $(BUILDTOOL_JAR_FILE)
|
||||
$(RM) -r $(BUILDTOOLCLASSDIR)/$(PKGDIR) \
|
||||
$(BUILDTOOL_MANIFEST_FILE) \
|
||||
$(BUILDTOOL_JAR_FILE)
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 1998-1999 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 1998-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -56,11 +56,3 @@ ifndef USE_IMPLICITS
|
||||
%: %.sh
|
||||
endif
|
||||
|
||||
#
|
||||
# If you are using RCS, you must set the variable USE_RCS at the make
|
||||
# command line. Otherwise we disable RCS.
|
||||
#
|
||||
ifndef USE_RCS
|
||||
%:: %,v
|
||||
%:: RCS/%,v
|
||||
endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 1995-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 1995-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -310,125 +310,32 @@ endef
|
||||
SUBDIRS_MAKEFLAGS-clobber = INCREMENTAL_BUILD=false
|
||||
SUBDIRS_MAKEFLAGS-clean = INCREMENTAL_BUILD=false
|
||||
|
||||
# Current directory
|
||||
CURRENT_DIRECTORY := $(shell $(PWD))
|
||||
|
||||
# If no timing wanted, we need to define these as empty
|
||||
ifdef NO_TIMING
|
||||
|
||||
TIMING_ID:=NA
|
||||
|
||||
define TIMING_start
|
||||
t=0:0:0:0
|
||||
endef
|
||||
|
||||
define TIMING_end
|
||||
time_used=0
|
||||
endef
|
||||
|
||||
else # NO_TIMING
|
||||
|
||||
# Default timing id
|
||||
TIMING_ID:=$(shell $(BASENAME) $(CURRENT_DIRECTORY))
|
||||
|
||||
# Timing start (must be used in same shell, e.g. same command line)
|
||||
# Defines the shell variable $1 to have the start time.
|
||||
define TIMING_start
|
||||
$1=`$(DATE) +%j:%H:%M:%S`
|
||||
endef
|
||||
|
||||
# Timing end (must be used in same shell, e.g. same command line)
|
||||
# Expects shell variable $1 to have been defined as the start time.
|
||||
# Expects shell variable $2 to have timing id string
|
||||
# Sets total_seconds shell variable as the total seconds used.
|
||||
# Sets time_used shell variable to contain format "%dh%dm%ds"
|
||||
define TIMING_end
|
||||
begTime="$${$1}"; \
|
||||
timing_id="$${$2}"; \
|
||||
endTime=`$(DATE) +%j:%H:%M:%S`; \
|
||||
d1=`$(ECHO) $${begTime} | $(CUT) -d':' -f1 | $(SED) -e 's@^0*@@'`; \
|
||||
if [ "$${d1}" = "" ] ; then d1=0; fi; \
|
||||
h1=`$(ECHO) $${begTime} | $(CUT) -d':' -f2 | $(SED) -e 's@^0*@@'`; \
|
||||
if [ "$${h1}" = "" ] ; then h1=0; fi; \
|
||||
m1=`$(ECHO) $${begTime} | $(CUT) -d':' -f3 | $(SED) -e 's@^0*@@'`; \
|
||||
if [ "$${m1}" = "" ] ; then m1=0; fi; \
|
||||
s1=`$(ECHO) $${begTime} | $(CUT) -d':' -f4 | $(SED) -e 's@^0*@@'`; \
|
||||
if [ "$${s1}" = "" ] ; then s1=0; fi; \
|
||||
d2=`$(ECHO) $${endTime} | $(CUT) -d':' -f1 | $(SED) -e 's@^0*@@'`; \
|
||||
if [ "$${d2}" = "" ] ; then d2=0; fi; \
|
||||
h2=`$(ECHO) $${endTime} | $(CUT) -d':' -f2 | $(SED) -e 's@^0*@@'`; \
|
||||
if [ "$${h2}" = "" ] ; then h2=0; fi; \
|
||||
m2=`$(ECHO) $${endTime} | $(CUT) -d':' -f3 | $(SED) -e 's@^0*@@'`; \
|
||||
if [ "$${m2}" = "" ] ; then m2=0; fi; \
|
||||
s2=`$(ECHO) $${endTime} | $(CUT) -d':' -f4 | $(SED) -e 's@^0*@@'`; \
|
||||
if [ "$${s2}" = "" ] ; then s2=0; fi; \
|
||||
t1_secs=`$(EXPR) $${d1} '*' 60 '*' 60 '*' 24 '+' $${h1} '*' 60 '*' 60 \
|
||||
'+' $${m1} '*' 60 '+' $${s1}`; \
|
||||
t2_secs=`$(EXPR) $${d2} '*' 60 '*' 60 '*' 24 '+' $${h2} '*' 60 '*' 60 \
|
||||
'+' $${m2} '*' 60 '+' $${s2}`; \
|
||||
total_seconds=`$(EXPR) $${t2_secs} '-' $${t1_secs}`; \
|
||||
if [ "$${total_seconds}" -lt 0 ] ; then total_seconds=0; fi; \
|
||||
t_hour=`$(EXPR) $${total_seconds} '/' '(' 60 '*' 60 ')'`h; \
|
||||
t_min=`$(EXPR) '(' $${total_seconds} '%' '(' 60 '*' 60 ')' ')' '/' 60`m; \
|
||||
t_sec=`$(EXPR) $${total_seconds} '%' 60`s; \
|
||||
time_used=$${t_sec}; \
|
||||
if [ "$${t_hour}" != "0h" ] ; then \
|
||||
time_used=$${t_hour}$${t_min}$${t_sec}; \
|
||||
elif [ "$${t_min}" != "0m" ] ; then \
|
||||
time_used=$${t_min}$${t_sec}; \
|
||||
else \
|
||||
time_used=$${t_sec}; \
|
||||
fi; \
|
||||
$(PRINTF) " Timing: %05d seconds or %s for %s\n" \
|
||||
$${total_seconds} $${time_used} $${timing_id}
|
||||
endef
|
||||
|
||||
endif # NO_TIMING
|
||||
|
||||
# Given a SUBDIRS list, cd into them and make them
|
||||
# SUBDIRS_MAKEFLAGS Make settings for a subdir make
|
||||
# SUBDIRS_MAKEFLAGS-$@ Make settings specific to this target
|
||||
define SUBDIRS-loop
|
||||
@$(ECHO) "Begin Processing SUBDIRS: $(SUBDIRS)"
|
||||
@for i in DUMMY $(SUBDIRS) ; do \
|
||||
if [ "$$i" != "DUMMY" ] ; then \
|
||||
$(ECHO) ">>>Recursively making "$$i" "$@" @ `$(DATE)` ..."; \
|
||||
timing_id="$(TIMING_ID)-`$(BASENAME) $${i}`"; \
|
||||
$(call TIMING_start,startTime); \
|
||||
curDir=$(CURRENT_DIRECTORY); \
|
||||
$(CD) $$i; $(MAKE) $@ TIMING_ID=$${timing_id} \
|
||||
$(SUBDIRS_MAKEFLAGS) \
|
||||
$(SUBDIRS_MAKEFLAGS-$@) \
|
||||
FULL_VERSION=$(FULL_VERSION) \
|
||||
RELEASE=$(RELEASE) || exit 1; \
|
||||
$(CD) $${curDir}; \
|
||||
$(call TIMING_end,startTime,timing_id); \
|
||||
$(ECHO) "<<<Finished Recursively making "$$i" "$@" @ `$(DATE)`." ; \
|
||||
$(MAKE) -C $${i} $@ \
|
||||
$(SUBDIRS_MAKEFLAGS) \
|
||||
$(SUBDIRS_MAKEFLAGS-$@) \
|
||||
FULL_VERSION=$(FULL_VERSION) \
|
||||
RELEASE=$(RELEASE) || exit 1; \
|
||||
fi ; \
|
||||
done
|
||||
@$(ECHO) "Done Processing SUBDIRS: $(SUBDIRS)"
|
||||
endef
|
||||
|
||||
# Given a OTHERSUBDIRS list, cd into them and make them (extra loop define)
|
||||
# OTHERSUBDIRS_MAKEFLAGS Make settings for a subdir make
|
||||
define OTHERSUBDIRS-loop
|
||||
@$(ECHO) "Begin Processing OTHERSUBDIRS: $(OTHERSUBDIRS)"
|
||||
@for i in DUMMY $(OTHERSUBDIRS) ; do \
|
||||
if [ "$$i" != "DUMMY" ] ; then \
|
||||
$(ECHO) ">>>Recursively making "$$i" "$@" @ `$(DATE)` ..."; \
|
||||
timing_id="$(TIMING_ID)-`$(BASENAME) $${i}`"; \
|
||||
$(call TIMING_start,startTime); \
|
||||
curDir=$(CURRENT_DIRECTORY); \
|
||||
$(CD) $$i; $(MAKE) $@ TIMING_ID=$${timing_id} \
|
||||
$(OTHERSUBDIRS_MAKEFLAGS) \
|
||||
FULL_VERSION=$(FULL_VERSION) \
|
||||
RELEASE=$(RELEASE) || exit 1; \
|
||||
$(CD) $${curDir}; \
|
||||
$(call TIMING_end,startTime,timing_id); \
|
||||
$(ECHO) "<<<Finished Recursively making "$$i" "$@" @ `$(DATE)`." ; \
|
||||
$(MAKE) -C $${i} $@ \
|
||||
$(OTHERSUBDIRS_MAKEFLAGS) \
|
||||
FULL_VERSION=$(FULL_VERSION) \
|
||||
RELEASE=$(RELEASE) || exit 1; \
|
||||
fi ; \
|
||||
done
|
||||
@$(ECHO) "Done Processing OTHERSUBDIRS: $(OTHERSUBDIRS)"
|
||||
endef
|
||||
|
||||
#
|
||||
@ -460,46 +367,23 @@ else
|
||||
VERSION_DEFINES = -DRELEASE='"$(RELEASE)"'
|
||||
endif
|
||||
|
||||
# Note: As a rule, GNU Make rules should not appear in any of the
|
||||
# Defs*.gmk files. These were added for Kestrel-Solaris and do address
|
||||
# a TeamWare bug. They should be moved elsewhere for Merlin.
|
||||
#
|
||||
# Override gnumake built-in rules which do sccs get operations badly.
|
||||
# (They put the checked out code in the current directory, not in the
|
||||
# directory of the original file.)
|
||||
# Since this is a symptom of a teamware failure, complain and die on the spot.
|
||||
|
||||
# This message immediately goes to stdout and the build terminates.
|
||||
define SCCS-trouble
|
||||
$(error \
|
||||
"ERROR: File $@ referenced while building in $(CURRENT_DIRECTORY) \
|
||||
is out of date with respect to its SCCS file $<. \
|
||||
This can happen from an unresolved Teamware conflict, a file movement, or \
|
||||
a failure in which SCCS files are updated but the 'sccs get' was not done. \
|
||||
You should double check for other out of date files in your workspace. \
|
||||
Or run: cd $(TOPDIR) && $(MAKE) sccs_get")
|
||||
endef
|
||||
|
||||
%:: s.%
|
||||
@$(SCCS-trouble)
|
||||
%:: SCCS/s.%
|
||||
@$(SCCS-trouble)
|
||||
@$(ECHO) " is out of date with respect to its SCCS file." >> $(WARNING_FILE)
|
||||
@$(ECHO) " This file may be from an unresolved Teamware conflict." >> $(WARNING_FILE)
|
||||
@$(ECHO) " This is also a symptom of a Teamware bringover/putback failure" >> $(WARNING_FILE)
|
||||
@$(ECHO) " in which SCCS files are updated but not checked out." >> $(WARNING_FILE)
|
||||
@$(ECHO) " Check for other out of date files in your workspace." >> $(WARNING_FILE)
|
||||
@$(ECHO) "" >> $(WARNING_FILE)
|
||||
@#exit 666
|
||||
# Prevent the use of many default suffix rules we do not need
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .o .h .obj .cpp .hpp .java .class
|
||||
|
||||
# Make sure we are all insane
|
||||
ifdef INSANE
|
||||
export INSANE
|
||||
endif
|
||||
|
||||
ifdef ALT_COPYRIGHT_YEAR
|
||||
COPYRIGHT_YEAR = $(ALT_COPYRIGHT_YEAR)
|
||||
else
|
||||
COPYRIGHT_YEAR = $(shell $(DATE) '+%Y')
|
||||
# Make sure we have the current year
|
||||
ifndef COPYRIGHT_YEAR
|
||||
ifdef ALT_COPYRIGHT_YEAR
|
||||
COPYRIGHT_YEAR := $(ALT_COPYRIGHT_YEAR)
|
||||
else
|
||||
COPYRIGHT_YEAR := $(shell $(DATE) '+%Y')
|
||||
endif
|
||||
export COPYRIGHT_YEAR
|
||||
endif
|
||||
|
||||
# Install of imported file (JDK_IMPORT_PATH, or some other external location)
|
||||
|
@ -27,17 +27,6 @@
|
||||
#
|
||||
# Rules shared by all Java makefiles.
|
||||
#
|
||||
# Used to apply to source file $<, checks code conventions, issues warnings.
|
||||
define check-conventions
|
||||
if [ "$(CONVENTION_WATCH)" = "true" ] ; then \
|
||||
if [ "`$(CAT) -n -v -t $< | $(EGREP) -v '\@\(\#\)' | $(EGREP) '\^[MLI]'`" != "" ] ; then \
|
||||
$(ECHO) "WARNING: File contains tabs, ^M, or ^L characters: $<"; \
|
||||
if [ "$(CONVENTION_DETAILS)" = "true" ] ; then \
|
||||
$(CAT) -n -v -t $< | $(EGREP) -v '\@\(\#\)' | $(EGREP) '\^[MLI]' ; \
|
||||
fi; \
|
||||
fi; \
|
||||
fi
|
||||
endef
|
||||
|
||||
# Make sure the default rule is all
|
||||
rules_default_rule: all
|
||||
@ -162,7 +151,6 @@ JAVA_SOURCE_LIST=$(TEMPDIR)/.classes.list
|
||||
# Add a java source to the list
|
||||
define add-java-file
|
||||
$(ECHO) "$?" >> $(JAVA_SOURCE_LIST)
|
||||
$(check-conventions)
|
||||
endef
|
||||
|
||||
$(CLASSDESTDIR)/%.class: $(GENSRCDIR)/%.java
|
||||
@ -197,11 +185,8 @@ JAVAC_PREFER_SOURCE = -Xprefer:source
|
||||
|
||||
.compile.classlist : $(JAVA_SOURCE_LIST)
|
||||
@$(MKDIR) -p $(CLASSDESTDIR)
|
||||
@if [ `$(CAT) $(JAVA_SOURCE_LIST) | $(WC) -l` -ge 1 ] ; then \
|
||||
$(ECHO) "# Java sources to be compiled: (listed in file $(JAVA_SOURCE_LIST))"; \
|
||||
if [ -s $(JAVA_SOURCE_LIST) ] ; then \
|
||||
$(CAT) $(JAVA_SOURCE_LIST); \
|
||||
$(ECHO) "# Running javac:"; \
|
||||
$(ECHO) $(JAVAC_CMD) $(JAVAC_PREFER_SOURCE) -sourcepath "$(SOURCEPATH)" -d $(CLASSDESTDIR) @$(JAVA_SOURCE_LIST); \
|
||||
$(JAVAC_CMD) $(JAVAC_PREFER_SOURCE) -sourcepath "$(SOURCEPATH)" -d $(CLASSDESTDIR) @$(JAVA_SOURCE_LIST); \
|
||||
fi
|
||||
@$(java-vm-cleanup)
|
||||
@ -220,10 +205,7 @@ endif
|
||||
packages.clean:
|
||||
ifeq ($(DONT_CLOBBER_CLASSES),false)
|
||||
ifdef AUTO_FILES_JAVA_DIRS
|
||||
@for sdir in $(AUTO_FILES_JAVA_DIRS); do \
|
||||
$(ECHO) "$(RM) -r $(CLASSDESTDIR)/$$sdir"; \
|
||||
$(RM) -r $(CLASSDESTDIR)/$$sdir; \
|
||||
done
|
||||
$(RM) -r $(patsubst %, $(CLASSDESTDIR)/%, $(AUTO_FILES_JAVA_DIRS))
|
||||
else
|
||||
$(RM) -r $(CLASSDESTDIR)/$(PKGDIR)
|
||||
endif
|
||||
@ -259,15 +241,13 @@ classheaders: classes $(CLASSHDR_DOTFILE)
|
||||
|
||||
$(CLASSHDR_DOTFILE): $(CLASSES_export)
|
||||
$(prep-target)
|
||||
@$(ECHO) "# Running javah:"
|
||||
$(JAVAH_CMD) -d $(CLASSHDRDIR)/ \
|
||||
$(CLASSES.export) $(subst $$,\$$,$(EXPORTED_inner))
|
||||
@$(java-vm-cleanup)
|
||||
@$(TOUCH) $@
|
||||
|
||||
classheaders.clean:
|
||||
$(RM) $(CLASSHDR_DOTFILE)
|
||||
$(RM) -r $(CLASSHDRDIR)
|
||||
$(RM) -r $(CLASSHDRDIR) $(CLASSHDR_DOTFILE)
|
||||
|
||||
else # FILES_export
|
||||
|
||||
|
@ -48,11 +48,17 @@ ifeq ($(PLATFORM), windows)
|
||||
NMAKE = MFLAGS= MAKEFLAGS= $(COMPILER_PATH)nmake -nologo
|
||||
|
||||
# Compiler version and type (Always get word after "Version")
|
||||
CC_VER := $(shell $(CC) 2>&1 | $(HEAD) -n 1 | $(SED) 's/.*\(Version.*\)/\1/' | $(NAWK) '{print $$2}')
|
||||
|
||||
ifndef CC_VER
|
||||
CC_VER := $(shell $(CC) 2>&1 | $(HEAD) -n 1 | $(SED) 's/.*\(Version.*\)/\1/' | $(NAWK) '{print $$2}')
|
||||
export CC_VER
|
||||
endif
|
||||
|
||||
# SDK-64 and MSVC6 put REBASE.EXE in a different places - go figure...
|
||||
ifeq ($(ARCH_DATA_MODEL), 32)
|
||||
LINK_VER := $(shell $(LINK) | $(HEAD) -n 1 | $(NAWK) '{print $$6}')
|
||||
ifndef LINK_VER
|
||||
LINK_VER := $(shell $(LINK) | $(HEAD) -n 1 | $(NAWK) '{print $$6}')
|
||||
export LINK_VER
|
||||
endif
|
||||
CC_MAJORVER :=$(call MajorVersion,$(CC_VER))
|
||||
ifeq ($(CC_MAJORVER), 13)
|
||||
# This should be: CC_VER=13.10.3077 LINK_VER=7.10.3077
|
||||
@ -93,7 +99,10 @@ ifeq ($(PLATFORM), windows)
|
||||
endif
|
||||
else
|
||||
# else ARCH_DATA_MODEL is 64
|
||||
LINK_VER := $(shell $(LINK) | $(HEAD) -n 1 | $(NAWK) '{print $$6}')
|
||||
ifndef LINK_VER
|
||||
LINK_VER := $(shell $(LINK) | $(HEAD) -n 1 | $(NAWK) '{print $$6}')
|
||||
export LINK_VER
|
||||
endif
|
||||
CC_MAJORVER :=$(call MajorVersion,$(CC_VER))
|
||||
CC_MINORVER :=$(call MinorVersion,$(CC_VER))
|
||||
CC_MICROVER :=$(call MicroVersion,$(CC_VER))
|
||||
|
@ -55,10 +55,21 @@ else
|
||||
ADD_CLIENT_VM_OPTION = true
|
||||
endif
|
||||
endif
|
||||
JAVA_JVM_FLAGS =
|
||||
|
||||
# Options for hotspot to turn off printing of options with fastdebug version
|
||||
# and creating the hotspot.log file.
|
||||
JAVA_HOTSPOT_DISABLE_PRINT_VMOPTIONS = \
|
||||
-XX:-PrintVMOptions -XX:+UnlockDiagnosticVMOptions -XX:-LogVMOutput
|
||||
|
||||
# JVM options
|
||||
JAVA_JVM_FLAGS = $(JAVA_HOTSPOT_DISABLE_PRINT_VMOPTIONS)
|
||||
|
||||
ifeq ($(ADD_CLIENT_VM_OPTION), true)
|
||||
JAVA_JVM_FLAGS += -client
|
||||
endif
|
||||
ifdef USE_HOTSPOT_INTERPRETER_MODE
|
||||
JAVA_JVM_FLAGS += -Xint
|
||||
endif
|
||||
|
||||
# Various VM flags
|
||||
JAVA_TOOLS_FLAGS = $(JAVA_JVM_FLAGS) $(JAVA_MEM_FLAGS)
|
||||
@ -100,7 +111,10 @@ JAVACFLAGS =
|
||||
ifeq ($(DEBUG_CLASSFILES),true)
|
||||
JAVACFLAGS += -g
|
||||
endif
|
||||
ifeq ($(COMPILER_WARNINGS_FATAL), true)
|
||||
ifeq ($(JAVAC_MAX_WARNINGS), true)
|
||||
JAVACFLAGS += -Xlint:all
|
||||
endif
|
||||
ifeq ($(JAVAC_WARNINGS_FATAL), true)
|
||||
JAVACFLAGS += -Werror
|
||||
endif
|
||||
|
||||
@ -108,7 +122,8 @@ NO_PROPRIETARY_API_WARNINGS = -XDignore.symbol.file=true
|
||||
JAVACFLAGS += $(NO_PROPRIETARY_API_WARNINGS)
|
||||
|
||||
# Add the source level
|
||||
LANGUAGE_VERSION = -source 7
|
||||
SOURCE_LANGUAGE_VERSION = 7
|
||||
LANGUAGE_VERSION = -source $(SOURCE_LANGUAGE_VERSION)
|
||||
JAVACFLAGS += $(LANGUAGE_VERSION)
|
||||
|
||||
# Add the class version we want
|
||||
@ -176,10 +191,17 @@ endif
|
||||
# The javac options supplied to the boot javac is limited. This compiler
|
||||
# should only be used to build the 'make/tools' sources, which are not
|
||||
# class files that end up in the classes directory.
|
||||
ifeq ($(COMPILER_WARNINGS_FATAL), true)
|
||||
ifeq ($(JAVAC_MAX_WARNINGS), true)
|
||||
BOOT_JAVACFLAGS += -Xlint:all
|
||||
endif
|
||||
ifeq ($(JAVAC_WARNINGS_FATAL), true)
|
||||
BOOT_JAVACFLAGS += -Werror
|
||||
endif
|
||||
BOOT_JAVACFLAGS += -encoding ascii
|
||||
|
||||
BOOT_SOURCE_LANGUAGE_VERSION = 6
|
||||
BOOT_TARGET_CLASS_VERSION = 6
|
||||
BOOT_JAVACFLAGS += -encoding ascii -source $(BOOT_SOURCE_LANGUAGE_VERSION) -target $(BOOT_TARGET_CLASS_VERSION)
|
||||
BOOT_JAR_JFLAGS += $(JAR_JFLAGS)
|
||||
|
||||
BOOT_JAVA_CMD = $(BOOTDIR)/bin/java $(JAVA_TOOLS_FLAGS)
|
||||
BOOT_JAVAC_CMD = $(BOOTDIR)/bin/javac $(JAVAC_JVM_FLAGS) $(BOOT_JAVACFLAGS)
|
||||
|
@ -116,7 +116,6 @@ RC = $(UTILS_COMMAND_PATH)rc
|
||||
RMDIR = $(UTILS_COMMAND_PATH)rmdir
|
||||
RPM = $(UTILS_COMMAND_PATH)rpm
|
||||
RPMBUILD = $(UTILS_COMMAND_PATH)rpmbuild
|
||||
SCCS = $(UTILS_CCS_BIN_PATH)sccs
|
||||
SED = $(UTILS_COMMAND_PATH)sed
|
||||
SH = $(UTILS_COMMAND_PATH)sh
|
||||
SHOWREV = $(UTILS_USR_BIN_PATH)showrev
|
||||
|
@ -113,32 +113,38 @@ _system_drive:=$(call CheckValue,_system_drive,C:)
|
||||
|
||||
# UNIXCOMMAND_PATH: path to where the most common Unix commands are.
|
||||
# NOTE: Must end with / so that it could be empty, allowing PATH usage.
|
||||
ifdef ALT_UNIXCOMMAND_PATH
|
||||
xALT_UNIXCOMMAND_PATH :="$(subst \,/,$(ALT_UNIXCOMMAND_PATH))"
|
||||
fxALT_UNIXCOMMAND_PATH :=$(call FullPath,$(xALT_UNIXCOMMAND_PATH))
|
||||
UNIXCOMMAND_PATH :=$(call PrefixPath,$(fxALT_UNIXCOMMAND_PATH))
|
||||
else
|
||||
ifdef USING_CYGWIN
|
||||
UNIXCOMMAND_PATH :=$(call PrefixPath,/usr/bin)
|
||||
ifndef UNIXCOMMAND_PATH
|
||||
ifdef ALT_UNIXCOMMAND_PATH
|
||||
xALT_UNIXCOMMAND_PATH :="$(subst \,/,$(ALT_UNIXCOMMAND_PATH))"
|
||||
fxALT_UNIXCOMMAND_PATH :=$(call FullPath,$(xALT_UNIXCOMMAND_PATH))
|
||||
UNIXCOMMAND_PATH :=$(call PrefixPath,$(fxALT_UNIXCOMMAND_PATH))
|
||||
else
|
||||
ifdef ROOTDIR
|
||||
xROOTDIR :="$(subst \,/,$(ROOTDIR))"
|
||||
_rootdir :=$(call FullPath,$(xROOTDIR))
|
||||
ifdef USING_CYGWIN
|
||||
UNIXCOMMAND_PATH :=$(call PrefixPath,/usr/bin)
|
||||
else
|
||||
xROOTDIR :="$(_system_drive)/mksnt"
|
||||
_rootdir :=$(call FullPath,$(xROOTDIR))
|
||||
endif
|
||||
ifneq ($(_rootdir),)
|
||||
UNIXCOMMAND_PATH :=$(call PrefixPath,$(_rootdir)/mksnt)
|
||||
ifdef ROOTDIR
|
||||
xROOTDIR :="$(subst \,/,$(ROOTDIR))"
|
||||
_rootdir :=$(call FullPath,$(xROOTDIR))
|
||||
else
|
||||
xROOTDIR :="$(_system_drive)/mksnt"
|
||||
_rootdir :=$(call FullPath,$(xROOTDIR))
|
||||
endif
|
||||
ifneq ($(_rootdir),)
|
||||
UNIXCOMMAND_PATH :=$(call PrefixPath,$(_rootdir)/mksnt)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
UNIXCOMMAND_PATH:=$(call AltCheckSpaces,UNIXCOMMAND_PATH)
|
||||
export UNIXCOMMAND_PATH
|
||||
endif
|
||||
UNIXCOMMAND_PATH:=$(call AltCheckSpaces,UNIXCOMMAND_PATH)
|
||||
|
||||
# Get version of MKS or CYGWIN
|
||||
ifdef USING_CYGWIN
|
||||
_CYGWIN_VER :=$(shell $(UNAME))
|
||||
CYGWIN_VER :=$(call GetVersion,$(_CYGWIN_VER))
|
||||
ifndef CYGWIN_VER
|
||||
_CYGWIN_VER :=$(shell $(UNAME))
|
||||
CYGWIN_VER :=$(call GetVersion,$(_CYGWIN_VER))
|
||||
export CYGWIN_VER
|
||||
endif
|
||||
else # MKS
|
||||
_MKS_VER :=$(shell $(MKSINFO) 2>&1 | $(GREP) Release | $(TAIL) -1 | $(SED) -e 's@.*\(Release.*\)@\1@')
|
||||
MKS_VER :=$(call GetVersion,$(_MKS_VER))
|
||||
@ -168,235 +174,234 @@ endif # MKS
|
||||
|
||||
# Process Windows values into FullPath values, these paths may have \ chars
|
||||
|
||||
# System root
|
||||
ifdef SYSTEMROOT
|
||||
xSYSTEMROOT :="$(subst \,/,$(SYSTEMROOT))"
|
||||
_system_root :=$(call FullPath,$(xSYSTEMROOT))
|
||||
else
|
||||
ifdef SystemRoot
|
||||
xSYSTEMROOT :="$(subst \,/,$(SystemRoot))"
|
||||
_system_root :=$(call FullPath,$(xSYSTEMROOT))
|
||||
# Program Files directory
|
||||
ifndef SHORTPROGRAMFILES
|
||||
ifdef PROGRAMFILES
|
||||
xPROGRAMFILES :="$(subst \,/,$(PROGRAMFILES))"
|
||||
else
|
||||
ifdef WINDIR
|
||||
xWINDIR :="$(subst \,/,$(WINDIR))"
|
||||
_system_root :=$(call FullPath,$(xWINDIR))
|
||||
ifeq ($(ARCH_DATA_MODEL), 32)
|
||||
xPROGRAMFILES :="$(_system_drive)/Program Files"
|
||||
else
|
||||
ifdef windir
|
||||
xWINDIR :="$(subst \,/,$(windir))"
|
||||
_system_root :=$(call FullPath,$(xWINDIR))
|
||||
endif
|
||||
xPROGRAMFILES :="$(_system_drive)/Program Files (x86)"
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
_system_root:=$(call CheckValue,_system_root,$(_system_drive)/WINNT)
|
||||
|
||||
# Program Files directory
|
||||
ifdef PROGRAMFILES
|
||||
xPROGRAMFILES :="$(subst \,/,$(PROGRAMFILES))"
|
||||
else
|
||||
ifeq ($(ARCH_DATA_MODEL), 32)
|
||||
xPROGRAMFILES :="$(_system_drive)/Program Files"
|
||||
SHORTPROGRAMFILES :=$(call FullPath,$(xPROGRAMFILES))
|
||||
else
|
||||
xPROGRAMFILES :="$(_system_drive)/Program Files (x86)"
|
||||
ifdef PROGRAMW6432
|
||||
xPROGRAMW6432 :="$(subst \,/,$(PROGRAMW6432))"
|
||||
else
|
||||
xPROGRAMW6432 :="$(_system_drive)/Program Files"
|
||||
endif
|
||||
SHORTPROGRAMFILES :=$(call FullPath,$(xPROGRAMW6432))
|
||||
endif
|
||||
endif
|
||||
ifeq ($(ARCH_DATA_MODEL), 32)
|
||||
_program_files :=$(call FullPath,$(xPROGRAMFILES))
|
||||
else
|
||||
ifdef PROGRAMW6432
|
||||
xPROGRAMW6432 :="$(subst \,/,$(PROGRAMW6432))"
|
||||
else
|
||||
xPROGRAMW6432 :="$(_system_drive)/Program Files"
|
||||
ifneq ($(word 1,$(SHORTPROGRAMFILES)),$(SHORTPROGRAMFILES))
|
||||
SHORTPROGRAMFILES :=
|
||||
endif
|
||||
_program_files :=$(call FullPath,$(xPROGRAMW6432))
|
||||
_program_files32 :=$(call FullPath,$(xPROGRAMFILES))
|
||||
ifneq ($(word 1,$(_program_files32)),$(_program_files32))
|
||||
_program_files32:=
|
||||
endif
|
||||
endif
|
||||
ifneq ($(word 1,$(_program_files)),$(_program_files))
|
||||
_program_files:=
|
||||
export SHORTPROGRAMFILES
|
||||
endif
|
||||
|
||||
# Compilers, SDK, and Visual Studio (MSDEV) [32bit is different from 64bit]
|
||||
ifeq ($(ARCH_DATA_MODEL), 32)
|
||||
# Try looking in MSVCDIR or MSVCDir area first (set by vcvars32.bat)
|
||||
ifdef MSVCDIR
|
||||
xMSVCDIR :="$(subst \,/,$(MSVCDIR))"
|
||||
_msvc_dir :=$(call FullPath,$(xMSVCDIR))
|
||||
else
|
||||
ifdef MSVCDir
|
||||
xMSVCDIR :="$(subst \,/,$(MSVCDir))"
|
||||
_msvc_dir :=$(call FullPath,$(xMSVCDIR))
|
||||
ifndef SHORTMSVCDIR
|
||||
# Try looking in MSVCDIR or MSVCDir area first (set by vcvars32.bat)
|
||||
ifdef MSVCDIR
|
||||
xMSVCDIR :="$(subst \,/,$(MSVCDIR))"
|
||||
SHORTMSVCDIR :=$(call FullPath,$(xMSVCDIR))
|
||||
else
|
||||
ifneq ($(_program_files),)
|
||||
xMSVCDIR :="$(_program_files)/Microsoft Visual Studio .NET 2003/Vc7"
|
||||
_msvc_dir :=$(call FullPath,$(xMSVCDIR))
|
||||
ifdef MSVCDir
|
||||
xMSVCDIR :="$(subst \,/,$(MSVCDir))"
|
||||
SHORTMSVCDIR :=$(call FullPath,$(xMSVCDIR))
|
||||
else
|
||||
ifneq ($(SHORTPROGRAMFILES),)
|
||||
xMSVCDIR :="$(SHORTPROGRAMFILES)/Microsoft Visual Studio .NET 2003/Vc7"
|
||||
SHORTMSVCDIR :=$(call FullPath,$(xMSVCDIR))
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifneq ($(subst MSDev98,OLDOLDOLD,$(_msvc_dir)),$(_msvc_dir))
|
||||
_msvc_dir :=
|
||||
endif
|
||||
# If we still don't have it, look for VS71COMNTOOLS, setup by installer?
|
||||
ifeq ($(_msvc_dir),)
|
||||
ifdef VS71COMNTOOLS # /Common/Tools directory, use ../../Vc7
|
||||
xVS71COMNTOOLS :="$(subst \,/,$(VS71COMNTOOLS))"
|
||||
_vs71tools :=$(call FullPath,$(xVS71COMNTOOLS))
|
||||
ifneq ($(subst MSDev98,OLDOLDOLD,$(SHORTMSVCDIR)),$(SHORTMSVCDIR))
|
||||
SHORTMSVCDIR :=
|
||||
endif
|
||||
ifneq ($(_vs71tools),)
|
||||
_msvc_dir :=$(_vs71tools)/../../Vc7
|
||||
# If we still don't have it, look for VS71COMNTOOLS, setup by installer?
|
||||
ifeq ($(SHORTMSVCDIR),)
|
||||
ifdef VS71COMNTOOLS # /Common/Tools directory, use ../../Vc7
|
||||
xVS71COMNTOOLS :="$(subst \,/,$(VS71COMNTOOLS))"
|
||||
_vs71tools :=$(call FullPath,$(xVS71COMNTOOLS))
|
||||
endif
|
||||
ifneq ($(_vs71tools),)
|
||||
SHORTMSVCDIR :=$(_vs71tools)/../../Vc7
|
||||
endif
|
||||
endif
|
||||
export SHORTMSVCDIR
|
||||
endif
|
||||
ifneq ($(_msvc_dir),)
|
||||
_compiler_bin :=$(_msvc_dir)/Bin
|
||||
_redist_sdk :=$(_msvc_dir)/../SDK/v1.1/Bin
|
||||
_ms_sdk :=$(_msvc_dir)/PlatformSDK
|
||||
ifneq ($(SHORTMSVCDIR),)
|
||||
SHORTCOMPILERBIN :=$(SHORTMSVCDIR)/Bin
|
||||
SHORTPSDK :=$(SHORTMSVCDIR)/PlatformSDK
|
||||
export SHORTCOMPILERBIN
|
||||
export SHORTPSDK
|
||||
endif
|
||||
endif
|
||||
|
||||
# The Microsoft Platform SDK installed by itself
|
||||
ifneq ($(_program_files),)
|
||||
xPSDK :="$(_program_files)/Microsoft Platform SDK"
|
||||
_psdk :=$(call FullPath,$(xPSDK))
|
||||
ifeq ($(_psdk),)
|
||||
xPSDK :="$(_program_files)/Microsoft SDK"
|
||||
_psdk :=$(call FullPath,$(xMSSDK))
|
||||
ifneq ($(SHORTPROGRAMFILES),)
|
||||
ifndef SHORTPSDK
|
||||
xPSDK :="$(SHORTPROGRAMFILES)/Microsoft Platform SDK"
|
||||
SHORTPSDK :=$(call FullPath,$(xPSDK))
|
||||
ifeq ($(SHORTPSDK),)
|
||||
xPSDK :="$(SHORTPROGRAMFILES)/Microsoft SDK"
|
||||
SHORTPSDK :=$(call FullPath,$(xMSSDK))
|
||||
endif
|
||||
export SHORTPSDK
|
||||
endif
|
||||
endif
|
||||
|
||||
# If no SDK found yet, look in other places
|
||||
ifeq ($(_ms_sdk),)
|
||||
ifndef SHORTPSDK
|
||||
ifdef MSSDK
|
||||
xMSSDK :="$(subst \,/,$(MSSDK))"
|
||||
_ms_sdk :=$(call FullPath,$(xMSSDK))
|
||||
xMSSDK :="$(subst \,/,$(MSSDK))"
|
||||
SHORTPSDK :=$(call FullPath,$(xMSSDK))
|
||||
else
|
||||
ifdef MSSdk
|
||||
xMSSDK :="$(subst \,/,$(MSSdk))"
|
||||
_ms_sdk :=$(call FullPath,$(xMSSDK))
|
||||
else
|
||||
_ms_sdk :=$(_psdk)
|
||||
xMSSDK :="$(subst \,/,$(MSSdk))"
|
||||
SHORTPSDK :=$(call FullPath,$(xMSSDK))
|
||||
endif
|
||||
endif
|
||||
export SHORTPSDK
|
||||
endif
|
||||
|
||||
# Compilers for 64bit are from SDK
|
||||
ifeq ($(ARCH_DATA_MODEL), 64)
|
||||
xMSSDK61 :="C:/Program Files/Microsoft SDKs/Windows/v6.1/"
|
||||
MSSDK61 :=$(call FullPath,$(xMSSDK61))
|
||||
xVS2008 :="C:/Program Files (x86)/Microsoft Visual Studio 9.0/"
|
||||
_vs2008 :=$(call FullPath,$(xVS2008))
|
||||
ifneq ($(_vs2008),)
|
||||
ifeq ($(ARCH), ia64)
|
||||
_compiler_bin :=$(_vs2008)/VC/Bin/x86_ia64
|
||||
endif
|
||||
ifeq ($(ARCH), amd64)
|
||||
_compiler_bin :=$(_vs2008)/VC/Bin/$(ARCH)
|
||||
_redist_sdk :=$(MSSDK61)/VC/redist
|
||||
endif
|
||||
else
|
||||
ifneq ($(_ms_sdk),)
|
||||
ifndef SHORTCOMPILERBIN
|
||||
xMSSDK61 :="C:/Program Files/Microsoft SDKs/Windows/v6.1/"
|
||||
MSSDK61 :=$(call FullPath,$(xMSSDK61))
|
||||
xVS2008 :="C:/Program Files (x86)/Microsoft Visual Studio 9.0/"
|
||||
_vs2008 :=$(call FullPath,$(xVS2008))
|
||||
ifneq ($(_vs2008),)
|
||||
ifeq ($(ARCH), ia64)
|
||||
_compiler_bin :=$(_ms_sdk)/Bin/Win64
|
||||
SHORTCOMPILERBIN :=$(_vs2008)/VC/Bin/x86_ia64
|
||||
endif
|
||||
ifeq ($(ARCH), amd64)
|
||||
_compiler_bin :=$(_ms_sdk)/Bin/Win64/x86/$(ARCH)
|
||||
_redist_sdk :=$(_ms_sdk)/redist/win64/AMD64
|
||||
SHORTCOMPILERBIN :=$(_vs2008)/VC/Bin/$(ARCH)
|
||||
endif
|
||||
else
|
||||
ifneq ($(SHORTPSDK),)
|
||||
ifeq ($(ARCH), ia64)
|
||||
SHORTCOMPILERBIN :=$(SHORTPSDK)/Bin/Win64
|
||||
endif
|
||||
ifeq ($(ARCH), amd64)
|
||||
SHORTCOMPILERBIN :=$(SHORTPSDK)/Bin/Win64/x86/$(ARCH)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
export SHORTCOMPILERBIN
|
||||
endif
|
||||
endif
|
||||
|
||||
# Location on system where jdk installs might be
|
||||
ifneq ($(_program_files),)
|
||||
USRJDKINSTANCES_PATH =$(_program_files)/Java
|
||||
ifneq ($(SHORTPROGRAMFILES),)
|
||||
USRJDKINSTANCES_PATH =$(SHORTPROGRAMFILES)/Java
|
||||
else
|
||||
USRJDKINSTANCES_PATH =$(_system_drive)/
|
||||
endif
|
||||
|
||||
# SLASH_JAVA: location of all network accessable files
|
||||
ifdef ALT_SLASH_JAVA
|
||||
xALT_SLASH_JAVA :="$(subst \,/,$(ALT_SLASH_JAVA))"
|
||||
SLASH_JAVA :=$(call FullPath,$(xALT_SLASH_JAVA))
|
||||
else
|
||||
ifdef ALT_JDK_JAVA_DRIVE
|
||||
SLASH_JAVA =$(JDK_JAVA_DRIVE)
|
||||
ifndef SLASH_JAVA
|
||||
ifdef ALT_SLASH_JAVA
|
||||
xALT_SLASH_JAVA :="$(subst \,/,$(ALT_SLASH_JAVA))"
|
||||
SLASH_JAVA :=$(call FullPath,$(xALT_SLASH_JAVA))
|
||||
else
|
||||
SLASH_JAVA =J:
|
||||
ifdef ALT_JDK_JAVA_DRIVE
|
||||
SLASH_JAVA =$(JDK_JAVA_DRIVE)
|
||||
else
|
||||
SLASH_JAVA =J:
|
||||
endif
|
||||
endif
|
||||
SLASH_JAVA:=$(call AltCheckSpaces,SLASH_JAVA)
|
||||
SLASH_JAVA:=$(call AltCheckValue,SLASH_JAVA)
|
||||
export SLASH_JAVA
|
||||
endif
|
||||
SLASH_JAVA:=$(call AltCheckSpaces,SLASH_JAVA)
|
||||
SLASH_JAVA:=$(call AltCheckValue,SLASH_JAVA)
|
||||
|
||||
# JDK_DEVTOOLS_DIR: common path for all the java devtools
|
||||
ifdef ALT_JDK_DEVTOOLS_DIR
|
||||
xALT_JDK_DEVTOOLS_DIR :="$(subst \,/,$(ALT_JDK_DEVTOOLS_DIR))"
|
||||
JDK_DEVTOOLS_DIR :=$(call FullPath,$(xALT_JDK_DEVTOOLS_DIR))
|
||||
else
|
||||
JDK_DEVTOOLS_DIR =$(SLASH_JAVA)/devtools
|
||||
ifndef JDK_DEVTOOLS_DIR
|
||||
ifdef ALT_JDK_DEVTOOLS_DIR
|
||||
xALT_JDK_DEVTOOLS_DIR :="$(subst \,/,$(ALT_JDK_DEVTOOLS_DIR))"
|
||||
JDK_DEVTOOLS_DIR :=$(call FullPath,$(xALT_JDK_DEVTOOLS_DIR))
|
||||
else
|
||||
JDK_DEVTOOLS_DIR =$(SLASH_JAVA)/devtools
|
||||
endif
|
||||
JDK_DEVTOOLS_DIR:=$(call AltCheckSpaces,JDK_DEVTOOLS_DIR)
|
||||
JDK_DEVTOOLS_DIR:=$(call AltCheckValue,JDK_DEVTOOLS_DIR)
|
||||
export JDK_DEVTOOLS_DIR
|
||||
endif
|
||||
JDK_DEVTOOLS_DIR:=$(call AltCheckSpaces,JDK_DEVTOOLS_DIR)
|
||||
JDK_DEVTOOLS_DIR:=$(call AltCheckValue,JDK_DEVTOOLS_DIR)
|
||||
|
||||
# COMPILER_PATH: path to where the compiler and tools are installed.
|
||||
# NOTE: Must end with / so that it could be empty, allowing PATH usage.
|
||||
ifdef ALT_COMPILER_PATH
|
||||
xALT_COMPILER_PATH :="$(subst \,/,$(ALT_COMPILER_PATH))"
|
||||
fxALT_COMPILER_PATH :=$(call FullPath,$(xALT_COMPILER_PATH))
|
||||
COMPILER_PATH :=$(call PrefixPath,$(fxALT_COMPILER_PATH))
|
||||
else
|
||||
COMPILER_PATH :=$(call PrefixPath,$(_compiler_bin))
|
||||
ifndef COMPILER_PATH
|
||||
ifdef ALT_COMPILER_PATH
|
||||
xALT_COMPILER_PATH :="$(subst \,/,$(ALT_COMPILER_PATH))"
|
||||
fxALT_COMPILER_PATH :=$(call FullPath,$(xALT_COMPILER_PATH))
|
||||
COMPILER_PATH :=$(call PrefixPath,$(fxALT_COMPILER_PATH))
|
||||
else
|
||||
COMPILER_PATH :=$(call PrefixPath,$(SHORTCOMPILERBIN))
|
||||
endif
|
||||
COMPILER_PATH :=$(call AltCheckSpaces,COMPILER_PATH)
|
||||
export COMPILER_PATH
|
||||
endif
|
||||
COMPILER_PATH :=$(call AltCheckSpaces,COMPILER_PATH)
|
||||
|
||||
# MSDEVTOOLS_PATH: path to where the additional MS Compiler tools are.
|
||||
# NOTE: Must end with / so that it could be empty, allowing PATH usage.
|
||||
ifdef ALT_MSDEVTOOLS_PATH
|
||||
xALT_MSDEVTOOLS_PATH :="$(subst \,/,$(ALT_MSDEVTOOLS_PATH))"
|
||||
fxALT_MSDEVTOOLS_PATH :=$(call FullPath,$(xALT_MSDEVTOOLS_PATH))
|
||||
MSDEVTOOLS_PATH :=$(call PrefixPath,$(fxALT_MSDEVTOOLS_PATH))
|
||||
else
|
||||
ifeq ($(ARCH_DATA_MODEL), 64)
|
||||
ifdef MSTOOLS
|
||||
xMSTOOLS :="$(subst \,/,$(MSTOOLS))"
|
||||
_ms_tools :=$(call FullPath,$(xMSTOOLS))
|
||||
else
|
||||
ifdef Mstools
|
||||
xMSTOOLS :="$(subst \,/,$(Mstools))"
|
||||
ifndef MSDEVTOOLS_PATH
|
||||
ifdef ALT_MSDEVTOOLS_PATH
|
||||
xALT_MSDEVTOOLS_PATH :="$(subst \,/,$(ALT_MSDEVTOOLS_PATH))"
|
||||
fxALT_MSDEVTOOLS_PATH :=$(call FullPath,$(xALT_MSDEVTOOLS_PATH))
|
||||
MSDEVTOOLS_PATH :=$(call PrefixPath,$(fxALT_MSDEVTOOLS_PATH))
|
||||
else
|
||||
ifeq ($(ARCH_DATA_MODEL), 64)
|
||||
ifdef MSTOOLS
|
||||
xMSTOOLS :="$(subst \,/,$(MSTOOLS))"
|
||||
_ms_tools :=$(call FullPath,$(xMSTOOLS))
|
||||
else
|
||||
_ms_tools :=
|
||||
ifdef Mstools
|
||||
xMSTOOLS :="$(subst \,/,$(Mstools))"
|
||||
_ms_tools :=$(call FullPath,$(xMSTOOLS))
|
||||
else
|
||||
_ms_tools :=
|
||||
endif
|
||||
endif
|
||||
ifneq ($(_ms_tools),)
|
||||
_ms_tools_bin :=$(_ms_tools)/Bin
|
||||
else
|
||||
# Assumes compiler bin is .../Bin/win64/x86/AMD64, rc.exe is 3 levels up
|
||||
_ms_tools_bin :=$(SHORTCOMPILERBIN)/../../..
|
||||
endif
|
||||
endif
|
||||
ifneq ($(_ms_tools),)
|
||||
_ms_tools_bin :=$(_ms_tools)/Bin
|
||||
else
|
||||
# Assumes compiler bin is .../Bin/win64/x86/AMD64, rc.exe is 3 levels up
|
||||
_ms_tools_bin :=$(_compiler_bin)/../../..
|
||||
_ms_tools_bin :=$(SHORTCOMPILERBIN)
|
||||
endif
|
||||
else
|
||||
_ms_tools_bin :=$(_compiler_bin)
|
||||
MSDEVTOOLS_PATH :=$(call PrefixPath,$(_ms_tools_bin))
|
||||
endif
|
||||
MSDEVTOOLS_PATH :=$(call PrefixPath,$(_ms_tools_bin))
|
||||
MSDEVTOOLS_PATH:=$(call AltCheckSpaces,MSDEVTOOLS_PATH)
|
||||
export MSDEVTOOLS_PATH
|
||||
endif
|
||||
MSDEVTOOLS_PATH:=$(call AltCheckSpaces,MSDEVTOOLS_PATH)
|
||||
|
||||
# DEVTOOLS_PATH: for other tools required for building (such as zip, etc.)
|
||||
# NOTE: Must end with / so that it could be empty, allowing PATH usage.
|
||||
ifdef ALT_DEVTOOLS_PATH
|
||||
xALT_DEVTOOLS_PATH :="$(subst \,/,$(ALT_DEVTOOLS_PATH))"
|
||||
fxALT_DEVTOOLS_PATH :=$(call FullPath,$(xALT_DEVTOOLS_PATH))
|
||||
DEVTOOLS_PATH :=$(call PrefixPath,$(fxALT_DEVTOOLS_PATH))
|
||||
else
|
||||
ifdef USING_CYGWIN
|
||||
DEVTOOLS_PATH :=$(UNIXCOMMAND_PATH)
|
||||
ifndef DEVTOOLS_PATH
|
||||
ifdef ALT_DEVTOOLS_PATH
|
||||
xALT_DEVTOOLS_PATH :="$(subst \,/,$(ALT_DEVTOOLS_PATH))"
|
||||
fxALT_DEVTOOLS_PATH :=$(call FullPath,$(xALT_DEVTOOLS_PATH))
|
||||
DEVTOOLS_PATH :=$(call PrefixPath,$(fxALT_DEVTOOLS_PATH))
|
||||
else
|
||||
xDEVTOOLS_PATH :="$(_system_drive)/utils"
|
||||
fxDEVTOOLS_PATH :=$(call FullPath,$(xDEVTOOLS_PATH))
|
||||
DEVTOOLS_PATH :=$(call PrefixPath,$(fxDEVTOOLS_PATH))
|
||||
ifdef USING_CYGWIN
|
||||
DEVTOOLS_PATH :=$(UNIXCOMMAND_PATH)
|
||||
else
|
||||
xDEVTOOLS_PATH :="$(_system_drive)/utils"
|
||||
fxDEVTOOLS_PATH :=$(call FullPath,$(xDEVTOOLS_PATH))
|
||||
DEVTOOLS_PATH :=$(call PrefixPath,$(fxDEVTOOLS_PATH))
|
||||
endif
|
||||
endif
|
||||
DEVTOOLS_PATH:=$(call AltCheckSpaces,DEVTOOLS_PATH)
|
||||
export DEVTOOLS_PATH
|
||||
endif
|
||||
DEVTOOLS_PATH:=$(call AltCheckSpaces,DEVTOOLS_PATH)
|
||||
|
||||
# _BOOTDIR1: First choice for a Bootstrap JDK, previous released JDK.
|
||||
# _BOOTDIR2: Second choice
|
||||
@ -410,20 +415,26 @@ endif
|
||||
|
||||
# BUILD_JDK_IMPORT_PATH: location of JDK install trees to import for
|
||||
# multiple platforms, e.g. windows-i586, solaris-sparc, linux-586, etc.
|
||||
ifdef ALT_BUILD_JDK_IMPORT_PATH
|
||||
BUILD_JDK_IMPORT_PATH :=$(call FullPath,$(ALT_BUILD_JDK_IMPORT_PATH))
|
||||
else
|
||||
BUILD_JDK_IMPORT_PATH = $(PROMOTED_BUILD_BINARIES)
|
||||
ifndef BUILD_JDK_IMPORT_PATH
|
||||
ifdef ALT_BUILD_JDK_IMPORT_PATH
|
||||
BUILD_JDK_IMPORT_PATH :=$(call FullPath,$(ALT_BUILD_JDK_IMPORT_PATH))
|
||||
else
|
||||
BUILD_JDK_IMPORT_PATH = $(PROMOTED_BUILD_BINARIES)
|
||||
endif
|
||||
BUILD_JDK_IMPORT_PATH:=$(call AltCheckSpaces,BUILD_JDK_IMPORT_PATH)
|
||||
BUILD_JDK_IMPORT_PATH:=$(call AltCheckValue,BUILD_JDK_IMPORT_PATH)
|
||||
export BUILD_JDK_IMPORT_PATH
|
||||
endif
|
||||
BUILD_JDK_IMPORT_PATH:=$(call AltCheckSpaces,BUILD_JDK_IMPORT_PATH)
|
||||
BUILD_JDK_IMPORT_PATH:=$(call AltCheckValue,BUILD_JDK_IMPORT_PATH)
|
||||
|
||||
# JDK_IMPORT_PATH: location of previously built JDK (this version) to import
|
||||
ifdef ALT_JDK_IMPORT_PATH
|
||||
JDK_IMPORT_PATH :=$(call FullPath,$(ALT_JDK_IMPORT_PATH))
|
||||
else
|
||||
JDK_IMPORT_PATH = $(BUILD_JDK_IMPORT_PATH)/$(PLATFORM)-$(ARCH)$(_JDK_IMPORT_VARIANT)
|
||||
ifndef JDK_IMPORT_PATH
|
||||
ifdef ALT_JDK_IMPORT_PATH
|
||||
JDK_IMPORT_PATH :=$(call FullPath,$(ALT_JDK_IMPORT_PATH))
|
||||
else
|
||||
JDK_IMPORT_PATH = $(BUILD_JDK_IMPORT_PATH)/$(PLATFORM)-$(ARCH)$(_JDK_IMPORT_VARIANT)
|
||||
endif
|
||||
JDK_IMPORT_PATH:=$(call AltCheckSpaces,JDK_IMPORT_PATH)
|
||||
JDK_IMPORT_PATH:=$(call AltCheckValue,JDK_IMPORT_PATH)
|
||||
export JDK_IMPORT_PATH
|
||||
endif
|
||||
JDK_IMPORT_PATH:=$(call AltCheckSpaces,JDK_IMPORT_PATH)
|
||||
JDK_IMPORT_PATH:=$(call AltCheckValue,JDK_IMPORT_PATH)
|
||||
|
||||
|
@ -228,12 +228,15 @@ else
|
||||
endif
|
||||
|
||||
# FULL_VERSION is RELEASE and -BUILD_NUMBER if BUILD_NUMBER is set
|
||||
ifdef BUILD_NUMBER
|
||||
FULL_VERSION = $(RELEASE)-$(BUILD_NUMBER)
|
||||
else
|
||||
BUILD_NUMBER = b00
|
||||
USER_RELEASE_SUFFIX := $(shell echo $(USER)_`date '+%d_%b_%Y_%H_%M' | tr "A-Z" "a-z"`)
|
||||
FULL_VERSION = $(RELEASE)-$(USER_RELEASE_SUFFIX)-$(BUILD_NUMBER)
|
||||
ifndef FULL_VERSION
|
||||
ifdef BUILD_NUMBER
|
||||
FULL_VERSION = $(RELEASE)-$(BUILD_NUMBER)
|
||||
else
|
||||
BUILD_NUMBER = b00
|
||||
USER_RELEASE_SUFFIX := $(shell echo $(USER)_`date '+%d_%b_%Y_%H_%M' | tr "A-Z" "a-z"`)
|
||||
FULL_VERSION = $(RELEASE)-$(USER_RELEASE_SUFFIX)-$(BUILD_NUMBER)
|
||||
endif
|
||||
export FULL_VERSION
|
||||
endif
|
||||
|
||||
# Promoted build location
|
||||
|
@ -84,21 +84,14 @@ PLATFORM_SHARED=done
|
||||
# REQUIRED_LINUX_VER linux only: required version of linux
|
||||
# REQUIRED_LINUX_FULLVER linux only: required full version of linux
|
||||
|
||||
SYSTEM_UNAME := $(shell uname)
|
||||
ifndef SYSTEM_UNAME
|
||||
SYSTEM_UNAME := $(shell uname)
|
||||
export SYSTEM_UNAME
|
||||
endif
|
||||
|
||||
# Normal boot jdk is previous release, but a hard requirement is a 1.5 boot
|
||||
REQUIRED_BOOT_VER = 1.5
|
||||
|
||||
#
|
||||
# Prune out all known SCM (Source Code Management) directories
|
||||
# so they will not be included when copying directory trees
|
||||
# or packaging up .jar files, etc. This applies to all workspaces.
|
||||
#
|
||||
SCM_DIRs = .hg .svn CVS RCS SCCS Codemgr_wsdata deleted_files
|
||||
# When changing SCM_DIRs also change SCM_DIRS_rexp and SCM_DIRS_prune:
|
||||
SCM_DIRS_rexp = ".hg|.svn|CVS|RCS|SCCS|Codemgr_wsdata|deleted_files"
|
||||
SCM_DIRS_prune = \( -name .hg -o -name .svn -o -name CVS -o -name RCS -o -name SCCS -o -name Codemgr_wsdata -o -name deleted_files \) -prune
|
||||
|
||||
# Don't define this unless it's not defined
|
||||
ifndef VARIANT
|
||||
VARIANT=OPT
|
||||
@ -372,14 +365,17 @@ ifeq ($(PLATFORM), windows)
|
||||
REQUIRED_FREE_SPACE=500000
|
||||
OS_VENDOR = Microsoft
|
||||
# How much RAM does this machine have:
|
||||
MB_OF_MEMORY := $(shell \
|
||||
if [ -f "C:/cygwin/bin/free.exe" ] ; then \
|
||||
( C:/cygwin/bin/bash.exe -c "C:/cygwin/bin/free.exe -m" ) | \
|
||||
grep Mem: | \
|
||||
sed -e 's@\ \ *@ @g' | cut -d' ' -f2 ; \
|
||||
else \
|
||||
echo "512"; \
|
||||
fi)
|
||||
ifndef MB_OF_MEMORY
|
||||
MB_OF_MEMORY := $(shell \
|
||||
if [ -f "C:/cygwin/bin/free.exe" ] ; then \
|
||||
( C:/cygwin/bin/bash.exe -c "C:/cygwin/bin/free.exe -m" ) | \
|
||||
grep Mem: | \
|
||||
sed -e 's@\ \ *@ @g' | cut -d' ' -f2 ; \
|
||||
else \
|
||||
echo "512"; \
|
||||
fi)
|
||||
export MB_OF_MEMORY
|
||||
endif
|
||||
endif
|
||||
|
||||
# Machines with 512Mb or less of real memory are considered low memory
|
||||
@ -387,30 +383,36 @@ endif
|
||||
# system swapping during the build.
|
||||
# If we don't know, assume 512. Subtract 128 from MB for VM MAX.
|
||||
# Don't set VM max over 1024-128=896.
|
||||
ifneq ($(MB_OF_MEMORY),)
|
||||
LOW_MEMORY_MACHINE := $(shell \
|
||||
if [ $(MB_OF_MEMORY) -le 512 ] ; then \
|
||||
echo "true"; \
|
||||
else \
|
||||
echo "false"; \
|
||||
fi)
|
||||
MAX_VM_MEMORY := $(shell \
|
||||
if [ $(MB_OF_MEMORY) -le 1024 ] ; then \
|
||||
expr $(MB_OF_MEMORY) '-' 128 ; \
|
||||
else \
|
||||
echo "896"; \
|
||||
fi)
|
||||
MIN_VM_MEMORY := $(shell \
|
||||
if [ $(MAX_VM_MEMORY) -le 128 ] ; then \
|
||||
expr $(MAX_VM_MEMORY) '-' 8 ; \
|
||||
else \
|
||||
echo "128"; \
|
||||
fi)
|
||||
else
|
||||
MB_OF_MEMORY := unknown
|
||||
LOW_MEMORY_MACHINE := true
|
||||
MAX_VM_MEMORY := 384
|
||||
MIN_VM_MEMORY := 128
|
||||
ifndef MAX_VM_MEMORY
|
||||
ifneq ($(MB_OF_MEMORY),)
|
||||
LOW_MEMORY_MACHINE := $(shell \
|
||||
if [ $(MB_OF_MEMORY) -le 512 ] ; then \
|
||||
echo "true"; \
|
||||
else \
|
||||
echo "false"; \
|
||||
fi)
|
||||
MAX_VM_MEMORY := $(shell \
|
||||
if [ $(MB_OF_MEMORY) -le 1024 ] ; then \
|
||||
expr $(MB_OF_MEMORY) '-' 128 ; \
|
||||
else \
|
||||
echo "896"; \
|
||||
fi)
|
||||
MIN_VM_MEMORY := $(shell \
|
||||
if [ $(MAX_VM_MEMORY) -le 128 ] ; then \
|
||||
expr $(MAX_VM_MEMORY) '-' 8 ; \
|
||||
else \
|
||||
echo "128"; \
|
||||
fi)
|
||||
else
|
||||
MB_OF_MEMORY := unknown
|
||||
LOW_MEMORY_MACHINE := true
|
||||
MAX_VM_MEMORY := 384
|
||||
MIN_VM_MEMORY := 128
|
||||
endif
|
||||
export MAX_VM_MEMORY
|
||||
export MIN_VM_MEMORY
|
||||
export LOW_MEMORY_MACHINE
|
||||
export MAX_VM_MEMORY
|
||||
endif
|
||||
|
||||
REQUIRED_ZIP_VER = 2.2
|
||||
|
@ -34,8 +34,8 @@ solaris_i586_5.10,\
|
||||
solaris_x64_5.10,\
|
||||
linux_i586_2.6,\
|
||||
linux_x64_2.6,\
|
||||
windows_i586,\
|
||||
windows_x64
|
||||
windows_i586_5.0,\
|
||||
windows_x64_5.2
|
||||
|
||||
# The different build flavors we want
|
||||
jprt.build.flavors=product,fastdebug
|
||||
|
@ -44,3 +44,6 @@ ba313800759b678979434d6da8ed3bf49eb8bea4 jdk7-b65
|
||||
18f526145aea355a9320b724373386fc2170f183 jdk7-b67
|
||||
d07e68298d4e17ebf93d8299e43fcc3ded26472a jdk7-b68
|
||||
54fd4d9232969ea6cd3d236e5ad276183bb0d423 jdk7-b69
|
||||
0632c3e615a315ff11e2ab1d64f4d82ff9853461 jdk7-b70
|
||||
50a95aa4a247f0cbbf66df285a8b1d78ffb153d9 jdk7-b71
|
||||
a94714c550658fd6741793ef036cb9625dc2ab1a jdk7-b72
|
||||
|
@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -48,6 +48,8 @@ if [ "$OS" = "Linux" ]; then
|
||||
CPU=i386
|
||||
fi
|
||||
else
|
||||
LD_AUDIT_32=$STARTDIR/../src/os/solaris/proc/`uname -p`/libsaproc_audit.so
|
||||
export LD_AUDIT_32
|
||||
SA_LIBPATH=$STARTDIR/../src/os/solaris/proc/`uname -p`:$STARTDIR/solaris/`uname -p`
|
||||
OPTIONS="-Dsa.library.path=$SA_LIBPATH -Dsun.jvm.hotspot.debugger.useProcDebugger"
|
||||
CPU=sparc
|
||||
|
@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -43,6 +43,8 @@ else
|
||||
fi
|
||||
fi
|
||||
|
||||
LD_AUDIT_64=$STARTDIR/../src/os/solaris/proc/$CPU/libsaproc_audit.so
|
||||
export LD_AUDIT_64
|
||||
SA_LIBPATH=$STARTDIR/../src/os/solaris/proc/$CPU:$STARTDIR/solaris/$CPU
|
||||
|
||||
OPTIONS="-Dsa.library.path=$SA_LIBPATH -Dsun.jvm.hotspot.debugger.useProcDebugger"
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 2002-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -56,24 +56,28 @@ i386:: javahomecheck
|
||||
@javah -classpath $(CLASSES_DIR) -jni sun.jvm.hotspot.debugger.proc.ProcDebuggerLocal
|
||||
CC -G -KPIC -I${JAVA_HOME}/include -I${JAVA_HOME}/include/solaris saproc.cpp \
|
||||
-M mapfile -o $@/libsaproc.so -ldemangle
|
||||
CC -o $@/libsaproc_audit.so -G -Kpic -z defs saproc_audit.cpp -lmapmalloc -ldl -lc
|
||||
|
||||
amd64:: javahomecheck
|
||||
$(MKDIRS) $@
|
||||
@javah -classpath $(CLASSES_DIR) -jni sun.jvm.hotspot.debugger.proc.ProcDebuggerLocal
|
||||
CC -G -KPIC -xarch=amd64 -I${JAVA_HOME}/include -I${JAVA_HOME}/include/solaris saproc.cpp \
|
||||
-M mapfile -o $@/libsaproc.so -ldemangle
|
||||
CC -xarch=amd64 -o $@/libsaproc_audit.so -G -Kpic -z defs saproc_audit.cpp -lmapmalloc -ldl -lc
|
||||
|
||||
sparc:: javahomecheck
|
||||
$(MKDIRS) $@
|
||||
@javah -classpath $(CLASSES_DIR) -jni sun.jvm.hotspot.debugger.proc.ProcDebuggerLocal
|
||||
CC -G -KPIC -xarch=v8 -I${JAVA_HOME}/include -I${JAVA_HOME}/include/solaris saproc.cpp \
|
||||
-M mapfile -o $@/libsaproc.so -ldemangle
|
||||
CC -xarch=v8 -o $@/libsaproc_audit.so -G -Kpic -z defs saproc_audit.cpp -lmapmalloc -ldl -lc
|
||||
|
||||
sparcv9:: javahomecheck
|
||||
$(MKDIRS) $@
|
||||
@javah -classpath $(CLASSES_DIR) -jni sun.jvm.hotspot.debugger.proc.ProcDebuggerLocal
|
||||
CC -G -KPIC -xarch=v9 -I${JAVA_HOME}/include -I${JAVA_HOME}/include/solaris saproc.cpp \
|
||||
-M mapfile -o $@/libsaproc.so -ldemangle
|
||||
CC -xarch=v9 -o $@/libsaproc_audit.so -G -Kpic -z defs saproc_audit.cpp -lmapmalloc -ldl -lc
|
||||
|
||||
clean::
|
||||
$(RM) -rf sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal.h
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -45,6 +45,8 @@ SUNWprivate_1.1 {
|
||||
Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_resume0;
|
||||
Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_suspend0;
|
||||
Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_writeBytesToProcess0;
|
||||
# this is needed by saproc_audit.c to redirect opens in libproc.so
|
||||
libsaproc_open;
|
||||
local:
|
||||
*;
|
||||
};
|
||||
|
@ -214,49 +214,58 @@ static void init_alt_root() {
|
||||
}
|
||||
}
|
||||
|
||||
static int find_file_hook(const char * name, int elf_checksum) {
|
||||
init_alt_root();
|
||||
// This function is a complete substitute for the open system call
|
||||
// since it's also used to override open calls from libproc to
|
||||
// implement as a pathmap style facility for the SA. If libproc
|
||||
// starts using other interfaces then this might have to extended to
|
||||
// cover other calls.
|
||||
extern "C" int libsaproc_open(const char * name, int oflag, ...) {
|
||||
if (oflag == O_RDONLY) {
|
||||
init_alt_root();
|
||||
|
||||
if (_libsaproc_debug) {
|
||||
printf("libsaproc DEBUG: find_file_hook %s 0x%x\n", name, elf_checksum);
|
||||
}
|
||||
|
||||
if (alt_root_len > 0) {
|
||||
int fd = -1;
|
||||
char alt_path[PATH_MAX+1];
|
||||
|
||||
strcpy(alt_path, alt_root);
|
||||
strcat(alt_path, name);
|
||||
fd = open(alt_path, O_RDONLY);
|
||||
if (fd >= 0) {
|
||||
if (_libsaproc_debug) {
|
||||
printf("libsaproc DEBUG: find_file_hook substituted %s\n", alt_path);
|
||||
}
|
||||
return fd;
|
||||
if (_libsaproc_debug) {
|
||||
printf("libsaproc DEBUG: libsaproc_open %s\n", name);
|
||||
}
|
||||
|
||||
if (strrchr(name, '/')) {
|
||||
if (alt_root_len > 0) {
|
||||
int fd = -1;
|
||||
char alt_path[PATH_MAX+1];
|
||||
|
||||
strcpy(alt_path, alt_root);
|
||||
strcat(alt_path, strrchr(name, '/'));
|
||||
strcat(alt_path, name);
|
||||
fd = open(alt_path, O_RDONLY);
|
||||
if (fd >= 0) {
|
||||
if (_libsaproc_debug) {
|
||||
printf("libsaproc DEBUG: find_file_hook substituted %s\n", alt_path);
|
||||
printf("libsaproc DEBUG: libsaproc_open substituted %s\n", alt_path);
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
if (strrchr(name, '/')) {
|
||||
strcpy(alt_path, alt_root);
|
||||
strcat(alt_path, strrchr(name, '/'));
|
||||
fd = open(alt_path, O_RDONLY);
|
||||
if (fd >= 0) {
|
||||
if (_libsaproc_debug) {
|
||||
printf("libsaproc DEBUG: libsaproc_open substituted %s\n", alt_path);
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
|
||||
{
|
||||
mode_t mode;
|
||||
va_list ap;
|
||||
va_start(ap, oflag);
|
||||
mode = va_arg(ap, mode_t);
|
||||
va_end(ap);
|
||||
|
||||
return open(name, oflag, mode);
|
||||
}
|
||||
}
|
||||
|
||||
static int pathmap_open(const char* name) {
|
||||
int fd = open(name, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
fd = find_file_hook(name, 0);
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
static void * pathmap_dlopen(const char * name, int mode) {
|
||||
init_alt_root();
|
||||
@ -608,7 +617,7 @@ init_classsharing_workaround(void *cd, const prmap_t* pmap, const char* obj_name
|
||||
print_debug("looking for %s\n", classes_jsa);
|
||||
|
||||
// open the classes[_g].jsa
|
||||
int fd = pathmap_open(classes_jsa);
|
||||
int fd = libsaproc_open(classes_jsa, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
char errMsg[ERR_MSG_SIZE];
|
||||
sprintf(errMsg, "can't open shared archive file %s", classes_jsa);
|
||||
@ -1209,8 +1218,6 @@ JNIEXPORT jstring JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_d
|
||||
return res;
|
||||
}
|
||||
|
||||
typedef int (*find_file_hook_t)(const char *, int elf_checksum);
|
||||
|
||||
/*
|
||||
* Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
|
||||
* Method: initIDs
|
||||
@ -1230,16 +1237,6 @@ JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_init
|
||||
if (libproc_handle == 0)
|
||||
THROW_NEW_DEBUGGER_EXCEPTION("can't load libproc.so, if you are using Solaris 5.7 or below, copy libproc.so from 5.8!");
|
||||
|
||||
// If possible, set shared object find file hook.
|
||||
void (*set_hook)(find_file_hook_t) = (void(*)(find_file_hook_t))dlsym(libproc_handle, "Pset_find_file_hook");
|
||||
if (set_hook) {
|
||||
// we found find file hook symbol, set up our hook function.
|
||||
set_hook(find_file_hook);
|
||||
} else if (getenv(SA_ALTROOT)) {
|
||||
printf("libsaproc WARNING: %s set, but can't set file hook. " \
|
||||
"Did you use right version of libproc.so?\n", SA_ALTROOT);
|
||||
}
|
||||
|
||||
p_ps_prochandle_ID = env->GetFieldID(clazz, "p_ps_prochandle", "J");
|
||||
CHECK_EXCEPTION;
|
||||
|
||||
|
98
hotspot/agent/src/os/solaris/proc/saproc_audit.cpp
Normal file
98
hotspot/agent/src/os/solaris/proc/saproc_audit.cpp
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <link.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <varargs.h>
|
||||
|
||||
// This class sets up an interposer on open calls from libproc.so to
|
||||
// support a pathmap facility in the SA.
|
||||
|
||||
static uintptr_t* libproc_cookie;
|
||||
static uintptr_t* libc_cookie;
|
||||
static uintptr_t* libsaproc_cookie;
|
||||
|
||||
|
||||
uint_t
|
||||
la_version(uint_t version)
|
||||
{
|
||||
return (LAV_CURRENT);
|
||||
}
|
||||
|
||||
|
||||
uint_t
|
||||
la_objopen(Link_map * lmp, Lmid_t lmid, uintptr_t * cookie)
|
||||
{
|
||||
if (strstr(lmp->l_name, "/libproc.so") != NULL) {
|
||||
libproc_cookie = cookie;
|
||||
return LA_FLG_BINDFROM;
|
||||
}
|
||||
if (strstr(lmp->l_name, "/libc.so") != NULL) {
|
||||
libc_cookie = cookie;
|
||||
return LA_FLG_BINDTO;
|
||||
}
|
||||
if (strstr(lmp->l_name, "/libsaproc.so") != NULL) {
|
||||
libsaproc_cookie = cookie;
|
||||
return LA_FLG_BINDTO | LA_FLG_BINDFROM;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#if defined(_LP64)
|
||||
uintptr_t
|
||||
la_symbind64(Elf64_Sym *symp, uint_t symndx, uintptr_t *refcook,
|
||||
uintptr_t *defcook, uint_t *sb_flags, const char *sym_name)
|
||||
#else
|
||||
uintptr_t
|
||||
la_symbind32(Elf32_Sym *symp, uint_t symndx, uintptr_t *refcook,
|
||||
uintptr_t *defcook, uint_t *sb_flags)
|
||||
#endif
|
||||
{
|
||||
#if !defined(_LP64)
|
||||
const char *sym_name = (const char *)symp->st_name;
|
||||
#endif
|
||||
if (strcmp(sym_name, "open") == 0 && refcook == libproc_cookie) {
|
||||
// redirect all open calls from libproc.so through libsaproc_open which will
|
||||
// try the alternate library locations first.
|
||||
void* handle = dlmopen(LM_ID_BASE, "libsaproc.so", RTLD_NOLOAD);
|
||||
if (handle == NULL) {
|
||||
fprintf(stderr, "libsaproc_audit.so: didn't find libsaproc.so during linking\n");
|
||||
} else {
|
||||
uintptr_t libsaproc_open = (uintptr_t)dlsym(handle, "libsaproc_open");
|
||||
if (libsaproc_open == 0) {
|
||||
fprintf(stderr, "libsaproc_audit.so: didn't find libsaproc_open during linking\n");
|
||||
} else {
|
||||
return libsaproc_open;
|
||||
}
|
||||
}
|
||||
}
|
||||
return symp->st_value;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -259,7 +259,7 @@ public class NMethod extends CodeBlob {
|
||||
if (Assert.ASSERTS_ENABLED) {
|
||||
Assert.that(pd != null, "scope must be present");
|
||||
}
|
||||
return new ScopeDesc(this, pd.getScopeDecodeOffset());
|
||||
return new ScopeDesc(this, pd.getScopeDecodeOffset(), pd.getReexecute());
|
||||
}
|
||||
|
||||
/** This is only for use by the debugging system, and is only
|
||||
@ -291,7 +291,7 @@ public class NMethod extends CodeBlob {
|
||||
public ScopeDesc getScopeDescNearDbg(Address pc) {
|
||||
PCDesc pd = getPCDescNearDbg(pc);
|
||||
if (pd == null) return null;
|
||||
return new ScopeDesc(this, pd.getScopeDecodeOffset());
|
||||
return new ScopeDesc(this, pd.getScopeDecodeOffset(), pd.getReexecute());
|
||||
}
|
||||
|
||||
public Map/*<Address, PcDesc>*/ getSafepoints() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2004 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -36,6 +36,7 @@ import sun.jvm.hotspot.types.*;
|
||||
public class PCDesc extends VMObject {
|
||||
private static CIntegerField pcOffsetField;
|
||||
private static CIntegerField scopeDecodeOffsetField;
|
||||
private static CIntegerField pcFlagsField;
|
||||
|
||||
static {
|
||||
VM.registerVMInitializedObserver(new Observer() {
|
||||
@ -50,6 +51,7 @@ public class PCDesc extends VMObject {
|
||||
|
||||
pcOffsetField = type.getCIntegerField("_pc_offset");
|
||||
scopeDecodeOffsetField = type.getCIntegerField("_scope_decode_offset");
|
||||
pcFlagsField = type.getCIntegerField("_flags");
|
||||
}
|
||||
|
||||
public PCDesc(Address addr) {
|
||||
@ -70,6 +72,12 @@ public class PCDesc extends VMObject {
|
||||
return code.instructionsBegin().addOffsetTo(getPCOffset());
|
||||
}
|
||||
|
||||
|
||||
public boolean getReexecute() {
|
||||
int flags = (int)pcFlagsField.getValue(addr);
|
||||
return ((flags & 0x1)== 1); //first is the reexecute bit
|
||||
}
|
||||
|
||||
public void print(NMethod code) {
|
||||
printOn(System.out, code);
|
||||
}
|
||||
@ -82,6 +90,7 @@ public class PCDesc extends VMObject {
|
||||
tty.print(" ");
|
||||
sd.getMethod().printValueOn(tty);
|
||||
tty.print(" @" + sd.getBCI());
|
||||
tty.print(" reexecute=" + sd.getReexecute());
|
||||
tty.println();
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ public class ScopeDesc {
|
||||
private NMethod code;
|
||||
private Method method;
|
||||
private int bci;
|
||||
private boolean reexecute;
|
||||
/** Decoding offsets */
|
||||
private int decodeOffset;
|
||||
private int senderDecodeOffset;
|
||||
@ -51,10 +52,11 @@ public class ScopeDesc {
|
||||
private List objects; // ArrayList<ScopeValue>
|
||||
|
||||
|
||||
public ScopeDesc(NMethod code, int decodeOffset) {
|
||||
public ScopeDesc(NMethod code, int decodeOffset, boolean reexecute) {
|
||||
this.code = code;
|
||||
this.decodeOffset = decodeOffset;
|
||||
this.objects = decodeObjectValues(DebugInformationRecorder.SERIALIZED_NULL);
|
||||
this.reexecute = reexecute;
|
||||
|
||||
// Decode header
|
||||
DebugInfoReadStream stream = streamAt(decodeOffset);
|
||||
@ -68,10 +70,11 @@ public class ScopeDesc {
|
||||
monitorsDecodeOffset = stream.readInt();
|
||||
}
|
||||
|
||||
public ScopeDesc(NMethod code, int decodeOffset, int objectDecodeOffset) {
|
||||
public ScopeDesc(NMethod code, int decodeOffset, int objectDecodeOffset, boolean reexecute) {
|
||||
this.code = code;
|
||||
this.decodeOffset = decodeOffset;
|
||||
this.objects = decodeObjectValues(objectDecodeOffset);
|
||||
this.reexecute = reexecute;
|
||||
|
||||
// Decode header
|
||||
DebugInfoReadStream stream = streamAt(decodeOffset);
|
||||
@ -85,9 +88,10 @@ public class ScopeDesc {
|
||||
monitorsDecodeOffset = stream.readInt();
|
||||
}
|
||||
|
||||
public NMethod getNMethod() { return code; }
|
||||
public Method getMethod() { return method; }
|
||||
public int getBCI() { return bci; }
|
||||
public NMethod getNMethod() { return code; }
|
||||
public Method getMethod() { return method; }
|
||||
public int getBCI() { return bci; }
|
||||
public boolean getReexecute() { return reexecute;}
|
||||
|
||||
/** Returns a List<ScopeValue> */
|
||||
public List getLocals() {
|
||||
@ -115,7 +119,7 @@ public class ScopeDesc {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new ScopeDesc(code, senderDecodeOffset);
|
||||
return new ScopeDesc(code, senderDecodeOffset, false);
|
||||
}
|
||||
|
||||
/** Returns where the scope was decoded */
|
||||
@ -149,7 +153,8 @@ public class ScopeDesc {
|
||||
public void printValueOn(PrintStream tty) {
|
||||
tty.print("ScopeDesc for ");
|
||||
method.printValueOn(tty);
|
||||
tty.println(" @bci " + bci);
|
||||
tty.print(" @bci " + bci);
|
||||
tty.println(" reexecute=" + reexecute);
|
||||
}
|
||||
|
||||
// FIXME: add more accessors
|
||||
@ -157,7 +162,6 @@ public class ScopeDesc {
|
||||
//--------------------------------------------------------------------------------
|
||||
// Internals only below this point
|
||||
//
|
||||
|
||||
private DebugInfoReadStream streamAt(int decodeOffset) {
|
||||
return new DebugInfoReadStream(code, decodeOffset, objects);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -176,19 +176,6 @@ public class CompactibleFreeListSpace extends CompactibleSpace {
|
||||
|
||||
for (; cur.lessThan(limit);) {
|
||||
Address klassOop = cur.getAddressAt(addressSize);
|
||||
// FIXME: need to do a better job here.
|
||||
// can I use bitMap here?
|
||||
if (klassOop == null) {
|
||||
//Find the object size using Printezis bits and skip over
|
||||
System.err.println("Finding object size using Printezis bits and skipping over...");
|
||||
long size = collector().blockSizeUsingPrintezisBits(cur);
|
||||
if (size == -1) {
|
||||
System.err.println("Printezis bits not set...");
|
||||
break;
|
||||
}
|
||||
cur = cur.addOffsetTo(adjustObjectSizeInBytes(size));
|
||||
}
|
||||
|
||||
if (FreeChunk.indicatesFreeChunk(cur)) {
|
||||
if (! cur.equals(regionStart)) {
|
||||
res.add(new MemRegion(regionStart, cur));
|
||||
@ -200,12 +187,21 @@ public class CompactibleFreeListSpace extends CompactibleSpace {
|
||||
}
|
||||
// note that fc.size() gives chunk size in heap words
|
||||
cur = cur.addOffsetTo(chunkSize * addressSize);
|
||||
System.err.println("Free chunk in CMS heap, size="+chunkSize * addressSize);
|
||||
regionStart = cur;
|
||||
} else if (klassOop != null) {
|
||||
Oop obj = heap.newOop(cur.addOffsetToAsOopHandle(0));
|
||||
long objectSize = obj.getObjectSize();
|
||||
cur = cur.addOffsetTo(adjustObjectSizeInBytes(objectSize));
|
||||
} else {
|
||||
// FIXME: need to do a better job here.
|
||||
// can I use bitMap here?
|
||||
//Find the object size using Printezis bits and skip over
|
||||
long size = collector().blockSizeUsingPrintezisBits(cur);
|
||||
if (size == -1) {
|
||||
System.err.println("Printezis bits not set...");
|
||||
break;
|
||||
}
|
||||
cur = cur.addOffsetTo(adjustObjectSizeInBytes(size));
|
||||
}
|
||||
}
|
||||
return res;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -63,7 +63,7 @@ public class FreeChunk extends VMObject {
|
||||
|
||||
public long size() {
|
||||
if (VM.getVM().isCompressedOopsEnabled()) {
|
||||
Mark mark = new Mark(sizeField.getValue(addr));
|
||||
Mark mark = new Mark(addr.addOffsetTo(sizeField.getOffset()));
|
||||
return mark.getSize();
|
||||
} else {
|
||||
Address size = sizeField.getValue(addr);
|
||||
@ -83,7 +83,7 @@ public class FreeChunk extends VMObject {
|
||||
|
||||
public boolean isFree() {
|
||||
if (VM.getVM().isCompressedOopsEnabled()) {
|
||||
Mark mark = new Mark(sizeField.getValue(addr));
|
||||
Mark mark = new Mark(addr.addOffsetTo(sizeField.getOffset()));
|
||||
return mark.isCmsFreeChunk();
|
||||
} else {
|
||||
Address prev = prevField.getValue(addr);
|
||||
|
@ -33,9 +33,9 @@
|
||||
# Don't put quotes (fail windows build).
|
||||
HOTSPOT_VM_COPYRIGHT=Copyright 2009
|
||||
|
||||
HS_MAJOR_VER=16
|
||||
HS_MAJOR_VER=17
|
||||
HS_MINOR_VER=0
|
||||
HS_BUILD_NUMBER=07
|
||||
HS_BUILD_NUMBER=02
|
||||
|
||||
JDK_MAJOR_VER=1
|
||||
JDK_MINOR_VER=7
|
||||
|
@ -40,6 +40,10 @@ jprt.need.sibling.build=false
|
||||
|
||||
jprt.tools.default.release=${jprt.submit.release}
|
||||
|
||||
# Disable syncing the source after builds and tests are done.
|
||||
|
||||
jprt.sync.push=false
|
||||
|
||||
# Define the Solaris platforms we want for the various releases
|
||||
|
||||
jprt.my.solaris.sparc.jdk7=solaris_sparc_5.10
|
||||
@ -306,7 +310,6 @@ jprt.my.windows.x64.test.targets = \
|
||||
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_ParallelGC, \
|
||||
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_ParNewGC, \
|
||||
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_CMS, \
|
||||
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_G1, \
|
||||
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_ParOldGC, \
|
||||
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_default, \
|
||||
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_SerialGC, \
|
||||
|
@ -70,10 +70,10 @@ all: $(JvmtiGeneratedFiles)
|
||||
both = $(JvmtiGenClass) $(JvmtiSrcDir)/jvmti.xml $(JvmtiSrcDir)/jvmtiLib.xsl
|
||||
|
||||
$(JvmtiGenClass): $(JvmtiGenSource)
|
||||
$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -g -d $(JvmtiOutDir) $(JvmtiGenSource)
|
||||
$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -d $(JvmtiOutDir) $(JvmtiGenSource)
|
||||
|
||||
$(JvmtiEnvFillClass): $(JvmtiEnvFillSource)
|
||||
$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -g -d $(JvmtiOutDir) $(JvmtiEnvFillSource)
|
||||
$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -d $(JvmtiOutDir) $(JvmtiEnvFillSource)
|
||||
|
||||
$(JvmtiOutDir)/jvmtiEnter.cpp: $(both) $(JvmtiSrcDir)/jvmtiEnter.xsl
|
||||
@echo Generating $@
|
||||
|
@ -74,6 +74,7 @@ SUNWprivate_1.1 {
|
||||
JVM_CurrentTimeMillis;
|
||||
JVM_DefineClass;
|
||||
JVM_DefineClassWithSource;
|
||||
JVM_DefineClassWithSourceCond;
|
||||
JVM_DesiredAssertionStatus;
|
||||
JVM_DisableCompiler;
|
||||
JVM_DoPrivileged;
|
||||
|
@ -74,6 +74,7 @@ SUNWprivate_1.1 {
|
||||
JVM_CurrentTimeMillis;
|
||||
JVM_DefineClass;
|
||||
JVM_DefineClassWithSource;
|
||||
JVM_DefineClassWithSourceCond;
|
||||
JVM_DesiredAssertionStatus;
|
||||
JVM_DisableCompiler;
|
||||
JVM_DoPrivileged;
|
||||
|
@ -122,12 +122,20 @@ endif
|
||||
endif
|
||||
endif
|
||||
|
||||
COMPILE.JAVAC += $(BOOTSTRAP_JAVAC_FLAGS)
|
||||
|
||||
SUM = /usr/bin/sum
|
||||
|
||||
# 'gmake MAKE_VERBOSE=y' gives all the gory details.
|
||||
QUIETLY$(MAKE_VERBOSE) = @
|
||||
RUN.JAR$(MAKE_VERBOSE) += >/dev/null
|
||||
|
||||
# Settings for javac
|
||||
BOOT_SOURCE_LANGUAGE_VERSION = 6
|
||||
BOOT_TARGET_CLASS_VERSION = 6
|
||||
JAVAC_FLAGS = -g -encoding ascii
|
||||
BOOTSTRAP_JAVAC_FLAGS = $(JAVAC_FLAGS) -source $(BOOT_SOURCE_LANGUAGE_VERSION) -target $(BOOT_TARGET_CLASS_VERSION)
|
||||
|
||||
# With parallel makes, print a message at the end of compilation.
|
||||
ifeq ($(findstring j,$(MFLAGS)),j)
|
||||
COMPILE_DONE = && { echo Done with $<; }
|
||||
|
@ -74,8 +74,8 @@ $(GENERATED)/sa-jdi.jar: $(AGENT_FILES1) $(AGENT_FILES2)
|
||||
mkdir -p $(SA_CLASSDIR); \
|
||||
fi
|
||||
|
||||
$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES1)
|
||||
$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES2)
|
||||
$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES1)
|
||||
$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES2)
|
||||
|
||||
$(QUIETLY) $(REMOTE) $(COMPILE.RMIC) -classpath $(SA_CLASSDIR) -d $(SA_CLASSDIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
|
||||
$(QUIETLY) echo "$(SA_BUILD_VERSION_PROP)" > $(SA_PROPERTIES)
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
# top.make is included in the Makefile in the build directories.
|
||||
# It DOES NOT include the vm dependency info in order to be faster.
|
||||
# It's main job is to implement the incremental form of make lists.
|
||||
# Its main job is to implement the incremental form of make lists.
|
||||
# It also:
|
||||
# -builds and runs adlc via adlc.make
|
||||
# -generates JVMTI source and docs via jvmti.make (JSR-163)
|
||||
@ -114,7 +114,7 @@ vm_build_preliminaries: checks $(Incremental_Lists) $(AD_Files_If_Required) jvm
|
||||
# make makeDeps: (and zap the cached db files to force a nonincremental run)
|
||||
|
||||
$(GENERATED)/$(MakeDepsClass): $(MakeDepsSources)
|
||||
@$(REMOTE) $(COMPILE.JAVAC) -classpath $(GAMMADIR)/src/share/tools/MakeDeps -g -d $(GENERATED) $(MakeDepsSources)
|
||||
@$(REMOTE) $(COMPILE.JAVAC) -classpath $(GAMMADIR)/src/share/tools/MakeDeps -d $(GENERATED) $(MakeDepsSources)
|
||||
@echo Removing $(Incremental_Lists) to force regeneration.
|
||||
@rm -f $(Incremental_Lists)
|
||||
@$(CDG) echo >$(Cached_plat)
|
||||
|
@ -69,10 +69,10 @@ all: $(JvmtiGeneratedFiles)
|
||||
both = $(JvmtiGenClass) $(JvmtiSrcDir)/jvmti.xml $(JvmtiSrcDir)/jvmtiLib.xsl
|
||||
|
||||
$(JvmtiGenClass): $(JvmtiGenSource)
|
||||
$(QUIETLY) $(COMPILE.JAVAC) -g -d $(JvmtiOutDir) $(JvmtiGenSource)
|
||||
$(QUIETLY) $(COMPILE.JAVAC) -d $(JvmtiOutDir) $(JvmtiGenSource)
|
||||
|
||||
$(JvmtiEnvFillClass): $(JvmtiEnvFillSource)
|
||||
$(QUIETLY) $(COMPILE.JAVAC) -g -d $(JvmtiOutDir) $(JvmtiEnvFillSource)
|
||||
$(QUIETLY) $(COMPILE.JAVAC) -d $(JvmtiOutDir) $(JvmtiEnvFillSource)
|
||||
|
||||
$(JvmtiOutDir)/jvmtiEnter.cpp: $(both) $(JvmtiSrcDir)/jvmtiEnter.xsl
|
||||
@echo Generating $@
|
||||
|
@ -74,6 +74,7 @@ SUNWprivate_1.1 {
|
||||
JVM_CurrentTimeMillis;
|
||||
JVM_DefineClass;
|
||||
JVM_DefineClassWithSource;
|
||||
JVM_DefineClassWithSourceCond;
|
||||
JVM_DesiredAssertionStatus;
|
||||
JVM_DisableCompiler;
|
||||
JVM_DoPrivileged;
|
||||
|
@ -122,12 +122,20 @@ endif
|
||||
endif
|
||||
endif
|
||||
|
||||
COMPILE.JAVAC += $(BOOTSTRAP_JAVAC_FLAGS)
|
||||
|
||||
SUM = /usr/bin/sum
|
||||
|
||||
# 'gmake MAKE_VERBOSE=y' gives all the gory details.
|
||||
QUIETLY$(MAKE_VERBOSE) = @
|
||||
RUN.JAR$(MAKE_VERBOSE) += >/dev/null
|
||||
|
||||
# Settings for javac
|
||||
BOOT_SOURCE_LANGUAGE_VERSION = 6
|
||||
BOOT_TARGET_CLASS_VERSION = 6
|
||||
JAVAC_FLAGS = -g -encoding ascii
|
||||
BOOTSTRAP_JAVAC_FLAGS = $(JAVAC_FLAGS) -source $(BOOT_SOURCE_LANGUAGE_VERSION) -target $(BOOT_TARGET_CLASS_VERSION)
|
||||
|
||||
# With parallel makes, print a message at the end of compilation.
|
||||
ifeq ($(findstring j,$(MFLAGS)),j)
|
||||
COMPILE_DONE = && { echo Done with $<; }
|
||||
|
@ -67,8 +67,8 @@ $(GENERATED)/sa-jdi.jar: $(AGENT_FILES1) $(AGENT_FILES2)
|
||||
$(QUIETLY) if [ ! -d $(SA_CLASSDIR) ] ; then \
|
||||
mkdir -p $(SA_CLASSDIR); \
|
||||
fi
|
||||
$(QUIETLY) $(COMPILE.JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES1)
|
||||
$(QUIETLY) $(COMPILE.JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES2)
|
||||
$(QUIETLY) $(COMPILE.JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES1)
|
||||
$(QUIETLY) $(COMPILE.JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES2)
|
||||
|
||||
$(QUIETLY) $(COMPILE.RMIC) -classpath $(SA_CLASSDIR) -d $(SA_CLASSDIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
|
||||
$(QUIETLY) echo "$(SA_BUILD_VERSION_PROP)" > $(SA_PROPERTIES)
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
# top.make is included in the Makefile in the build directories.
|
||||
# It DOES NOT include the vm dependency info in order to be faster.
|
||||
# It's main job is to implement the incremental form of make lists.
|
||||
# Its main job is to implement the incremental form of make lists.
|
||||
# It also:
|
||||
# -builds and runs adlc via adlc.make
|
||||
# -generates JVMTI source and docs via jvmti.make (JSR-163)
|
||||
@ -112,7 +112,7 @@ vm_build_preliminaries: checks $(Incremental_Lists) $(AD_Files_If_Required) jvm
|
||||
# make makeDeps: (and zap the cached db files to force a nonincremental run)
|
||||
|
||||
$(GENERATED)/$(MakeDepsClass): $(MakeDepsSources)
|
||||
@$(COMPILE.JAVAC) -classpath $(GAMMADIR)/src/share/tools/MakeDeps -g -d $(GENERATED) $(MakeDepsSources)
|
||||
@$(COMPILE.JAVAC) -classpath $(GAMMADIR)/src/share/tools/MakeDeps -d $(GENERATED) $(MakeDepsSources)
|
||||
@echo Removing $(Incremental_Lists) to force regeneration.
|
||||
@rm -f $(Incremental_Lists)
|
||||
@$(CDG) echo >$(Cached_plat)
|
||||
|
@ -91,7 +91,7 @@ includeDB.current Dependencies: classes/MakeDeps.class $(IncludeDBs)
|
||||
classes/MakeDeps.class: $(MakeDepsSources)
|
||||
if exist classes rmdir /s /q classes
|
||||
mkdir classes
|
||||
$(COMPILE_JAVAC) -classpath $(WorkSpace)\src\share\tools\MakeDeps -g -d classes $(MakeDepsSources)
|
||||
$(COMPILE_JAVAC) -classpath $(WorkSpace)\src\share\tools\MakeDeps -d classes $(MakeDepsSources)
|
||||
|
||||
!if ("$(Variant)" == "compiler2") || ("$(Variant)" == "tiered")
|
||||
|
||||
|
@ -68,10 +68,10 @@ default::
|
||||
@if not exist $(JvmtiOutDir) mkdir $(JvmtiOutDir)
|
||||
|
||||
$(JvmtiGenClass): $(JvmtiGenSource)
|
||||
$(COMPILE_JAVAC) -g -d $(JvmtiOutDir) $(JvmtiGenSource)
|
||||
$(COMPILE_JAVAC) -d $(JvmtiOutDir) $(JvmtiGenSource)
|
||||
|
||||
$(JvmtiEnvFillClass): $(JvmtiEnvFillSource)
|
||||
@$(COMPILE_JAVAC) -g -d $(JvmtiOutDir) $(JvmtiEnvFillSource)
|
||||
@$(COMPILE_JAVAC) -d $(JvmtiOutDir) $(JvmtiEnvFillSource)
|
||||
|
||||
$(JvmtiOutDir)/jvmtiEnter.cpp: $(both) $(JvmtiSrcDir)/jvmtiEnter.xsl
|
||||
@echo Generating $@
|
||||
|
@ -29,7 +29,7 @@ RUN_JAVA=$(BootStrapDir)\bin\java
|
||||
RUN_JAVAP=$(BootStrapDir)\bin\javap
|
||||
RUN_JAVAH=$(BootStrapDir)\bin\javah
|
||||
RUN_JAR=$(BootStrapDir)\bin\jar
|
||||
COMPILE_JAVAC=$(BootStrapDir)\bin\javac
|
||||
COMPILE_JAVAC=$(BootStrapDir)\bin\javac $(BOOTSTRAP_JAVAC_FLAGS)
|
||||
COMPILE_RMIC=$(BootStrapDir)\bin\rmic
|
||||
BOOT_JAVA_HOME=$(BootStrapDir)
|
||||
!else
|
||||
@ -37,11 +37,17 @@ RUN_JAVA=java
|
||||
RUN_JAVAP=javap
|
||||
RUN_JAVAH=javah
|
||||
RUN_JAR=jar
|
||||
COMPILE_JAVAC=javac
|
||||
COMPILE_JAVAC=javac $(BOOTSTRAP_JAVAC_FLAGS)
|
||||
COMPILE_RMIC=rmic
|
||||
BOOT_JAVA_HOME=
|
||||
!endif
|
||||
|
||||
# Settings for javac
|
||||
BOOT_SOURCE_LANGUAGE_VERSION=6
|
||||
BOOT_TARGET_CLASS_VERSION=6
|
||||
JAVAC_FLAGS=-g -encoding ascii
|
||||
BOOTSTRAP_JAVAC_FLAGS=$(JAVAC_FLAGS) -source $(BOOT_SOURCE_LANGUAGE_VERSION) -target $(BOOT_TARGET_CLASS_VERSION)
|
||||
|
||||
ProjectFile=vm.vcproj
|
||||
|
||||
!if "$(MSC_VER)" == "1200"
|
||||
|
@ -55,9 +55,9 @@ default:: $(GENERATED)\sa-jdi.jar
|
||||
$(GENERATED)\sa-jdi.jar: $(AGENT_FILES1:/=\) $(AGENT_FILES2:/=\)
|
||||
@if not exist $(SA_CLASSDIR) mkdir $(SA_CLASSDIR)
|
||||
@echo ...Building sa-jdi.jar
|
||||
@echo ...$(COMPILE_JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -g -d $(SA_CLASSDIR) ....
|
||||
@$(COMPILE_JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES1:/=\)
|
||||
@$(COMPILE_JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES2:/=\)
|
||||
@echo ...$(COMPILE_JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -d $(SA_CLASSDIR) ....
|
||||
@$(COMPILE_JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES1:/=\)
|
||||
@$(COMPILE_JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES2:/=\)
|
||||
$(COMPILE_RMIC) -classpath $(SA_CLASSDIR) -d $(SA_CLASSDIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
|
||||
$(QUIETLY) echo $(SA_BUILD_VERSION_PROP)> $(SA_PROPERTIES)
|
||||
$(QUIETLY) rm -f $(SA_CLASSDIR)/sun/jvm/hotspot/utilities/soql/sa.js
|
||||
|
@ -179,6 +179,6 @@ clean:
|
||||
$(HOTSPOTBUILDSPACE)/classes/MakeDeps.class: $(MakeDepsSources)
|
||||
@if exist $(HOTSPOTBUILDSPACE)\classes rmdir /s /q $(HOTSPOTBUILDSPACE)\classes
|
||||
@mkdir $(HOTSPOTBUILDSPACE)\classes
|
||||
@$(COMPILE_JAVAC) -classpath $(HOTSPOTWORKSPACE)\src\share\tools\MakeDeps -g -d $(HOTSPOTBUILDSPACE)/classes $(MakeDepsSources)
|
||||
@$(COMPILE_JAVAC) -classpath $(HOTSPOTWORKSPACE)\src\share\tools\MakeDeps -d $(HOTSPOTBUILDSPACE)/classes $(MakeDepsSources)
|
||||
|
||||
FORCE:
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -38,7 +38,7 @@ enum {
|
||||
// registers
|
||||
enum {
|
||||
pd_nof_cpu_regs_frame_map = 32, // number of registers used during code emission
|
||||
pd_nof_caller_save_cpu_regs_frame_map = 6, // number of cpu registers killed by calls
|
||||
pd_nof_caller_save_cpu_regs_frame_map = 10, // number of cpu registers killed by calls
|
||||
pd_nof_cpu_regs_reg_alloc = 20, // number of registers that are visible to register allocator
|
||||
pd_nof_cpu_regs_linearscan = 32,// number of registers visible linear scan
|
||||
pd_first_cpu_reg = 0,
|
||||
|
@ -320,6 +320,10 @@ void FrameMap::init () {
|
||||
_caller_save_cpu_regs[3] = FrameMap::O3_opr;
|
||||
_caller_save_cpu_regs[4] = FrameMap::O4_opr;
|
||||
_caller_save_cpu_regs[5] = FrameMap::O5_opr;
|
||||
_caller_save_cpu_regs[6] = FrameMap::G1_opr;
|
||||
_caller_save_cpu_regs[7] = FrameMap::G3_opr;
|
||||
_caller_save_cpu_regs[8] = FrameMap::G4_opr;
|
||||
_caller_save_cpu_regs[9] = FrameMap::G5_opr;
|
||||
for (int i = 0; i < nof_caller_save_fpu_regs; i++) {
|
||||
_caller_save_fpu_regs[i] = LIR_OprFact::single_fpu(i);
|
||||
}
|
||||
|
@ -749,6 +749,10 @@ void LIRGenerator::do_MathIntrinsic(Intrinsic* x) {
|
||||
|
||||
void LIRGenerator::do_ArrayCopy(Intrinsic* x) {
|
||||
assert(x->number_of_arguments() == 5, "wrong type");
|
||||
|
||||
// Make all state_for calls early since they can emit code
|
||||
CodeEmitInfo* info = state_for(x, x->state());
|
||||
|
||||
// Note: spill caller save before setting the item
|
||||
LIRItem src (x->argument_at(0), this);
|
||||
LIRItem src_pos (x->argument_at(1), this);
|
||||
@ -767,7 +771,6 @@ void LIRGenerator::do_ArrayCopy(Intrinsic* x) {
|
||||
ciArrayKlass* expected_type;
|
||||
arraycopy_helper(x, &flags, &expected_type);
|
||||
|
||||
CodeEmitInfo* info = state_for(x, x->state());
|
||||
__ arraycopy(src.result(), src_pos.result(), dst.result(), dst_pos.result(),
|
||||
length.result(), rlock_callee_saved(T_INT),
|
||||
expected_type, flags, info);
|
||||
@ -878,6 +881,9 @@ void LIRGenerator::do_NewInstance(NewInstance* x) {
|
||||
|
||||
|
||||
void LIRGenerator::do_NewTypeArray(NewTypeArray* x) {
|
||||
// Evaluate state_for early since it may emit code
|
||||
CodeEmitInfo* info = state_for(x, x->state());
|
||||
|
||||
LIRItem length(x->length(), this);
|
||||
length.load_item();
|
||||
|
||||
@ -892,7 +898,6 @@ void LIRGenerator::do_NewTypeArray(NewTypeArray* x) {
|
||||
|
||||
__ oop2reg(ciTypeArrayKlass::make(elem_type)->encoding(), klass_reg);
|
||||
|
||||
CodeEmitInfo* info = state_for(x, x->state());
|
||||
CodeStub* slow_path = new NewTypeArrayStub(klass_reg, len, reg, info);
|
||||
__ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, elem_type, klass_reg, slow_path);
|
||||
|
||||
@ -902,7 +907,8 @@ void LIRGenerator::do_NewTypeArray(NewTypeArray* x) {
|
||||
|
||||
|
||||
void LIRGenerator::do_NewObjectArray(NewObjectArray* x) {
|
||||
LIRItem length(x->length(), this);
|
||||
// Evaluate state_for early since it may emit code.
|
||||
CodeEmitInfo* info = state_for(x, x->state());
|
||||
// in case of patching (i.e., object class is not yet loaded), we need to reexecute the instruction
|
||||
// and therefore provide the state before the parameters have been consumed
|
||||
CodeEmitInfo* patching_info = NULL;
|
||||
@ -910,6 +916,7 @@ void LIRGenerator::do_NewObjectArray(NewObjectArray* x) {
|
||||
patching_info = state_for(x, x->state_before());
|
||||
}
|
||||
|
||||
LIRItem length(x->length(), this);
|
||||
length.load_item();
|
||||
|
||||
const LIR_Opr reg = result_register_for(x->type());
|
||||
@ -919,7 +926,6 @@ void LIRGenerator::do_NewObjectArray(NewObjectArray* x) {
|
||||
LIR_Opr tmp4 = FrameMap::O1_oop_opr;
|
||||
LIR_Opr klass_reg = FrameMap::G5_oop_opr;
|
||||
LIR_Opr len = length.result();
|
||||
CodeEmitInfo* info = state_for(x, x->state());
|
||||
|
||||
CodeStub* slow_path = new NewObjectArrayStub(klass_reg, len, reg, info);
|
||||
ciObject* obj = (ciObject*) ciObjArrayKlass::make(x->klass());
|
||||
@ -943,25 +949,22 @@ void LIRGenerator::do_NewMultiArray(NewMultiArray* x) {
|
||||
items->at_put(i, size);
|
||||
}
|
||||
|
||||
// need to get the info before, as the items may become invalid through item_free
|
||||
// Evaluate state_for early since it may emit code.
|
||||
CodeEmitInfo* patching_info = NULL;
|
||||
if (!x->klass()->is_loaded() || PatchALot) {
|
||||
patching_info = state_for(x, x->state_before());
|
||||
|
||||
// cannot re-use same xhandlers for multiple CodeEmitInfos, so
|
||||
// clone all handlers
|
||||
// clone all handlers. This is handled transparently in other
|
||||
// places by the CodeEmitInfo cloning logic but is handled
|
||||
// specially here because a stub isn't being used.
|
||||
x->set_exception_handlers(new XHandlers(x->exception_handlers()));
|
||||
}
|
||||
CodeEmitInfo* info = state_for(x, x->state());
|
||||
|
||||
i = dims->length();
|
||||
while (i-- > 0) {
|
||||
LIRItem* size = items->at(i);
|
||||
// if a patching_info was generated above then debug information for the state before
|
||||
// the call is going to be emitted. The LIRGenerator calls above may have left some values
|
||||
// in registers and that's been recorded in the CodeEmitInfo. In that case the items
|
||||
// for those values can't simply be freed if they are registers because the values
|
||||
// might be destroyed by store_stack_parameter. So in the case of patching, delay the
|
||||
// freeing of the items that already were in registers
|
||||
size->load_item();
|
||||
store_stack_parameter (size->result(),
|
||||
in_ByteSize(STACK_BIAS +
|
||||
@ -972,8 +975,6 @@ void LIRGenerator::do_NewMultiArray(NewMultiArray* x) {
|
||||
// This instruction can be deoptimized in the slow path : use
|
||||
// O0 as result register.
|
||||
const LIR_Opr reg = result_register_for(x->type());
|
||||
CodeEmitInfo* info = state_for(x, x->state());
|
||||
|
||||
jobject2reg_with_patching(reg, x->klass(), patching_info);
|
||||
LIR_Opr rank = FrameMap::O1_opr;
|
||||
__ move(LIR_OprFact::intConst(x->rank()), rank);
|
||||
|
@ -1696,6 +1696,9 @@ void InterpreterMacroAssembler::profile_virtual_call(Register receiver,
|
||||
void InterpreterMacroAssembler::record_klass_in_profile_helper(
|
||||
Register receiver, Register scratch,
|
||||
int start_row, Label& done) {
|
||||
if (TypeProfileWidth == 0)
|
||||
return;
|
||||
|
||||
int last_row = VirtualCallData::row_limit() - 1;
|
||||
assert(start_row <= last_row, "must be work left to do");
|
||||
// Test this row for both the receiver and for null.
|
||||
|
@ -5707,7 +5707,7 @@ instruct loadUS2L_immI16(iRegL dst, memory mem, immI16 mask, iRegL tmp) %{
|
||||
effect(TEMP dst, TEMP tmp);
|
||||
ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
|
||||
|
||||
size(3*4);
|
||||
size((3+1)*4); // set may use two instructions.
|
||||
format %{ "LDUH $mem,$dst\t! ushort/char & 16-bit mask -> long\n\t"
|
||||
"SET $mask,$tmp\n\t"
|
||||
"AND $dst,$tmp,$dst" %}
|
||||
@ -5851,7 +5851,7 @@ instruct loadI2L_immI(iRegL dst, memory mem, immI mask, iRegL tmp) %{
|
||||
effect(TEMP dst, TEMP tmp);
|
||||
ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
|
||||
|
||||
size(3*4);
|
||||
size((3+1)*4); // set may use two instructions.
|
||||
format %{ "LDUW $mem,$dst\t! int & 32-bit mask -> long\n\t"
|
||||
"SET $mask,$tmp\n\t"
|
||||
"AND $dst,$tmp,$dst" %}
|
||||
|
@ -8335,15 +8335,13 @@ void MacroAssembler::decode_heap_oop_not_null(Register r) {
|
||||
// Cannot assert, unverified entry point counts instructions (see .ad file)
|
||||
// vtableStubs also counts instructions in pd_code_size_limit.
|
||||
// Also do not verify_oop as this is called by verify_oop.
|
||||
if (Universe::narrow_oop_base() == NULL) {
|
||||
if (Universe::narrow_oop_shift() != 0) {
|
||||
assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
|
||||
shlq(r, LogMinObjAlignmentInBytes);
|
||||
}
|
||||
} else {
|
||||
assert (Address::times_8 == LogMinObjAlignmentInBytes &&
|
||||
Address::times_8 == Universe::narrow_oop_shift(), "decode alg wrong");
|
||||
if (Universe::narrow_oop_shift() != 0) {
|
||||
assert (Address::times_8 == LogMinObjAlignmentInBytes &&
|
||||
Address::times_8 == Universe::narrow_oop_shift(), "decode alg wrong");
|
||||
// Don't use Shift since it modifies flags.
|
||||
leaq(r, Address(r12_heapbase, r, Address::times_8, 0));
|
||||
} else {
|
||||
assert (Universe::narrow_oop_base() == NULL, "sanity");
|
||||
}
|
||||
}
|
||||
|
||||
@ -8358,6 +8356,7 @@ void MacroAssembler::decode_heap_oop_not_null(Register dst, Register src) {
|
||||
Address::times_8 == Universe::narrow_oop_shift(), "decode alg wrong");
|
||||
leaq(dst, Address(r12_heapbase, src, Address::times_8, 0));
|
||||
} else if (dst != src) {
|
||||
assert (Universe::narrow_oop_base() == NULL, "sanity");
|
||||
movq(dst, src);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2005-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -827,8 +827,8 @@ void LIRGenerator::do_MathIntrinsic(Intrinsic* x) {
|
||||
case vmIntrinsics::_dsin: __ sin (calc_input, calc_result, tmp1, tmp2); break;
|
||||
case vmIntrinsics::_dcos: __ cos (calc_input, calc_result, tmp1, tmp2); break;
|
||||
case vmIntrinsics::_dtan: __ tan (calc_input, calc_result, tmp1, tmp2); break;
|
||||
case vmIntrinsics::_dlog: __ log (calc_input, calc_result, LIR_OprFact::illegalOpr); break;
|
||||
case vmIntrinsics::_dlog10: __ log10(calc_input, calc_result, LIR_OprFact::illegalOpr); break;
|
||||
case vmIntrinsics::_dlog: __ log (calc_input, calc_result, tmp1); break;
|
||||
case vmIntrinsics::_dlog10: __ log10(calc_input, calc_result, tmp1); break;
|
||||
default: ShouldNotReachHere();
|
||||
}
|
||||
|
||||
@ -1047,16 +1047,17 @@ void LIRGenerator::do_NewMultiArray(NewMultiArray* x) {
|
||||
items->at_put(i, size);
|
||||
}
|
||||
|
||||
// need to get the info before, as the items may become invalid through item_free
|
||||
// Evaluate state_for early since it may emit code.
|
||||
CodeEmitInfo* patching_info = NULL;
|
||||
if (!x->klass()->is_loaded() || PatchALot) {
|
||||
patching_info = state_for(x, x->state_before());
|
||||
|
||||
// cannot re-use same xhandlers for multiple CodeEmitInfos, so
|
||||
// clone all handlers.
|
||||
// clone all handlers. This is handled transparently in other
|
||||
// places by the CodeEmitInfo cloning logic but is handled
|
||||
// specially here because a stub isn't being used.
|
||||
x->set_exception_handlers(new XHandlers(x->exception_handlers()));
|
||||
}
|
||||
|
||||
CodeEmitInfo* info = state_for(x, x->state());
|
||||
|
||||
i = dims->length();
|
||||
|
@ -764,8 +764,6 @@ void FpuStackAllocator::handle_op2(LIR_Op2* op2) {
|
||||
break;
|
||||
}
|
||||
|
||||
case lir_log:
|
||||
case lir_log10:
|
||||
case lir_abs:
|
||||
case lir_sqrt: {
|
||||
// Right argument appears to be unused
|
||||
@ -785,6 +783,30 @@ void FpuStackAllocator::handle_op2(LIR_Op2* op2) {
|
||||
break;
|
||||
}
|
||||
|
||||
case lir_log:
|
||||
case lir_log10: {
|
||||
// log and log10 needs one temporary fpu stack slot, so there is ontemporary
|
||||
// registers stored in temp of the operation.
|
||||
// the stack allocator must guarantee that the stack slots are really free,
|
||||
// otherwise there might be a stack overflow.
|
||||
assert(right->is_illegal(), "must be");
|
||||
assert(left->is_fpu_register(), "must be");
|
||||
assert(res->is_fpu_register(), "must be");
|
||||
assert(op2->tmp_opr()->is_fpu_register(), "must be");
|
||||
|
||||
insert_free_if_dead(op2->tmp_opr());
|
||||
insert_free_if_dead(res, left);
|
||||
insert_exchange(left);
|
||||
do_rename(left, res);
|
||||
|
||||
new_left = to_fpu_stack_top(res);
|
||||
new_res = new_left;
|
||||
|
||||
op2->set_fpu_stack_size(sim()->stack_size());
|
||||
assert(sim()->stack_size() <= 7, "at least one stack slot must be free");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case lir_tan:
|
||||
case lir_sin:
|
||||
|
@ -1262,6 +1262,9 @@ void InterpreterMacroAssembler::record_klass_in_profile_helper(
|
||||
Register receiver, Register mdp,
|
||||
Register reg2,
|
||||
int start_row, Label& done) {
|
||||
if (TypeProfileWidth == 0)
|
||||
return;
|
||||
|
||||
int last_row = VirtualCallData::row_limit() - 1;
|
||||
assert(start_row <= last_row, "must be work left to do");
|
||||
// Test this row for both the receiver and for null.
|
||||
|
@ -1272,6 +1272,9 @@ void InterpreterMacroAssembler::record_klass_in_profile_helper(
|
||||
Register receiver, Register mdp,
|
||||
Register reg2,
|
||||
int start_row, Label& done) {
|
||||
if (TypeProfileWidth == 0)
|
||||
return;
|
||||
|
||||
int last_row = VirtualCallData::row_limit() - 1;
|
||||
assert(start_row <= last_row, "must be work left to do");
|
||||
// Test this row for both the receiver and for null.
|
||||
|
@ -2381,7 +2381,7 @@ void SharedRuntime::generate_deopt_blob() {
|
||||
|
||||
// Save everything in sight.
|
||||
|
||||
map = RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words);
|
||||
map = RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words, false);
|
||||
// Normal deoptimization
|
||||
__ push(Deoptimization::Unpack_deopt);
|
||||
__ jmp(cont);
|
||||
@ -2392,7 +2392,7 @@ void SharedRuntime::generate_deopt_blob() {
|
||||
// return address is the pc describes what bci to do re-execute at
|
||||
|
||||
// No need to update map as each call to save_live_registers will produce identical oopmap
|
||||
(void) RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words);
|
||||
(void) RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words, false);
|
||||
|
||||
__ push(Deoptimization::Unpack_reexecute);
|
||||
__ jmp(cont);
|
||||
@ -2428,7 +2428,7 @@ void SharedRuntime::generate_deopt_blob() {
|
||||
// Save everything in sight.
|
||||
|
||||
// No need to update map as each call to save_live_registers will produce identical oopmap
|
||||
(void) RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words);
|
||||
(void) RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words, false);
|
||||
|
||||
// Now it is safe to overwrite any register
|
||||
|
||||
@ -2515,6 +2515,11 @@ void SharedRuntime::generate_deopt_blob() {
|
||||
|
||||
RegisterSaver::restore_result_registers(masm);
|
||||
|
||||
// Non standard control word may be leaked out through a safepoint blob, and we can
|
||||
// deopt at a poll point with the non standard control word. However, we should make
|
||||
// sure the control word is correct after restore_result_registers.
|
||||
__ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std()));
|
||||
|
||||
// All of the register save area has been popped of the stack. Only the
|
||||
// return address remains.
|
||||
|
||||
|
@ -1643,7 +1643,8 @@ inline hrtime_t oldgetTimeNanos() {
|
||||
inline hrtime_t getTimeNanos() {
|
||||
if (VM_Version::supports_cx8()) {
|
||||
const hrtime_t now = gethrtime();
|
||||
const hrtime_t prev = max_hrtime;
|
||||
// Use atomic long load since 32-bit x86 uses 2 registers to keep long.
|
||||
const hrtime_t prev = Atomic::load((volatile jlong*)&max_hrtime);
|
||||
if (now <= prev) return prev; // same or retrograde time;
|
||||
const hrtime_t obsv = Atomic::cmpxchg(now, (volatile jlong*)&max_hrtime, prev);
|
||||
assert(obsv >= prev, "invariant"); // Monotonicity
|
||||
|
@ -616,12 +616,13 @@ julong os::available_memory() {
|
||||
}
|
||||
|
||||
julong os::win32::available_memory() {
|
||||
// FIXME: GlobalMemoryStatus() may return incorrect value if total memory
|
||||
// is larger than 4GB
|
||||
MEMORYSTATUS ms;
|
||||
GlobalMemoryStatus(&ms);
|
||||
// Use GlobalMemoryStatusEx() because GlobalMemoryStatus() may return incorrect
|
||||
// value if total memory is larger than 4GB
|
||||
MEMORYSTATUSEX ms;
|
||||
ms.dwLength = sizeof(ms);
|
||||
GlobalMemoryStatusEx(&ms);
|
||||
|
||||
return (julong)ms.dwAvailPhys;
|
||||
return (julong)ms.ullAvailPhys;
|
||||
}
|
||||
|
||||
julong os::physical_memory() {
|
||||
@ -1525,7 +1526,8 @@ void os::print_os_info(outputStream* st) {
|
||||
case 5000: st->print(" Windows 2000"); break;
|
||||
case 5001: st->print(" Windows XP"); break;
|
||||
case 5002:
|
||||
case 6000: {
|
||||
case 6000:
|
||||
case 6001: {
|
||||
// Retrieve SYSTEM_INFO from GetNativeSystemInfo call so that we could
|
||||
// find out whether we are running on 64 bit processor or not.
|
||||
SYSTEM_INFO si;
|
||||
@ -1548,13 +1550,27 @@ void os::print_os_info(outputStream* st) {
|
||||
st->print(" Windows XP x64 Edition");
|
||||
else
|
||||
st->print(" Windows Server 2003 family");
|
||||
} else { // os_vers == 6000
|
||||
} else if (os_vers == 6000) {
|
||||
if (osvi.wProductType == VER_NT_WORKSTATION)
|
||||
st->print(" Windows Vista");
|
||||
else
|
||||
st->print(" Windows Server 2008");
|
||||
if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
|
||||
st->print(" , 64 bit");
|
||||
} else if (os_vers == 6001) {
|
||||
if (osvi.wProductType == VER_NT_WORKSTATION) {
|
||||
st->print(" Windows 7");
|
||||
} else {
|
||||
// Unrecognized windows, print out its major and minor versions
|
||||
st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion);
|
||||
}
|
||||
if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
|
||||
st->print(" , 64 bit");
|
||||
} else { // future os
|
||||
// Unrecognized windows, print out its major and minor versions
|
||||
st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion);
|
||||
if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
|
||||
st->print(" , 64 bit");
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1579,16 +1595,17 @@ void os::print_memory_info(outputStream* st) {
|
||||
st->print("Memory:");
|
||||
st->print(" %dk page", os::vm_page_size()>>10);
|
||||
|
||||
// FIXME: GlobalMemoryStatus() may return incorrect value if total memory
|
||||
// is larger than 4GB
|
||||
MEMORYSTATUS ms;
|
||||
GlobalMemoryStatus(&ms);
|
||||
// Use GlobalMemoryStatusEx() because GlobalMemoryStatus() may return incorrect
|
||||
// value if total memory is larger than 4GB
|
||||
MEMORYSTATUSEX ms;
|
||||
ms.dwLength = sizeof(ms);
|
||||
GlobalMemoryStatusEx(&ms);
|
||||
|
||||
st->print(", physical %uk", os::physical_memory() >> 10);
|
||||
st->print("(%uk free)", os::available_memory() >> 10);
|
||||
|
||||
st->print(", swap %uk", ms.dwTotalPageFile >> 10);
|
||||
st->print("(%uk free)", ms.dwAvailPageFile >> 10);
|
||||
st->print(", swap %uk", ms.ullTotalPageFile >> 10);
|
||||
st->print("(%uk free)", ms.ullAvailPageFile >> 10);
|
||||
st->cr();
|
||||
}
|
||||
|
||||
@ -3135,11 +3152,13 @@ void os::win32::initialize_system_info() {
|
||||
_processor_level = si.wProcessorLevel;
|
||||
_processor_count = si.dwNumberOfProcessors;
|
||||
|
||||
MEMORYSTATUS ms;
|
||||
MEMORYSTATUSEX ms;
|
||||
ms.dwLength = sizeof(ms);
|
||||
|
||||
// also returns dwAvailPhys (free physical memory bytes), dwTotalVirtual, dwAvailVirtual,
|
||||
// dwMemoryLoad (% of memory in use)
|
||||
GlobalMemoryStatus(&ms);
|
||||
_physical_memory = ms.dwTotalPhys;
|
||||
GlobalMemoryStatusEx(&ms);
|
||||
_physical_memory = ms.ullTotalPhys;
|
||||
|
||||
OSVERSIONINFO oi;
|
||||
oi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -46,6 +46,8 @@ inline void Atomic::dec (volatile jint* dest) { (void)add (-1, dest);
|
||||
inline void Atomic::dec_ptr(volatile intptr_t* dest) { (void)add_ptr(-1, dest); }
|
||||
inline void Atomic::dec_ptr(volatile void* dest) { (void)add_ptr(-1, dest); }
|
||||
|
||||
inline jlong Atomic::load(volatile jlong* src) { return *src; }
|
||||
|
||||
#ifdef _GNU_SOURCE
|
||||
|
||||
inline jint Atomic::add (jint add_value, volatile jint* dest) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -99,6 +99,8 @@ inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void*
|
||||
return (void*)_Atomic_cmpxchg_long((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value, (int) os::is_MP());
|
||||
}
|
||||
|
||||
inline jlong Atomic::load(volatile jlong* src) { return *src; }
|
||||
|
||||
#else // !AMD64
|
||||
|
||||
inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) {
|
||||
@ -131,6 +133,15 @@ inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t*
|
||||
inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value) {
|
||||
return (void*)cmpxchg((jint)exchange_value, (volatile jint*)dest, (jint)compare_value);
|
||||
}
|
||||
|
||||
extern "C" void _Atomic_load_long(volatile jlong* src, volatile jlong* dst);
|
||||
|
||||
inline jlong Atomic::load(volatile jlong* src) {
|
||||
volatile jlong dest;
|
||||
_Atomic_load_long(src, &dest);
|
||||
return dest;
|
||||
}
|
||||
|
||||
#endif // AMD64
|
||||
|
||||
#ifdef _GNU_SOURCE
|
||||
|
@ -97,6 +97,15 @@
|
||||
popl %ebx
|
||||
.end
|
||||
|
||||
// Support for void Atomic::load(volatile jlong* src, volatile jlong* dest).
|
||||
.inline _Atomic_load_long,2
|
||||
movl 0(%esp), %eax // src
|
||||
fildll (%eax)
|
||||
movl 4(%esp), %eax // dest
|
||||
fistpll (%eax)
|
||||
.end
|
||||
|
||||
|
||||
// Support for OrderAccess::acquire()
|
||||
.inline _OrderAccess_acquire,0
|
||||
movl 0(%esp), %eax
|
||||
|
@ -1031,7 +1031,8 @@ void ArchDesc::initBaseOpTypes() {
|
||||
//---------------------------addSUNcopyright-------------------------------
|
||||
// output SUN copyright info
|
||||
void ArchDesc::addSunCopyright(char* legal, int size, FILE *fp) {
|
||||
fwrite(legal, size, 1, fp);
|
||||
size_t count = fwrite(legal, 1, size, fp);
|
||||
assert(count == (size_t) size, "copyright info truncated");
|
||||
fprintf(fp,"\n");
|
||||
fprintf(fp,"// Machine Generated File. Do Not Edit!\n");
|
||||
fprintf(fp,"\n");
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -208,6 +208,15 @@ int IRScope::top_scope_bci() const {
|
||||
return scope->caller_bci();
|
||||
}
|
||||
|
||||
bool IRScopeDebugInfo::should_reexecute() {
|
||||
ciMethod* cur_method = scope()->method();
|
||||
int cur_bci = bci();
|
||||
if (cur_method != NULL && cur_bci != SynchronizationEntryBCI) {
|
||||
Bytecodes::Code code = cur_method->java_code_at_bci(cur_bci);
|
||||
return Interpreter::bytecode_should_reexecute(code);
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Implementation of CodeEmitInfo
|
||||
@ -253,7 +262,7 @@ CodeEmitInfo::CodeEmitInfo(CodeEmitInfo* info, bool lock_stack_only)
|
||||
void CodeEmitInfo::record_debug_info(DebugInformationRecorder* recorder, int pc_offset) {
|
||||
// record the safepoint before recording the debug info for enclosing scopes
|
||||
recorder->add_safepoint(pc_offset, _oop_map->deep_copy());
|
||||
_scope_debug_info->record_debug_info(recorder, pc_offset);
|
||||
_scope_debug_info->record_debug_info(recorder, pc_offset, true/*topmost*/);
|
||||
recorder->end_safepoint(pc_offset);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -239,15 +239,20 @@ class IRScopeDebugInfo: public CompilationResourceObj {
|
||||
GrowableArray<MonitorValue*>* monitors() { return _monitors; }
|
||||
IRScopeDebugInfo* caller() { return _caller; }
|
||||
|
||||
void record_debug_info(DebugInformationRecorder* recorder, int pc_offset) {
|
||||
//Whether we should reexecute this bytecode for deopt
|
||||
bool should_reexecute();
|
||||
|
||||
void record_debug_info(DebugInformationRecorder* recorder, int pc_offset, bool topmost) {
|
||||
if (caller() != NULL) {
|
||||
// Order is significant: Must record caller first.
|
||||
caller()->record_debug_info(recorder, pc_offset);
|
||||
caller()->record_debug_info(recorder, pc_offset, false/*topmost*/);
|
||||
}
|
||||
DebugToken* locvals = recorder->create_scope_values(locals());
|
||||
DebugToken* expvals = recorder->create_scope_values(expressions());
|
||||
DebugToken* monvals = recorder->create_monitor_values(monitors());
|
||||
recorder->describe_scope(pc_offset, scope()->method(), bci(), locvals, expvals, monvals);
|
||||
// reexecute allowed only for the topmost frame
|
||||
bool reexecute = topmost ? should_reexecute() : false;
|
||||
recorder->describe_scope(pc_offset, scope()->method(), bci(), reexecute, locvals, expvals, monvals);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -567,8 +567,6 @@ void LIR_OpVisitState::visit(LIR_Op* op) {
|
||||
case lir_rem:
|
||||
case lir_sqrt:
|
||||
case lir_abs:
|
||||
case lir_log:
|
||||
case lir_log10:
|
||||
case lir_logic_and:
|
||||
case lir_logic_or:
|
||||
case lir_logic_xor:
|
||||
@ -644,13 +642,16 @@ void LIR_OpVisitState::visit(LIR_Op* op) {
|
||||
|
||||
case lir_tan:
|
||||
case lir_sin:
|
||||
case lir_cos: {
|
||||
case lir_cos:
|
||||
case lir_log:
|
||||
case lir_log10: {
|
||||
assert(op->as_Op2() != NULL, "must be");
|
||||
LIR_Op2* op2 = (LIR_Op2*)op;
|
||||
|
||||
// sin and cos need two temporary fpu stack slots, so register
|
||||
// two temp operands. Register input operand as temp to
|
||||
// guarantee that they do not overlap
|
||||
// On x86 tan/sin/cos need two temporary fpu stack slots and
|
||||
// log/log10 need one so handle opr2 and tmp as temp inputs.
|
||||
// Register input operand as temp to guarantee that it doesn't
|
||||
// overlap with the input.
|
||||
assert(op2->_info == NULL, "not used");
|
||||
assert(op2->_opr1->is_valid(), "used");
|
||||
do_input(op2->_opr1); do_temp(op2->_opr1);
|
||||
|
@ -1840,8 +1840,8 @@ class LIR_List: public CompilationResourceObj {
|
||||
|
||||
void abs (LIR_Opr from, LIR_Opr to, LIR_Opr tmp) { append(new LIR_Op2(lir_abs , from, tmp, to)); }
|
||||
void sqrt(LIR_Opr from, LIR_Opr to, LIR_Opr tmp) { append(new LIR_Op2(lir_sqrt, from, tmp, to)); }
|
||||
void log (LIR_Opr from, LIR_Opr to, LIR_Opr tmp) { append(new LIR_Op2(lir_log, from, tmp, to)); }
|
||||
void log10 (LIR_Opr from, LIR_Opr to, LIR_Opr tmp) { append(new LIR_Op2(lir_log10, from, tmp, to)); }
|
||||
void log (LIR_Opr from, LIR_Opr to, LIR_Opr tmp) { append(new LIR_Op2(lir_log, from, LIR_OprFact::illegalOpr, to, tmp)); }
|
||||
void log10 (LIR_Opr from, LIR_Opr to, LIR_Opr tmp) { append(new LIR_Op2(lir_log10, from, LIR_OprFact::illegalOpr, to, tmp)); }
|
||||
void sin (LIR_Opr from, LIR_Opr to, LIR_Opr tmp1, LIR_Opr tmp2) { append(new LIR_Op2(lir_sin , from, tmp1, to, tmp2)); }
|
||||
void cos (LIR_Opr from, LIR_Opr to, LIR_Opr tmp1, LIR_Opr tmp2) { append(new LIR_Op2(lir_cos , from, tmp1, to, tmp2)); }
|
||||
void tan (LIR_Opr from, LIR_Opr to, LIR_Opr tmp1, LIR_Opr tmp2) { append(new LIR_Op2(lir_tan , from, tmp1, to, tmp2)); }
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -379,7 +379,8 @@ void LIR_Assembler::record_non_safepoint_debug_info() {
|
||||
ValueStack* s = nth_oldest(vstack, n, s_bci);
|
||||
if (s == NULL) break;
|
||||
IRScope* scope = s->scope();
|
||||
debug_info->describe_scope(pc_offset, scope->method(), s_bci);
|
||||
//Always pass false for reexecute since these ScopeDescs are never used for deopt
|
||||
debug_info->describe_scope(pc_offset, scope->method(), s_bci, false/*reexecute*/);
|
||||
}
|
||||
|
||||
debug_info->end_non_safepoint(pc_offset);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -219,24 +219,27 @@ ciObject* ciObjectFactory::get(oop key) {
|
||||
ASSERT_IN_VM;
|
||||
|
||||
#ifdef ASSERT
|
||||
oop last = NULL;
|
||||
for (int j = 0; j< _ci_objects->length(); j++) {
|
||||
oop o = _ci_objects->at(j)->get_oop();
|
||||
assert(last < o, "out of order");
|
||||
last = o;
|
||||
if (CIObjectFactoryVerify) {
|
||||
oop last = NULL;
|
||||
for (int j = 0; j< _ci_objects->length(); j++) {
|
||||
oop o = _ci_objects->at(j)->get_oop();
|
||||
assert(last < o, "out of order");
|
||||
last = o;
|
||||
}
|
||||
}
|
||||
#endif // ASSERT
|
||||
int len = _ci_objects->length();
|
||||
int index = find(key, _ci_objects);
|
||||
#ifdef ASSERT
|
||||
for (int i=0; i<_ci_objects->length(); i++) {
|
||||
if (_ci_objects->at(i)->get_oop() == key) {
|
||||
assert(index == i, " bad lookup");
|
||||
if (CIObjectFactoryVerify) {
|
||||
for (int i=0; i<_ci_objects->length(); i++) {
|
||||
if (_ci_objects->at(i)->get_oop() == key) {
|
||||
assert(index == i, " bad lookup");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!is_found_at(index, key, _ci_objects)) {
|
||||
|
||||
// Check in the non-perm area before putting it in the list.
|
||||
NonPermObject* &bucket = find_non_perm(key);
|
||||
if (bucket != NULL) {
|
||||
@ -539,11 +542,13 @@ void ciObjectFactory::insert(int index, ciObject* obj, GrowableArray<ciObject*>*
|
||||
objects->at_put(index, obj);
|
||||
}
|
||||
#ifdef ASSERT
|
||||
oop last = NULL;
|
||||
for (int j = 0; j< objects->length(); j++) {
|
||||
oop o = objects->at(j)->get_oop();
|
||||
assert(last < o, "out of order");
|
||||
last = o;
|
||||
if (CIObjectFactoryVerify) {
|
||||
oop last = NULL;
|
||||
for (int j = 0; j< objects->length(); j++) {
|
||||
oop o = objects->at(j)->get_oop();
|
||||
assert(last < o, "out of order");
|
||||
last = o;
|
||||
}
|
||||
}
|
||||
#endif // ASSERT
|
||||
}
|
||||
|
@ -547,7 +547,6 @@ objArrayHandle ClassFileParser::parse_interfaces(constantPoolHandle cp,
|
||||
int length,
|
||||
Handle class_loader,
|
||||
Handle protection_domain,
|
||||
PerfTraceTime* vmtimer,
|
||||
symbolHandle class_name,
|
||||
TRAPS) {
|
||||
ClassFileStream* cfs = stream();
|
||||
@ -575,13 +574,11 @@ objArrayHandle ClassFileParser::parse_interfaces(constantPoolHandle cp,
|
||||
guarantee_property(unresolved_klass->byte_at(0) != JVM_SIGNATURE_ARRAY,
|
||||
"Bad interface name in class file %s", CHECK_(nullHandle));
|
||||
|
||||
vmtimer->suspend(); // do not count recursive loading twice
|
||||
// Call resolve_super so classcircularity is checked
|
||||
klassOop k = SystemDictionary::resolve_super_or_fail(class_name,
|
||||
unresolved_klass, class_loader, protection_domain,
|
||||
false, CHECK_(nullHandle));
|
||||
interf = KlassHandle(THREAD, k);
|
||||
vmtimer->resume();
|
||||
|
||||
if (LinkWellKnownClasses) // my super type is well known to me
|
||||
cp->klass_at_put(interface_index, interf()); // eagerly resolve
|
||||
@ -769,16 +766,16 @@ enum FieldAllocationType {
|
||||
|
||||
|
||||
struct FieldAllocationCount {
|
||||
int static_oop_count;
|
||||
int static_byte_count;
|
||||
int static_short_count;
|
||||
int static_word_count;
|
||||
int static_double_count;
|
||||
int nonstatic_oop_count;
|
||||
int nonstatic_byte_count;
|
||||
int nonstatic_short_count;
|
||||
int nonstatic_word_count;
|
||||
int nonstatic_double_count;
|
||||
unsigned int static_oop_count;
|
||||
unsigned int static_byte_count;
|
||||
unsigned int static_short_count;
|
||||
unsigned int static_word_count;
|
||||
unsigned int static_double_count;
|
||||
unsigned int nonstatic_oop_count;
|
||||
unsigned int nonstatic_byte_count;
|
||||
unsigned int nonstatic_short_count;
|
||||
unsigned int nonstatic_word_count;
|
||||
unsigned int nonstatic_double_count;
|
||||
};
|
||||
|
||||
typeArrayHandle ClassFileParser::parse_fields(constantPoolHandle cp, bool is_interface,
|
||||
@ -2550,6 +2547,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
|
||||
KlassHandle host_klass,
|
||||
GrowableArray<Handle>* cp_patches,
|
||||
symbolHandle& parsed_name,
|
||||
bool verify,
|
||||
TRAPS) {
|
||||
// So that JVMTI can cache class file in the state before retransformable agents
|
||||
// have modified it
|
||||
@ -2558,7 +2556,15 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
|
||||
|
||||
ClassFileStream* cfs = stream();
|
||||
// Timing
|
||||
PerfTraceTime vmtimer(ClassLoader::perf_accumulated_time());
|
||||
assert(THREAD->is_Java_thread(), "must be a JavaThread");
|
||||
JavaThread* jt = (JavaThread*) THREAD;
|
||||
|
||||
PerfClassTraceTime ctimer(ClassLoader::perf_class_parse_time(),
|
||||
ClassLoader::perf_class_parse_selftime(),
|
||||
NULL,
|
||||
jt->get_thread_stat()->perf_recursion_counts_addr(),
|
||||
jt->get_thread_stat()->perf_timers_addr(),
|
||||
PerfClassTraceTime::PARSE_CLASS);
|
||||
|
||||
_has_finalizer = _has_empty_finalizer = _has_vanilla_constructor = false;
|
||||
|
||||
@ -2586,7 +2592,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
|
||||
instanceKlassHandle nullHandle;
|
||||
|
||||
// Figure out whether we can skip format checking (matching classic VM behavior)
|
||||
_need_verify = Verifier::should_verify_for(class_loader());
|
||||
_need_verify = Verifier::should_verify_for(class_loader(), verify);
|
||||
|
||||
// Set the verify flag in stream
|
||||
cfs->set_verify(_need_verify);
|
||||
@ -2738,7 +2744,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
|
||||
if (itfs_len == 0) {
|
||||
local_interfaces = objArrayHandle(THREAD, Universe::the_empty_system_obj_array());
|
||||
} else {
|
||||
local_interfaces = parse_interfaces(cp, itfs_len, class_loader, protection_domain, &vmtimer, _class_name, CHECK_(nullHandle));
|
||||
local_interfaces = parse_interfaces(cp, itfs_len, class_loader, protection_domain, _class_name, CHECK_(nullHandle));
|
||||
}
|
||||
|
||||
// Fields (offsets are filled in later)
|
||||
@ -2782,6 +2788,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
|
||||
protection_domain,
|
||||
true,
|
||||
CHECK_(nullHandle));
|
||||
|
||||
KlassHandle kh (THREAD, k);
|
||||
super_klass = instanceKlassHandle(THREAD, kh());
|
||||
if (LinkWellKnownClasses) // my super class is well known to me
|
||||
@ -2902,11 +2909,11 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
|
||||
}
|
||||
// end of "discovered" field compactibility fix
|
||||
|
||||
int nonstatic_double_count = fac.nonstatic_double_count;
|
||||
int nonstatic_word_count = fac.nonstatic_word_count;
|
||||
int nonstatic_short_count = fac.nonstatic_short_count;
|
||||
int nonstatic_byte_count = fac.nonstatic_byte_count;
|
||||
int nonstatic_oop_count = fac.nonstatic_oop_count;
|
||||
unsigned int nonstatic_double_count = fac.nonstatic_double_count;
|
||||
unsigned int nonstatic_word_count = fac.nonstatic_word_count;
|
||||
unsigned int nonstatic_short_count = fac.nonstatic_short_count;
|
||||
unsigned int nonstatic_byte_count = fac.nonstatic_byte_count;
|
||||
unsigned int nonstatic_oop_count = fac.nonstatic_oop_count;
|
||||
|
||||
bool super_has_nonstatic_fields =
|
||||
(super_klass() != NULL && super_klass->has_nonstatic_fields());
|
||||
@ -2916,26 +2923,26 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
|
||||
nonstatic_oop_count) != 0);
|
||||
|
||||
|
||||
// Prepare list of oops for oop maps generation.
|
||||
u2* nonstatic_oop_offsets;
|
||||
u2* nonstatic_oop_length;
|
||||
int nonstatic_oop_map_count = 0;
|
||||
// Prepare list of oops for oop map generation.
|
||||
int* nonstatic_oop_offsets;
|
||||
unsigned int* nonstatic_oop_counts;
|
||||
unsigned int nonstatic_oop_map_count = 0;
|
||||
|
||||
nonstatic_oop_offsets = NEW_RESOURCE_ARRAY_IN_THREAD(
|
||||
THREAD, u2, nonstatic_oop_count+1);
|
||||
nonstatic_oop_length = NEW_RESOURCE_ARRAY_IN_THREAD(
|
||||
THREAD, u2, nonstatic_oop_count+1);
|
||||
THREAD, int, nonstatic_oop_count + 1);
|
||||
nonstatic_oop_counts = NEW_RESOURCE_ARRAY_IN_THREAD(
|
||||
THREAD, unsigned int, nonstatic_oop_count + 1);
|
||||
|
||||
// Add fake fields for java.lang.Class instances (also see above).
|
||||
// FieldsAllocationStyle and CompactFields values will be reset to default.
|
||||
if(class_name() == vmSymbols::java_lang_Class() && class_loader.is_null()) {
|
||||
java_lang_Class_fix_post(&next_nonstatic_field_offset);
|
||||
nonstatic_oop_offsets[0] = (u2)first_nonstatic_field_offset;
|
||||
int fake_oop_count = (( next_nonstatic_field_offset -
|
||||
first_nonstatic_field_offset ) / heapOopSize);
|
||||
nonstatic_oop_length [0] = (u2)fake_oop_count;
|
||||
nonstatic_oop_map_count = 1;
|
||||
nonstatic_oop_count -= fake_oop_count;
|
||||
nonstatic_oop_offsets[0] = first_nonstatic_field_offset;
|
||||
const uint fake_oop_count = (next_nonstatic_field_offset -
|
||||
first_nonstatic_field_offset) / heapOopSize;
|
||||
nonstatic_oop_counts[0] = fake_oop_count;
|
||||
nonstatic_oop_map_count = 1;
|
||||
nonstatic_oop_count -= fake_oop_count;
|
||||
first_nonstatic_oop_offset = first_nonstatic_field_offset;
|
||||
} else {
|
||||
first_nonstatic_oop_offset = 0; // will be set for first oop field
|
||||
@ -3113,13 +3120,15 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
|
||||
// Update oop maps
|
||||
if( nonstatic_oop_map_count > 0 &&
|
||||
nonstatic_oop_offsets[nonstatic_oop_map_count - 1] ==
|
||||
(u2)(real_offset - nonstatic_oop_length[nonstatic_oop_map_count - 1] * heapOopSize) ) {
|
||||
real_offset -
|
||||
int(nonstatic_oop_counts[nonstatic_oop_map_count - 1]) *
|
||||
heapOopSize ) {
|
||||
// Extend current oop map
|
||||
nonstatic_oop_length[nonstatic_oop_map_count - 1] += 1;
|
||||
nonstatic_oop_counts[nonstatic_oop_map_count - 1] += 1;
|
||||
} else {
|
||||
// Create new oop map
|
||||
nonstatic_oop_offsets[nonstatic_oop_map_count] = (u2)real_offset;
|
||||
nonstatic_oop_length [nonstatic_oop_map_count] = 1;
|
||||
nonstatic_oop_offsets[nonstatic_oop_map_count] = real_offset;
|
||||
nonstatic_oop_counts [nonstatic_oop_map_count] = 1;
|
||||
nonstatic_oop_map_count += 1;
|
||||
if( first_nonstatic_oop_offset == 0 ) { // Undefined
|
||||
first_nonstatic_oop_offset = real_offset;
|
||||
@ -3176,8 +3185,10 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
|
||||
|
||||
assert(instance_size == align_object_size(align_size_up((instanceOopDesc::base_offset_in_bytes() + nonstatic_field_size*heapOopSize), wordSize) / wordSize), "consistent layout helper value");
|
||||
|
||||
// Size of non-static oop map blocks (in words) allocated at end of klass
|
||||
int nonstatic_oop_map_size = compute_oop_map_size(super_klass, nonstatic_oop_map_count, first_nonstatic_oop_offset);
|
||||
// Number of non-static oop map blocks allocated at end of klass.
|
||||
const unsigned int total_oop_map_count =
|
||||
compute_oop_map_count(super_klass, nonstatic_oop_map_count,
|
||||
first_nonstatic_oop_offset);
|
||||
|
||||
// Compute reference type
|
||||
ReferenceType rt;
|
||||
@ -3188,17 +3199,19 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
|
||||
}
|
||||
|
||||
// We can now create the basic klassOop for this klass
|
||||
klassOop ik = oopFactory::new_instanceKlass(
|
||||
vtable_size, itable_size,
|
||||
static_field_size, nonstatic_oop_map_size,
|
||||
rt, CHECK_(nullHandle));
|
||||
klassOop ik = oopFactory::new_instanceKlass(vtable_size, itable_size,
|
||||
static_field_size,
|
||||
total_oop_map_count,
|
||||
rt, CHECK_(nullHandle));
|
||||
instanceKlassHandle this_klass (THREAD, ik);
|
||||
|
||||
assert(this_klass->static_field_size() == static_field_size &&
|
||||
this_klass->nonstatic_oop_map_size() == nonstatic_oop_map_size, "sanity check");
|
||||
assert(this_klass->static_field_size() == static_field_size, "sanity");
|
||||
assert(this_klass->nonstatic_oop_map_count() == total_oop_map_count,
|
||||
"sanity");
|
||||
|
||||
// Fill in information already parsed
|
||||
this_klass->set_access_flags(access_flags);
|
||||
this_klass->set_should_verify_class(verify);
|
||||
jint lh = Klass::instance_layout_helper(instance_size, false);
|
||||
this_klass->set_layout_helper(lh);
|
||||
assert(this_klass->oop_is_instance(), "layout is correct");
|
||||
@ -3218,6 +3231,12 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
|
||||
this_klass->set_has_final_method();
|
||||
}
|
||||
this_klass->set_method_ordering(method_ordering());
|
||||
// The instanceKlass::_methods_jmethod_ids cache and the
|
||||
// instanceKlass::_methods_cached_itable_indices cache are
|
||||
// both managed on the assumption that the initial cache
|
||||
// size is equal to the number of methods in the class. If
|
||||
// that changes, then instanceKlass::idnum_can_increment()
|
||||
// has to be changed accordingly.
|
||||
this_klass->set_initial_method_idnum(methods->length());
|
||||
this_klass->set_name(cp->klass_name_at(this_class_index));
|
||||
if (LinkWellKnownClasses || is_anonymous()) // I am well known to myself
|
||||
@ -3276,7 +3295,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
|
||||
klassItable::setup_itable_offset_table(this_klass);
|
||||
|
||||
// Do final class setup
|
||||
fill_oop_maps(this_klass, nonstatic_oop_map_count, nonstatic_oop_offsets, nonstatic_oop_length);
|
||||
fill_oop_maps(this_klass, nonstatic_oop_map_count, nonstatic_oop_offsets, nonstatic_oop_counts);
|
||||
|
||||
set_precomputed_flags(this_klass);
|
||||
|
||||
@ -3369,66 +3388,73 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
|
||||
}
|
||||
|
||||
|
||||
int ClassFileParser::compute_oop_map_size(instanceKlassHandle super, int nonstatic_oop_map_count, int first_nonstatic_oop_offset) {
|
||||
int map_size = super.is_null() ? 0 : super->nonstatic_oop_map_size();
|
||||
unsigned int
|
||||
ClassFileParser::compute_oop_map_count(instanceKlassHandle super,
|
||||
unsigned int nonstatic_oop_map_count,
|
||||
int first_nonstatic_oop_offset) {
|
||||
unsigned int map_count =
|
||||
super.is_null() ? 0 : super->nonstatic_oop_map_count();
|
||||
if (nonstatic_oop_map_count > 0) {
|
||||
// We have oops to add to map
|
||||
if (map_size == 0) {
|
||||
map_size = nonstatic_oop_map_count;
|
||||
if (map_count == 0) {
|
||||
map_count = nonstatic_oop_map_count;
|
||||
} else {
|
||||
// Check whether we should add a new map block or whether the last one can be extended
|
||||
OopMapBlock* first_map = super->start_of_nonstatic_oop_maps();
|
||||
OopMapBlock* last_map = first_map + map_size - 1;
|
||||
// Check whether we should add a new map block or whether the last one can
|
||||
// be extended
|
||||
OopMapBlock* const first_map = super->start_of_nonstatic_oop_maps();
|
||||
OopMapBlock* const last_map = first_map + map_count - 1;
|
||||
|
||||
int next_offset = last_map->offset() + (last_map->length() * heapOopSize);
|
||||
int next_offset = last_map->offset() + last_map->count() * heapOopSize;
|
||||
if (next_offset == first_nonstatic_oop_offset) {
|
||||
// There is no gap bettwen superklass's last oop field and first
|
||||
// local oop field, merge maps.
|
||||
nonstatic_oop_map_count -= 1;
|
||||
} else {
|
||||
// Superklass didn't end with a oop field, add extra maps
|
||||
assert(next_offset<first_nonstatic_oop_offset, "just checking");
|
||||
assert(next_offset < first_nonstatic_oop_offset, "just checking");
|
||||
}
|
||||
map_size += nonstatic_oop_map_count;
|
||||
map_count += nonstatic_oop_map_count;
|
||||
}
|
||||
}
|
||||
return map_size;
|
||||
return map_count;
|
||||
}
|
||||
|
||||
|
||||
void ClassFileParser::fill_oop_maps(instanceKlassHandle k,
|
||||
int nonstatic_oop_map_count,
|
||||
u2* nonstatic_oop_offsets, u2* nonstatic_oop_length) {
|
||||
unsigned int nonstatic_oop_map_count,
|
||||
int* nonstatic_oop_offsets,
|
||||
unsigned int* nonstatic_oop_counts) {
|
||||
OopMapBlock* this_oop_map = k->start_of_nonstatic_oop_maps();
|
||||
OopMapBlock* last_oop_map = this_oop_map + k->nonstatic_oop_map_size();
|
||||
instanceKlass* super = k->superklass();
|
||||
if (super != NULL) {
|
||||
int super_oop_map_size = super->nonstatic_oop_map_size();
|
||||
OopMapBlock* super_oop_map = super->start_of_nonstatic_oop_maps();
|
||||
const instanceKlass* const super = k->superklass();
|
||||
const unsigned int super_count = super ? super->nonstatic_oop_map_count() : 0;
|
||||
if (super_count > 0) {
|
||||
// Copy maps from superklass
|
||||
while (super_oop_map_size-- > 0) {
|
||||
OopMapBlock* super_oop_map = super->start_of_nonstatic_oop_maps();
|
||||
for (unsigned int i = 0; i < super_count; ++i) {
|
||||
*this_oop_map++ = *super_oop_map++;
|
||||
}
|
||||
}
|
||||
|
||||
if (nonstatic_oop_map_count > 0) {
|
||||
if (this_oop_map + nonstatic_oop_map_count > last_oop_map) {
|
||||
// Calculated in compute_oop_map_size() number of oop maps is less then
|
||||
// collected oop maps since there is no gap between superklass's last oop
|
||||
// field and first local oop field. Extend the last oop map copied
|
||||
if (super_count + nonstatic_oop_map_count > k->nonstatic_oop_map_count()) {
|
||||
// The counts differ because there is no gap between superklass's last oop
|
||||
// field and the first local oop field. Extend the last oop map copied
|
||||
// from the superklass instead of creating new one.
|
||||
nonstatic_oop_map_count--;
|
||||
nonstatic_oop_offsets++;
|
||||
this_oop_map--;
|
||||
this_oop_map->set_length(this_oop_map->length() + *nonstatic_oop_length++);
|
||||
this_oop_map->set_count(this_oop_map->count() + *nonstatic_oop_counts++);
|
||||
this_oop_map++;
|
||||
}
|
||||
assert((this_oop_map + nonstatic_oop_map_count) == last_oop_map, "just checking");
|
||||
|
||||
// Add new map blocks, fill them
|
||||
while (nonstatic_oop_map_count-- > 0) {
|
||||
this_oop_map->set_offset(*nonstatic_oop_offsets++);
|
||||
this_oop_map->set_length(*nonstatic_oop_length++);
|
||||
this_oop_map->set_count(*nonstatic_oop_counts++);
|
||||
this_oop_map++;
|
||||
}
|
||||
assert(k->start_of_nonstatic_oop_maps() + k->nonstatic_oop_map_count() ==
|
||||
this_oop_map, "sanity");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,6 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
||||
int length,
|
||||
Handle class_loader,
|
||||
Handle protection_domain,
|
||||
PerfTraceTime* vmtimer,
|
||||
symbolHandle class_name,
|
||||
TRAPS);
|
||||
|
||||
@ -126,10 +125,13 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
||||
int runtime_invisible_annotations_length, TRAPS);
|
||||
|
||||
// Final setup
|
||||
int compute_oop_map_size(instanceKlassHandle super, int nonstatic_oop_count,
|
||||
int first_nonstatic_oop_offset);
|
||||
void fill_oop_maps(instanceKlassHandle k, int nonstatic_oop_map_count,
|
||||
u2* nonstatic_oop_offsets, u2* nonstatic_oop_length);
|
||||
unsigned int compute_oop_map_count(instanceKlassHandle super,
|
||||
unsigned int nonstatic_oop_count,
|
||||
int first_nonstatic_oop_offset);
|
||||
void fill_oop_maps(instanceKlassHandle k,
|
||||
unsigned int nonstatic_oop_map_count,
|
||||
int* nonstatic_oop_offsets,
|
||||
unsigned int* nonstatic_oop_counts);
|
||||
void set_precomputed_flags(instanceKlassHandle k);
|
||||
objArrayHandle compute_transitive_interfaces(instanceKlassHandle super,
|
||||
objArrayHandle local_ifs, TRAPS);
|
||||
@ -258,9 +260,10 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
||||
Handle class_loader,
|
||||
Handle protection_domain,
|
||||
symbolHandle& parsed_name,
|
||||
bool verify,
|
||||
TRAPS) {
|
||||
KlassHandle no_host_klass;
|
||||
return parseClassFile(name, class_loader, protection_domain, no_host_klass, NULL, parsed_name, THREAD);
|
||||
return parseClassFile(name, class_loader, protection_domain, no_host_klass, NULL, parsed_name, verify, THREAD);
|
||||
}
|
||||
instanceKlassHandle parseClassFile(symbolHandle name,
|
||||
Handle class_loader,
|
||||
@ -268,6 +271,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
||||
KlassHandle host_klass,
|
||||
GrowableArray<Handle>* cp_patches,
|
||||
symbolHandle& parsed_name,
|
||||
bool verify,
|
||||
TRAPS);
|
||||
|
||||
// Verifier checks
|
||||
|
@ -48,9 +48,26 @@ static canonicalize_fn_t CanonicalizeEntry = NULL;
|
||||
PerfCounter* ClassLoader::_perf_accumulated_time = NULL;
|
||||
PerfCounter* ClassLoader::_perf_classes_inited = NULL;
|
||||
PerfCounter* ClassLoader::_perf_class_init_time = NULL;
|
||||
PerfCounter* ClassLoader::_perf_class_init_selftime = NULL;
|
||||
PerfCounter* ClassLoader::_perf_classes_verified = NULL;
|
||||
PerfCounter* ClassLoader::_perf_class_verify_time = NULL;
|
||||
PerfCounter* ClassLoader::_perf_class_verify_selftime = NULL;
|
||||
PerfCounter* ClassLoader::_perf_classes_linked = NULL;
|
||||
PerfCounter* ClassLoader::_perf_class_link_time = NULL;
|
||||
PerfCounter* ClassLoader::_perf_class_link_selftime = NULL;
|
||||
PerfCounter* ClassLoader::_perf_class_parse_time = NULL;
|
||||
PerfCounter* ClassLoader::_perf_class_parse_selftime = NULL;
|
||||
PerfCounter* ClassLoader::_perf_sys_class_lookup_time = NULL;
|
||||
PerfCounter* ClassLoader::_perf_shared_classload_time = NULL;
|
||||
PerfCounter* ClassLoader::_perf_sys_classload_time = NULL;
|
||||
PerfCounter* ClassLoader::_perf_app_classload_time = NULL;
|
||||
PerfCounter* ClassLoader::_perf_app_classload_selftime = NULL;
|
||||
PerfCounter* ClassLoader::_perf_app_classload_count = NULL;
|
||||
PerfCounter* ClassLoader::_perf_define_appclasses = NULL;
|
||||
PerfCounter* ClassLoader::_perf_define_appclass_time = NULL;
|
||||
PerfCounter* ClassLoader::_perf_define_appclass_selftime = NULL;
|
||||
PerfCounter* ClassLoader::_perf_app_classfile_bytes_read = NULL;
|
||||
PerfCounter* ClassLoader::_perf_sys_classfile_bytes_read = NULL;
|
||||
PerfCounter* ClassLoader::_sync_systemLoaderLockContentionRate = NULL;
|
||||
PerfCounter* ClassLoader::_sync_nonSystemLoaderLockContentionRate = NULL;
|
||||
PerfCounter* ClassLoader::_sync_JVMFindLoadedClassLockFreeCounter = NULL;
|
||||
@ -152,6 +169,9 @@ ClassFileStream* ClassPathDirEntry::open_stream(const char* name) {
|
||||
hpi::close(file_handle);
|
||||
// construct ClassFileStream
|
||||
if (num_read == (size_t)st.st_size) {
|
||||
if (UsePerfData) {
|
||||
ClassLoader::perf_sys_classfile_bytes_read()->inc(num_read);
|
||||
}
|
||||
return new ClassFileStream(buffer, st.st_size, _dir); // Resource allocated
|
||||
}
|
||||
}
|
||||
@ -198,6 +218,9 @@ ClassFileStream* ClassPathZipEntry::open_stream(const char* name) {
|
||||
buffer = NEW_RESOURCE_ARRAY(u1, filesize);
|
||||
if (!(*ReadEntry)(_zip, entry, buffer, filename)) return NULL;
|
||||
}
|
||||
if (UsePerfData) {
|
||||
ClassLoader::perf_sys_classfile_bytes_read()->inc(filesize);
|
||||
}
|
||||
// return result
|
||||
return new ClassFileStream(buffer, filesize, _zip_name); // Resource allocated
|
||||
}
|
||||
@ -825,7 +848,9 @@ instanceKlassHandle ClassLoader::load_classfile(symbolHandle h_name, TRAPS) {
|
||||
ClassFileStream* stream = NULL;
|
||||
int classpath_index = 0;
|
||||
{
|
||||
PerfTraceTime vmtimer(perf_accumulated_time());
|
||||
PerfClassTraceTime vmtimer(perf_sys_class_lookup_time(),
|
||||
((JavaThread*) THREAD)->get_thread_stat()->perf_timers_addr(),
|
||||
PerfClassTraceTime::CLASS_LOAD);
|
||||
ClassPathEntry* e = _first_entry;
|
||||
while (e != NULL) {
|
||||
stream = e->open_stream(name);
|
||||
@ -849,6 +874,7 @@ instanceKlassHandle ClassLoader::load_classfile(symbolHandle h_name, TRAPS) {
|
||||
class_loader,
|
||||
protection_domain,
|
||||
parsed_name,
|
||||
false,
|
||||
CHECK_(h));
|
||||
|
||||
// add to package table
|
||||
@ -890,11 +916,29 @@ void ClassLoader::initialize() {
|
||||
// jvmstat performance counters
|
||||
NEWPERFTICKCOUNTER(_perf_accumulated_time, SUN_CLS, "time");
|
||||
NEWPERFTICKCOUNTER(_perf_class_init_time, SUN_CLS, "classInitTime");
|
||||
NEWPERFTICKCOUNTER(_perf_class_init_selftime, SUN_CLS, "classInitTime.self");
|
||||
NEWPERFTICKCOUNTER(_perf_class_verify_time, SUN_CLS, "classVerifyTime");
|
||||
NEWPERFTICKCOUNTER(_perf_class_verify_selftime, SUN_CLS, "classVerifyTime.self");
|
||||
NEWPERFTICKCOUNTER(_perf_class_link_time, SUN_CLS, "classLinkedTime");
|
||||
|
||||
NEWPERFTICKCOUNTER(_perf_class_link_selftime, SUN_CLS, "classLinkedTime.self");
|
||||
NEWPERFEVENTCOUNTER(_perf_classes_inited, SUN_CLS, "initializedClasses");
|
||||
NEWPERFEVENTCOUNTER(_perf_classes_linked, SUN_CLS, "linkedClasses");
|
||||
NEWPERFEVENTCOUNTER(_perf_classes_verified, SUN_CLS, "verifiedClasses");
|
||||
|
||||
NEWPERFTICKCOUNTER(_perf_class_parse_time, SUN_CLS, "parseClassTime");
|
||||
NEWPERFTICKCOUNTER(_perf_class_parse_selftime, SUN_CLS, "parseClassTime.self");
|
||||
NEWPERFTICKCOUNTER(_perf_sys_class_lookup_time, SUN_CLS, "lookupSysClassTime");
|
||||
NEWPERFTICKCOUNTER(_perf_shared_classload_time, SUN_CLS, "sharedClassLoadTime");
|
||||
NEWPERFTICKCOUNTER(_perf_sys_classload_time, SUN_CLS, "sysClassLoadTime");
|
||||
NEWPERFTICKCOUNTER(_perf_app_classload_time, SUN_CLS, "appClassLoadTime");
|
||||
NEWPERFTICKCOUNTER(_perf_app_classload_selftime, SUN_CLS, "appClassLoadTime.self");
|
||||
NEWPERFEVENTCOUNTER(_perf_app_classload_count, SUN_CLS, "appClassLoadCount");
|
||||
NEWPERFTICKCOUNTER(_perf_define_appclasses, SUN_CLS, "defineAppClasses");
|
||||
NEWPERFTICKCOUNTER(_perf_define_appclass_time, SUN_CLS, "defineAppClassTime");
|
||||
NEWPERFTICKCOUNTER(_perf_define_appclass_selftime, SUN_CLS, "defineAppClassTime.self");
|
||||
NEWPERFBYTECOUNTER(_perf_app_classfile_bytes_read, SUN_CLS, "appClassBytes");
|
||||
NEWPERFBYTECOUNTER(_perf_sys_classfile_bytes_read, SUN_CLS, "sysClassBytes");
|
||||
|
||||
|
||||
// The following performance counters are added for measuring the impact
|
||||
// of the bug fix of 6365597. They are mainly focused on finding out
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -149,9 +149,26 @@ class ClassLoader: AllStatic {
|
||||
static PerfCounter* _perf_accumulated_time;
|
||||
static PerfCounter* _perf_classes_inited;
|
||||
static PerfCounter* _perf_class_init_time;
|
||||
static PerfCounter* _perf_class_init_selftime;
|
||||
static PerfCounter* _perf_classes_verified;
|
||||
static PerfCounter* _perf_class_verify_time;
|
||||
static PerfCounter* _perf_class_verify_selftime;
|
||||
static PerfCounter* _perf_classes_linked;
|
||||
static PerfCounter* _perf_class_link_time;
|
||||
static PerfCounter* _perf_class_link_selftime;
|
||||
static PerfCounter* _perf_class_parse_time;
|
||||
static PerfCounter* _perf_class_parse_selftime;
|
||||
static PerfCounter* _perf_sys_class_lookup_time;
|
||||
static PerfCounter* _perf_shared_classload_time;
|
||||
static PerfCounter* _perf_sys_classload_time;
|
||||
static PerfCounter* _perf_app_classload_time;
|
||||
static PerfCounter* _perf_app_classload_selftime;
|
||||
static PerfCounter* _perf_app_classload_count;
|
||||
static PerfCounter* _perf_define_appclasses;
|
||||
static PerfCounter* _perf_define_appclass_time;
|
||||
static PerfCounter* _perf_define_appclass_selftime;
|
||||
static PerfCounter* _perf_app_classfile_bytes_read;
|
||||
static PerfCounter* _perf_sys_classfile_bytes_read;
|
||||
|
||||
static PerfCounter* _sync_systemLoaderLockContentionRate;
|
||||
static PerfCounter* _sync_nonSystemLoaderLockContentionRate;
|
||||
@ -196,12 +213,29 @@ class ClassLoader: AllStatic {
|
||||
static void print_bootclasspath();
|
||||
|
||||
// Timing
|
||||
static PerfCounter* perf_accumulated_time() { return _perf_accumulated_time; }
|
||||
static PerfCounter* perf_classes_inited() { return _perf_classes_inited; }
|
||||
static PerfCounter* perf_class_init_time() { return _perf_class_init_time; }
|
||||
static PerfCounter* perf_class_verify_time() { return _perf_class_verify_time; }
|
||||
static PerfCounter* perf_classes_linked() { return _perf_classes_linked; }
|
||||
static PerfCounter* perf_class_link_time() { return _perf_class_link_time; }
|
||||
static PerfCounter* perf_accumulated_time() { return _perf_accumulated_time; }
|
||||
static PerfCounter* perf_classes_inited() { return _perf_classes_inited; }
|
||||
static PerfCounter* perf_class_init_time() { return _perf_class_init_time; }
|
||||
static PerfCounter* perf_class_init_selftime() { return _perf_class_init_selftime; }
|
||||
static PerfCounter* perf_classes_verified() { return _perf_classes_verified; }
|
||||
static PerfCounter* perf_class_verify_time() { return _perf_class_verify_time; }
|
||||
static PerfCounter* perf_class_verify_selftime() { return _perf_class_verify_selftime; }
|
||||
static PerfCounter* perf_classes_linked() { return _perf_classes_linked; }
|
||||
static PerfCounter* perf_class_link_time() { return _perf_class_link_time; }
|
||||
static PerfCounter* perf_class_link_selftime() { return _perf_class_link_selftime; }
|
||||
static PerfCounter* perf_class_parse_time() { return _perf_class_parse_time; }
|
||||
static PerfCounter* perf_class_parse_selftime() { return _perf_class_parse_selftime; }
|
||||
static PerfCounter* perf_sys_class_lookup_time() { return _perf_sys_class_lookup_time; }
|
||||
static PerfCounter* perf_shared_classload_time() { return _perf_shared_classload_time; }
|
||||
static PerfCounter* perf_sys_classload_time() { return _perf_sys_classload_time; }
|
||||
static PerfCounter* perf_app_classload_time() { return _perf_app_classload_time; }
|
||||
static PerfCounter* perf_app_classload_selftime() { return _perf_app_classload_selftime; }
|
||||
static PerfCounter* perf_app_classload_count() { return _perf_app_classload_count; }
|
||||
static PerfCounter* perf_define_appclasses() { return _perf_define_appclasses; }
|
||||
static PerfCounter* perf_define_appclass_time() { return _perf_define_appclass_time; }
|
||||
static PerfCounter* perf_define_appclass_selftime() { return _perf_define_appclass_selftime; }
|
||||
static PerfCounter* perf_app_classfile_bytes_read() { return _perf_app_classfile_bytes_read; }
|
||||
static PerfCounter* perf_sys_classfile_bytes_read() { return _perf_sys_classfile_bytes_read; }
|
||||
|
||||
// Record how often system loader lock object is contended
|
||||
static PerfCounter* sync_systemLoaderLockContentionRate() {
|
||||
@ -307,3 +341,118 @@ class ClassLoader: AllStatic {
|
||||
static int compile_the_world_counter() { return _compile_the_world_counter; }
|
||||
#endif //PRODUCT
|
||||
};
|
||||
|
||||
// PerfClassTraceTime is used to measure time for class loading related events.
|
||||
// This class tracks cumulative time and exclusive time for specific event types.
|
||||
// During the execution of one event, other event types (e.g. class loading and
|
||||
// resolution) as well as recursive calls of the same event type could happen.
|
||||
// Only one elapsed timer (cumulative) and one thread-local self timer (exclusive)
|
||||
// (i.e. only one event type) are active at a time even multiple PerfClassTraceTime
|
||||
// instances have been created as multiple events are happening.
|
||||
class PerfClassTraceTime {
|
||||
public:
|
||||
enum {
|
||||
CLASS_LOAD = 0,
|
||||
PARSE_CLASS = 1,
|
||||
CLASS_LINK = 2,
|
||||
CLASS_VERIFY = 3,
|
||||
CLASS_CLINIT = 4,
|
||||
DEFINE_CLASS = 5,
|
||||
EVENT_TYPE_COUNT = 6
|
||||
};
|
||||
protected:
|
||||
// _t tracks time from initialization to destruction of this timer instance
|
||||
// including time for all other event types, and recursive calls of this type.
|
||||
// When a timer is called recursively, the elapsedTimer _t would not be used.
|
||||
elapsedTimer _t;
|
||||
PerfLongCounter* _timep;
|
||||
PerfLongCounter* _selftimep;
|
||||
PerfLongCounter* _eventp;
|
||||
// pointer to thread-local recursion counter and timer array
|
||||
// The thread_local timers track cumulative time for specific event types
|
||||
// exclusive of time for other event types, but including recursive calls
|
||||
// of the same type.
|
||||
int* _recursion_counters;
|
||||
elapsedTimer* _timers;
|
||||
int _event_type;
|
||||
int _prev_active_event;
|
||||
|
||||
public:
|
||||
|
||||
inline PerfClassTraceTime(PerfLongCounter* timep, /* counter incremented with inclusive time */
|
||||
PerfLongCounter* selftimep, /* counter incremented with exclusive time */
|
||||
PerfLongCounter* eventp, /* event counter */
|
||||
int* recursion_counters, /* thread-local recursion counter array */
|
||||
elapsedTimer* timers, /* thread-local timer array */
|
||||
int type /* event type */ ) :
|
||||
_timep(timep), _selftimep(selftimep), _eventp(eventp), _recursion_counters(recursion_counters), _timers(timers), _event_type(type) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
inline PerfClassTraceTime(PerfLongCounter* timep, /* counter incremented with inclusive time */
|
||||
elapsedTimer* timers, /* thread-local timer array */
|
||||
int type /* event type */ ) :
|
||||
_timep(timep), _selftimep(NULL), _eventp(NULL), _recursion_counters(NULL), _timers(timers), _event_type(type) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
void initialize() {
|
||||
if (!UsePerfData) return;
|
||||
|
||||
if (_eventp != NULL) {
|
||||
// increment the event counter
|
||||
_eventp->inc();
|
||||
}
|
||||
|
||||
// stop the current active thread-local timer to measure inclusive time
|
||||
_prev_active_event = -1;
|
||||
for (int i=0; i < EVENT_TYPE_COUNT; i++) {
|
||||
if (_timers[i].is_active()) {
|
||||
assert(_prev_active_event == -1, "should have only one active timer");
|
||||
_prev_active_event = i;
|
||||
_timers[i].stop();
|
||||
}
|
||||
}
|
||||
|
||||
if (_recursion_counters == NULL || (_recursion_counters[_event_type])++ == 0) {
|
||||
// start the inclusive timer if not recursively called
|
||||
_t.start();
|
||||
}
|
||||
|
||||
// start thread-local timer of the given event type
|
||||
if (!_timers[_event_type].is_active()) {
|
||||
_timers[_event_type].start();
|
||||
}
|
||||
}
|
||||
|
||||
inline void suspend() { _t.stop(); _timers[_event_type].stop(); }
|
||||
inline void resume() { _t.start(); _timers[_event_type].start(); }
|
||||
|
||||
~PerfClassTraceTime() {
|
||||
if (!UsePerfData) return;
|
||||
|
||||
// stop the thread-local timer as the event completes
|
||||
// and resume the thread-local timer of the event next on the stack
|
||||
_timers[_event_type].stop();
|
||||
jlong selftime = _timers[_event_type].ticks();
|
||||
|
||||
if (_prev_active_event >= 0) {
|
||||
_timers[_prev_active_event].start();
|
||||
}
|
||||
|
||||
if (_recursion_counters != NULL && --(_recursion_counters[_event_type]) > 0) return;
|
||||
|
||||
// increment the counters only on the leaf call
|
||||
_t.stop();
|
||||
_timep->inc(_t.ticks());
|
||||
if (_selftimep != NULL) {
|
||||
_selftimep->inc(selftime);
|
||||
}
|
||||
// add all class loading related event selftime to the accumulated time counter
|
||||
ClassLoader::perf_accumulated_time()->inc(selftime);
|
||||
|
||||
// reset the timer
|
||||
_timers[_event_type].reset();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -252,7 +252,7 @@ symbolHandle java_lang_String::as_symbol(Handle java_string, TRAPS) {
|
||||
typeArrayOop value = java_lang_String::value(obj);
|
||||
int offset = java_lang_String::offset(obj);
|
||||
int length = java_lang_String::length(obj);
|
||||
jchar* base = value->char_at_addr(offset);
|
||||
jchar* base = (length == 0) ? NULL : value->char_at_addr(offset);
|
||||
symbolOop sym = SymbolTable::lookup_unicode(base, length, THREAD);
|
||||
return symbolHandle(THREAD, sym);
|
||||
}
|
||||
@ -261,7 +261,7 @@ symbolOop java_lang_String::as_symbol_or_null(oop java_string) {
|
||||
typeArrayOop value = java_lang_String::value(java_string);
|
||||
int offset = java_lang_String::offset(java_string);
|
||||
int length = java_lang_String::length(java_string);
|
||||
jchar* base = value->char_at_addr(offset);
|
||||
jchar* base = (length == 0) ? NULL : value->char_at_addr(offset);
|
||||
return SymbolTable::probe_unicode(base, length);
|
||||
}
|
||||
|
||||
|
@ -970,6 +970,7 @@ klassOop SystemDictionary::parse_stream(symbolHandle class_name,
|
||||
host_klass,
|
||||
cp_patches,
|
||||
parsed_name,
|
||||
true,
|
||||
THREAD);
|
||||
|
||||
|
||||
@ -1025,6 +1026,7 @@ klassOop SystemDictionary::resolve_from_stream(symbolHandle class_name,
|
||||
Handle class_loader,
|
||||
Handle protection_domain,
|
||||
ClassFileStream* st,
|
||||
bool verify,
|
||||
TRAPS) {
|
||||
|
||||
// Classloaders that support parallelism, e.g. bootstrap classloader,
|
||||
@ -1055,6 +1057,7 @@ klassOop SystemDictionary::resolve_from_stream(symbolHandle class_name,
|
||||
class_loader,
|
||||
protection_domain,
|
||||
parsed_name,
|
||||
verify,
|
||||
THREAD);
|
||||
|
||||
const char* pkg = "java/";
|
||||
@ -1306,13 +1309,18 @@ static instanceKlassHandle download_and_retry_class_load(
|
||||
instanceKlassHandle SystemDictionary::load_instance_class(symbolHandle class_name, Handle class_loader, TRAPS) {
|
||||
instanceKlassHandle nh = instanceKlassHandle(); // null Handle
|
||||
if (class_loader.is_null()) {
|
||||
|
||||
// Search the shared system dictionary for classes preloaded into the
|
||||
// shared spaces.
|
||||
instanceKlassHandle k;
|
||||
k = load_shared_class(class_name, class_loader, THREAD);
|
||||
{
|
||||
PerfTraceTime vmtimer(ClassLoader::perf_shared_classload_time());
|
||||
k = load_shared_class(class_name, class_loader, THREAD);
|
||||
}
|
||||
|
||||
if (k.is_null()) {
|
||||
// Use VM class loader
|
||||
PerfTraceTime vmtimer(ClassLoader::perf_sys_classload_time());
|
||||
k = ClassLoader::load_classfile(class_name, CHECK_(nh));
|
||||
}
|
||||
|
||||
@ -1334,6 +1342,16 @@ instanceKlassHandle SystemDictionary::load_instance_class(symbolHandle class_nam
|
||||
// Use user specified class loader to load class. Call loadClass operation on class_loader.
|
||||
ResourceMark rm(THREAD);
|
||||
|
||||
assert(THREAD->is_Java_thread(), "must be a JavaThread");
|
||||
JavaThread* jt = (JavaThread*) THREAD;
|
||||
|
||||
PerfClassTraceTime vmtimer(ClassLoader::perf_app_classload_time(),
|
||||
ClassLoader::perf_app_classload_selftime(),
|
||||
ClassLoader::perf_app_classload_count(),
|
||||
jt->get_thread_stat()->perf_recursion_counts_addr(),
|
||||
jt->get_thread_stat()->perf_timers_addr(),
|
||||
PerfClassTraceTime::CLASS_LOAD);
|
||||
|
||||
Handle s = java_lang_String::create_from_symbol(class_name, CHECK_(nh));
|
||||
// Translate to external class name format, i.e., convert '/' chars to '.'
|
||||
Handle string = java_lang_String::externalize_classname(s, CHECK_(nh));
|
||||
|
@ -259,7 +259,9 @@ public:
|
||||
TRAPS);
|
||||
|
||||
// Resolve from stream (called by jni_DefineClass and JVM_DefineClass)
|
||||
static klassOop resolve_from_stream(symbolHandle class_name, Handle class_loader, Handle protection_domain, ClassFileStream* st, TRAPS);
|
||||
static klassOop resolve_from_stream(symbolHandle class_name, Handle class_loader,
|
||||
Handle protection_domain,
|
||||
ClassFileStream* st, bool verify, TRAPS);
|
||||
|
||||
// Lookup an already loaded class. If not found NULL is returned.
|
||||
static klassOop find(symbolHandle class_name, Handle class_loader, Handle protection_domain, TRAPS);
|
||||
|
@ -53,8 +53,8 @@ static void* verify_byte_codes_fn() {
|
||||
|
||||
// Methods in Verifier
|
||||
|
||||
bool Verifier::should_verify_for(oop class_loader) {
|
||||
return class_loader == NULL ?
|
||||
bool Verifier::should_verify_for(oop class_loader, bool should_verify_class) {
|
||||
return (class_loader == NULL || !should_verify_class) ?
|
||||
BytecodeVerificationLocal : BytecodeVerificationRemote;
|
||||
}
|
||||
|
||||
@ -68,7 +68,7 @@ bool Verifier::relax_verify_for(oop loader) {
|
||||
return !need_verify;
|
||||
}
|
||||
|
||||
bool Verifier::verify(instanceKlassHandle klass, Verifier::Mode mode, TRAPS) {
|
||||
bool Verifier::verify(instanceKlassHandle klass, Verifier::Mode mode, bool should_verify_class, TRAPS) {
|
||||
ResourceMark rm(THREAD);
|
||||
HandleMark hm;
|
||||
|
||||
@ -81,7 +81,7 @@ bool Verifier::verify(instanceKlassHandle klass, Verifier::Mode mode, TRAPS) {
|
||||
// If the class should be verified, first see if we can use the split
|
||||
// verifier. If not, or if verification fails and FailOverToOldVerifier
|
||||
// is set, then call the inference verifier.
|
||||
if (is_eligible_for_verification(klass)) {
|
||||
if (is_eligible_for_verification(klass, should_verify_class)) {
|
||||
if (TraceClassInitialization) {
|
||||
tty->print_cr("Start class verification for: %s", klassName);
|
||||
}
|
||||
@ -141,12 +141,13 @@ bool Verifier::verify(instanceKlassHandle klass, Verifier::Mode mode, TRAPS) {
|
||||
}
|
||||
}
|
||||
|
||||
bool Verifier::is_eligible_for_verification(instanceKlassHandle klass) {
|
||||
bool Verifier::is_eligible_for_verification(instanceKlassHandle klass, bool should_verify_class) {
|
||||
symbolOop name = klass->name();
|
||||
klassOop refl_magic_klass = SystemDictionary::reflect_magic_klass();
|
||||
|
||||
return (should_verify_for(klass->class_loader()) &&
|
||||
return (should_verify_for(klass->class_loader(), should_verify_class) &&
|
||||
// return if the class is a bootstrapping class
|
||||
// or defineClass specified not to verify by default (flags override passed arg)
|
||||
// We need to skip the following four for bootstraping
|
||||
name != vmSymbols::java_lang_Object() &&
|
||||
name != vmSymbols::java_lang_Class() &&
|
||||
|
@ -34,16 +34,18 @@ class Verifier : AllStatic {
|
||||
* Otherwise, no exception is thrown and the return indicates the
|
||||
* error.
|
||||
*/
|
||||
static bool verify(instanceKlassHandle klass, Mode mode, TRAPS);
|
||||
static bool verify(instanceKlassHandle klass, Mode mode, bool should_verify_class, TRAPS);
|
||||
|
||||
// Return false if the class is loaded by the bootstrap loader.
|
||||
static bool should_verify_for(oop class_loader);
|
||||
// Return false if the class is loaded by the bootstrap loader,
|
||||
// or if defineClass was called requesting skipping verification
|
||||
// -Xverify:all/none override this value
|
||||
static bool should_verify_for(oop class_loader, bool should_verify_class);
|
||||
|
||||
// Relax certain verifier checks to enable some broken 1.1 apps to run on 1.2.
|
||||
static bool relax_verify_for(oop class_loader);
|
||||
|
||||
private:
|
||||
static bool is_eligible_for_verification(instanceKlassHandle klass);
|
||||
static bool is_eligible_for_verification(instanceKlassHandle klass, bool should_verify_class);
|
||||
static symbolHandle inference_verify(
|
||||
instanceKlassHandle klass, char* msg, size_t msg_len, TRAPS);
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1998-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -280,6 +280,7 @@ int DebugInformationRecorder::find_sharable_decode_offset(int stream_offset) {
|
||||
void DebugInformationRecorder::describe_scope(int pc_offset,
|
||||
ciMethod* method,
|
||||
int bci,
|
||||
bool reexecute,
|
||||
DebugToken* locals,
|
||||
DebugToken* expressions,
|
||||
DebugToken* monitors) {
|
||||
@ -291,6 +292,9 @@ void DebugInformationRecorder::describe_scope(int pc_offset,
|
||||
int stream_offset = stream()->position();
|
||||
last_pd->set_scope_decode_offset(stream_offset);
|
||||
|
||||
// Record reexecute bit into pcDesc
|
||||
last_pd->set_should_reexecute(reexecute);
|
||||
|
||||
// serialize sender stream offest
|
||||
stream()->write_int(sender_stream_offset);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1998-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -87,6 +87,7 @@ class DebugInformationRecorder: public ResourceObj {
|
||||
void describe_scope(int pc_offset,
|
||||
ciMethod* method,
|
||||
int bci,
|
||||
bool reexecute,
|
||||
DebugToken* locals = NULL,
|
||||
DebugToken* expressions = NULL,
|
||||
DebugToken* monitors = NULL);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -966,7 +966,7 @@ ScopeDesc* nmethod::scope_desc_at(address pc) {
|
||||
PcDesc* pd = pc_desc_at(pc);
|
||||
guarantee(pd != NULL, "scope must be present");
|
||||
return new ScopeDesc(this, pd->scope_decode_offset(),
|
||||
pd->obj_decode_offset());
|
||||
pd->obj_decode_offset(), pd->should_reexecute());
|
||||
}
|
||||
|
||||
|
||||
@ -1079,6 +1079,10 @@ void nmethod::make_unloaded(BoolObjectClosure* is_alive, oop cause) {
|
||||
this, (address)_method, (address)cause);
|
||||
cause->klass()->print();
|
||||
}
|
||||
// Unlink the osr method, so we do not look this up again
|
||||
if (is_osr_method()) {
|
||||
invalidate_osr_method();
|
||||
}
|
||||
// If _method is already NULL the methodOop is about to be unloaded,
|
||||
// so we don't have to break the cycle. Note that it is possible to
|
||||
// have the methodOop live here, in case we unload the nmethod because
|
||||
@ -1148,7 +1152,7 @@ void nmethod::make_not_entrant_or_zombie(int state) {
|
||||
// will never be used anymore. That the nmethods only gets removed when class unloading
|
||||
// happens, make life much simpler, since the nmethods are not just going to disappear
|
||||
// out of the blue.
|
||||
if (is_osr_only_method()) {
|
||||
if (is_osr_method()) {
|
||||
if (osr_entry_bci() != InvalidOSREntryBci) {
|
||||
// only log this once
|
||||
log_state_change(state);
|
||||
@ -1520,6 +1524,17 @@ void nmethod::do_unloading(BoolObjectClosure* is_alive,
|
||||
#endif // !PRODUCT
|
||||
}
|
||||
|
||||
// This method is called twice during GC -- once while
|
||||
// tracing the "active" nmethods on thread stacks during
|
||||
// the (strong) marking phase, and then again when walking
|
||||
// the code cache contents during the weak roots processing
|
||||
// phase. The two uses are distinguished by means of the
|
||||
// do_nmethods() method in the closure "f" below -- which
|
||||
// answers "yes" in the first case, and "no" in the second
|
||||
// case. We want to walk the weak roots in the nmethod
|
||||
// only in the second case. The weak roots in the nmethod
|
||||
// are the oops in the ExceptionCache and the InlineCache
|
||||
// oops.
|
||||
void nmethod::oops_do(OopClosure* f) {
|
||||
// make sure the oops ready to receive visitors
|
||||
assert(!is_zombie() && !is_unloaded(),
|
||||
@ -1538,19 +1553,25 @@ void nmethod::oops_do(OopClosure* f) {
|
||||
|
||||
// Compiled code
|
||||
f->do_oop((oop*) &_method);
|
||||
ExceptionCache* ec = exception_cache();
|
||||
while(ec != NULL) {
|
||||
f->do_oop((oop*)ec->exception_type_addr());
|
||||
ec = ec->next();
|
||||
}
|
||||
if (!f->do_nmethods()) {
|
||||
// weak roots processing phase -- update ExceptionCache oops
|
||||
ExceptionCache* ec = exception_cache();
|
||||
while(ec != NULL) {
|
||||
f->do_oop((oop*)ec->exception_type_addr());
|
||||
ec = ec->next();
|
||||
}
|
||||
} // Else strong roots phase -- skip oops in ExceptionCache
|
||||
|
||||
RelocIterator iter(this, low_boundary);
|
||||
|
||||
while (iter.next()) {
|
||||
if (iter.type() == relocInfo::oop_type ) {
|
||||
oop_Relocation* r = iter.oop_reloc();
|
||||
// In this loop, we must only follow those oops directly embedded in
|
||||
// the code. Other oops (oop_index>0) are seen as part of scopes_oops.
|
||||
assert(1 == (r->oop_is_immediate()) + (r->oop_addr() >= oops_begin() && r->oop_addr() < oops_end()), "oop must be found in exactly one place");
|
||||
assert(1 == (r->oop_is_immediate()) +
|
||||
(r->oop_addr() >= oops_begin() && r->oop_addr() < oops_end()),
|
||||
"oop must be found in exactly one place");
|
||||
if (r->oop_is_immediate() && r->oop_value() != NULL) {
|
||||
f->do_oop(r->oop_addr());
|
||||
}
|
||||
@ -1932,7 +1953,7 @@ void nmethod::verify_interrupt_point(address call_site) {
|
||||
PcDesc* pd = pc_desc_at(ic->end_of_call());
|
||||
assert(pd != NULL, "PcDesc must exist");
|
||||
for (ScopeDesc* sd = new ScopeDesc(this, pd->scope_decode_offset(),
|
||||
pd->obj_decode_offset());
|
||||
pd->obj_decode_offset(), pd->should_reexecute());
|
||||
!sd->is_top(); sd = sd->sender()) {
|
||||
sd->verify();
|
||||
}
|
||||
@ -2181,7 +2202,7 @@ ScopeDesc* nmethod::scope_desc_in(address begin, address end) {
|
||||
PcDesc* p = pc_desc_near(begin+1);
|
||||
if (p != NULL && p->real_pc(this) <= end) {
|
||||
return new ScopeDesc(this, p->scope_decode_offset(),
|
||||
p->obj_decode_offset());
|
||||
p->obj_decode_offset(), p->should_reexecute());
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -314,7 +314,6 @@ class nmethod : public CodeBlob {
|
||||
bool is_java_method() const { return !method()->is_native(); }
|
||||
bool is_native_method() const { return method()->is_native(); }
|
||||
bool is_osr_method() const { return _entry_bci != InvocationEntryBci; }
|
||||
bool is_osr_only_method() const { return is_osr_method(); }
|
||||
|
||||
bool is_compiled_by_c1() const;
|
||||
bool is_compiled_by_c2() const;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,9 +26,11 @@
|
||||
# include "incls/_pcDesc.cpp.incl"
|
||||
|
||||
PcDesc::PcDesc(int pc_offset, int scope_decode_offset, int obj_decode_offset) {
|
||||
assert(sizeof(PcDescFlags) <= 4, "occupies more than a word");
|
||||
_pc_offset = pc_offset;
|
||||
_scope_decode_offset = scope_decode_offset;
|
||||
_obj_decode_offset = obj_decode_offset;
|
||||
_flags.word = 0;
|
||||
}
|
||||
|
||||
address PcDesc::real_pc(const nmethod* code) const {
|
||||
@ -50,6 +52,7 @@ void PcDesc::print(nmethod* code) {
|
||||
tty->print(" ");
|
||||
sd->method()->print_short_name(tty);
|
||||
tty->print(" @%d", sd->bci());
|
||||
tty->print(" reexecute=%s", sd->should_reexecute()?"true":"false");
|
||||
tty->cr();
|
||||
}
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -34,6 +34,13 @@ class PcDesc VALUE_OBJ_CLASS_SPEC {
|
||||
int _scope_decode_offset; // offset for scope in nmethod
|
||||
int _obj_decode_offset;
|
||||
|
||||
union PcDescFlags {
|
||||
int word;
|
||||
struct {
|
||||
unsigned int reexecute: 1;
|
||||
} bits;
|
||||
} _flags;
|
||||
|
||||
public:
|
||||
int pc_offset() const { return _pc_offset; }
|
||||
int scope_decode_offset() const { return _scope_decode_offset; }
|
||||
@ -53,6 +60,10 @@ class PcDesc VALUE_OBJ_CLASS_SPEC {
|
||||
upper_offset_limit = (unsigned int)-1 >> 1
|
||||
};
|
||||
|
||||
// Flags
|
||||
bool should_reexecute() const { return _flags.bits.reexecute; }
|
||||
void set_should_reexecute(bool z) { _flags.bits.reexecute = z; }
|
||||
|
||||
// Returns the real pc
|
||||
address real_pc(const nmethod* code) const;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,17 +26,19 @@
|
||||
# include "incls/_scopeDesc.cpp.incl"
|
||||
|
||||
|
||||
ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset) {
|
||||
ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute) {
|
||||
_code = code;
|
||||
_decode_offset = decode_offset;
|
||||
_objects = decode_object_values(obj_decode_offset);
|
||||
_reexecute = reexecute;
|
||||
decode_body();
|
||||
}
|
||||
|
||||
ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset) {
|
||||
ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, bool reexecute) {
|
||||
_code = code;
|
||||
_decode_offset = decode_offset;
|
||||
_objects = decode_object_values(DebugInformationRecorder::serialized_null);
|
||||
_reexecute = reexecute;
|
||||
decode_body();
|
||||
}
|
||||
|
||||
@ -45,6 +47,7 @@ ScopeDesc::ScopeDesc(const ScopeDesc* parent) {
|
||||
_code = parent->_code;
|
||||
_decode_offset = parent->_sender_decode_offset;
|
||||
_objects = parent->_objects;
|
||||
_reexecute = false; //reexecute only applies to the first scope
|
||||
decode_body();
|
||||
}
|
||||
|
||||
@ -66,6 +69,7 @@ void ScopeDesc::decode_body() {
|
||||
_sender_decode_offset = stream->read_int();
|
||||
_method = methodHandle((methodOop) stream->read_oop());
|
||||
_bci = stream->read_bci();
|
||||
|
||||
// decode offsets for body and sender
|
||||
_locals_decode_offset = stream->read_int();
|
||||
_expressions_decode_offset = stream->read_int();
|
||||
@ -170,6 +174,7 @@ void ScopeDesc::print_on(outputStream* st, PcDesc* pd) const {
|
||||
st->print("ScopeDesc[%d]@" PTR_FORMAT " ", _decode_offset, _code->instructions_begin());
|
||||
st->print_cr(" offset: %d", _decode_offset);
|
||||
st->print_cr(" bci: %d", bci());
|
||||
st->print_cr(" reexecute: %s", should_reexecute() ? "true" : "false");
|
||||
st->print_cr(" locals: %d", _locals_decode_offset);
|
||||
st->print_cr(" stack: %d", _expressions_decode_offset);
|
||||
st->print_cr(" monitor: %d", _monitors_decode_offset);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -52,16 +52,17 @@ class SimpleScopeDesc : public StackObj {
|
||||
class ScopeDesc : public ResourceObj {
|
||||
public:
|
||||
// Constructor
|
||||
ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset);
|
||||
ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute);
|
||||
|
||||
// Calls above, giving default value of "serialized_null" to the
|
||||
// "obj_decode_offset" argument. (We don't use a default argument to
|
||||
// avoid a .hpp-.hpp dependency.)
|
||||
ScopeDesc(const nmethod* code, int decode_offset);
|
||||
ScopeDesc(const nmethod* code, int decode_offset, bool reexecute);
|
||||
|
||||
// JVM state
|
||||
methodHandle method() const { return _method; }
|
||||
int bci() const { return _bci; }
|
||||
methodHandle method() const { return _method; }
|
||||
int bci() const { return _bci; }
|
||||
bool should_reexecute() const { return _reexecute; }
|
||||
|
||||
GrowableArray<ScopeValue*>* locals();
|
||||
GrowableArray<ScopeValue*>* expressions();
|
||||
@ -86,6 +87,7 @@ class ScopeDesc : public ResourceObj {
|
||||
// JVM state
|
||||
methodHandle _method;
|
||||
int _bci;
|
||||
bool _reexecute;
|
||||
|
||||
// Decoding offsets
|
||||
int _decode_offset;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1998-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1998-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -92,17 +92,50 @@ class MarkRefsIntoVerifyClosure: public OopsInGenClosure {
|
||||
}
|
||||
};
|
||||
|
||||
// The non-parallel version (the parallel version appears further below).
|
||||
class PushAndMarkClosure: public OopClosure {
|
||||
private:
|
||||
// KlassRememberingOopClosure is used when marking of the permanent generation
|
||||
// is being done. It adds fields to support revisiting of klasses
|
||||
// for class unloading. _should_remember_klasses should be set to
|
||||
// indicate if klasses should be remembered. Currently that is whenever
|
||||
// CMS class unloading is turned on. The _revisit_stack is used
|
||||
// to save the klasses for later processing.
|
||||
class KlassRememberingOopClosure : public OopClosure {
|
||||
protected:
|
||||
CMSCollector* _collector;
|
||||
CMSMarkStack* _revisit_stack;
|
||||
bool const _should_remember_klasses;
|
||||
public:
|
||||
void check_remember_klasses() const PRODUCT_RETURN;
|
||||
virtual const bool should_remember_klasses() const {
|
||||
check_remember_klasses();
|
||||
return _should_remember_klasses;
|
||||
}
|
||||
virtual void remember_klass(Klass* k);
|
||||
|
||||
KlassRememberingOopClosure(CMSCollector* collector,
|
||||
ReferenceProcessor* rp,
|
||||
CMSMarkStack* revisit_stack);
|
||||
};
|
||||
|
||||
// Similar to KlassRememberingOopClosure for use when multiple
|
||||
// GC threads will execute the closure.
|
||||
|
||||
class Par_KlassRememberingOopClosure : public KlassRememberingOopClosure {
|
||||
public:
|
||||
Par_KlassRememberingOopClosure(CMSCollector* collector,
|
||||
ReferenceProcessor* rp,
|
||||
CMSMarkStack* revisit_stack):
|
||||
KlassRememberingOopClosure(collector, rp, revisit_stack) {}
|
||||
virtual void remember_klass(Klass* k);
|
||||
};
|
||||
|
||||
// The non-parallel version (the parallel version appears further below).
|
||||
class PushAndMarkClosure: public KlassRememberingOopClosure {
|
||||
private:
|
||||
MemRegion _span;
|
||||
CMSBitMap* _bit_map;
|
||||
CMSBitMap* _mod_union_table;
|
||||
CMSMarkStack* _mark_stack;
|
||||
CMSMarkStack* _revisit_stack;
|
||||
bool _concurrent_precleaning;
|
||||
bool const _should_remember_klasses;
|
||||
protected:
|
||||
DO_OOP_WORK_DEFN
|
||||
public:
|
||||
@ -122,10 +155,12 @@ class PushAndMarkClosure: public OopClosure {
|
||||
Prefetch::style prefetch_style() {
|
||||
return Prefetch::do_read;
|
||||
}
|
||||
virtual const bool should_remember_klasses() const {
|
||||
return _should_remember_klasses;
|
||||
// In support of class unloading
|
||||
virtual const bool should_remember_mdo() const {
|
||||
return false;
|
||||
// return _should_remember_klasses;
|
||||
}
|
||||
virtual void remember_klass(Klass* k);
|
||||
virtual void remember_mdo(DataLayout* v);
|
||||
};
|
||||
|
||||
// In the parallel case, the revisit stack, the bit map and the
|
||||
@ -134,14 +169,11 @@ class PushAndMarkClosure: public OopClosure {
|
||||
// synchronization (for instance, via CAS). The marking stack
|
||||
// used in the non-parallel case above is here replaced with
|
||||
// an OopTaskQueue structure to allow efficient work stealing.
|
||||
class Par_PushAndMarkClosure: public OopClosure {
|
||||
class Par_PushAndMarkClosure: public Par_KlassRememberingOopClosure {
|
||||
private:
|
||||
CMSCollector* _collector;
|
||||
MemRegion _span;
|
||||
CMSBitMap* _bit_map;
|
||||
OopTaskQueue* _work_queue;
|
||||
CMSMarkStack* _revisit_stack;
|
||||
bool const _should_remember_klasses;
|
||||
protected:
|
||||
DO_OOP_WORK_DEFN
|
||||
public:
|
||||
@ -159,10 +191,12 @@ class Par_PushAndMarkClosure: public OopClosure {
|
||||
Prefetch::style prefetch_style() {
|
||||
return Prefetch::do_read;
|
||||
}
|
||||
virtual const bool should_remember_klasses() const {
|
||||
return _should_remember_klasses;
|
||||
// In support of class unloading
|
||||
virtual const bool should_remember_mdo() const {
|
||||
return false;
|
||||
// return _should_remember_klasses;
|
||||
}
|
||||
virtual void remember_klass(Klass* k);
|
||||
virtual void remember_mdo(DataLayout* v);
|
||||
};
|
||||
|
||||
// The non-parallel version (the parallel version appears further below).
|
||||
@ -201,6 +235,12 @@ class MarkRefsIntoAndScanClosure: public OopsInGenClosure {
|
||||
void set_freelistLock(Mutex* m) {
|
||||
_freelistLock = m;
|
||||
}
|
||||
virtual const bool should_remember_klasses() const {
|
||||
return _pushAndMarkClosure.should_remember_klasses();
|
||||
}
|
||||
virtual void remember_klass(Klass* k) {
|
||||
_pushAndMarkClosure.remember_klass(k);
|
||||
}
|
||||
|
||||
private:
|
||||
inline void do_yield_check();
|
||||
@ -234,6 +274,16 @@ class Par_MarkRefsIntoAndScanClosure: public OopsInGenClosure {
|
||||
inline void do_oop_nv(narrowOop* p) { Par_MarkRefsIntoAndScanClosure::do_oop_work(p); }
|
||||
bool do_header() { return true; }
|
||||
virtual const bool do_nmethods() const { return true; }
|
||||
// When ScanMarkedObjectsAgainClosure is used,
|
||||
// it passes [Par_]MarkRefsIntoAndScanClosure to oop_oop_iterate(),
|
||||
// and this delegation is used.
|
||||
virtual const bool should_remember_klasses() const {
|
||||
return _par_pushAndMarkClosure.should_remember_klasses();
|
||||
}
|
||||
// See comment on should_remember_klasses() above.
|
||||
virtual void remember_klass(Klass* k) {
|
||||
_par_pushAndMarkClosure.remember_klass(k);
|
||||
}
|
||||
Prefetch::style prefetch_style() {
|
||||
return Prefetch::do_read;
|
||||
}
|
||||
@ -243,17 +293,14 @@ class Par_MarkRefsIntoAndScanClosure: public OopsInGenClosure {
|
||||
// This closure is used during the concurrent marking phase
|
||||
// following the first checkpoint. Its use is buried in
|
||||
// the closure MarkFromRootsClosure.
|
||||
class PushOrMarkClosure: public OopClosure {
|
||||
class PushOrMarkClosure: public KlassRememberingOopClosure {
|
||||
private:
|
||||
CMSCollector* _collector;
|
||||
MemRegion _span;
|
||||
CMSBitMap* _bitMap;
|
||||
CMSMarkStack* _markStack;
|
||||
CMSMarkStack* _revisitStack;
|
||||
HeapWord* const _finger;
|
||||
MarkFromRootsClosure* const
|
||||
_parent;
|
||||
bool const _should_remember_klasses;
|
||||
protected:
|
||||
DO_OOP_WORK_DEFN
|
||||
public:
|
||||
@ -268,10 +315,13 @@ class PushOrMarkClosure: public OopClosure {
|
||||
virtual void do_oop(narrowOop* p);
|
||||
inline void do_oop_nv(oop* p) { PushOrMarkClosure::do_oop_work(p); }
|
||||
inline void do_oop_nv(narrowOop* p) { PushOrMarkClosure::do_oop_work(p); }
|
||||
virtual const bool should_remember_klasses() const {
|
||||
return _should_remember_klasses;
|
||||
// In support of class unloading
|
||||
virtual const bool should_remember_mdo() const {
|
||||
return false;
|
||||
// return _should_remember_klasses;
|
||||
}
|
||||
virtual void remember_klass(Klass* k);
|
||||
virtual void remember_mdo(DataLayout* v);
|
||||
|
||||
// Deal with a stack overflow condition
|
||||
void handle_stack_overflow(HeapWord* lost);
|
||||
private:
|
||||
@ -282,20 +332,17 @@ class PushOrMarkClosure: public OopClosure {
|
||||
// This closure is used during the concurrent marking phase
|
||||
// following the first checkpoint. Its use is buried in
|
||||
// the closure Par_MarkFromRootsClosure.
|
||||
class Par_PushOrMarkClosure: public OopClosure {
|
||||
class Par_PushOrMarkClosure: public Par_KlassRememberingOopClosure {
|
||||
private:
|
||||
CMSCollector* _collector;
|
||||
MemRegion _whole_span;
|
||||
MemRegion _span; // local chunk
|
||||
CMSBitMap* _bit_map;
|
||||
OopTaskQueue* _work_queue;
|
||||
CMSMarkStack* _overflow_stack;
|
||||
CMSMarkStack* _revisit_stack;
|
||||
HeapWord* const _finger;
|
||||
HeapWord** const _global_finger_addr;
|
||||
Par_MarkFromRootsClosure* const
|
||||
_parent;
|
||||
bool const _should_remember_klasses;
|
||||
protected:
|
||||
DO_OOP_WORK_DEFN
|
||||
public:
|
||||
@ -312,10 +359,13 @@ class Par_PushOrMarkClosure: public OopClosure {
|
||||
virtual void do_oop(narrowOop* p);
|
||||
inline void do_oop_nv(oop* p) { Par_PushOrMarkClosure::do_oop_work(p); }
|
||||
inline void do_oop_nv(narrowOop* p) { Par_PushOrMarkClosure::do_oop_work(p); }
|
||||
virtual const bool should_remember_klasses() const {
|
||||
return _should_remember_klasses;
|
||||
// In support of class unloading
|
||||
virtual const bool should_remember_mdo() const {
|
||||
return false;
|
||||
// return _should_remember_klasses;
|
||||
}
|
||||
virtual void remember_klass(Klass* k);
|
||||
virtual void remember_mdo(DataLayout* v);
|
||||
|
||||
// Deal with a stack overflow condition
|
||||
void handle_stack_overflow(HeapWord* lost);
|
||||
private:
|
||||
@ -328,9 +378,8 @@ class Par_PushOrMarkClosure: public OopClosure {
|
||||
// processing phase of the CMS final checkpoint step, as
|
||||
// well as during the concurrent precleaning of the discovered
|
||||
// reference lists.
|
||||
class CMSKeepAliveClosure: public OopClosure {
|
||||
class CMSKeepAliveClosure: public KlassRememberingOopClosure {
|
||||
private:
|
||||
CMSCollector* _collector;
|
||||
const MemRegion _span;
|
||||
CMSMarkStack* _mark_stack;
|
||||
CMSBitMap* _bit_map;
|
||||
@ -340,14 +389,7 @@ class CMSKeepAliveClosure: public OopClosure {
|
||||
public:
|
||||
CMSKeepAliveClosure(CMSCollector* collector, MemRegion span,
|
||||
CMSBitMap* bit_map, CMSMarkStack* mark_stack,
|
||||
bool cpc):
|
||||
_collector(collector),
|
||||
_span(span),
|
||||
_bit_map(bit_map),
|
||||
_mark_stack(mark_stack),
|
||||
_concurrent_precleaning(cpc) {
|
||||
assert(!_span.is_empty(), "Empty span could spell trouble");
|
||||
}
|
||||
CMSMarkStack* revisit_stack, bool cpc);
|
||||
bool concurrent_precleaning() const { return _concurrent_precleaning; }
|
||||
virtual void do_oop(oop* p);
|
||||
virtual void do_oop(narrowOop* p);
|
||||
@ -355,9 +397,8 @@ class CMSKeepAliveClosure: public OopClosure {
|
||||
inline void do_oop_nv(narrowOop* p) { CMSKeepAliveClosure::do_oop_work(p); }
|
||||
};
|
||||
|
||||
class CMSInnerParMarkAndPushClosure: public OopClosure {
|
||||
class CMSInnerParMarkAndPushClosure: public Par_KlassRememberingOopClosure {
|
||||
private:
|
||||
CMSCollector* _collector;
|
||||
MemRegion _span;
|
||||
OopTaskQueue* _work_queue;
|
||||
CMSBitMap* _bit_map;
|
||||
@ -366,11 +407,8 @@ class CMSInnerParMarkAndPushClosure: public OopClosure {
|
||||
public:
|
||||
CMSInnerParMarkAndPushClosure(CMSCollector* collector,
|
||||
MemRegion span, CMSBitMap* bit_map,
|
||||
OopTaskQueue* work_queue):
|
||||
_collector(collector),
|
||||
_span(span),
|
||||
_bit_map(bit_map),
|
||||
_work_queue(work_queue) { }
|
||||
CMSMarkStack* revisit_stack,
|
||||
OopTaskQueue* work_queue);
|
||||
virtual void do_oop(oop* p);
|
||||
virtual void do_oop(narrowOop* p);
|
||||
inline void do_oop_nv(oop* p) { CMSInnerParMarkAndPushClosure::do_oop_work(p); }
|
||||
@ -380,9 +418,8 @@ class CMSInnerParMarkAndPushClosure: public OopClosure {
|
||||
// A parallel (MT) version of the above, used when
|
||||
// reference processing is parallel; the only difference
|
||||
// is in the do_oop method.
|
||||
class CMSParKeepAliveClosure: public OopClosure {
|
||||
class CMSParKeepAliveClosure: public Par_KlassRememberingOopClosure {
|
||||
private:
|
||||
CMSCollector* _collector;
|
||||
MemRegion _span;
|
||||
OopTaskQueue* _work_queue;
|
||||
CMSBitMap* _bit_map;
|
||||
@ -394,7 +431,8 @@ class CMSParKeepAliveClosure: public OopClosure {
|
||||
DO_OOP_WORK_DEFN
|
||||
public:
|
||||
CMSParKeepAliveClosure(CMSCollector* collector, MemRegion span,
|
||||
CMSBitMap* bit_map, OopTaskQueue* work_queue);
|
||||
CMSBitMap* bit_map, CMSMarkStack* revisit_stack,
|
||||
OopTaskQueue* work_queue);
|
||||
virtual void do_oop(oop* p);
|
||||
virtual void do_oop(narrowOop* p);
|
||||
inline void do_oop_nv(oop* p) { CMSParKeepAliveClosure::do_oop_work(p); }
|
||||
|
@ -37,16 +37,34 @@ inline void Par_MarkRefsIntoAndScanClosure::trim_queue(uint max) {
|
||||
}
|
||||
}
|
||||
|
||||
inline void PushOrMarkClosure::remember_klass(Klass* k) {
|
||||
if (!_revisitStack->push(oop(k))) {
|
||||
#ifndef PRODUCT
|
||||
void KlassRememberingOopClosure::check_remember_klasses() const {
|
||||
assert(_should_remember_klasses == must_remember_klasses(),
|
||||
"Should remember klasses in this context.");
|
||||
}
|
||||
#endif
|
||||
|
||||
void KlassRememberingOopClosure::remember_klass(Klass* k) {
|
||||
if (!_revisit_stack->push(oop(k))) {
|
||||
fatal("Revisit stack overflow in PushOrMarkClosure");
|
||||
}
|
||||
check_remember_klasses();
|
||||
}
|
||||
|
||||
inline void Par_PushOrMarkClosure::remember_klass(Klass* k) {
|
||||
inline void PushOrMarkClosure::remember_mdo(DataLayout* v) {
|
||||
// TBD
|
||||
}
|
||||
|
||||
|
||||
void Par_KlassRememberingOopClosure::remember_klass(Klass* k) {
|
||||
if (!_revisit_stack->par_push(oop(k))) {
|
||||
fatal("Revisit stack overflow in PushOrMarkClosure");
|
||||
fatal("Revisit stack overflow in Par_KlassRememberingOopClosure");
|
||||
}
|
||||
check_remember_klasses();
|
||||
}
|
||||
|
||||
inline void Par_PushOrMarkClosure::remember_mdo(DataLayout* v) {
|
||||
// TBD
|
||||
}
|
||||
|
||||
inline void PushOrMarkClosure::do_yield_check() {
|
||||
|
@ -2276,7 +2276,7 @@ void CMSCollector::collect_in_background(bool clear_all_soft_refs) {
|
||||
|
||||
VM_CMS_Final_Remark final_remark_op(this);
|
||||
VMThread::execute(&final_remark_op);
|
||||
}
|
||||
}
|
||||
assert(_foregroundGCShouldWait, "block post-condition");
|
||||
break;
|
||||
case Sweeping:
|
||||
@ -3499,6 +3499,7 @@ void CMSCollector::checkpointRootsInitialWork(bool asynch) {
|
||||
ref_processor()->set_enqueuing_is_done(false);
|
||||
|
||||
{
|
||||
// This is not needed. DEBUG_ONLY(RememberKlassesChecker imx(true);)
|
||||
COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;)
|
||||
gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
|
||||
gch->gen_process_strong_roots(_cmsGen->level(),
|
||||
@ -3623,6 +3624,8 @@ bool CMSCollector::markFromRootsWork(bool asynch) {
|
||||
verify_overflow_empty();
|
||||
assert(_revisitStack.isEmpty(), "tabula rasa");
|
||||
|
||||
DEBUG_ONLY(RememberKlassesChecker cmx(CMSClassUnloadingEnabled);)
|
||||
|
||||
bool result = false;
|
||||
if (CMSConcurrentMTEnabled && ParallelCMSThreads > 0) {
|
||||
result = do_marking_mt(asynch);
|
||||
@ -3958,24 +3961,24 @@ void CMSConcMarkingTask::do_scan_and_mark(int i, CompactibleFreeListSpace* sp) {
|
||||
pst->all_tasks_completed();
|
||||
}
|
||||
|
||||
class Par_ConcMarkingClosure: public OopClosure {
|
||||
class Par_ConcMarkingClosure: public Par_KlassRememberingOopClosure {
|
||||
private:
|
||||
CMSCollector* _collector;
|
||||
MemRegion _span;
|
||||
CMSBitMap* _bit_map;
|
||||
CMSMarkStack* _overflow_stack;
|
||||
CMSMarkStack* _revisit_stack; // XXXXXX Check proper use
|
||||
OopTaskQueue* _work_queue;
|
||||
protected:
|
||||
DO_OOP_WORK_DEFN
|
||||
public:
|
||||
Par_ConcMarkingClosure(CMSCollector* collector, OopTaskQueue* work_queue,
|
||||
CMSBitMap* bit_map, CMSMarkStack* overflow_stack):
|
||||
_collector(collector),
|
||||
CMSBitMap* bit_map, CMSMarkStack* overflow_stack,
|
||||
CMSMarkStack* revisit_stack):
|
||||
Par_KlassRememberingOopClosure(collector, NULL, revisit_stack),
|
||||
_span(_collector->_span),
|
||||
_work_queue(work_queue),
|
||||
_bit_map(bit_map),
|
||||
_overflow_stack(overflow_stack) { } // need to initialize revisit stack etc.
|
||||
_overflow_stack(overflow_stack)
|
||||
{ }
|
||||
virtual void do_oop(oop* p);
|
||||
virtual void do_oop(narrowOop* p);
|
||||
void trim_queue(size_t max);
|
||||
@ -4063,8 +4066,9 @@ void CMSConcMarkingTask::do_work_steal(int i) {
|
||||
oop obj_to_scan;
|
||||
CMSBitMap* bm = &(_collector->_markBitMap);
|
||||
CMSMarkStack* ovflw = &(_collector->_markStack);
|
||||
CMSMarkStack* revisit = &(_collector->_revisitStack);
|
||||
int* seed = _collector->hash_seed(i);
|
||||
Par_ConcMarkingClosure cl(_collector, work_q, bm, ovflw);
|
||||
Par_ConcMarkingClosure cl(_collector, work_q, bm, ovflw, revisit);
|
||||
while (true) {
|
||||
cl.trim_queue(0);
|
||||
assert(work_q->size() == 0, "Should have been emptied above");
|
||||
@ -4089,6 +4093,7 @@ void CMSConcMarkingTask::coordinator_yield() {
|
||||
assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
|
||||
"CMS thread should hold CMS token");
|
||||
|
||||
DEBUG_ONLY(RememberKlassesChecker mux(false);)
|
||||
// First give up the locks, then yield, then re-lock
|
||||
// We should probably use a constructor/destructor idiom to
|
||||
// do this unlock/lock or modify the MutexUnlocker class to
|
||||
@ -4165,6 +4170,8 @@ bool CMSCollector::do_marking_mt(bool asynch) {
|
||||
// multi-threaded marking phase.
|
||||
ReferenceProcessorMTMutator mt(ref_processor(), num_workers > 1);
|
||||
|
||||
DEBUG_ONLY(RememberKlassesChecker cmx(CMSClassUnloadingEnabled);)
|
||||
|
||||
conc_workers()->start_task(&tsk);
|
||||
while (tsk.yielded()) {
|
||||
tsk.coordinator_yield();
|
||||
@ -4404,7 +4411,8 @@ size_t CMSCollector::preclean_work(bool clean_refs, bool clean_survivor) {
|
||||
CMSPrecleanRefsYieldClosure yield_cl(this);
|
||||
assert(rp->span().equals(_span), "Spans should be equal");
|
||||
CMSKeepAliveClosure keep_alive(this, _span, &_markBitMap,
|
||||
&_markStack, true /* preclean */);
|
||||
&_markStack, &_revisitStack,
|
||||
true /* preclean */);
|
||||
CMSDrainMarkingStackClosure complete_trace(this,
|
||||
_span, &_markBitMap, &_markStack,
|
||||
&keep_alive, true /* preclean */);
|
||||
@ -4424,6 +4432,7 @@ size_t CMSCollector::preclean_work(bool clean_refs, bool clean_survivor) {
|
||||
bitMapLock());
|
||||
startTimer();
|
||||
sample_eden();
|
||||
|
||||
// The following will yield to allow foreground
|
||||
// collection to proceed promptly. XXX YSR:
|
||||
// The code in this method may need further
|
||||
@ -4453,6 +4462,7 @@ size_t CMSCollector::preclean_work(bool clean_refs, bool clean_survivor) {
|
||||
SurvivorSpacePrecleanClosure
|
||||
sss_cl(this, _span, &_markBitMap, &_markStack,
|
||||
&pam_cl, before_count, CMSYield);
|
||||
DEBUG_ONLY(RememberKlassesChecker mx(CMSClassUnloadingEnabled);)
|
||||
dng->from()->object_iterate_careful(&sss_cl);
|
||||
dng->to()->object_iterate_careful(&sss_cl);
|
||||
}
|
||||
@ -4554,6 +4564,13 @@ size_t CMSCollector::preclean_mod_union_table(
|
||||
verify_work_stacks_empty();
|
||||
verify_overflow_empty();
|
||||
|
||||
// Turn off checking for this method but turn it back on
|
||||
// selectively. There are yield points in this method
|
||||
// but it is difficult to turn the checking off just around
|
||||
// the yield points. It is simpler to selectively turn
|
||||
// it on.
|
||||
DEBUG_ONLY(RememberKlassesChecker mux(false);)
|
||||
|
||||
// strategy: starting with the first card, accumulate contiguous
|
||||
// ranges of dirty cards; clear these cards, then scan the region
|
||||
// covered by these cards.
|
||||
@ -4582,6 +4599,7 @@ size_t CMSCollector::preclean_mod_union_table(
|
||||
MemRegion dirtyRegion;
|
||||
{
|
||||
stopTimer();
|
||||
// Potential yield point
|
||||
CMSTokenSync ts(true);
|
||||
startTimer();
|
||||
sample_eden();
|
||||
@ -4607,6 +4625,7 @@ size_t CMSCollector::preclean_mod_union_table(
|
||||
assert(numDirtyCards > 0, "consistency check");
|
||||
HeapWord* stop_point = NULL;
|
||||
stopTimer();
|
||||
// Potential yield point
|
||||
CMSTokenSyncWithLocks ts(true, gen->freelistLock(),
|
||||
bitMapLock());
|
||||
startTimer();
|
||||
@ -4614,6 +4633,7 @@ size_t CMSCollector::preclean_mod_union_table(
|
||||
verify_work_stacks_empty();
|
||||
verify_overflow_empty();
|
||||
sample_eden();
|
||||
DEBUG_ONLY(RememberKlassesChecker mx(CMSClassUnloadingEnabled);)
|
||||
stop_point =
|
||||
gen->cmsSpace()->object_iterate_careful_m(dirtyRegion, cl);
|
||||
}
|
||||
@ -4701,6 +4721,7 @@ size_t CMSCollector::preclean_card_table(ConcurrentMarkSweepGeneration* gen,
|
||||
sample_eden();
|
||||
verify_work_stacks_empty();
|
||||
verify_overflow_empty();
|
||||
DEBUG_ONLY(RememberKlassesChecker mx(CMSClassUnloadingEnabled);)
|
||||
HeapWord* stop_point =
|
||||
gen->cmsSpace()->object_iterate_careful_m(dirtyRegion, cl);
|
||||
if (stop_point != NULL) {
|
||||
@ -4800,6 +4821,7 @@ void CMSCollector::checkpointRootsFinalWork(bool asynch,
|
||||
assert(haveFreelistLocks(), "must have free list locks");
|
||||
assert_lock_strong(bitMapLock());
|
||||
|
||||
DEBUG_ONLY(RememberKlassesChecker fmx(CMSClassUnloadingEnabled);)
|
||||
if (!init_mark_was_synchronous) {
|
||||
// We might assume that we need not fill TLAB's when
|
||||
// CMSScavengeBeforeRemark is set, because we may have just done
|
||||
@ -4903,6 +4925,9 @@ void CMSCollector::checkpointRootsFinalWork(bool asynch,
|
||||
_markStack._hit_limit = 0;
|
||||
_markStack._failed_double = 0;
|
||||
|
||||
// Check that all the klasses have been checked
|
||||
assert(_revisitStack.isEmpty(), "Not all klasses revisited");
|
||||
|
||||
if ((VerifyAfterGC || VerifyDuringGC) &&
|
||||
GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
|
||||
verify_after_remark();
|
||||
@ -5574,9 +5599,13 @@ public:
|
||||
void CMSRefProcTaskProxy::work(int i) {
|
||||
assert(_collector->_span.equals(_span), "Inconsistency in _span");
|
||||
CMSParKeepAliveClosure par_keep_alive(_collector, _span,
|
||||
_mark_bit_map, work_queue(i));
|
||||
_mark_bit_map,
|
||||
&_collector->_revisitStack,
|
||||
work_queue(i));
|
||||
CMSParDrainMarkingStackClosure par_drain_stack(_collector, _span,
|
||||
_mark_bit_map, work_queue(i));
|
||||
_mark_bit_map,
|
||||
&_collector->_revisitStack,
|
||||
work_queue(i));
|
||||
CMSIsAliveClosure is_alive_closure(_span, _mark_bit_map);
|
||||
_task.work(i, is_alive_closure, par_keep_alive, par_drain_stack);
|
||||
if (_task.marks_oops_alive()) {
|
||||
@ -5604,12 +5633,13 @@ public:
|
||||
};
|
||||
|
||||
CMSParKeepAliveClosure::CMSParKeepAliveClosure(CMSCollector* collector,
|
||||
MemRegion span, CMSBitMap* bit_map, OopTaskQueue* work_queue):
|
||||
_collector(collector),
|
||||
MemRegion span, CMSBitMap* bit_map, CMSMarkStack* revisit_stack,
|
||||
OopTaskQueue* work_queue):
|
||||
Par_KlassRememberingOopClosure(collector, NULL, revisit_stack),
|
||||
_span(span),
|
||||
_bit_map(bit_map),
|
||||
_work_queue(work_queue),
|
||||
_mark_and_push(collector, span, bit_map, work_queue),
|
||||
_mark_and_push(collector, span, bit_map, revisit_stack, work_queue),
|
||||
_low_water_mark(MIN2((uint)(work_queue->max_elems()/4),
|
||||
(uint)(CMSWorkQueueDrainThreshold * ParallelGCThreads)))
|
||||
{ }
|
||||
@ -5696,7 +5726,8 @@ void CMSCollector::refProcessingWork(bool asynch, bool clear_all_soft_refs) {
|
||||
verify_work_stacks_empty();
|
||||
|
||||
CMSKeepAliveClosure cmsKeepAliveClosure(this, _span, &_markBitMap,
|
||||
&_markStack, false /* !preclean */);
|
||||
&_markStack, &_revisitStack,
|
||||
false /* !preclean */);
|
||||
CMSDrainMarkingStackClosure cmsDrainMarkingStackClosure(this,
|
||||
_span, &_markBitMap, &_markStack,
|
||||
&cmsKeepAliveClosure, false /* !preclean */);
|
||||
@ -6531,6 +6562,7 @@ void MarkRefsIntoAndScanClosure::do_yield_work() {
|
||||
assert_lock_strong(_freelistLock);
|
||||
assert_lock_strong(_bit_map->lock());
|
||||
// relinquish the free_list_lock and bitMaplock()
|
||||
DEBUG_ONLY(RememberKlassesChecker mux(false);)
|
||||
_bit_map->lock()->unlock();
|
||||
_freelistLock->unlock();
|
||||
ConcurrentMarkSweepThread::desynchronize(true);
|
||||
@ -6703,6 +6735,7 @@ void ScanMarkedObjectsAgainCarefullyClosure::do_yield_work() {
|
||||
"CMS thread should hold CMS token");
|
||||
assert_lock_strong(_freelistLock);
|
||||
assert_lock_strong(_bitMap->lock());
|
||||
DEBUG_ONLY(RememberKlassesChecker mux(false);)
|
||||
// relinquish the free_list_lock and bitMaplock()
|
||||
_bitMap->lock()->unlock();
|
||||
_freelistLock->unlock();
|
||||
@ -6779,6 +6812,7 @@ void SurvivorSpacePrecleanClosure::do_yield_work() {
|
||||
assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
|
||||
"CMS thread should hold CMS token");
|
||||
assert_lock_strong(_bit_map->lock());
|
||||
DEBUG_ONLY(RememberKlassesChecker smx(false);)
|
||||
// Relinquish the bit map lock
|
||||
_bit_map->lock()->unlock();
|
||||
ConcurrentMarkSweepThread::desynchronize(true);
|
||||
@ -6941,6 +6975,7 @@ void MarkFromRootsClosure::do_yield_work() {
|
||||
assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
|
||||
"CMS thread should hold CMS token");
|
||||
assert_lock_strong(_bitMap->lock());
|
||||
DEBUG_ONLY(RememberKlassesChecker mux(false);)
|
||||
_bitMap->lock()->unlock();
|
||||
ConcurrentMarkSweepThread::desynchronize(true);
|
||||
ConcurrentMarkSweepThread::acknowledge_yield_request();
|
||||
@ -7295,15 +7330,12 @@ PushOrMarkClosure::PushOrMarkClosure(CMSCollector* collector,
|
||||
CMSBitMap* bitMap, CMSMarkStack* markStack,
|
||||
CMSMarkStack* revisitStack,
|
||||
HeapWord* finger, MarkFromRootsClosure* parent) :
|
||||
OopClosure(collector->ref_processor()),
|
||||
_collector(collector),
|
||||
KlassRememberingOopClosure(collector, collector->ref_processor(), revisitStack),
|
||||
_span(span),
|
||||
_bitMap(bitMap),
|
||||
_markStack(markStack),
|
||||
_revisitStack(revisitStack),
|
||||
_finger(finger),
|
||||
_parent(parent),
|
||||
_should_remember_klasses(collector->should_unload_classes())
|
||||
_parent(parent)
|
||||
{ }
|
||||
|
||||
Par_PushOrMarkClosure::Par_PushOrMarkClosure(CMSCollector* collector,
|
||||
@ -7315,18 +7347,17 @@ Par_PushOrMarkClosure::Par_PushOrMarkClosure(CMSCollector* collector,
|
||||
HeapWord* finger,
|
||||
HeapWord** global_finger_addr,
|
||||
Par_MarkFromRootsClosure* parent) :
|
||||
OopClosure(collector->ref_processor()),
|
||||
_collector(collector),
|
||||
Par_KlassRememberingOopClosure(collector,
|
||||
collector->ref_processor(),
|
||||
revisit_stack),
|
||||
_whole_span(collector->_span),
|
||||
_span(span),
|
||||
_bit_map(bit_map),
|
||||
_work_queue(work_queue),
|
||||
_overflow_stack(overflow_stack),
|
||||
_revisit_stack(revisit_stack),
|
||||
_finger(finger),
|
||||
_global_finger_addr(global_finger_addr),
|
||||
_parent(parent),
|
||||
_should_remember_klasses(collector->should_unload_classes())
|
||||
_parent(parent)
|
||||
{ }
|
||||
|
||||
// Assumes thread-safe access by callers, who are
|
||||
@ -7456,6 +7487,14 @@ void Par_PushOrMarkClosure::do_oop(oop obj) {
|
||||
void Par_PushOrMarkClosure::do_oop(oop* p) { Par_PushOrMarkClosure::do_oop_work(p); }
|
||||
void Par_PushOrMarkClosure::do_oop(narrowOop* p) { Par_PushOrMarkClosure::do_oop_work(p); }
|
||||
|
||||
KlassRememberingOopClosure::KlassRememberingOopClosure(CMSCollector* collector,
|
||||
ReferenceProcessor* rp,
|
||||
CMSMarkStack* revisit_stack) :
|
||||
OopClosure(rp),
|
||||
_collector(collector),
|
||||
_revisit_stack(revisit_stack),
|
||||
_should_remember_klasses(collector->should_unload_classes()) {}
|
||||
|
||||
PushAndMarkClosure::PushAndMarkClosure(CMSCollector* collector,
|
||||
MemRegion span,
|
||||
ReferenceProcessor* rp,
|
||||
@ -7464,15 +7503,12 @@ PushAndMarkClosure::PushAndMarkClosure(CMSCollector* collector,
|
||||
CMSMarkStack* mark_stack,
|
||||
CMSMarkStack* revisit_stack,
|
||||
bool concurrent_precleaning):
|
||||
OopClosure(rp),
|
||||
_collector(collector),
|
||||
KlassRememberingOopClosure(collector, rp, revisit_stack),
|
||||
_span(span),
|
||||
_bit_map(bit_map),
|
||||
_mod_union_table(mod_union_table),
|
||||
_mark_stack(mark_stack),
|
||||
_revisit_stack(revisit_stack),
|
||||
_concurrent_precleaning(concurrent_precleaning),
|
||||
_should_remember_klasses(collector->should_unload_classes())
|
||||
_concurrent_precleaning(concurrent_precleaning)
|
||||
{
|
||||
assert(_ref_processor != NULL, "_ref_processor shouldn't be NULL");
|
||||
}
|
||||
@ -7540,13 +7576,10 @@ Par_PushAndMarkClosure::Par_PushAndMarkClosure(CMSCollector* collector,
|
||||
CMSBitMap* bit_map,
|
||||
OopTaskQueue* work_queue,
|
||||
CMSMarkStack* revisit_stack):
|
||||
OopClosure(rp),
|
||||
_collector(collector),
|
||||
Par_KlassRememberingOopClosure(collector, rp, revisit_stack),
|
||||
_span(span),
|
||||
_bit_map(bit_map),
|
||||
_work_queue(work_queue),
|
||||
_revisit_stack(revisit_stack),
|
||||
_should_remember_klasses(collector->should_unload_classes())
|
||||
_work_queue(work_queue)
|
||||
{
|
||||
assert(_ref_processor != NULL, "_ref_processor shouldn't be NULL");
|
||||
}
|
||||
@ -7599,19 +7632,16 @@ void Par_PushAndMarkClosure::do_oop(oop obj) {
|
||||
void Par_PushAndMarkClosure::do_oop(oop* p) { Par_PushAndMarkClosure::do_oop_work(p); }
|
||||
void Par_PushAndMarkClosure::do_oop(narrowOop* p) { Par_PushAndMarkClosure::do_oop_work(p); }
|
||||
|
||||
void PushAndMarkClosure::remember_klass(Klass* k) {
|
||||
if (!_revisit_stack->push(oop(k))) {
|
||||
fatal("Revisit stack overflowed in PushAndMarkClosure");
|
||||
}
|
||||
void PushAndMarkClosure::remember_mdo(DataLayout* v) {
|
||||
// TBD
|
||||
}
|
||||
|
||||
void Par_PushAndMarkClosure::remember_klass(Klass* k) {
|
||||
if (!_revisit_stack->par_push(oop(k))) {
|
||||
fatal("Revist stack overflowed in Par_PushAndMarkClosure");
|
||||
}
|
||||
void Par_PushAndMarkClosure::remember_mdo(DataLayout* v) {
|
||||
// TBD
|
||||
}
|
||||
|
||||
void CMSPrecleanRefsYieldClosure::do_yield_work() {
|
||||
DEBUG_ONLY(RememberKlassesChecker mux(false);)
|
||||
Mutex* bml = _collector->bitMapLock();
|
||||
assert_lock_strong(bml);
|
||||
assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
|
||||
@ -8302,6 +8332,19 @@ bool CMSIsAliveClosure::do_object_b(oop obj) {
|
||||
(!_span.contains(addr) || _bit_map->isMarked(addr));
|
||||
}
|
||||
|
||||
CMSKeepAliveClosure::CMSKeepAliveClosure( CMSCollector* collector,
|
||||
MemRegion span,
|
||||
CMSBitMap* bit_map, CMSMarkStack* mark_stack,
|
||||
CMSMarkStack* revisit_stack, bool cpc):
|
||||
KlassRememberingOopClosure(collector, NULL, revisit_stack),
|
||||
_span(span),
|
||||
_bit_map(bit_map),
|
||||
_mark_stack(mark_stack),
|
||||
_concurrent_precleaning(cpc) {
|
||||
assert(!_span.is_empty(), "Empty span could spell trouble");
|
||||
}
|
||||
|
||||
|
||||
// CMSKeepAliveClosure: the serial version
|
||||
void CMSKeepAliveClosure::do_oop(oop obj) {
|
||||
HeapWord* addr = (HeapWord*)obj;
|
||||
@ -8385,6 +8428,16 @@ void CMSParKeepAliveClosure::trim_queue(uint max) {
|
||||
}
|
||||
}
|
||||
|
||||
CMSInnerParMarkAndPushClosure::CMSInnerParMarkAndPushClosure(
|
||||
CMSCollector* collector,
|
||||
MemRegion span, CMSBitMap* bit_map,
|
||||
CMSMarkStack* revisit_stack,
|
||||
OopTaskQueue* work_queue):
|
||||
Par_KlassRememberingOopClosure(collector, NULL, revisit_stack),
|
||||
_span(span),
|
||||
_bit_map(bit_map),
|
||||
_work_queue(work_queue) { }
|
||||
|
||||
void CMSInnerParMarkAndPushClosure::do_oop(oop obj) {
|
||||
HeapWord* addr = (HeapWord*)obj;
|
||||
if (_span.contains(addr) &&
|
||||
|
@ -1790,12 +1790,13 @@ class CMSParDrainMarkingStackClosure: public VoidClosure {
|
||||
public:
|
||||
CMSParDrainMarkingStackClosure(CMSCollector* collector,
|
||||
MemRegion span, CMSBitMap* bit_map,
|
||||
CMSMarkStack* revisit_stack,
|
||||
OopTaskQueue* work_queue):
|
||||
_collector(collector),
|
||||
_span(span),
|
||||
_bit_map(bit_map),
|
||||
_work_queue(work_queue),
|
||||
_mark_and_push(collector, span, bit_map, work_queue) { }
|
||||
_mark_and_push(collector, span, bit_map, revisit_stack, work_queue) { }
|
||||
|
||||
public:
|
||||
void trim_queue(uint max);
|
||||
|
@ -25,11 +25,21 @@
|
||||
#include "incls/_precompiled.incl"
|
||||
#include "incls/_concurrentG1Refine.cpp.incl"
|
||||
|
||||
// Possible sizes for the card counts cache: odd primes that roughly double in size.
|
||||
// (See jvmtiTagMap.cpp).
|
||||
int ConcurrentG1Refine::_cc_cache_sizes[] = {
|
||||
16381, 32771, 76831, 150001, 307261,
|
||||
614563, 1228891, 2457733, 4915219, 9830479,
|
||||
19660831, 39321619, 78643219, 157286461, -1
|
||||
};
|
||||
|
||||
ConcurrentG1Refine::ConcurrentG1Refine() :
|
||||
_card_counts(NULL), _cur_card_count_histo(NULL), _cum_card_count_histo(NULL),
|
||||
_card_counts(NULL), _card_epochs(NULL),
|
||||
_n_card_counts(0), _max_n_card_counts(0),
|
||||
_cache_size_index(0), _expand_card_counts(false),
|
||||
_hot_cache(NULL),
|
||||
_def_use_cache(false), _use_cache(false),
|
||||
_n_periods(0), _total_cards(0), _total_travs(0),
|
||||
_n_periods(0),
|
||||
_threads(NULL), _n_threads(0)
|
||||
{
|
||||
if (G1ConcRefine) {
|
||||
@ -57,32 +67,51 @@ size_t ConcurrentG1Refine::thread_num() {
|
||||
}
|
||||
|
||||
void ConcurrentG1Refine::init() {
|
||||
if (G1ConcRSLogCacheSize > 0 || G1ConcRSCountTraversals) {
|
||||
G1CollectedHeap* g1h = G1CollectedHeap::heap();
|
||||
_n_card_counts =
|
||||
(unsigned) (g1h->g1_reserved_obj_bytes() >> CardTableModRefBS::card_shift);
|
||||
_card_counts = NEW_C_HEAP_ARRAY(unsigned char, _n_card_counts);
|
||||
for (size_t i = 0; i < _n_card_counts; i++) _card_counts[i] = 0;
|
||||
ModRefBarrierSet* bs = g1h->mr_bs();
|
||||
guarantee(bs->is_a(BarrierSet::CardTableModRef), "Precondition");
|
||||
CardTableModRefBS* ctbs = (CardTableModRefBS*)bs;
|
||||
_ct_bot = ctbs->byte_for_const(g1h->reserved_region().start());
|
||||
if (G1ConcRSCountTraversals) {
|
||||
_cur_card_count_histo = NEW_C_HEAP_ARRAY(unsigned, 256);
|
||||
_cum_card_count_histo = NEW_C_HEAP_ARRAY(unsigned, 256);
|
||||
for (int i = 0; i < 256; i++) {
|
||||
_cur_card_count_histo[i] = 0;
|
||||
_cum_card_count_histo[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (G1ConcRSLogCacheSize > 0) {
|
||||
_g1h = G1CollectedHeap::heap();
|
||||
_max_n_card_counts =
|
||||
(unsigned) (_g1h->g1_reserved_obj_bytes() >> CardTableModRefBS::card_shift);
|
||||
|
||||
size_t max_card_num = ((size_t)1 << (sizeof(unsigned)*BitsPerByte-1)) - 1;
|
||||
guarantee(_max_n_card_counts < max_card_num, "card_num representation");
|
||||
|
||||
int desired = _max_n_card_counts / InitialCacheFraction;
|
||||
for (_cache_size_index = 0;
|
||||
_cc_cache_sizes[_cache_size_index] >= 0; _cache_size_index++) {
|
||||
if (_cc_cache_sizes[_cache_size_index] >= desired) break;
|
||||
}
|
||||
_cache_size_index = MAX2(0, (_cache_size_index - 1));
|
||||
|
||||
int initial_size = _cc_cache_sizes[_cache_size_index];
|
||||
if (initial_size < 0) initial_size = _max_n_card_counts;
|
||||
|
||||
// Make sure we don't go bigger than we will ever need
|
||||
_n_card_counts = MIN2((unsigned) initial_size, _max_n_card_counts);
|
||||
|
||||
_card_counts = NEW_C_HEAP_ARRAY(CardCountCacheEntry, _n_card_counts);
|
||||
_card_epochs = NEW_C_HEAP_ARRAY(CardEpochCacheEntry, _n_card_counts);
|
||||
|
||||
Copy::fill_to_bytes(&_card_counts[0],
|
||||
_n_card_counts * sizeof(CardCountCacheEntry));
|
||||
Copy::fill_to_bytes(&_card_epochs[0], _n_card_counts * sizeof(CardEpochCacheEntry));
|
||||
|
||||
ModRefBarrierSet* bs = _g1h->mr_bs();
|
||||
guarantee(bs->is_a(BarrierSet::CardTableModRef), "Precondition");
|
||||
_ct_bs = (CardTableModRefBS*)bs;
|
||||
_ct_bot = _ct_bs->byte_for_const(_g1h->reserved_region().start());
|
||||
|
||||
_def_use_cache = true;
|
||||
_use_cache = true;
|
||||
_hot_cache_size = (1 << G1ConcRSLogCacheSize);
|
||||
_hot_cache = NEW_C_HEAP_ARRAY(jbyte*, _hot_cache_size);
|
||||
_n_hot = 0;
|
||||
_hot_cache_idx = 0;
|
||||
|
||||
// For refining the cards in the hot cache in parallel
|
||||
int n_workers = (ParallelGCThreads > 0 ?
|
||||
_g1h->workers()->total_workers() : 1);
|
||||
_hot_cache_par_chunk_size = MAX2(1, _hot_cache_size / n_workers);
|
||||
_hot_cache_par_claimed_idx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,15 +124,11 @@ void ConcurrentG1Refine::stop() {
|
||||
}
|
||||
|
||||
ConcurrentG1Refine::~ConcurrentG1Refine() {
|
||||
if (G1ConcRSLogCacheSize > 0 || G1ConcRSCountTraversals) {
|
||||
assert(_card_counts != NULL, "Logic");
|
||||
FREE_C_HEAP_ARRAY(unsigned char, _card_counts);
|
||||
assert(_cur_card_count_histo != NULL, "Logic");
|
||||
FREE_C_HEAP_ARRAY(unsigned, _cur_card_count_histo);
|
||||
assert(_cum_card_count_histo != NULL, "Logic");
|
||||
FREE_C_HEAP_ARRAY(unsigned, _cum_card_count_histo);
|
||||
}
|
||||
if (G1ConcRSLogCacheSize > 0) {
|
||||
assert(_card_counts != NULL, "Logic");
|
||||
FREE_C_HEAP_ARRAY(CardCountCacheEntry, _card_counts);
|
||||
assert(_card_epochs != NULL, "Logic");
|
||||
FREE_C_HEAP_ARRAY(CardEpochCacheEntry, _card_epochs);
|
||||
assert(_hot_cache != NULL, "Logic");
|
||||
FREE_C_HEAP_ARRAY(jbyte*, _hot_cache);
|
||||
}
|
||||
@ -123,165 +148,232 @@ void ConcurrentG1Refine::threads_do(ThreadClosure *tc) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int ConcurrentG1Refine::add_card_count(jbyte* card_ptr) {
|
||||
size_t card_num = (card_ptr - _ct_bot);
|
||||
guarantee(0 <= card_num && card_num < _n_card_counts, "Bounds");
|
||||
unsigned char cnt = _card_counts[card_num];
|
||||
if (cnt < 255) _card_counts[card_num]++;
|
||||
return cnt;
|
||||
_total_travs++;
|
||||
bool ConcurrentG1Refine::is_young_card(jbyte* card_ptr) {
|
||||
HeapWord* start = _ct_bs->addr_for(card_ptr);
|
||||
HeapRegion* r = _g1h->heap_region_containing(start);
|
||||
if (r != NULL && r->is_young()) {
|
||||
return true;
|
||||
}
|
||||
// This card is not associated with a heap region
|
||||
// so can't be young.
|
||||
return false;
|
||||
}
|
||||
|
||||
jbyte* ConcurrentG1Refine::cache_insert(jbyte* card_ptr) {
|
||||
int count = add_card_count(card_ptr);
|
||||
// Count previously unvisited cards.
|
||||
if (count == 0) _total_cards++;
|
||||
// We'll assume a traversal unless we store it in the cache.
|
||||
if (count < G1ConcRSHotCardLimit) {
|
||||
_total_travs++;
|
||||
return card_ptr;
|
||||
jbyte* ConcurrentG1Refine::add_card_count(jbyte* card_ptr, int* count, bool* defer) {
|
||||
unsigned new_card_num = ptr_2_card_num(card_ptr);
|
||||
unsigned bucket = hash(new_card_num);
|
||||
assert(0 <= bucket && bucket < _n_card_counts, "Bounds");
|
||||
|
||||
CardCountCacheEntry* count_ptr = &_card_counts[bucket];
|
||||
CardEpochCacheEntry* epoch_ptr = &_card_epochs[bucket];
|
||||
|
||||
// We have to construct a new entry if we haven't updated the counts
|
||||
// during the current period, or if the count was updated for a
|
||||
// different card number.
|
||||
unsigned int new_epoch = (unsigned int) _n_periods;
|
||||
julong new_epoch_entry = make_epoch_entry(new_card_num, new_epoch);
|
||||
|
||||
while (true) {
|
||||
// Fetch the previous epoch value
|
||||
julong prev_epoch_entry = epoch_ptr->_value;
|
||||
julong cas_res;
|
||||
|
||||
if (extract_epoch(prev_epoch_entry) != new_epoch) {
|
||||
// This entry has not yet been updated during this period.
|
||||
// Note: we update the epoch value atomically to ensure
|
||||
// that there is only one winner that updates the cached
|
||||
// card_ptr value even though all the refine threads share
|
||||
// the same epoch value.
|
||||
|
||||
cas_res = (julong) Atomic::cmpxchg((jlong) new_epoch_entry,
|
||||
(volatile jlong*)&epoch_ptr->_value,
|
||||
(jlong) prev_epoch_entry);
|
||||
|
||||
if (cas_res == prev_epoch_entry) {
|
||||
// We have successfully won the race to update the
|
||||
// epoch and card_num value. Make it look like the
|
||||
// count and eviction count were previously cleared.
|
||||
count_ptr->_count = 1;
|
||||
count_ptr->_evict_count = 0;
|
||||
*count = 0;
|
||||
// We can defer the processing of card_ptr
|
||||
*defer = true;
|
||||
return card_ptr;
|
||||
}
|
||||
// We did not win the race to update the epoch field, so some other
|
||||
// thread must have done it. The value that gets returned by CAS
|
||||
// should be the new epoch value.
|
||||
assert(extract_epoch(cas_res) == new_epoch, "unexpected epoch");
|
||||
// We could 'continue' here or just re-read the previous epoch value
|
||||
prev_epoch_entry = epoch_ptr->_value;
|
||||
}
|
||||
|
||||
// The epoch entry for card_ptr has been updated during this period.
|
||||
unsigned old_card_num = extract_card_num(prev_epoch_entry);
|
||||
|
||||
// The card count that will be returned to caller
|
||||
*count = count_ptr->_count;
|
||||
|
||||
// Are we updating the count for the same card?
|
||||
if (new_card_num == old_card_num) {
|
||||
// Same card - just update the count. We could have more than one
|
||||
// thread racing to update count for the current card. It should be
|
||||
// OK not to use a CAS as the only penalty should be some missed
|
||||
// increments of the count which delays identifying the card as "hot".
|
||||
|
||||
if (*count < max_jubyte) count_ptr->_count++;
|
||||
// We can defer the processing of card_ptr
|
||||
*defer = true;
|
||||
return card_ptr;
|
||||
}
|
||||
|
||||
// Different card - evict old card info
|
||||
if (count_ptr->_evict_count < max_jubyte) count_ptr->_evict_count++;
|
||||
if (count_ptr->_evict_count > G1CardCountCacheExpandThreshold) {
|
||||
// Trigger a resize the next time we clear
|
||||
_expand_card_counts = true;
|
||||
}
|
||||
|
||||
cas_res = (julong) Atomic::cmpxchg((jlong) new_epoch_entry,
|
||||
(volatile jlong*)&epoch_ptr->_value,
|
||||
(jlong) prev_epoch_entry);
|
||||
|
||||
if (cas_res == prev_epoch_entry) {
|
||||
// We successfully updated the card num value in the epoch entry
|
||||
count_ptr->_count = 0; // initialize counter for new card num
|
||||
|
||||
// Even though the region containg the card at old_card_num was not
|
||||
// in the young list when old_card_num was recorded in the epoch
|
||||
// cache it could have been added to the free list and subsequently
|
||||
// added to the young list in the intervening time. If the evicted
|
||||
// card is in a young region just return the card_ptr and the evicted
|
||||
// card will not be cleaned. See CR 6817995.
|
||||
|
||||
jbyte* old_card_ptr = card_num_2_ptr(old_card_num);
|
||||
if (is_young_card(old_card_ptr)) {
|
||||
*count = 0;
|
||||
// We can defer the processing of card_ptr
|
||||
*defer = true;
|
||||
return card_ptr;
|
||||
}
|
||||
|
||||
// We do not want to defer processing of card_ptr in this case
|
||||
// (we need to refine old_card_ptr and card_ptr)
|
||||
*defer = false;
|
||||
return old_card_ptr;
|
||||
}
|
||||
// Someone else beat us - try again.
|
||||
}
|
||||
// Otherwise, it's hot.
|
||||
}
|
||||
|
||||
jbyte* ConcurrentG1Refine::cache_insert(jbyte* card_ptr, bool* defer) {
|
||||
int count;
|
||||
jbyte* cached_ptr = add_card_count(card_ptr, &count, defer);
|
||||
assert(cached_ptr != NULL, "bad cached card ptr");
|
||||
assert(!is_young_card(cached_ptr), "shouldn't get a card in young region");
|
||||
|
||||
// The card pointer we obtained from card count cache is not hot
|
||||
// so do not store it in the cache; return it for immediate
|
||||
// refining.
|
||||
if (count < G1ConcRSHotCardLimit) {
|
||||
return cached_ptr;
|
||||
}
|
||||
|
||||
// Otherwise, the pointer we got from the _card_counts is hot.
|
||||
jbyte* res = NULL;
|
||||
MutexLockerEx x(HotCardCache_lock, Mutex::_no_safepoint_check_flag);
|
||||
if (_n_hot == _hot_cache_size) {
|
||||
_total_travs++;
|
||||
res = _hot_cache[_hot_cache_idx];
|
||||
_n_hot--;
|
||||
}
|
||||
// Now _n_hot < _hot_cache_size, and we can insert at _hot_cache_idx.
|
||||
_hot_cache[_hot_cache_idx] = card_ptr;
|
||||
_hot_cache[_hot_cache_idx] = cached_ptr;
|
||||
_hot_cache_idx++;
|
||||
if (_hot_cache_idx == _hot_cache_size) _hot_cache_idx = 0;
|
||||
_n_hot++;
|
||||
|
||||
if (res != NULL) {
|
||||
// Even though the region containg res was not in the young list
|
||||
// when it was recorded in the hot cache it could have been added
|
||||
// to the free list and subsequently added to the young list in
|
||||
// the intervening time. If res is in a young region, return NULL
|
||||
// so that res is not cleaned. See CR 6817995.
|
||||
|
||||
if (is_young_card(res)) {
|
||||
res = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
void ConcurrentG1Refine::clean_up_cache(int worker_i, G1RemSet* g1rs) {
|
||||
assert(!use_cache(), "cache should be disabled");
|
||||
int start_ind = _hot_cache_idx-1;
|
||||
for (int i = 0; i < _n_hot; i++) {
|
||||
int ind = start_ind - i;
|
||||
if (ind < 0) ind = ind + _hot_cache_size;
|
||||
jbyte* entry = _hot_cache[ind];
|
||||
if (entry != NULL) {
|
||||
g1rs->concurrentRefineOneCard(entry, worker_i);
|
||||
int start_idx;
|
||||
|
||||
while ((start_idx = _hot_cache_par_claimed_idx) < _n_hot) { // read once
|
||||
int end_idx = start_idx + _hot_cache_par_chunk_size;
|
||||
|
||||
if (start_idx ==
|
||||
Atomic::cmpxchg(end_idx, &_hot_cache_par_claimed_idx, start_idx)) {
|
||||
// The current worker has successfully claimed the chunk [start_idx..end_idx)
|
||||
end_idx = MIN2(end_idx, _n_hot);
|
||||
for (int i = start_idx; i < end_idx; i++) {
|
||||
jbyte* entry = _hot_cache[i];
|
||||
if (entry != NULL) {
|
||||
g1rs->concurrentRefineOneCard(entry, worker_i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConcurrentG1Refine::expand_card_count_cache() {
|
||||
if (_n_card_counts < _max_n_card_counts) {
|
||||
int new_idx = _cache_size_index+1;
|
||||
int new_size = _cc_cache_sizes[new_idx];
|
||||
if (new_size < 0) new_size = _max_n_card_counts;
|
||||
|
||||
// Make sure we don't go bigger than we will ever need
|
||||
new_size = MIN2((unsigned) new_size, _max_n_card_counts);
|
||||
|
||||
// Expand the card count and card epoch tables
|
||||
if (new_size > (int)_n_card_counts) {
|
||||
// We can just free and allocate a new array as we're
|
||||
// not interested in preserving the contents
|
||||
assert(_card_counts != NULL, "Logic!");
|
||||
assert(_card_epochs != NULL, "Logic!");
|
||||
FREE_C_HEAP_ARRAY(CardCountCacheEntry, _card_counts);
|
||||
FREE_C_HEAP_ARRAY(CardEpochCacheEntry, _card_epochs);
|
||||
_n_card_counts = new_size;
|
||||
_card_counts = NEW_C_HEAP_ARRAY(CardCountCacheEntry, _n_card_counts);
|
||||
_card_epochs = NEW_C_HEAP_ARRAY(CardEpochCacheEntry, _n_card_counts);
|
||||
_cache_size_index = new_idx;
|
||||
}
|
||||
}
|
||||
_n_hot = 0;
|
||||
_hot_cache_idx = 0;
|
||||
}
|
||||
|
||||
void ConcurrentG1Refine::clear_and_record_card_counts() {
|
||||
if (G1ConcRSLogCacheSize == 0 && !G1ConcRSCountTraversals) return;
|
||||
if (G1ConcRSLogCacheSize == 0) return;
|
||||
|
||||
#ifndef PRODUCT
|
||||
double start = os::elapsedTime();
|
||||
#endif
|
||||
|
||||
if (_expand_card_counts) {
|
||||
expand_card_count_cache();
|
||||
_expand_card_counts = false;
|
||||
// Only need to clear the epochs.
|
||||
Copy::fill_to_bytes(&_card_epochs[0], _n_card_counts * sizeof(CardEpochCacheEntry));
|
||||
}
|
||||
|
||||
int this_epoch = (int) _n_periods;
|
||||
assert((this_epoch+1) <= max_jint, "to many periods");
|
||||
// Update epoch
|
||||
_n_periods++;
|
||||
if (G1ConcRSCountTraversals) {
|
||||
for (size_t i = 0; i < _n_card_counts; i++) {
|
||||
unsigned char bucket = _card_counts[i];
|
||||
_cur_card_count_histo[bucket]++;
|
||||
_card_counts[i] = 0;
|
||||
}
|
||||
gclog_or_tty->print_cr("Card counts:");
|
||||
for (int i = 0; i < 256; i++) {
|
||||
if (_cur_card_count_histo[i] > 0) {
|
||||
gclog_or_tty->print_cr(" %3d: %9d", i, _cur_card_count_histo[i]);
|
||||
_cum_card_count_histo[i] += _cur_card_count_histo[i];
|
||||
_cur_card_count_histo[i] = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
assert(G1ConcRSLogCacheSize > 0, "Logic");
|
||||
Copy::fill_to_words((HeapWord*)(&_card_counts[0]),
|
||||
_n_card_counts / HeapWordSize);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ConcurrentG1Refine::
|
||||
print_card_count_histo_range(unsigned* histo, int from, int to,
|
||||
float& cum_card_pct,
|
||||
float& cum_travs_pct) {
|
||||
unsigned cards = 0;
|
||||
unsigned travs = 0;
|
||||
guarantee(to <= 256, "Precondition");
|
||||
for (int i = from; i < to-1; i++) {
|
||||
cards += histo[i];
|
||||
travs += histo[i] * i;
|
||||
}
|
||||
if (to == 256) {
|
||||
unsigned histo_card_sum = 0;
|
||||
unsigned histo_trav_sum = 0;
|
||||
for (int i = 1; i < 255; i++) {
|
||||
histo_trav_sum += histo[i] * i;
|
||||
}
|
||||
cards += histo[255];
|
||||
// correct traversals for the last one.
|
||||
unsigned travs_255 = (unsigned) (_total_travs - histo_trav_sum);
|
||||
travs += travs_255;
|
||||
|
||||
} else {
|
||||
cards += histo[to-1];
|
||||
travs += histo[to-1] * (to-1);
|
||||
}
|
||||
float fperiods = (float)_n_periods;
|
||||
float f_tot_cards = (float)_total_cards/fperiods;
|
||||
float f_tot_travs = (float)_total_travs/fperiods;
|
||||
if (cards > 0) {
|
||||
float fcards = (float)cards/fperiods;
|
||||
float ftravs = (float)travs/fperiods;
|
||||
if (to == 256) {
|
||||
gclog_or_tty->print(" %4d- %10.2f%10.2f", from, fcards, ftravs);
|
||||
} else {
|
||||
gclog_or_tty->print(" %4d-%4d %10.2f%10.2f", from, to-1, fcards, ftravs);
|
||||
}
|
||||
float pct_cards = fcards*100.0/f_tot_cards;
|
||||
cum_card_pct += pct_cards;
|
||||
float pct_travs = ftravs*100.0/f_tot_travs;
|
||||
cum_travs_pct += pct_travs;
|
||||
gclog_or_tty->print_cr("%10.2f%10.2f%10.2f%10.2f",
|
||||
pct_cards, cum_card_pct,
|
||||
pct_travs, cum_travs_pct);
|
||||
}
|
||||
}
|
||||
|
||||
void ConcurrentG1Refine::print_final_card_counts() {
|
||||
if (!G1ConcRSCountTraversals) return;
|
||||
|
||||
gclog_or_tty->print_cr("Did %d total traversals of %d distinct cards.",
|
||||
_total_travs, _total_cards);
|
||||
float fperiods = (float)_n_periods;
|
||||
gclog_or_tty->print_cr(" This is an average of %8.2f traversals, %8.2f cards, "
|
||||
"per collection.", (float)_total_travs/fperiods,
|
||||
(float)_total_cards/fperiods);
|
||||
gclog_or_tty->print_cr(" This is an average of %8.2f traversals/distinct "
|
||||
"dirty card.\n",
|
||||
_total_cards > 0 ?
|
||||
(float)_total_travs/(float)_total_cards : 0.0);
|
||||
|
||||
|
||||
gclog_or_tty->print_cr("Histogram:\n\n%10s %10s%10s%10s%10s%10s%10s",
|
||||
"range", "# cards", "# travs", "% cards", "(cum)",
|
||||
"% travs", "(cum)");
|
||||
gclog_or_tty->print_cr("------------------------------------------------------------"
|
||||
"-------------");
|
||||
float cum_cards_pct = 0.0;
|
||||
float cum_travs_pct = 0.0;
|
||||
for (int i = 1; i < 10; i++) {
|
||||
print_card_count_histo_range(_cum_card_count_histo, i, i+1,
|
||||
cum_cards_pct, cum_travs_pct);
|
||||
}
|
||||
for (int i = 10; i < 100; i += 10) {
|
||||
print_card_count_histo_range(_cum_card_count_histo, i, i+10,
|
||||
cum_cards_pct, cum_travs_pct);
|
||||
}
|
||||
print_card_count_histo_range(_cum_card_count_histo, 100, 150,
|
||||
cum_cards_pct, cum_travs_pct);
|
||||
print_card_count_histo_range(_cum_card_count_histo, 150, 200,
|
||||
cum_cards_pct, cum_travs_pct);
|
||||
print_card_count_histo_range(_cum_card_count_histo, 150, 255,
|
||||
cum_cards_pct, cum_travs_pct);
|
||||
print_card_count_histo_range(_cum_card_count_histo, 255, 256,
|
||||
cum_cards_pct, cum_travs_pct);
|
||||
|
||||
#ifndef PRODUCT
|
||||
double elapsed = os::elapsedTime() - start;
|
||||
_g1h->g1_policy()->record_cc_clear_time(elapsed * 1000.0);
|
||||
#endif
|
||||
}
|
||||
|
@ -29,29 +29,117 @@ class G1RemSet;
|
||||
class ConcurrentG1Refine: public CHeapObj {
|
||||
ConcurrentG1RefineThread** _threads;
|
||||
int _n_threads;
|
||||
// The cache for card refinement.
|
||||
bool _use_cache;
|
||||
bool _def_use_cache;
|
||||
size_t _n_periods;
|
||||
size_t _total_cards;
|
||||
size_t _total_travs;
|
||||
|
||||
unsigned char* _card_counts;
|
||||
// The cache for card refinement.
|
||||
bool _use_cache;
|
||||
bool _def_use_cache;
|
||||
|
||||
size_t _n_periods; // Used as clearing epoch
|
||||
|
||||
// An evicting cache of the number of times each card
|
||||
// is accessed. Reduces, but does not eliminate, the amount
|
||||
// of duplicated processing of dirty cards.
|
||||
|
||||
enum SomePrivateConstants {
|
||||
epoch_bits = 32,
|
||||
card_num_shift = epoch_bits,
|
||||
epoch_mask = AllBits,
|
||||
card_num_mask = AllBits,
|
||||
|
||||
// The initial cache size is approximately this fraction
|
||||
// of a maximal cache (i.e. the size needed for all cards
|
||||
// in the heap)
|
||||
InitialCacheFraction = 512
|
||||
};
|
||||
|
||||
const static julong card_num_mask_in_place =
|
||||
(julong) card_num_mask << card_num_shift;
|
||||
|
||||
typedef struct {
|
||||
julong _value; // | card_num | epoch |
|
||||
} CardEpochCacheEntry;
|
||||
|
||||
julong make_epoch_entry(unsigned int card_num, unsigned int epoch) {
|
||||
assert(0 <= card_num && card_num < _max_n_card_counts, "Bounds");
|
||||
assert(0 <= epoch && epoch <= _n_periods, "must be");
|
||||
|
||||
return ((julong) card_num << card_num_shift) | epoch;
|
||||
}
|
||||
|
||||
unsigned int extract_epoch(julong v) {
|
||||
return (v & epoch_mask);
|
||||
}
|
||||
|
||||
unsigned int extract_card_num(julong v) {
|
||||
return (v & card_num_mask_in_place) >> card_num_shift;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
unsigned char _count;
|
||||
unsigned char _evict_count;
|
||||
} CardCountCacheEntry;
|
||||
|
||||
CardCountCacheEntry* _card_counts;
|
||||
CardEpochCacheEntry* _card_epochs;
|
||||
|
||||
// The current number of buckets in the card count cache
|
||||
unsigned _n_card_counts;
|
||||
|
||||
// The max number of buckets required for the number of
|
||||
// cards for the entire reserved heap
|
||||
unsigned _max_n_card_counts;
|
||||
|
||||
// Possible sizes of the cache: odd primes that roughly double in size.
|
||||
// (See jvmtiTagMap.cpp).
|
||||
static int _cc_cache_sizes[];
|
||||
|
||||
// The index in _cc_cache_sizes corresponding to the size of
|
||||
// _card_counts.
|
||||
int _cache_size_index;
|
||||
|
||||
bool _expand_card_counts;
|
||||
|
||||
const jbyte* _ct_bot;
|
||||
unsigned* _cur_card_count_histo;
|
||||
unsigned* _cum_card_count_histo;
|
||||
jbyte** _hot_cache;
|
||||
int _hot_cache_size;
|
||||
int _n_hot;
|
||||
int _hot_cache_idx;
|
||||
|
||||
jbyte** _hot_cache;
|
||||
int _hot_cache_size;
|
||||
int _n_hot;
|
||||
int _hot_cache_idx;
|
||||
|
||||
int _hot_cache_par_chunk_size;
|
||||
volatile int _hot_cache_par_claimed_idx;
|
||||
|
||||
// Needed to workaround 6817995
|
||||
CardTableModRefBS* _ct_bs;
|
||||
G1CollectedHeap* _g1h;
|
||||
|
||||
// Expands the array that holds the card counts to the next size up
|
||||
void expand_card_count_cache();
|
||||
|
||||
// hash a given key (index of card_ptr) with the specified size
|
||||
static unsigned int hash(size_t key, int size) {
|
||||
return (unsigned int) key % size;
|
||||
}
|
||||
|
||||
// hash a given key (index of card_ptr)
|
||||
unsigned int hash(size_t key) {
|
||||
return hash(key, _n_card_counts);
|
||||
}
|
||||
|
||||
unsigned ptr_2_card_num(jbyte* card_ptr) {
|
||||
return (unsigned) (card_ptr - _ct_bot);
|
||||
}
|
||||
|
||||
jbyte* card_num_2_ptr(unsigned card_num) {
|
||||
return (jbyte*) (_ct_bot + card_num);
|
||||
}
|
||||
|
||||
// Returns the count of this card after incrementing it.
|
||||
int add_card_count(jbyte* card_ptr);
|
||||
jbyte* add_card_count(jbyte* card_ptr, int* count, bool* defer);
|
||||
|
||||
// Returns true if this card is in a young region
|
||||
bool is_young_card(jbyte* card_ptr);
|
||||
|
||||
void print_card_count_histo_range(unsigned* histo, int from, int to,
|
||||
float& cum_card_pct,
|
||||
float& cum_travs_pct);
|
||||
public:
|
||||
ConcurrentG1Refine();
|
||||
~ConcurrentG1Refine();
|
||||
@ -65,11 +153,16 @@ class ConcurrentG1Refine: public CHeapObj {
|
||||
// If this is the first entry for the slot, writes into the cache and
|
||||
// returns NULL. If it causes an eviction, returns the evicted pointer.
|
||||
// Otherwise, its a cache hit, and returns NULL.
|
||||
jbyte* cache_insert(jbyte* card_ptr);
|
||||
jbyte* cache_insert(jbyte* card_ptr, bool* defer);
|
||||
|
||||
// Process the cached entries.
|
||||
void clean_up_cache(int worker_i, G1RemSet* g1rs);
|
||||
|
||||
// Set up for parallel processing of the cards in the hot cache
|
||||
void clear_hot_cache_claimed_index() {
|
||||
_hot_cache_par_claimed_idx = 0;
|
||||
}
|
||||
|
||||
// Discard entries in the hot cache.
|
||||
void clear_hot_cache() {
|
||||
_hot_cache_idx = 0; _n_hot = 0;
|
||||
@ -84,7 +177,6 @@ class ConcurrentG1Refine: public CHeapObj {
|
||||
}
|
||||
|
||||
void clear_and_record_card_counts();
|
||||
void print_final_card_counts();
|
||||
|
||||
static size_t thread_num();
|
||||
};
|
||||
|
@ -39,7 +39,6 @@ ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r, ConcurrentG1RefineThread *nex
|
||||
_next(next),
|
||||
_cg1r(cg1r),
|
||||
_vtime_accum(0.0),
|
||||
_co_tracker(G1CRGroup),
|
||||
_interval_ms(5.0)
|
||||
{
|
||||
create_and_start();
|
||||
@ -76,9 +75,6 @@ void ConcurrentG1RefineThread::run() {
|
||||
_vtime_start = os::elapsedVTime();
|
||||
wait_for_universe_init();
|
||||
|
||||
_co_tracker.enable();
|
||||
_co_tracker.start();
|
||||
|
||||
while (!_should_terminate) {
|
||||
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
|
||||
// Wait for completed log buffers to exist.
|
||||
@ -104,17 +100,17 @@ void ConcurrentG1RefineThread::run() {
|
||||
double start_vtime_sec; // only used when G1SmoothConcRefine is on
|
||||
int prev_buffer_num; // only used when G1SmoothConcRefine is on
|
||||
// This thread activation threshold
|
||||
int threshold = DCQBarrierProcessCompletedThreshold * _worker_id;
|
||||
int threshold = G1UpdateBufferQueueProcessingThreshold * _worker_id;
|
||||
// Next thread activation threshold
|
||||
int next_threshold = threshold + DCQBarrierProcessCompletedThreshold;
|
||||
int deactivation_threshold = MAX2<int>(threshold - DCQBarrierProcessCompletedThreshold / 2, 0);
|
||||
int next_threshold = threshold + G1UpdateBufferQueueProcessingThreshold;
|
||||
int deactivation_threshold = MAX2<int>(threshold - G1UpdateBufferQueueProcessingThreshold / 2, 0);
|
||||
|
||||
if (G1SmoothConcRefine) {
|
||||
lower_limit = 0;
|
||||
start_vtime_sec = os::elapsedVTime();
|
||||
prev_buffer_num = (int) dcqs.completed_buffers_num();
|
||||
} else {
|
||||
lower_limit = DCQBarrierProcessCompletedThreshold / 4; // For now.
|
||||
lower_limit = G1UpdateBufferQueueProcessingThreshold / 4; // For now.
|
||||
}
|
||||
while (dcqs.apply_closure_to_completed_buffer(_worker_id + _worker_id_offset, lower_limit)) {
|
||||
double end_vtime_sec;
|
||||
@ -147,7 +143,6 @@ void ConcurrentG1RefineThread::run() {
|
||||
}
|
||||
break;
|
||||
}
|
||||
_co_tracker.update(false);
|
||||
|
||||
// Check if we need to activate the next thread.
|
||||
if (curr_buffer_num > next_threshold && _next != NULL && !_next->is_active()) {
|
||||
@ -168,7 +163,6 @@ void ConcurrentG1RefineThread::run() {
|
||||
}
|
||||
n_logs++;
|
||||
}
|
||||
_co_tracker.update(false);
|
||||
_sts.leave();
|
||||
|
||||
if (os::supports_vtime()) {
|
||||
@ -177,9 +171,6 @@ void ConcurrentG1RefineThread::run() {
|
||||
_vtime_accum = 0.0;
|
||||
}
|
||||
}
|
||||
_sts.join();
|
||||
_co_tracker.update(true);
|
||||
_sts.leave();
|
||||
assert(_should_terminate, "just checking");
|
||||
|
||||
terminate();
|
||||
|
@ -51,7 +51,6 @@ class ConcurrentG1RefineThread: public ConcurrentGCThread {
|
||||
private:
|
||||
ConcurrentG1Refine* _cg1r;
|
||||
|
||||
COTracker _co_tracker;
|
||||
double _interval_ms;
|
||||
|
||||
void decreaseInterval(int processing_time_ms) {
|
||||
|
@ -433,8 +433,7 @@ ConcurrentMark::ConcurrentMark(ReservedSpace rs,
|
||||
_total_counting_time(0.0),
|
||||
_total_rs_scrub_time(0.0),
|
||||
|
||||
_parallel_workers(NULL),
|
||||
_cleanup_co_tracker(G1CLGroup)
|
||||
_parallel_workers(NULL)
|
||||
{
|
||||
CMVerboseLevel verbose_level =
|
||||
(CMVerboseLevel) G1MarkingVerboseLevel;
|
||||
@ -823,18 +822,6 @@ void ConcurrentMark::checkpointRootsInitialPost() {
|
||||
// when marking is on. So, it's also called at the end of the
|
||||
// initial-mark pause to update the heap end, if the heap expands
|
||||
// during it. No need to call it here.
|
||||
|
||||
guarantee( !_cleanup_co_tracker.enabled(), "invariant" );
|
||||
|
||||
size_t max_marking_threads =
|
||||
MAX2((size_t) 1, parallel_marking_threads());
|
||||
for (int i = 0; i < (int)_max_task_num; ++i) {
|
||||
_tasks[i]->enable_co_tracker();
|
||||
if (i < (int) max_marking_threads)
|
||||
_tasks[i]->reset_co_tracker(marking_task_overhead());
|
||||
else
|
||||
_tasks[i]->reset_co_tracker(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
// Checkpoint the roots into this generation from outside
|
||||
@ -845,7 +832,6 @@ void ConcurrentMark::checkpointRootsInitial() {
|
||||
G1CollectedHeap* g1h = G1CollectedHeap::heap();
|
||||
|
||||
double start = os::elapsedTime();
|
||||
GCOverheadReporter::recordSTWStart(start);
|
||||
|
||||
G1CollectorPolicy* g1p = G1CollectedHeap::heap()->g1_policy();
|
||||
g1p->record_concurrent_mark_init_start();
|
||||
@ -876,7 +862,6 @@ void ConcurrentMark::checkpointRootsInitial() {
|
||||
// Statistics.
|
||||
double end = os::elapsedTime();
|
||||
_init_times.add((end - start) * 1000.0);
|
||||
GCOverheadReporter::recordSTWEnd(end);
|
||||
|
||||
g1p->record_concurrent_mark_init_end();
|
||||
}
|
||||
@ -1035,7 +1020,6 @@ public:
|
||||
|
||||
guarantee( (size_t)worker_i < _cm->active_tasks(), "invariant" );
|
||||
CMTask* the_task = _cm->task(worker_i);
|
||||
the_task->start_co_tracker();
|
||||
the_task->record_start_time();
|
||||
if (!_cm->has_aborted()) {
|
||||
do {
|
||||
@ -1061,8 +1045,6 @@ public:
|
||||
double end_time2_sec = os::elapsedTime();
|
||||
double elapsed_time2_sec = end_time2_sec - start_time_sec;
|
||||
|
||||
the_task->update_co_tracker();
|
||||
|
||||
#if 0
|
||||
gclog_or_tty->print_cr("CM: elapsed %1.4lf ms, sleep %1.4lf ms, "
|
||||
"overhead %1.4lf",
|
||||
@ -1079,7 +1061,6 @@ public:
|
||||
ConcurrentGCThread::stsLeave();
|
||||
|
||||
double end_vtime = os::elapsedVTime();
|
||||
the_task->update_co_tracker(true);
|
||||
_cm->update_accum_task_vtime(worker_i, end_vtime - start_vtime);
|
||||
}
|
||||
|
||||
@ -1133,7 +1114,6 @@ void ConcurrentMark::checkpointRootsFinal(bool clear_all_soft_refs) {
|
||||
g1p->record_concurrent_mark_remark_start();
|
||||
|
||||
double start = os::elapsedTime();
|
||||
GCOverheadReporter::recordSTWStart(start);
|
||||
|
||||
checkpointRootsFinalWork();
|
||||
|
||||
@ -1173,11 +1153,6 @@ void ConcurrentMark::checkpointRootsFinal(bool clear_all_soft_refs) {
|
||||
_remark_weak_ref_times.add((now - mark_work_end) * 1000.0);
|
||||
_remark_times.add((now - start) * 1000.0);
|
||||
|
||||
GCOverheadReporter::recordSTWEnd(now);
|
||||
for (int i = 0; i < (int)_max_task_num; ++i)
|
||||
_tasks[i]->disable_co_tracker();
|
||||
_cleanup_co_tracker.enable();
|
||||
_cleanup_co_tracker.reset(cleanup_task_overhead());
|
||||
g1p->record_concurrent_mark_remark_end();
|
||||
}
|
||||
|
||||
@ -1188,7 +1163,6 @@ class CalcLiveObjectsClosure: public HeapRegionClosure {
|
||||
|
||||
CMBitMapRO* _bm;
|
||||
ConcurrentMark* _cm;
|
||||
COTracker* _co_tracker;
|
||||
bool _changed;
|
||||
bool _yield;
|
||||
size_t _words_done;
|
||||
@ -1216,12 +1190,10 @@ class CalcLiveObjectsClosure: public HeapRegionClosure {
|
||||
public:
|
||||
CalcLiveObjectsClosure(bool final,
|
||||
CMBitMapRO *bm, ConcurrentMark *cm,
|
||||
BitMap* region_bm, BitMap* card_bm,
|
||||
COTracker* co_tracker) :
|
||||
BitMap* region_bm, BitMap* card_bm) :
|
||||
_bm(bm), _cm(cm), _changed(false), _yield(true),
|
||||
_words_done(0), _tot_live(0), _tot_used(0),
|
||||
_region_bm(region_bm), _card_bm(card_bm),
|
||||
_final(final), _co_tracker(co_tracker),
|
||||
_region_bm(region_bm), _card_bm(card_bm),_final(final),
|
||||
_regions_done(0), _start_vtime_sec(0.0)
|
||||
{
|
||||
_bottom_card_num =
|
||||
@ -1265,9 +1237,6 @@ public:
|
||||
}
|
||||
|
||||
bool doHeapRegion(HeapRegion* hr) {
|
||||
if (_co_tracker != NULL)
|
||||
_co_tracker->update();
|
||||
|
||||
if (!_final && _regions_done == 0)
|
||||
_start_vtime_sec = os::elapsedVTime();
|
||||
|
||||
@ -1396,12 +1365,6 @@ public:
|
||||
if (elapsed_vtime_sec > (10.0 / 1000.0)) {
|
||||
jlong sleep_time_ms =
|
||||
(jlong) (elapsed_vtime_sec * _cm->cleanup_sleep_factor() * 1000.0);
|
||||
#if 0
|
||||
gclog_or_tty->print_cr("CL: elapsed %1.4lf ms, sleep %1.4lf ms, "
|
||||
"overhead %1.4lf",
|
||||
elapsed_vtime_sec * 1000.0, (double) sleep_time_ms,
|
||||
_co_tracker->concOverhead(os::elapsedTime()));
|
||||
#endif
|
||||
os::sleep(Thread::current(), sleep_time_ms, false);
|
||||
_start_vtime_sec = end_vtime_sec;
|
||||
}
|
||||
@ -1421,15 +1384,11 @@ public:
|
||||
|
||||
|
||||
void ConcurrentMark::calcDesiredRegions() {
|
||||
guarantee( _cleanup_co_tracker.enabled(), "invariant" );
|
||||
_cleanup_co_tracker.start();
|
||||
|
||||
_region_bm.clear();
|
||||
_card_bm.clear();
|
||||
CalcLiveObjectsClosure calccl(false /*final*/,
|
||||
nextMarkBitMap(), this,
|
||||
&_region_bm, &_card_bm,
|
||||
&_cleanup_co_tracker);
|
||||
&_region_bm, &_card_bm);
|
||||
G1CollectedHeap *g1h = G1CollectedHeap::heap();
|
||||
g1h->heap_region_iterate(&calccl);
|
||||
|
||||
@ -1437,8 +1396,6 @@ void ConcurrentMark::calcDesiredRegions() {
|
||||
calccl.reset();
|
||||
g1h->heap_region_iterate(&calccl);
|
||||
} while (calccl.changed());
|
||||
|
||||
_cleanup_co_tracker.update(true);
|
||||
}
|
||||
|
||||
class G1ParFinalCountTask: public AbstractGangTask {
|
||||
@ -1472,8 +1429,7 @@ public:
|
||||
void work(int i) {
|
||||
CalcLiveObjectsClosure calccl(true /*final*/,
|
||||
_bm, _g1h->concurrent_mark(),
|
||||
_region_bm, _card_bm,
|
||||
NULL /* CO tracker */);
|
||||
_region_bm, _card_bm);
|
||||
calccl.no_yield();
|
||||
if (ParallelGCThreads > 0) {
|
||||
_g1h->heap_region_par_iterate_chunked(&calccl, i,
|
||||
@ -1663,13 +1619,10 @@ void ConcurrentMark::cleanup() {
|
||||
/* prev marking */ true);
|
||||
}
|
||||
|
||||
_cleanup_co_tracker.disable();
|
||||
|
||||
G1CollectorPolicy* g1p = G1CollectedHeap::heap()->g1_policy();
|
||||
g1p->record_concurrent_mark_cleanup_start();
|
||||
|
||||
double start = os::elapsedTime();
|
||||
GCOverheadReporter::recordSTWStart(start);
|
||||
|
||||
// Do counting once more with the world stopped for good measure.
|
||||
G1ParFinalCountTask g1_par_count_task(g1h, nextMarkBitMap(),
|
||||
@ -1774,7 +1727,6 @@ void ConcurrentMark::cleanup() {
|
||||
// Statistics.
|
||||
double end = os::elapsedTime();
|
||||
_cleanup_times.add((end - start) * 1000.0);
|
||||
GCOverheadReporter::recordSTWEnd(end);
|
||||
|
||||
// G1CollectedHeap::heap()->print();
|
||||
// gclog_or_tty->print_cr("HEAP GC TIME STAMP : %d",
|
||||
@ -2401,7 +2353,7 @@ class CSMarkOopClosure: public OopClosure {
|
||||
// Now process this portion of this one.
|
||||
int lim = MIN2(next_arr_ind, len);
|
||||
for (int j = arr_ind; j < lim; j++) {
|
||||
do_oop(aobj->obj_at_addr<T>(j));
|
||||
do_oop(aobj->objArrayOopDesc::obj_at_addr<T>(j));
|
||||
}
|
||||
|
||||
} else {
|
||||
@ -2625,24 +2577,6 @@ void ConcurrentMark::registerCSetRegion(HeapRegion* hr) {
|
||||
_should_gray_objects = true;
|
||||
}
|
||||
|
||||
void ConcurrentMark::disable_co_trackers() {
|
||||
if (has_aborted()) {
|
||||
if (_cleanup_co_tracker.enabled())
|
||||
_cleanup_co_tracker.disable();
|
||||
for (int i = 0; i < (int)_max_task_num; ++i) {
|
||||
CMTask* task = _tasks[i];
|
||||
if (task->co_tracker_enabled())
|
||||
task->disable_co_tracker();
|
||||
}
|
||||
} else {
|
||||
guarantee( !_cleanup_co_tracker.enabled(), "invariant" );
|
||||
for (int i = 0; i < (int)_max_task_num; ++i) {
|
||||
CMTask* task = _tasks[i];
|
||||
guarantee( !task->co_tracker_enabled(), "invariant" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// abandon current marking iteration due to a Full GC
|
||||
void ConcurrentMark::abort() {
|
||||
// Clear all marks to force marking thread to do nothing
|
||||
@ -4018,7 +3952,6 @@ CMTask::CMTask(int task_id,
|
||||
CMTaskQueue* task_queue,
|
||||
CMTaskQueueSet* task_queues)
|
||||
: _g1h(G1CollectedHeap::heap()),
|
||||
_co_tracker(G1CMGroup),
|
||||
_task_id(task_id), _cm(cm),
|
||||
_claimed(false),
|
||||
_nextMarkBitMap(NULL), _hash_seed(17),
|
||||
|
@ -407,8 +407,6 @@ protected:
|
||||
// verbose level
|
||||
CMVerboseLevel _verbose_level;
|
||||
|
||||
COTracker _cleanup_co_tracker;
|
||||
|
||||
// These two fields are used to implement the optimisation that
|
||||
// avoids pushing objects on the global/region stack if there are
|
||||
// no collection set regions above the lowest finger.
|
||||
@ -720,8 +718,6 @@ public:
|
||||
// Called to abort the marking cycle after a Full GC takes palce.
|
||||
void abort();
|
||||
|
||||
void disable_co_trackers();
|
||||
|
||||
// This prints the global/local fingers. It is used for debugging.
|
||||
NOT_PRODUCT(void print_finger();)
|
||||
|
||||
@ -773,9 +769,6 @@ private:
|
||||
// number of calls to this task
|
||||
int _calls;
|
||||
|
||||
// concurrent overhead over a single CPU for this task
|
||||
COTracker _co_tracker;
|
||||
|
||||
// when the virtual timer reaches this time, the marking step should
|
||||
// exit
|
||||
double _time_target_ms;
|
||||
@ -928,27 +921,6 @@ public:
|
||||
|
||||
void set_concurrent(bool concurrent) { _concurrent = concurrent; }
|
||||
|
||||
void enable_co_tracker() {
|
||||
guarantee( !_co_tracker.enabled(), "invariant" );
|
||||
_co_tracker.enable();
|
||||
}
|
||||
void disable_co_tracker() {
|
||||
guarantee( _co_tracker.enabled(), "invariant" );
|
||||
_co_tracker.disable();
|
||||
}
|
||||
bool co_tracker_enabled() {
|
||||
return _co_tracker.enabled();
|
||||
}
|
||||
void reset_co_tracker(double starting_conc_overhead = 0.0) {
|
||||
_co_tracker.reset(starting_conc_overhead);
|
||||
}
|
||||
void start_co_tracker() {
|
||||
_co_tracker.start();
|
||||
}
|
||||
void update_co_tracker(bool force_end = false) {
|
||||
_co_tracker.update(force_end);
|
||||
}
|
||||
|
||||
// The main method of this class which performs a marking step
|
||||
// trying not to exceed the given duration. However, it might exit
|
||||
// prematurely, according to some conditions (i.e. SATB buffers are
|
||||
|
@ -260,10 +260,6 @@ void ConcurrentMarkThread::run() {
|
||||
}
|
||||
}
|
||||
|
||||
_sts.join();
|
||||
_cm->disable_co_trackers();
|
||||
_sts.leave();
|
||||
|
||||
// we now want to allow clearing of the marking bitmap to be
|
||||
// suspended by a collection pause.
|
||||
_sts.join();
|
||||
|
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