mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-20 11:04:34 +02:00
Merge
This commit is contained in:
commit
a99f7bac50
165 changed files with 8440 additions and 2975 deletions
|
@ -14,3 +14,4 @@ bb1ef4ee3d2c8cbf43a37d372325a7952be590b9 jdk7-b33
|
||||||
744554f5a3290e11c71cd2ddb1aff49e431f9ed0 jdk7-b37
|
744554f5a3290e11c71cd2ddb1aff49e431f9ed0 jdk7-b37
|
||||||
cc47a76899ed33a2c513cb688348244c9b5a1288 jdk7-b38
|
cc47a76899ed33a2c513cb688348244c9b5a1288 jdk7-b38
|
||||||
ab523b49de1fc73fefe6855ce1e0349bdbd7af29 jdk7-b39
|
ab523b49de1fc73fefe6855ce1e0349bdbd7af29 jdk7-b39
|
||||||
|
44be42de6693063fb191989bf0e188de2fa51e7c jdk7-b40
|
||||||
|
|
|
@ -98,7 +98,8 @@
|
||||||
<h2><a name="MBE">Minimum Build Environments</a></h2>
|
<h2><a name="MBE">Minimum Build Environments</a></h2>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
This file often describes specific requirements for what we call the
|
This file often describes specific requirements for what we call the
|
||||||
"minimum build environments" (MBE) for the JDK.
|
"minimum build environments" (MBE) for this
|
||||||
|
specific release of the JDK,
|
||||||
Building with the MBE will generate the most compatible
|
Building with the MBE will generate the most compatible
|
||||||
bits that install on, and run correctly on, the most variations
|
bits that install on, and run correctly on, the most variations
|
||||||
of the same base OS and hardware architecture.
|
of the same base OS and hardware architecture.
|
||||||
|
@ -116,22 +117,22 @@
|
||||||
<tr>
|
<tr>
|
||||||
<th>Base OS and Architecture</th>
|
<th>Base OS and Architecture</th>
|
||||||
<th>OS</th>
|
<th>OS</th>
|
||||||
<th>Compiler</th>
|
<th>C/C++ Compiler</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Linux X86 (32bit)</td>
|
<td>Linux X86 (32-bit)</td>
|
||||||
<td>Red Hat Enterprise Linux 4 </td>
|
<td>Fedora 9</td>
|
||||||
<td>gcc 4 </td>
|
<td>gcc 4 </td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Linux X64 (64bit)</td>
|
<td>Linux X64 (64-bit)</td>
|
||||||
<td>Red Hat Enterprise Linux 4 </td>
|
<td>Fedora 9</td>
|
||||||
<td>gcc 4 </td>
|
<td>gcc 4 </td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Solaris SPARC (32bit)</td>
|
<td>Solaris SPARC (32-bit)</td>
|
||||||
<td>Solaris 10 + patches
|
<td>Solaris 10 + patches
|
||||||
<br>
|
<br>
|
||||||
See <a href="http://sunsolve.sun.com/pub-cgi/show.pl?target=patches/JavaSE" target="_blank">
|
See <a href="http://sunsolve.sun.com/pub-cgi/show.pl?target=patches/JavaSE" target="_blank">
|
||||||
|
@ -140,7 +141,7 @@
|
||||||
<td>Sun Studio 12</td>
|
<td>Sun Studio 12</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Solaris SPARCV9 (64bit)</td>
|
<td>Solaris SPARCV9 (64-bit)</td>
|
||||||
<td>Solaris 10 + patches
|
<td>Solaris 10 + patches
|
||||||
<br>
|
<br>
|
||||||
See <a href="http://sunsolve.sun.com/pub-cgi/show.pl?target=patches/JavaSE" target="_blank">
|
See <a href="http://sunsolve.sun.com/pub-cgi/show.pl?target=patches/JavaSE" target="_blank">
|
||||||
|
@ -149,7 +150,7 @@
|
||||||
<td>Sun Studio 12</td>
|
<td>Sun Studio 12</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Solaris X86 (32bit)</td>
|
<td>Solaris X86 (32-bit)</td>
|
||||||
<td>Solaris 10 + patches
|
<td>Solaris 10 + patches
|
||||||
<br>
|
<br>
|
||||||
See <a href="http://sunsolve.sun.com/pub-cgi/show.pl?target=patches/JavaSE" target="_blank">
|
See <a href="http://sunsolve.sun.com/pub-cgi/show.pl?target=patches/JavaSE" target="_blank">
|
||||||
|
@ -158,7 +159,7 @@
|
||||||
<td>Sun Studio 12</td>
|
<td>Sun Studio 12</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Solaris X64 (64bit)</td>
|
<td>Solaris X64 (64-bit)</td>
|
||||||
<td>Solaris 10 + patches
|
<td>Solaris 10 + patches
|
||||||
<br>
|
<br>
|
||||||
See <a href="http://sunsolve.sun.com/pub-cgi/show.pl?target=patches/JavaSE" target="_blank">
|
See <a href="http://sunsolve.sun.com/pub-cgi/show.pl?target=patches/JavaSE" target="_blank">
|
||||||
|
@ -167,17 +168,28 @@
|
||||||
<td>Sun Studio 12</td>
|
<td>Sun Studio 12</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Windows X86 (32bit)</td>
|
<td>Windows X86 (32-bit)</td>
|
||||||
<td>Windows XP</td>
|
<td>Windows XP</td>
|
||||||
<td>Microsoft Visual Studio .NET 2003 Professional</td>
|
<td>Microsoft Visual Studio C++ 2008 Standard Edition</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Windows X64 (64bit)</td>
|
<td>Windows X64 (64-bit)</td>
|
||||||
<td>Windows Server 2003 - Enterprise x64 Edition</td>
|
<td>Windows Server 2003 - Enterprise x64 Edition</td>
|
||||||
<td>Microsoft Platform SDK - April 2005</td>
|
<td>Microsoft Platform SDK - April 2005</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
<p>
|
||||||
|
These same sources do indeed build on many more systems than the
|
||||||
|
above older generation systems, again the above is just a minimum.
|
||||||
|
<p>
|
||||||
|
Compilation problems with newer or different C/C++ compilers is a
|
||||||
|
common problem.
|
||||||
|
Similarly, compilation problems related to changes to the
|
||||||
|
<tt>/usr/include</tt> or system header files is also a
|
||||||
|
common problem with newer or unreleased OS versions.
|
||||||
|
Please report these types of problems as bugs so that they
|
||||||
|
can be dealt with accordingly.
|
||||||
</blockquote>
|
</blockquote>
|
||||||
<!-- ------------------------------------------------------ -->
|
<!-- ------------------------------------------------------ -->
|
||||||
<hr>
|
<hr>
|
||||||
|
@ -488,7 +500,7 @@
|
||||||
not work due to a lack of support for MS-DOS drive letter paths
|
not work due to a lack of support for MS-DOS drive letter paths
|
||||||
like <tt>C:/</tt> or <tt>C:\</tt>.
|
like <tt>C:/</tt> or <tt>C:\</tt>.
|
||||||
Use a 3.80 version, or find a newer
|
Use a 3.80 version, or find a newer
|
||||||
version that has this problem fixed, like 3.82.
|
version that has this problem fixed.
|
||||||
The older 3.80 version of make.exe can be downloaded with this
|
The older 3.80 version of make.exe can be downloaded with this
|
||||||
<a href="http://cygwin.paracoda.com/release/make/make-3.80-1.tar.bz2" target="_blank">
|
<a href="http://cygwin.paracoda.com/release/make/make-3.80-1.tar.bz2" target="_blank">
|
||||||
link</a>.
|
link</a>.
|
||||||
|
@ -575,8 +587,8 @@
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
Install
|
Install
|
||||||
<a href="#ant">Ant</a>, set
|
<a href="#ant">Ant</a>,
|
||||||
<tt><a href="#ANT_HOME">ANT_HOME</a></tt>.
|
make sure it is in your PATH.
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
@ -592,7 +604,7 @@
|
||||||
Approximately 1.4 GB of free disk
|
Approximately 1.4 GB of free disk
|
||||||
space is needed for a 32-bit build.
|
space is needed for a 32-bit build.
|
||||||
<p>
|
<p>
|
||||||
If you are building the 64bit version, you should
|
If you are building the 64-bit version, you should
|
||||||
run the command "isainfo -v" to verify that you have a
|
run the command "isainfo -v" to verify that you have a
|
||||||
64-bit installation, it should say <tt>sparcv9</tt> or
|
64-bit installation, it should say <tt>sparcv9</tt> or
|
||||||
<tt>amd64</tt>.
|
<tt>amd64</tt>.
|
||||||
|
@ -640,8 +652,8 @@
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
Install
|
Install
|
||||||
<a href="#ant">Ant</a>, set
|
<a href="#ant">Ant</a>,
|
||||||
<tt><a href="#ANT_HOME">ANT_HOME</a></tt>.
|
make sure it is in your PATH.
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
@ -650,11 +662,11 @@
|
||||||
<h3><a name="windows">Basic Windows System Setup</a></h3>
|
<h3><a name="windows">Basic Windows System Setup</a></h3>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<strong>i586 only:</strong>
|
<strong>i586 only:</strong>
|
||||||
The minimum recommended hardware for building the 32bit or X86
|
The minimum recommended hardware for building the 32-bit or X86
|
||||||
Windows version is an Pentium class processor or better, at least
|
Windows version is an Pentium class processor or better, at least
|
||||||
512 MB of RAM, and approximately 600 MB of free disk space.
|
512 MB of RAM, and approximately 600 MB of free disk space.
|
||||||
<strong>
|
<strong>
|
||||||
NOTE: The Windows 2000 build machines need to use the
|
NOTE: The Windows build machines need to use the
|
||||||
file system NTFS.
|
file system NTFS.
|
||||||
Build machines formatted to FAT32 will not work
|
Build machines formatted to FAT32 will not work
|
||||||
because FAT32 doesn't support case-sensitivity in file names.
|
because FAT32 doesn't support case-sensitivity in file names.
|
||||||
|
@ -719,8 +731,11 @@
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
Install the
|
Install the
|
||||||
<a href="#msvc">Microsoft Visual Studio .NET 2003 Professional</a> (32bit) or the
|
<a href="#msvc">Microsoft Visual Studio Compilers</a> (32-bit).
|
||||||
<a href="#mssdk">Microsoft Platform SDK</a> (64bit).
|
</li>
|
||||||
|
<li>
|
||||||
|
Install the
|
||||||
|
<a href="#mssdk">Microsoft Platform SDK</a>.
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
Setup all environment variables for compilers
|
Setup all environment variables for compilers
|
||||||
|
@ -732,7 +747,8 @@
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
Install
|
Install
|
||||||
<a href="#ant">Ant</a>, set
|
<a href="#ant">Ant</a>,
|
||||||
|
make sure it is in your PATH and set
|
||||||
<tt><a href="#ANT_HOME">ANT_HOME</a></tt>.
|
<tt><a href="#ANT_HOME">ANT_HOME</a></tt>.
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
@ -787,7 +803,9 @@
|
||||||
you must first download and install the appropriate
|
you must first download and install the appropriate
|
||||||
binary plug bundles for the OpenJDK, go to the
|
binary plug bundles for the OpenJDK, go to the
|
||||||
<a href="http://openjdk.java.net" target="_blank">OpenJDK</a> site and select
|
<a href="http://openjdk.java.net" target="_blank">OpenJDK</a> site and select
|
||||||
the "<b>Bundles(7)</b>" link and download the binaryplugs for
|
the
|
||||||
|
"<b>Bundles(7)</b>"
|
||||||
|
link and download the binaryplugs for
|
||||||
your particular platform.
|
your particular platform.
|
||||||
The file downloaded is a jar file that must be extracted by running
|
The file downloaded is a jar file that must be extracted by running
|
||||||
the jar file with:
|
the jar file with:
|
||||||
|
@ -823,14 +841,12 @@
|
||||||
The Ant tool is available from the
|
The Ant tool is available from the
|
||||||
<a href="http://ant.apache.org/antlibs/bindownload.cgi" target="_blank">
|
<a href="http://ant.apache.org/antlibs/bindownload.cgi" target="_blank">
|
||||||
Ant download site</a>.
|
Ant download site</a>.
|
||||||
You should always set
|
You should always make sure <tt>ant</tt> is in your PATH, and
|
||||||
|
on Windows you may also need to set
|
||||||
<tt><a href="#ANT_HOME">ANT_HOME</a></tt>
|
<tt><a href="#ANT_HOME">ANT_HOME</a></tt>
|
||||||
to point to the location of
|
to point to the location of
|
||||||
the Ant installation, this is the directory pathname
|
the Ant installation, this is the directory pathname
|
||||||
that contains a <tt>bin and lib</tt>.
|
that contains a <tt>bin and lib</tt>.
|
||||||
It's also a good idea to also place its <tt>bin</tt> directory
|
|
||||||
in the <tt>PATH</tt> environment variable, although it's
|
|
||||||
not absolutely required.
|
|
||||||
</blockquote>
|
</blockquote>
|
||||||
<!-- ------------------------------------------------------ -->
|
<!-- ------------------------------------------------------ -->
|
||||||
<h4><a name="cacerts">Certificate Authority File (cacert)</a></h4>
|
<h4><a name="cacerts">Certificate Authority File (cacert)</a></h4>
|
||||||
|
@ -862,25 +878,9 @@
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<strong><a name="gcc">Linux gcc/binutils</a></strong>
|
<strong><a name="gcc">Linux gcc/binutils</a></strong>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
The GNU gcc compiler version should be 3.2.2 or newer.
|
The GNU gcc compiler version should be 4 or newer.
|
||||||
The binutils package should be 2.11.93.0.2-11 or newer.
|
|
||||||
The compiler used should be the default compiler installed
|
The compiler used should be the default compiler installed
|
||||||
in <tt>/usr/bin</tt>.
|
in <tt>/usr/bin</tt>.
|
||||||
<p>
|
|
||||||
Older Linux systems may require a gcc and bunutils update.
|
|
||||||
The Redhat Enterprise Advanced Server 2.1 update 2 system
|
|
||||||
is one of these systems.
|
|
||||||
RedHat Linux users can obtain this binutils package from
|
|
||||||
<a href="http://www.redhat.com"
|
|
||||||
target="_blank">Redhat web site</a>.
|
|
||||||
You will need to remove the default compiler and binutils
|
|
||||||
packages and install the required packages
|
|
||||||
into the default location on the system.
|
|
||||||
However if you have a new video card driver, like
|
|
||||||
Geforce 4 it is best to use
|
|
||||||
the same compiler as the kernel was built with to
|
|
||||||
build the new video card driver module.
|
|
||||||
So you should build the modules before making this change.
|
|
||||||
</blockquote>
|
</blockquote>
|
||||||
<strong><a name="studio">Solaris: Sun Studio</a></strong>
|
<strong><a name="studio">Solaris: Sun Studio</a></strong>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
|
@ -903,19 +903,20 @@
|
||||||
are also an option, although these compilers have not
|
are also an option, although these compilers have not
|
||||||
been extensively used yet.
|
been extensively used yet.
|
||||||
</blockquote>
|
</blockquote>
|
||||||
<strong><a name="msvc">Windows i586: Microsoft Visual Studio .NET 2003 Professional</a></strong>
|
<strong><a name="msvc">Windows i586: Microsoft Visual Studio Compilers</a></strong>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
The 32-bit OpenJDK Windows build
|
The 32-bit OpenJDK Windows build
|
||||||
requires Microsoft Visual Studio .NET 2003 (VS2003) Professional
|
requires
|
||||||
|
Microsoft Visual Studio C++ 2008 (VS2008) Standard
|
||||||
Edition compiler.
|
Edition compiler.
|
||||||
The compiler and other tools are expected to reside
|
The compiler and other tools are expected to reside
|
||||||
in the location defined by the variable <tt>VS71COMNTOOLS</tt> which
|
in the location defined by the variable
|
||||||
is set by the Microsoft Visual Studio .NET installer.
|
<tt>VS90COMNTOOLS</tt> which
|
||||||
|
is set by the Microsoft Visual Studio installer.
|
||||||
<p>
|
<p>
|
||||||
Once the compiler is installed,
|
Once the compiler is installed,
|
||||||
it is recommended that you run <tt>VCVARS32.BAT</tt>
|
it is recommended that you run <tt>VCVARS32.BAT</tt>
|
||||||
to set the compiler environment variables
|
to set the compiler environment variables
|
||||||
<tt>MSVCDIR</tt>,
|
|
||||||
<tt>INCLUDE</tt>,
|
<tt>INCLUDE</tt>,
|
||||||
<tt>LIB</tt>, and
|
<tt>LIB</tt>, and
|
||||||
<tt>PATH</tt>
|
<tt>PATH</tt>
|
||||||
|
@ -923,16 +924,12 @@
|
||||||
OpenJDK.
|
OpenJDK.
|
||||||
The above environment variables <b>MUST</b> be set.
|
The above environment variables <b>MUST</b> be set.
|
||||||
<p>
|
<p>
|
||||||
The Microsoft Visual Studio .NET 2005 (VS2005) compiler
|
|
||||||
will not work at this time due to the new runtime dll
|
|
||||||
and the manifest requirements.
|
|
||||||
<p>
|
|
||||||
<b>WARNING:</b> Make sure you check out the
|
<b>WARNING:</b> Make sure you check out the
|
||||||
<a href="#cygwin">CYGWIN link.exe WARNING</a>.
|
<a href="#cygwin">CYGWIN link.exe WARNING</a>.
|
||||||
The path <tt>/usr/bin</tt> must be after the path to the
|
The path <tt>/usr/bin</tt> must be after the path to the
|
||||||
Visual Studio product.
|
Visual Studio product.
|
||||||
</blockquote>
|
</blockquote>
|
||||||
<strong><a name="mssdk">Windows X64: Microsoft Platform SDK April 2005</a></strong>
|
<strong><a name="mssdk">Windows: Microsoft Platform SDK</a></strong>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
On <b>X64</b>, the Microsoft Platform Software
|
On <b>X64</b>, the Microsoft Platform Software
|
||||||
Development Kit (SDK), April 2005 Edition compiler,
|
Development Kit (SDK), April 2005 Edition compiler,
|
||||||
|
@ -953,10 +950,9 @@
|
||||||
OpenJDK.
|
OpenJDK.
|
||||||
The above environment variables <b>MUST</b> be set.
|
The above environment variables <b>MUST</b> be set.
|
||||||
<p>
|
<p>
|
||||||
Note that this compiler may say it's version is a
|
This Platform SDK compiler is only used on X64 builds
|
||||||
Microsoft Visual Studio .NET 2005 (VS2005), but be careful,
|
but other parts of the Platform SDK may be used
|
||||||
it will not match the official VS2005 product.
|
for the X86 builds.
|
||||||
This Platform SDK compiler is only used on X64 builds.
|
|
||||||
</blockquote>
|
</blockquote>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
<!-- ------------------------------------------------------ -->
|
<!-- ------------------------------------------------------ -->
|
||||||
|
@ -1241,37 +1237,37 @@
|
||||||
<strong><a name="msvcrt"><tt>MSVCRT.DLL</tt></a></strong>
|
<strong><a name="msvcrt"><tt>MSVCRT.DLL</tt></a></strong>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<strong>i586 only:</strong>
|
<strong>i586 only:</strong>
|
||||||
The OpenJDK 32bit build requires access to
|
The OpenJDK 32-bit build requires access to a redistributable
|
||||||
<tt>MSVCRT.DLL</tt> version 6.00.8337.0 or newer.
|
<tt>MSVCRT.DLL</tt>.
|
||||||
If the <tt>MSVCRT.DLL</tt> is not installed in
|
If the <tt>MSVCRT.DLL</tt> is not installed in
|
||||||
the system32 directory set the
|
the system32 directory set the
|
||||||
<a href="#ALT_MSVCRT_DLL_PATH"><tt>ALT_MSVCRT_DLL_PATH</tt></a>
|
<a href="#ALT_MSVCRT_DLL_PATH"><tt>ALT_MSVCRT_DLL_PATH</tt></a>
|
||||||
variable to the location.
|
variable to the location of this file.
|
||||||
<p>
|
<p>
|
||||||
<strong>X64 only:</strong>
|
<strong>X64 only:</strong>
|
||||||
The OpenJDK 64bit build requires access to
|
The OpenJDK 64-bit build requires access to a redistributable
|
||||||
<tt>MSVCRT.DLL</tt> version 7.0.3790.0 or newer, which is
|
<tt>MSVCRT.DLL</tt>, which is
|
||||||
usually supplied by the
|
usually supplied by the
|
||||||
<a href="#mssdk">Platform SDK</a>.
|
<a href="#mssdk">Platform SDK</a>.
|
||||||
If it is not available from the Platform SDK,
|
If it is not available from the Platform SDK,
|
||||||
set the
|
set the
|
||||||
<a href="#ALT_MSVCRT_DLL_PATH"><tt>ALT_MSVCRT_DLL_PATH</tt></a>
|
<a href="#ALT_MSVCRT_DLL_PATH"><tt>ALT_MSVCRT_DLL_PATH</tt></a>
|
||||||
variable to the location.
|
variable to the location of this file.
|
||||||
</blockquote>
|
</blockquote>
|
||||||
<strong><tt><a name="msvcr71">MSVCR71.DLL</a></tt></strong>
|
<strong><tt><a name="msvcr90">MSVCR90.DLL</a></tt></strong>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<strong>i586 only:</strong>
|
<strong>i586 only:</strong>
|
||||||
The
|
The
|
||||||
OpenJDK
|
OpenJDK
|
||||||
build requires access to
|
build requires access to a redistributable
|
||||||
MSVCR71.DLL version 7.10.3052.4 or newer which should be
|
<tt>MSVCR90.DLL</tt> which should be
|
||||||
supplied by the
|
supplied by the
|
||||||
<a href="#msvc">Visual Studio product</a>
|
<a href="#msvc">Visual Studio product</a>.
|
||||||
If the <tt>MSVCR71.DLL</tt> is not available from the
|
If the <tt>MSVCR90.DLL</tt> is not available from the
|
||||||
Visual Studio product
|
Visual Studio product
|
||||||
set the
|
set the
|
||||||
<a href="#ALT_MSVCR71_DLL_PATH"><tt>ALT_MSVCR71_DLL_PATH</tt></a>
|
<a href="#ALT_MSVCR90_DLL_PATH"><tt>ALT_MSVCR90_DLL_PATH</tt></a>
|
||||||
variable to the location.
|
variable to the location of this file.
|
||||||
</blockquote>
|
</blockquote>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
<!-- ------------------------------------------------------ -->
|
<!-- ------------------------------------------------------ -->
|
||||||
|
@ -1359,13 +1355,38 @@
|
||||||
document) that can impact the build are:
|
document) that can impact the build are:
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<dl>
|
<dl>
|
||||||
<dt><a name="ALT_BINARY_PLUGS_PATH"><tt>ALT_BINARY_PLUGS_PATH</tt></a></dt>
|
<dt><a name="path"><tt>PATH</tt></a> </dt>
|
||||||
|
<dd>Typically you want to set the <tt>PATH</tt> to include:
|
||||||
|
<ul>
|
||||||
|
<li>The location of the GNU make binary</li>
|
||||||
|
<li>The location of the Bootstrap JDK <tt>java</tt>
|
||||||
|
(see <a href="#bootjdk">Bootstrap JDK</a>)</li>
|
||||||
|
<li>The location of the C/C++ compilers
|
||||||
|
(see <a href="#compilers"><tt>compilers</tt></a>)</li>
|
||||||
|
<li>The location or locations for the Unix command utilities
|
||||||
|
(e.g. <tt>/usr/bin</tt>)</li>
|
||||||
|
</ul>
|
||||||
|
</dd>
|
||||||
|
<dt><tt>MILESTONE</tt> </dt>
|
||||||
<dd>
|
<dd>
|
||||||
The location of the binary plugs installation.
|
The milestone name for the build (<i>e.g.</i>"beta").
|
||||||
See <a href="#binaryplugs">Binary Plugs</a> for more information.
|
The default value is "internal".
|
||||||
You should always have a local copy of a
|
</dd>
|
||||||
recent Binary Plugs install image
|
<dt><tt>BUILD_NUMBER</tt> </dt>
|
||||||
and set this variable to that location.
|
<dd>
|
||||||
|
The build number for the build (<i>e.g.</i> "b27").
|
||||||
|
The default value is "b00".
|
||||||
|
</dd>
|
||||||
|
<dt><a name="arch_data_model"><tt>ARCH_DATA_MODEL</tt></a></dt>
|
||||||
|
<dd>The <tt>ARCH_DATA_MODEL</tt> variable
|
||||||
|
is used to specify whether the build is to generate 32-bit or 64-bit
|
||||||
|
binaries.
|
||||||
|
The Solaris build supports either 32-bit or 64-bit builds, but
|
||||||
|
Windows and Linux will support only one, depending on the specific
|
||||||
|
OS being used.
|
||||||
|
Normally, setting this variable is only necessary on Solaris.
|
||||||
|
Set <tt>ARCH_DATA_MODEL</tt> to <tt>32</tt> for generating 32-bit binaries,
|
||||||
|
or to <tt>64</tt> for generating 64-bit binaries.
|
||||||
</dd>
|
</dd>
|
||||||
<dt><a name="ALT_BOOTDIR"><tt>ALT_BOOTDIR</tt></a></dt>
|
<dt><a name="ALT_BOOTDIR"><tt>ALT_BOOTDIR</tt></a></dt>
|
||||||
<dd>
|
<dd>
|
||||||
|
@ -1374,25 +1395,89 @@
|
||||||
You should always install your own local Bootstrap JDK and
|
You should always install your own local Bootstrap JDK and
|
||||||
always set <tt>ALT_BOOTDIR</tt> explicitly.
|
always set <tt>ALT_BOOTDIR</tt> explicitly.
|
||||||
</dd>
|
</dd>
|
||||||
<dt><a name="ALT_BUILD_BINARY_PLUGS_PATH"><tt>ALT_BUILD_BINARY_PLUGS_PATH</tt></a></dt>
|
<dt><a name="ALT_BINARY_PLUGS_PATH"><tt>ALT_BINARY_PLUGS_PATH</tt></a></dt>
|
||||||
<dd>
|
<dd>
|
||||||
These are useful in managing builds on multiple platforms.
|
The location of the binary plugs installation.
|
||||||
The default network location for all of the binary plug images
|
See <a href="#binaryplugs">Binary Plugs</a> for more information.
|
||||||
for all platforms.
|
You should always have a local copy of a
|
||||||
If <tt><a href="#ALT_BINARY_PLUGS_PATH">ALT_BINARY_PLUGS_PATH</a></tt>
|
recent Binary Plugs install image
|
||||||
is not set, this directory will be used and should contain
|
and set this variable to that location.
|
||||||
the following directories:
|
</dd>
|
||||||
<tt>solaris-sparc</tt>,
|
<dt><a name="ALT_JDK_IMPORT_PATH"><tt>ALT_JDK_IMPORT_PATH</tt></a></dt>
|
||||||
<tt>solaris-i586</tt>,
|
<dd>
|
||||||
<tt>solaris-sparcv9</tt>,
|
The location of a previously built JDK installation.
|
||||||
<tt>solaris-amd64</tt>,
|
See <a href="#importjdk">Optional Import JDK</a> for more information.
|
||||||
<tt>linux-i586</tt>,
|
</dd>
|
||||||
<tt>linux-amd64</tt>,
|
<dt><a name="ALT_OUTPUTDIR"><tt>ALT_OUTPUTDIR</tt></a> </dt>
|
||||||
<tt>windows-i586</tt>,
|
<dd>
|
||||||
and
|
An override for specifying the (absolute) path of where the
|
||||||
<tt>windows-amd64</tt>.
|
build output is to go.
|
||||||
Where each of these directories contain the binary plugs image
|
The default output directory will be build/<i>platform</i>.
|
||||||
for that platform.
|
</dd>
|
||||||
|
<dt><a name="ALT_COMPILER_PATH"><tt>ALT_COMPILER_PATH</tt></a> </dt>
|
||||||
|
<dd>
|
||||||
|
The location of the C/C++ compiler.
|
||||||
|
The default varies depending on the platform.
|
||||||
|
</dd>
|
||||||
|
<dt><tt><a name="ALT_CACERTS_FILE">ALT_CACERTS_FILE</a></tt></dt>
|
||||||
|
<dd>
|
||||||
|
The location of the <a href="#cacerts">cacerts</a> file.
|
||||||
|
The default will refer to
|
||||||
|
<tt>jdk/src/share/lib/security/cacerts</tt>.
|
||||||
|
</dd>
|
||||||
|
<dt><a name="ALT_CUPS_HEADERS_PATH"><tt>ALT_CUPS_HEADERS_PATH</tt></a> </dt>
|
||||||
|
<dd>
|
||||||
|
The location of the CUPS header files.
|
||||||
|
See <a href="#cups">CUPS information</a> for more information.
|
||||||
|
If this path does not exist the fallback path is
|
||||||
|
<tt>/usr/include</tt>.
|
||||||
|
</dd>
|
||||||
|
<dt><a name="ALT_FREETYPE_LIB_PATH"><tt>ALT_FREETYPE_LIB_PATH</tt></a></dt>
|
||||||
|
<dd>
|
||||||
|
The location of the FreeType shared library.
|
||||||
|
See <a href="#freetype">FreeType information</a> for details.
|
||||||
|
</dd>
|
||||||
|
<dt><a name="ALT_FREETYPE_HEADERS_PATH"><tt>ALT_FREETYPE_HEADERS_PATH</tt></a></dt>
|
||||||
|
<dd>
|
||||||
|
The location of the FreeType header files.
|
||||||
|
See <a href="#freetype">FreeType information</a> for details.
|
||||||
|
</dd>
|
||||||
|
<dt><a name="ALT_JDK_DEVTOOLS_PATH"><tt>ALT_JDK_DEVTOOLS_PATH</tt></a></dt>
|
||||||
|
<dd>
|
||||||
|
The default root location of the devtools.
|
||||||
|
The default value is
|
||||||
|
<tt>$(ALT_SLASH_JAVA)/devtools</tt>.
|
||||||
|
</dd>
|
||||||
|
<dt><tt><a name="ALT_DEVTOOLS_PATH">ALT_DEVTOOLS_PATH</a></tt> </dt>
|
||||||
|
<dd>
|
||||||
|
The location of tools like the
|
||||||
|
<a href="#zip"><tt>zip</tt> and <tt>unzip</tt></a>
|
||||||
|
binaries, but might also contain the GNU make utility
|
||||||
|
(<tt><i>gmake</i></tt>).
|
||||||
|
So this area is a bit of a grab bag, especially on Windows.
|
||||||
|
The default value depends on the platform and
|
||||||
|
Unix Commands being used.
|
||||||
|
On Linux the default will be
|
||||||
|
<tt>$(ALT_JDK_DEVTOOLS_PATH)/linux/bin</tt>,
|
||||||
|
on Solaris
|
||||||
|
<tt>$(ALT_JDK_DEVTOOLS_PATH)/<i>{sparc,i386}</i>/bin</tt>,
|
||||||
|
and on Windows with CYGWIN
|
||||||
|
<tt>/usr/bin</tt>.
|
||||||
|
</dd>
|
||||||
|
<dt><a name="ALT_UNIXCCS_PATH"><tt>ALT_UNIXCCS_PATH</tt></a></dt>
|
||||||
|
<dd>
|
||||||
|
<strong>Solaris only:</strong>
|
||||||
|
An override for specifying where the Unix CCS
|
||||||
|
command set are located.
|
||||||
|
The default location is <tt>/usr/ccs/bin</tt>
|
||||||
|
</dd>
|
||||||
|
<dt><a name="ALT_SLASH_JAVA"><tt>ALT_SLASH_JAVA</tt></a></dt>
|
||||||
|
<dd>
|
||||||
|
The default root location for many of the ALT path locations
|
||||||
|
of the following ALT variables.
|
||||||
|
The default value is
|
||||||
|
<tt>"/java"</tt> on Solaris and Linux,
|
||||||
|
<tt>"J:"</tt> on Windows.
|
||||||
</dd>
|
</dd>
|
||||||
<dt><a name="ALT_BUILD_JDK_IMPORT_PATH"><tt>ALT_BUILD_JDK_IMPORT_PATH</tt></a></dt>
|
<dt><a name="ALT_BUILD_JDK_IMPORT_PATH"><tt>ALT_BUILD_JDK_IMPORT_PATH</tt></a></dt>
|
||||||
<dd>
|
<dd>
|
||||||
|
@ -1414,166 +1499,57 @@
|
||||||
Where each of these directories contain the import JDK image
|
Where each of these directories contain the import JDK image
|
||||||
for that platform.
|
for that platform.
|
||||||
</dd>
|
</dd>
|
||||||
<dt><tt><a name="ALT_CACERTS_FILE">ALT_CACERTS_FILE</a></tt></dt>
|
<dt><a name="ALT_BUILD_BINARY_PLUGS_PATH"><tt>ALT_BUILD_BINARY_PLUGS_PATH</tt></a></dt>
|
||||||
<dd>
|
<dd>
|
||||||
The location of the <a href="#cacerts">cacerts</a> file.
|
These are useful in managing builds on multiple platforms.
|
||||||
The default will refer to
|
The default network location for all of the binary plug images
|
||||||
<tt>jdk/src/share/lib/security/cacerts</tt>.
|
for all platforms.
|
||||||
|
If <tt><a href="#ALT_BINARY_PLUGS_PATH">ALT_BINARY_PLUGS_PATH</a></tt>
|
||||||
|
is not set, this directory will be used and should contain
|
||||||
|
the following directories:
|
||||||
|
<tt>solaris-sparc</tt>,
|
||||||
|
<tt>solaris-i586</tt>,
|
||||||
|
<tt>solaris-sparcv9</tt>,
|
||||||
|
<tt>solaris-amd64</tt>,
|
||||||
|
<tt>linux-i586</tt>,
|
||||||
|
<tt>linux-amd64</tt>,
|
||||||
|
<tt>windows-i586</tt>,
|
||||||
|
and
|
||||||
|
<tt>windows-amd64</tt>.
|
||||||
|
Where each of these directories contain the binary plugs image
|
||||||
|
for that platform.
|
||||||
</dd>
|
</dd>
|
||||||
<dt><a name="ALT_COMPILER_PATH"><tt>ALT_COMPILER_PATH</tt></a> </dt>
|
<dt><strong>Windows specific:</strong></dt>
|
||||||
<dd>
|
<dd>
|
||||||
The location of the C/C++ compiler.
|
<dl>
|
||||||
The default varies depending on the platform.
|
<dt><a name="ALT_MSDEVTOOLS_PATH"><tt>ALT_MSDEVTOOLS_PATH</tt></a> </dt>
|
||||||
</dd>
|
|
||||||
<dt><a name="ALT_CUPS_HEADERS_PATH"><tt>ALT_CUPS_HEADERS_PATH</tt></a> </dt>
|
|
||||||
<dd>
|
<dd>
|
||||||
The location of the CUPS header files.
|
The location of the
|
||||||
See <a href="#cups">CUPS information</a> for more information.
|
Microsoft Visual Studio
|
||||||
If this path does not exist the fallback path is
|
tools 'bin' directory.
|
||||||
<tt>/usr/include</tt>.
|
The default is usually derived from
|
||||||
</dd>
|
<a href="#ALT_COMPILER_PATH"><tt>ALT_COMPILER_PATH</tt></a>.
|
||||||
<dt><tt><a name="ALT_DEVTOOLS_PATH">ALT_DEVTOOLS_PATH</a></tt> </dt>
|
|
||||||
<dd>
|
|
||||||
The location of tools like the
|
|
||||||
<a href="#zip"><tt>zip</tt> and <tt>unzip</tt></a>
|
|
||||||
binaries, but might also contain the GNU make utility
|
|
||||||
(<tt><i>gmake</i></tt>).
|
|
||||||
So this area is a bit of a grab bag, especially on Windows.
|
|
||||||
The default value depends on the platform and
|
|
||||||
Unix Commands being used.
|
|
||||||
On Linux the default will be
|
|
||||||
<tt>$(ALT_JDK_DEVTOOLS_PATH)/linux/bin</tt>,
|
|
||||||
on Solaris
|
|
||||||
<tt>$(ALT_JDK_DEVTOOLS_PATH)/<i>{sparc,i386}</i>/bin</tt>,
|
|
||||||
on Windows with MKS
|
|
||||||
<tt>%SYSTEMDRIVE%/UTILS</tt>,
|
|
||||||
and on Windows with CYGWIN
|
|
||||||
<tt>/usr/bin</tt>.
|
|
||||||
</dd>
|
</dd>
|
||||||
<dt><tt><a name="ALT_DXSDK_PATH">ALT_DXSDK_PATH</a></tt> </dt>
|
<dt><tt><a name="ALT_DXSDK_PATH">ALT_DXSDK_PATH</a></tt> </dt>
|
||||||
<dd>
|
<dd>
|
||||||
<strong>Windows Only:</strong>
|
|
||||||
The location of the
|
The location of the
|
||||||
<a href="#dxsdk">Microsoft DirectX 9 SDK</a>.
|
<a href="#dxsdk">Microsoft DirectX 9 SDK</a>.
|
||||||
The default will be to try and use the DirectX environment
|
The default will be to try and use the DirectX environment
|
||||||
variable <tt>DXSDK_DIR</tt>,
|
variable <tt>DXSDK_DIR</tt>,
|
||||||
failing that, look in <tt>C:/DXSDK</tt>.
|
failing that, look in <tt>C:/DXSDK</tt>.
|
||||||
</dd>
|
</dd>
|
||||||
<dt><a name="ALT_FREETYPE_HEADERS_PATH"><tt>ALT_FREETYPE_HEADERS_PATH</tt></a></dt>
|
|
||||||
<dd>
|
|
||||||
The location of the FreeType header files.
|
|
||||||
See <a href="#freetype">FreeType information</a> for details.
|
|
||||||
</dd>
|
|
||||||
<dt><a name="ALT_FREETYPE_LIB_PATH"><tt>ALT_FREETYPE_LIB_PATH</tt></a></dt>
|
|
||||||
<dd>
|
|
||||||
The location of the FreeType shared library.
|
|
||||||
See <a href="#freetype">FreeType information</a> for details.
|
|
||||||
</dd>
|
|
||||||
<dt><a name="ALT_JDK_DEVTOOLS_PATH"><tt>ALT_JDK_DEVTOOLS_PATH</tt></a></dt>
|
|
||||||
<dd>
|
|
||||||
The default root location of the devtools.
|
|
||||||
The default value is
|
|
||||||
<tt>$(ALT_SLASH_JAVA)/devtools</tt>.
|
|
||||||
</dd>
|
|
||||||
<dt><a name="ALT_JDK_IMPORT_PATH"><tt>ALT_JDK_IMPORT_PATH</tt></a></dt>
|
|
||||||
<dd>
|
|
||||||
The location of a previously built JDK installation.
|
|
||||||
See <a href="#importjdk">Optional Import JDK</a> for more information.
|
|
||||||
</dd>
|
|
||||||
<dt><a name="ALT_MSDEVTOOLS_PATH"><tt>ALT_MSDEVTOOLS_PATH</tt></a> </dt>
|
|
||||||
<dd>
|
|
||||||
<strong>Windows Only:</strong>
|
|
||||||
The location of the Microsoft Visual Studio .NET 2003
|
|
||||||
tools 'bin' directory.
|
|
||||||
The default is usually derived from
|
|
||||||
<a href="#ALT_COMPILER_PATH"><tt>ALT_COMPILER_PATH</tt></a>.
|
|
||||||
</dd>
|
|
||||||
<dt><tt><a name="ALT_MSVCR71_DLL_PATH">ALT_MSVCR71_DLL_PATH</a></tt> </dt>
|
|
||||||
<dd>
|
|
||||||
<strong>Windows i586 only:</strong>
|
|
||||||
The location of the
|
|
||||||
<a href="#msvcr71"><tt>MSVCR71.DLL</tt></a>.
|
|
||||||
</dd>
|
|
||||||
<dt><tt><a name="ALT_MSVCRT_DLL_PATH">ALT_MSVCRT_DLL_PATH</a></tt> </dt>
|
<dt><tt><a name="ALT_MSVCRT_DLL_PATH">ALT_MSVCRT_DLL_PATH</a></tt> </dt>
|
||||||
<dd>
|
<dd>
|
||||||
<strong>Windows Only:</strong>
|
|
||||||
The location of the
|
The location of the
|
||||||
<a href="#msvcrt"><tt>MSVCRT.DLL</tt></a>.
|
<a href="#msvcrt"><tt>MSVCRT.DLL</tt></a>.
|
||||||
</dd>
|
</dd>
|
||||||
<dt><a name="ALT_OUTPUTDIR"><tt>ALT_OUTPUTDIR</tt></a> </dt>
|
<dt><tt><a name="ALT_MSVCR90_DLL_PATH">ALT_MSVCR90_DLL_PATH</a></tt> </dt>
|
||||||
<dd>
|
<dd>
|
||||||
An override for specifying the (absolute) path of where the
|
<strong>i586 only:</strong>
|
||||||
build output is to go.
|
The location of the
|
||||||
The default output directory will be build/<i>platform</i>.
|
<a href="#msvcr90"><tt>MSVCR90.DLL</tt></a>.
|
||||||
</dd>
|
</dd>
|
||||||
<dt><a name="ALT_SLASH_JAVA"><tt>ALT_SLASH_JAVA</tt></a></dt>
|
</dl>
|
||||||
<dd>
|
|
||||||
The default root location for many of the ALT path locations
|
|
||||||
of the following ALT variables.
|
|
||||||
The default value is
|
|
||||||
<tt>"/java"</tt> on Solaris and Linux,
|
|
||||||
<tt>"J:"</tt> on Windows.
|
|
||||||
</dd>
|
|
||||||
<dt><a name="ALT_UNIXCCS_PATH"><tt>ALT_UNIXCCS_PATH</tt></a></dt>
|
|
||||||
<dd>
|
|
||||||
<strong>Solaris only:</strong>
|
|
||||||
An override for specifying where the Unix CCS
|
|
||||||
command set are located.
|
|
||||||
The default location is <tt>/usr/ccs/bin</tt>
|
|
||||||
</dd>
|
|
||||||
<dt><a name="ALT_UNIXCOMMAND_PATH"><tt>ALT_UNIXCOMMAND_PATH</tt></a> </dt>
|
|
||||||
<dd>
|
|
||||||
An override for specifying where the
|
|
||||||
Unix command set are located.
|
|
||||||
The default location varies depending on the platform,
|
|
||||||
<tt>"%SYSTEMDRIVE%/MKSNT"</tt> or
|
|
||||||
<tt>$(ROOTDIR)</tt> on Windows with MKS, otherwise it's
|
|
||||||
<tt>"/bin"</tt> or <tt>/usr/bin</tt>.
|
|
||||||
</dd>
|
|
||||||
<dt><a name="ALT_USRBIN_PATH"><tt>ALT_USRBIN_PATH</tt></a></dt>
|
|
||||||
<dd>
|
|
||||||
An override for specifying where the
|
|
||||||
Unix <tt>/usr/bin</tt> commands are located. You usually do not need
|
|
||||||
to set this variable: the default location is <tt>/usr/bin</tt>)
|
|
||||||
</dd>
|
|
||||||
<dt><a name="ANT_HOME"><tt>ANT_HOME</tt></a></dt>
|
|
||||||
<dd>
|
|
||||||
The location of the Ant installation.
|
|
||||||
See <a href="#ant">Ant</a> for more information.
|
|
||||||
You should always set <tt>ANT_HOME</tt> explicitly.
|
|
||||||
</dd>
|
|
||||||
<dt><a name="arch_data_model"><tt>ARCH_DATA_MODEL</tt></a></dt>
|
|
||||||
<dd>The <tt>ARCH_DATA_MODEL</tt> variable
|
|
||||||
is used to specify whether the build is to generate 32-bit or 64-bit
|
|
||||||
binaries.
|
|
||||||
The Solaris build supports either 32-bit or 64-bit builds, but
|
|
||||||
Windows and Linux will support only one, depending on the specific
|
|
||||||
OS being used.
|
|
||||||
Normally, setting this variable is only necessary on Solaris.
|
|
||||||
Set <tt>ARCH_DATA_MODEL</tt> to <tt>32</tt> for generating 32-bit binaries,
|
|
||||||
or to <tt>64</tt> for generating 64-bit binaries.
|
|
||||||
</dd>
|
|
||||||
<dt><tt>BUILD_NUMBER</tt> </dt>
|
|
||||||
<dd>
|
|
||||||
The build number for the build (<i>e.g.</i> "b27").
|
|
||||||
The default value is "b00".
|
|
||||||
</dd>
|
|
||||||
<dt><tt>MILESTONE</tt> </dt>
|
|
||||||
<dd>
|
|
||||||
The milestone name for the build (<i>e.g.</i>"beta").
|
|
||||||
The default value is "internal".
|
|
||||||
</dd>
|
|
||||||
<dt><a name="path"><tt>PATH</tt></a> </dt>
|
|
||||||
<dd>Typically you want to set the <tt>PATH</tt> to include:
|
|
||||||
<ul>
|
|
||||||
<li>The location of the GNU make binary</li>
|
|
||||||
<li>The location of the Bootstrap JDK <tt>java</tt>
|
|
||||||
(see <a href="#bootjdk">Bootstrap JDK</a>)</li>
|
|
||||||
<li>The location of the C/C++ compilers
|
|
||||||
(see <a href="#compilers"><tt>compilers</tt></a>)</li>
|
|
||||||
<li>The location or locations for the Unix command utilities
|
|
||||||
(e.g. <tt>/usr/bin</tt>)</li>
|
|
||||||
</ul>
|
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
@ -1661,8 +1637,8 @@
|
||||||
This is caused by a missing libstdc++.a library.
|
This is caused by a missing libstdc++.a library.
|
||||||
This is installed as part of a specific package
|
This is installed as part of a specific package
|
||||||
(e.g. libstdc++.so.devel.386).
|
(e.g. libstdc++.so.devel.386).
|
||||||
By default some 64bit Linux versions (e.g. Fedora)
|
By default some 64-bit Linux versions (e.g. Fedora)
|
||||||
only install the 64bit version of the libstdc++ package.
|
only install the 64-bit version of the libstdc++ package.
|
||||||
Various parts of the JDK build require a static
|
Various parts of the JDK build require a static
|
||||||
link of the C++ runtime libraries to allow for maximum
|
link of the C++ runtime libraries to allow for maximum
|
||||||
portability of the built images.
|
portability of the built images.
|
||||||
|
|
|
@ -14,3 +14,4 @@ ef6af34d75a7b44e77083f1d4ee47631fa09d3b4 jdk7-b31
|
||||||
59d5848bdedebe91cc2753acce78911bcb4a66db jdk7-b37
|
59d5848bdedebe91cc2753acce78911bcb4a66db jdk7-b37
|
||||||
08be802754b0296c91a7713b6d85a015dbcd5349 jdk7-b38
|
08be802754b0296c91a7713b6d85a015dbcd5349 jdk7-b38
|
||||||
55078b6661e286e90387d1d9950bd865f5cc436e jdk7-b39
|
55078b6661e286e90387d1d9950bd865f5cc436e jdk7-b39
|
||||||
|
184e21992f47a8d730df1adc5b21a108f3125489 jdk7-b40
|
||||||
|
|
|
@ -14,3 +14,4 @@ e91159f921a58af3698e6479ea1fc5818da66d09 jdk7-b36
|
||||||
9ee9cf798b59e7d51f8c0a686959f313867a55d6 jdk7-b37
|
9ee9cf798b59e7d51f8c0a686959f313867a55d6 jdk7-b37
|
||||||
d9bc824aa078573829bb66572af847e26e1bd12e jdk7-b38
|
d9bc824aa078573829bb66572af847e26e1bd12e jdk7-b38
|
||||||
49ca90d77f34571b0757ebfcb8a7848ef2696b88 jdk7-b39
|
49ca90d77f34571b0757ebfcb8a7848ef2696b88 jdk7-b39
|
||||||
|
81a0cbe3b28460ce836109934ece03db7afaf9cc jdk7-b40
|
||||||
|
|
|
@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2008
|
||||||
|
|
||||||
HS_MAJOR_VER=14
|
HS_MAJOR_VER=14
|
||||||
HS_MINOR_VER=0
|
HS_MINOR_VER=0
|
||||||
HS_BUILD_NUMBER=07
|
HS_BUILD_NUMBER=08
|
||||||
|
|
||||||
JDK_MAJOR_VER=1
|
JDK_MAJOR_VER=1
|
||||||
JDK_MINOR_VER=7
|
JDK_MINOR_VER=7
|
||||||
|
|
|
@ -85,9 +85,9 @@ Incremental_Lists = $(Cached_db)
|
||||||
|
|
||||||
AD_Dir = $(GENERATED)/adfiles
|
AD_Dir = $(GENERATED)/adfiles
|
||||||
ADLC = $(AD_Dir)/adlc
|
ADLC = $(AD_Dir)/adlc
|
||||||
AD_Spec = $(GAMMADIR)/src/cpu/$(Platform_arch)/vm/$(Platform_arch).ad
|
AD_Spec = $(GAMMADIR)/src/cpu/$(Platform_arch)/vm/$(Platform_arch_model).ad
|
||||||
AD_Src = $(GAMMADIR)/src/share/vm/adlc
|
AD_Src = $(GAMMADIR)/src/share/vm/adlc
|
||||||
AD_Names = ad_$(Platform_arch).hpp ad_$(Platform_arch).cpp
|
AD_Names = ad_$(Platform_arch_model).hpp ad_$(Platform_arch_model).cpp
|
||||||
AD_Files = $(AD_Names:%=$(AD_Dir)/%)
|
AD_Files = $(AD_Names:%=$(AD_Dir)/%)
|
||||||
|
|
||||||
# AD_Files_If_Required/COMPILER1 = ad_stuff
|
# AD_Files_If_Required/COMPILER1 = ad_stuff
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
CFLAGS += -DVM_LITTLE_ENDIAN
|
CFLAGS += -DVM_LITTLE_ENDIAN
|
||||||
|
|
||||||
# Not included in includeDB because it has no dependencies
|
# Not included in includeDB because it has no dependencies
|
||||||
# Obj_Files += solaris_amd64.o
|
|
||||||
Obj_Files += solaris_x86_64.o
|
Obj_Files += solaris_x86_64.o
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -38,8 +37,6 @@ ifeq ("${Platform_compiler}", "sparcWorks")
|
||||||
|
|
||||||
# _lwp_create_interpose must have a frame
|
# _lwp_create_interpose must have a frame
|
||||||
OPT_CFLAGS/os_solaris_x86_64.o = -xO1
|
OPT_CFLAGS/os_solaris_x86_64.o = -xO1
|
||||||
# force C++ interpreter to be full optimization
|
|
||||||
#OPT_CFLAGS/interpret.o = -fast -O4
|
|
||||||
|
|
||||||
# Temporary until SS10 C++ compiler is fixed
|
# Temporary until SS10 C++ compiler is fixed
|
||||||
OPT_CFLAGS/generateOptoStub.o = -xO2
|
OPT_CFLAGS/generateOptoStub.o = -xO2
|
||||||
|
@ -51,8 +48,6 @@ ifeq ("${Platform_compiler}", "gcc")
|
||||||
# gcc
|
# gcc
|
||||||
# The serviceability agent relies on frame pointer (%rbp) to walk thread stack
|
# The serviceability agent relies on frame pointer (%rbp) to walk thread stack
|
||||||
CFLAGS += -fno-omit-frame-pointer
|
CFLAGS += -fno-omit-frame-pointer
|
||||||
# force C++ interpreter to be full optimization
|
|
||||||
#OPT_CFLAGS/interpret.o = -O3
|
|
||||||
|
|
||||||
else
|
else
|
||||||
# error
|
# error
|
||||||
|
|
|
@ -30,7 +30,7 @@ DEBUG_CFLAGS/BYFILE = $(DEBUG_CFLAGS/$@)$(DEBUG_CFLAGS/DEFAULT$(DEBUG_CFLAGS/$@)
|
||||||
|
|
||||||
ifeq ("${Platform_compiler}", "sparcWorks")
|
ifeq ("${Platform_compiler}", "sparcWorks")
|
||||||
|
|
||||||
ifeq ($(COMPILER_REV),5.8)
|
ifeq ($(COMPILER_REV_NUMERIC),508)
|
||||||
# SS11 SEGV when compiling with -g and -xarch=v8, using different backend
|
# SS11 SEGV when compiling with -g and -xarch=v8, using different backend
|
||||||
DEBUG_CFLAGS/compileBroker.o = $(DEBUG_CFLAGS) -xO0
|
DEBUG_CFLAGS/compileBroker.o = $(DEBUG_CFLAGS) -xO0
|
||||||
DEBUG_CFLAGS/jvmtiTagMap.o = $(DEBUG_CFLAGS) -xO0
|
DEBUG_CFLAGS/jvmtiTagMap.o = $(DEBUG_CFLAGS) -xO0
|
||||||
|
|
|
@ -87,17 +87,16 @@ ifneq ("${ISA}","${BUILDARCH}")
|
||||||
|
|
||||||
XLIBJVM_DB = 64/$(LIBJVM_DB)
|
XLIBJVM_DB = 64/$(LIBJVM_DB)
|
||||||
XLIBJVM_DTRACE = 64/$(LIBJVM_DTRACE)
|
XLIBJVM_DTRACE = 64/$(LIBJVM_DTRACE)
|
||||||
XARCH = $(subst sparcv9,v9,$(shell echo $(ISA)))
|
|
||||||
|
|
||||||
$(XLIBJVM_DB): $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS).h $(LIBJVM_DB_MAPFILE)
|
$(XLIBJVM_DB): $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS).h $(LIBJVM_DB_MAPFILE)
|
||||||
@echo Making $@
|
@echo Making $@
|
||||||
$(QUIETLY) mkdir -p 64/ ; \
|
$(QUIETLY) mkdir -p 64/ ; \
|
||||||
$(CC) $(SYMFLAG) $(ARCHFLAG/$(XARCH)) -D$(TYPE) -I. -I$(GENERATED) \
|
$(CC) $(SYMFLAG) $(ARCHFLAG/$(ISA)) -D$(TYPE) -I. -I$(GENERATED) \
|
||||||
$(SHARED_FLAG) $(LFLAGS_JVM_DB) -o $@ $(DTRACE_SRCDIR)/$(JVM_DB).c -lc
|
$(SHARED_FLAG) $(LFLAGS_JVM_DB) -o $@ $(DTRACE_SRCDIR)/$(JVM_DB).c -lc
|
||||||
$(XLIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE)
|
$(XLIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE)
|
||||||
@echo Making $@
|
@echo Making $@
|
||||||
$(QUIETLY) mkdir -p 64/ ; \
|
$(QUIETLY) mkdir -p 64/ ; \
|
||||||
$(CC) $(SYMFLAG) $(ARCHFLAG/$(XARCH)) -D$(TYPE) -I. \
|
$(CC) $(SYMFLAG) $(ARCHFLAG/$(ISA)) -D$(TYPE) -I. \
|
||||||
$(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c -lc -lthread -ldoor
|
$(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c -lc -lthread -ldoor
|
||||||
endif # ifneq ("${ISA}","${BUILDARCH}")
|
endif # ifneq ("${ISA}","${BUILDARCH}")
|
||||||
|
|
||||||
|
@ -116,27 +115,25 @@ $(GENOFFS): $(DTRACE_SRCDIR)/$(GENOFFS)Main.c lib$(GENOFFS).so
|
||||||
$(QUIETLY) $(LINK.CC) -z nodefs -o $@ $(DTRACE_SRCDIR)/$(GENOFFS)Main.c \
|
$(QUIETLY) $(LINK.CC) -z nodefs -o $@ $(DTRACE_SRCDIR)/$(GENOFFS)Main.c \
|
||||||
./lib$(GENOFFS).so
|
./lib$(GENOFFS).so
|
||||||
|
|
||||||
# $@.tmp is created first. It's to avoid empty $(JVMOFFS).h produced in error case.
|
CONDITIONALLY_UPDATE_JVMOFFS_TARGET = \
|
||||||
|
cmp -s $@ $@.tmp; \
|
||||||
|
case $$? in \
|
||||||
|
0) rm -f $@.tmp;; \
|
||||||
|
*) rm -f $@ && mv $@.tmp $@ && echo Updated $@;; \
|
||||||
|
esac
|
||||||
|
|
||||||
|
# $@.tmp is created first to avoid an empty $(JVMOFFS).h if an error occurs.
|
||||||
$(JVMOFFS).h: $(GENOFFS)
|
$(JVMOFFS).h: $(GENOFFS)
|
||||||
$(QUIETLY) LD_LIBRARY_PATH=. ./$(GENOFFS) -header > $@.tmp ; \
|
$(QUIETLY) LD_LIBRARY_PATH=. ./$(GENOFFS) -header > $@.tmp
|
||||||
if [ `diff $@.tmp $@ > /dev/null 2>&1; echo $$?` -ne 0 ] ; \
|
$(QUIETLY) $(CONDITIONALLY_UPDATE_JVMOFFS_TARGET)
|
||||||
then rm -f $@; mv $@.tmp $@; echo Updated $@ ; \
|
|
||||||
else rm -f $@.tmp; \
|
|
||||||
fi
|
|
||||||
|
|
||||||
$(JVMOFFS)Index.h: $(GENOFFS)
|
$(JVMOFFS)Index.h: $(GENOFFS)
|
||||||
$(QUIETLY) LD_LIBRARY_PATH=. ./$(GENOFFS) -index > $@.tmp ; \
|
$(QUIETLY) LD_LIBRARY_PATH=. ./$(GENOFFS) -index > $@.tmp
|
||||||
if [ `diff $@.tmp $@ > /dev/null 2>&1; echo $$?` -ne 0 ] ; \
|
$(QUIETLY) $(CONDITIONALLY_UPDATE_JVMOFFS_TARGET)
|
||||||
then rm -f $@; mv $@.tmp $@; echo Updated $@ ; \
|
|
||||||
else rm -f $@.tmp; \
|
|
||||||
fi
|
|
||||||
|
|
||||||
$(JVMOFFS).cpp: $(GENOFFS) $(JVMOFFS).h $(JVMOFFS)Index.h
|
$(JVMOFFS).cpp: $(GENOFFS) $(JVMOFFS).h $(JVMOFFS)Index.h
|
||||||
$(QUIETLY) LD_LIBRARY_PATH=. ./$(GENOFFS) -table > $@.tmp ; \
|
$(QUIETLY) LD_LIBRARY_PATH=. ./$(GENOFFS) -table > $@.tmp
|
||||||
if [ `diff $@.tmp $@ > /dev/null 2>&1; echo $$?` -ne 0 ] ; \
|
$(QUIETLY) $(CONDITIONALLY_UPDATE_JVMOFFS_TARGET)
|
||||||
then rm -f $@; mv $@.tmp $@; echo Updated $@ ; \
|
|
||||||
else rm -f $@.tmp; \
|
|
||||||
fi
|
|
||||||
|
|
||||||
$(JVMOFFS.o): $(JVMOFFS).h $(JVMOFFS).cpp
|
$(JVMOFFS.o): $(JVMOFFS).h $(JVMOFFS).cpp
|
||||||
$(QUIETLY) $(CCC) -c -I. -o $@ $(ARCHFLAG) -D$(TYPE) $(JVMOFFS).cpp
|
$(QUIETLY) $(CCC) -c -I. -o $@ $(ARCHFLAG) -D$(TYPE) $(JVMOFFS).cpp
|
||||||
|
|
|
@ -37,7 +37,7 @@ ifeq ("${Platform_compiler}", "sparcWorks")
|
||||||
OPT_CFLAGS/SLOWER = -xO2
|
OPT_CFLAGS/SLOWER = -xO2
|
||||||
|
|
||||||
# Problem with SS12 compiler, dtrace doesn't like the .o files (bug 6693876)
|
# Problem with SS12 compiler, dtrace doesn't like the .o files (bug 6693876)
|
||||||
ifeq ($(COMPILER_REV), 5.9)
|
ifeq ($(COMPILER_REV_NUMERIC), 509)
|
||||||
# To avoid jvm98 crash
|
# To avoid jvm98 crash
|
||||||
OPT_CFLAGS/instanceKlass.o = $(OPT_CFLAGS/SLOWER)
|
OPT_CFLAGS/instanceKlass.o = $(OPT_CFLAGS/SLOWER)
|
||||||
# Not clear this workaround could be skipped in some cases.
|
# Not clear this workaround could be skipped in some cases.
|
||||||
|
@ -46,47 +46,41 @@ ifeq ($(COMPILER_REV), 5.9)
|
||||||
OPT_CFLAGS/jni.o = $(OPT_CFLAGS/SLOWER)
|
OPT_CFLAGS/jni.o = $(OPT_CFLAGS/SLOWER)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(COMPILER_REV), 5.5)
|
ifeq ($(COMPILER_REV_NUMERIC), 505)
|
||||||
# CC 5.5 has bug 4908364 with -xO4 (Fixed in 5.6)
|
# CC 5.5 has bug 4908364 with -xO4 (Fixed in 5.6)
|
||||||
OPT_CFLAGS/library_call.o = $(OPT_CFLAGS/SLOWER)
|
OPT_CFLAGS/library_call.o = $(OPT_CFLAGS/SLOWER)
|
||||||
endif # COMPILER_REV == 5.5
|
endif # COMPILER_REV_NUMERIC == 505
|
||||||
|
|
||||||
ifeq ($(shell expr $(COMPILER_REV) \<= 5.4), 1)
|
ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \<= 504), 1)
|
||||||
# Compilation of *_<arch>.cpp can take an hour or more at O3. Use O2
|
# Compilation of *_<arch>.cpp can take an hour or more at O3. Use O2
|
||||||
# See comments at top of sparc.make.
|
# See comments at top of sparc.make.
|
||||||
OPT_CFLAGS/ad_$(Platform_arch).o = $(OPT_CFLAGS/SLOWER)
|
OPT_CFLAGS/ad_$(Platform_arch_model).o = $(OPT_CFLAGS/SLOWER)
|
||||||
OPT_CFLAGS/dfa_$(Platform_arch).o = $(OPT_CFLAGS/SLOWER)
|
OPT_CFLAGS/dfa_$(Platform_arch_model).o = $(OPT_CFLAGS/SLOWER)
|
||||||
endif # COMPILER_REV <= 5.4
|
endif # COMPILER_REV_NUMERIC <= 504
|
||||||
|
|
||||||
ifeq (${COMPILER_REV}, 5.0)
|
ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \< 505), 1)
|
||||||
# Avoid a compiler bug caused by using -xO<level> -g<level>
|
# Same problem with Solaris/x86 compiler (both 5.0 and 5.2) on ad_x86_{32,64}.cpp.
|
||||||
# Since the bug also occurs with -xO0, use an innocuous value (must not be null)
|
# CC build time is also too long for ad_$(Platform_arch_model)_{gen,misc}.o
|
||||||
OPT_CFLAGS/c1_LIROptimizer_i486.o = -c
|
OPT_CFLAGS/ad_$(Platform_arch_model).o = -c
|
||||||
endif
|
OPT_CFLAGS/ad_$(Platform_arch_model)_gen.o = -c
|
||||||
|
OPT_CFLAGS/ad_$(Platform_arch_model)_misc.o = -c
|
||||||
ifeq ($(shell expr $(COMPILER_REV) \< 5.5), 1)
|
ifeq ($(Platform_arch), x86)
|
||||||
# Same problem with Solaris/x86 compiler (both 5.0 and 5.2) on ad_i486.cpp.
|
|
||||||
# CC build time is also too long for ad_i486_{gen,misc}.o
|
|
||||||
OPT_CFLAGS/ad_i486.o = -c
|
|
||||||
OPT_CFLAGS/ad_i486_gen.o = -c
|
|
||||||
OPT_CFLAGS/ad_i486_misc.o = -c
|
|
||||||
ifeq ($(Platform_arch), i486)
|
|
||||||
# Same problem for the wrapper roosts: jni.o jvm.o
|
# Same problem for the wrapper roosts: jni.o jvm.o
|
||||||
OPT_CFLAGS/jni.o = -c
|
OPT_CFLAGS/jni.o = -c
|
||||||
OPT_CFLAGS/jvm.o = -c
|
OPT_CFLAGS/jvm.o = -c
|
||||||
# Same problem in parse2.o (probably the Big Switch over bytecodes)
|
# Same problem in parse2.o (probably the Big Switch over bytecodes)
|
||||||
OPT_CFLAGS/parse2.o = -c
|
OPT_CFLAGS/parse2.o = -c
|
||||||
endif # Platform_arch == i486
|
endif # Platform_arch == x86
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Frame size > 100k if we allow inlining via -g0!
|
# Frame size > 100k if we allow inlining via -g0!
|
||||||
DEBUG_CFLAGS/bytecodeInterpreter.o = -g
|
DEBUG_CFLAGS/bytecodeInterpreter.o = -g
|
||||||
DEBUG_CFLAGS/bytecodeInterpreterWithChecks.o = -g
|
DEBUG_CFLAGS/bytecodeInterpreterWithChecks.o = -g
|
||||||
ifeq ($(Platform_arch), i486)
|
ifeq ($(Platform_arch), x86)
|
||||||
# ube explodes on x86
|
# ube explodes on x86
|
||||||
OPT_CFLAGS/bytecodeInterpreter.o = -xO1
|
OPT_CFLAGS/bytecodeInterpreter.o = -xO1
|
||||||
OPT_CFLAGS/bytecodeInterpreterWithChecks.o = -xO1
|
OPT_CFLAGS/bytecodeInterpreterWithChecks.o = -xO1
|
||||||
endif # Platform_arch == i486
|
endif # Platform_arch == x86
|
||||||
|
|
||||||
endif # Platform_compiler == sparcWorks
|
endif # Platform_compiler == sparcWorks
|
||||||
|
|
||||||
|
|
|
@ -35,17 +35,13 @@ Obj_Files += solaris_x86_32.o
|
||||||
ifeq ("${Platform_compiler}", "sparcWorks")
|
ifeq ("${Platform_compiler}", "sparcWorks")
|
||||||
|
|
||||||
# _lwp_create_interpose must have a frame
|
# _lwp_create_interpose must have a frame
|
||||||
OPT_CFLAGS/os_solaris_i486.o = -xO1
|
OPT_CFLAGS/os_solaris_x86.o = -xO1
|
||||||
# force C++ interpreter to be full optimization
|
|
||||||
OPT_CFLAGS/interpret.o = -fast -O4
|
|
||||||
else
|
else
|
||||||
|
|
||||||
ifeq ("${Platform_compiler}", "gcc")
|
ifeq ("${Platform_compiler}", "gcc")
|
||||||
# gcc
|
# gcc
|
||||||
# _lwp_create_interpose must have a frame
|
# _lwp_create_interpose must have a frame
|
||||||
OPT_CFLAGS/os_solaris_i486.o = -fno-omit-frame-pointer
|
OPT_CFLAGS/os_solaris_x86.o = -fno-omit-frame-pointer
|
||||||
# force C++ interpreter to be full optimization
|
|
||||||
OPT_CFLAGS/interpret.o = -O3
|
|
||||||
#
|
#
|
||||||
else
|
else
|
||||||
# error
|
# error
|
||||||
|
@ -57,7 +53,7 @@ endif
|
||||||
|
|
||||||
ifeq ("${Platform_compiler}", "sparcWorks")
|
ifeq ("${Platform_compiler}", "sparcWorks")
|
||||||
# ILD is gone as of SS11 (5.8), not supported in SS10 (5.7)
|
# ILD is gone as of SS11 (5.8), not supported in SS10 (5.7)
|
||||||
ifeq ($(shell expr $(COMPILER_REV) \< 5.7), 1)
|
ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \< 507), 1)
|
||||||
#
|
#
|
||||||
# Bug in ild causes it to fail randomly. Until we get a fix we can't
|
# Bug in ild causes it to fail randomly. Until we get a fix we can't
|
||||||
# use ild.
|
# use ild.
|
||||||
|
|
|
@ -30,7 +30,7 @@ DEBUG_CFLAGS/BYFILE = $(DEBUG_CFLAGS/$@)$(DEBUG_CFLAGS/DEFAULT$(DEBUG_CFLAGS/$@)
|
||||||
|
|
||||||
ifeq ("${Platform_compiler}", "sparcWorks")
|
ifeq ("${Platform_compiler}", "sparcWorks")
|
||||||
|
|
||||||
ifeq ($(COMPILER_REV),5.8)
|
ifeq ($(COMPILER_REV_NUMERIC),508)
|
||||||
# SS11 SEGV when compiling with -g and -xarch=v8, using different backend
|
# SS11 SEGV when compiling with -g and -xarch=v8, using different backend
|
||||||
DEBUG_CFLAGS/compileBroker.o = $(DEBUG_CFLAGS) -xO0
|
DEBUG_CFLAGS/compileBroker.o = $(DEBUG_CFLAGS) -xO0
|
||||||
DEBUG_CFLAGS/jvmtiTagMap.o = $(DEBUG_CFLAGS) -xO0
|
DEBUG_CFLAGS/jvmtiTagMap.o = $(DEBUG_CFLAGS) -xO0
|
||||||
|
|
|
@ -33,7 +33,7 @@ OPT_CFLAGS/BYFILE = $(OPT_CFLAGS/$@)$(OPT_CFLAGS/DEFAULT$(OPT_CFLAGS/$@))
|
||||||
ifeq ("${Platform_compiler}", "sparcWorks")
|
ifeq ("${Platform_compiler}", "sparcWorks")
|
||||||
|
|
||||||
# Problem with SS12 compiler, dtrace doesn't like the .o files (bug 6693876)
|
# Problem with SS12 compiler, dtrace doesn't like the .o files (bug 6693876)
|
||||||
ifeq ($(COMPILER_REV),5.9)
|
ifeq ($(COMPILER_REV_NUMERIC),509)
|
||||||
# Not clear this workaround could be skipped in some cases.
|
# Not clear this workaround could be skipped in some cases.
|
||||||
OPT_CFLAGS/vmGCOperations.o = $(OPT_CFLAGS/SLOWER) -g
|
OPT_CFLAGS/vmGCOperations.o = $(OPT_CFLAGS/SLOWER) -g
|
||||||
OPT_CFLAGS/java.o = $(OPT_CFLAGS/SLOWER) -g
|
OPT_CFLAGS/java.o = $(OPT_CFLAGS/SLOWER) -g
|
||||||
|
@ -41,9 +41,9 @@ ifeq ($(COMPILER_REV),5.9)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Workaround SS11 bug 6345274 (all platforms) (Fixed in SS11 patch and SS12)
|
# Workaround SS11 bug 6345274 (all platforms) (Fixed in SS11 patch and SS12)
|
||||||
ifeq ($(COMPILER_REV),5.8))
|
ifeq ($(COMPILER_REV_NUMERIC),508))
|
||||||
OPT_CFLAGS/ciTypeFlow.o = $(OPT_CFLAGS/O2)
|
OPT_CFLAGS/ciTypeFlow.o = $(OPT_CFLAGS/O2)
|
||||||
endif # COMPILER_REV == 5.8
|
endif # COMPILER_REV_NUMERIC == 508
|
||||||
|
|
||||||
endif # Platform_compiler == sparcWorks
|
endif # Platform_compiler == sparcWorks
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ endif
|
||||||
ifeq ("${Platform_compiler}", "sparcWorks")
|
ifeq ("${Platform_compiler}", "sparcWorks")
|
||||||
|
|
||||||
# Problem with SS12 compiler, dtrace doesn't like the .o files (bug 6693876)
|
# Problem with SS12 compiler, dtrace doesn't like the .o files (bug 6693876)
|
||||||
ifeq ($(COMPILER_REV),5.9)
|
ifeq ($(COMPILER_REV_NUMERIC),509)
|
||||||
# Not clear this workaround could be skipped in some cases.
|
# Not clear this workaround could be skipped in some cases.
|
||||||
OPT_CFLAGS/vmGCOperations.o = $(OPT_CFLAGS/SLOWER) -g
|
OPT_CFLAGS/vmGCOperations.o = $(OPT_CFLAGS/SLOWER) -g
|
||||||
OPT_CFLAGS/java.o = $(OPT_CFLAGS/SLOWER) -g
|
OPT_CFLAGS/java.o = $(OPT_CFLAGS/SLOWER) -g
|
||||||
|
@ -49,9 +49,9 @@ ifeq ($(COMPILER_REV),5.9)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Workaround SS11 bug 6345274 (all platforms) (Fixed in SS11 patch and SS12)
|
# Workaround SS11 bug 6345274 (all platforms) (Fixed in SS11 patch and SS12)
|
||||||
ifeq ($(COMPILER_REV),5.8)
|
ifeq ($(COMPILER_REV_NUMERIC),508)
|
||||||
OPT_CFLAGS/ciTypeFlow.o = $(OPT_CFLAGS/O2)
|
OPT_CFLAGS/ciTypeFlow.o = $(OPT_CFLAGS/O2)
|
||||||
endif # COMPILER_REV == 5.8
|
endif # COMPILER_REV_NUMERIC == 508
|
||||||
|
|
||||||
endif # Platform_compiler == sparcWorks
|
endif # Platform_compiler == sparcWorks
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ Obj_Files += solaris_sparc.o
|
||||||
ASFLAGS += $(AS_ARCHFLAG)
|
ASFLAGS += $(AS_ARCHFLAG)
|
||||||
|
|
||||||
ifeq ("${Platform_compiler}", "sparcWorks")
|
ifeq ("${Platform_compiler}", "sparcWorks")
|
||||||
ifeq ($(shell expr $(COMPILER_REV) \< 5.5), 1)
|
ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \< 505), 1)
|
||||||
# For 5.2 ad_sparc file is compiled with -O2 %%%% remove when adlc is fixed
|
# For 5.2 ad_sparc file is compiled with -O2 %%%% remove when adlc is fixed
|
||||||
OPT_CFLAGS/ad_sparc.o = $(OPT_CFLAGS/SLOWER)
|
OPT_CFLAGS/ad_sparc.o = $(OPT_CFLAGS/SLOWER)
|
||||||
OPT_CFLAGS/dfa_sparc.o = $(OPT_CFLAGS/SLOWER)
|
OPT_CFLAGS/dfa_sparc.o = $(OPT_CFLAGS/SLOWER)
|
||||||
|
@ -39,7 +39,7 @@ OPT_CFLAGS/carRememberedSet.o = $(OPT_CFLAGS/O2)
|
||||||
OPT_CFLAGS/jniHandles.o = $(OPT_CFLAGS/O2)
|
OPT_CFLAGS/jniHandles.o = $(OPT_CFLAGS/O2)
|
||||||
# CC brings an US-II to its knees compiling the vmStructs asserts under -xO4
|
# CC brings an US-II to its knees compiling the vmStructs asserts under -xO4
|
||||||
OPT_CFLAGS/vmStructs.o = $(OPT_CFLAGS/O2)
|
OPT_CFLAGS/vmStructs.o = $(OPT_CFLAGS/O2)
|
||||||
endif
|
endif # COMPILER_REV_NUMERIC < 505
|
||||||
else
|
else
|
||||||
# Options for gcc
|
# Options for gcc
|
||||||
OPT_CFLAGS/ad_sparc.o = $(OPT_CFLAGS/SLOWER)
|
OPT_CFLAGS/ad_sparc.o = $(OPT_CFLAGS/SLOWER)
|
||||||
|
|
|
@ -41,9 +41,9 @@ REORDER_FLAG = -xF
|
||||||
|
|
||||||
# Get the last thing on the line that looks like x.x+ (x is a digit).
|
# Get the last thing on the line that looks like x.x+ (x is a digit).
|
||||||
COMPILER_REV := \
|
COMPILER_REV := \
|
||||||
$(shell $(CPP) -V 2>&1 | sed -e 's/^.*\([1-9]\.[0-9][0-9]*\).*/\1/')
|
$(shell $(CPP) -V 2>&1 | sed -n 's/^.*[ ,\t]C++[ ,\t]\([1-9]\.[0-9][0-9]*\).*/\1/p')
|
||||||
C_COMPILER_REV := \
|
C_COMPILER_REV := \
|
||||||
$(shell $(CC) -V 2>&1 | grep -i "cc:" | sed -e 's/^.*\([1-9]\.[0-9][0-9]*\).*/\1/')
|
$(shell $(CC) -V 2>&1 | sed -n 's/^.*[ ,\t]C[ ,\t]\([1-9]\.[0-9][0-9]*\).*/\1/p')
|
||||||
|
|
||||||
# Pick which compiler is validated
|
# Pick which compiler is validated
|
||||||
ifeq ($(JDK_MINOR_VERSION),6)
|
ifeq ($(JDK_MINOR_VERSION),6)
|
||||||
|
@ -60,17 +60,19 @@ endif
|
||||||
ENFORCE_COMPILER_REV${ENFORCE_COMPILER_REV} := ${VALIDATED_COMPILER_REV}
|
ENFORCE_COMPILER_REV${ENFORCE_COMPILER_REV} := ${VALIDATED_COMPILER_REV}
|
||||||
ifneq (${COMPILER_REV},${ENFORCE_COMPILER_REV})
|
ifneq (${COMPILER_REV},${ENFORCE_COMPILER_REV})
|
||||||
dummy_target_to_enforce_compiler_rev:=\
|
dummy_target_to_enforce_compiler_rev:=\
|
||||||
$(info WARNING: You are using CC version ${COMPILER_REV} \
|
$(shell echo >&2 WARNING: You are using CC version ${COMPILER_REV} \
|
||||||
and should be using version ${ENFORCE_COMPILER_REV})
|
and should be using version ${ENFORCE_COMPILER_REV}. Set ENFORCE_COMPILER_REV=${COMPILER_REV} to avoid this warning.)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ENFORCE_C_COMPILER_REV${ENFORCE_C_COMPILER_REV} := ${VALIDATED_C_COMPILER_REV}
|
ENFORCE_C_COMPILER_REV${ENFORCE_C_COMPILER_REV} := ${VALIDATED_C_COMPILER_REV}
|
||||||
ifneq (${C_COMPILER_REV},${ENFORCE_C_COMPILER_REV})
|
ifneq (${C_COMPILER_REV},${ENFORCE_C_COMPILER_REV})
|
||||||
dummy_target_to_enforce_c_compiler_rev:=\
|
dummy_target_to_enforce_c_compiler_rev:=\
|
||||||
$(info WARNING: You are using cc version ${C_COMPILER_REV} \
|
$(shell echo >&2 WARNING: You are using cc version ${C_COMPILER_REV} \
|
||||||
and should be using version ${ENFORCE_C_COMPILER_REV})
|
and should be using version ${ENFORCE_C_COMPILER_REV}. Set ENFORCE_C_COMPILER_REV=${C_COMPILER_REV} to avoid this warning.)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
COMPILER_REV_NUMERIC := $(shell echo $(COMPILER_REV) | awk -F. '{ print $$1 * 100 + $$2 }')
|
||||||
|
|
||||||
# Fail the build if __fabsf is used. __fabsf exists only in Solaris 8 2/04
|
# Fail the build if __fabsf is used. __fabsf exists only in Solaris 8 2/04
|
||||||
# and newer; objects with a dependency on this symbol will not run on older
|
# and newer; objects with a dependency on this symbol will not run on older
|
||||||
# Solaris 8.
|
# Solaris 8.
|
||||||
|
@ -120,7 +122,7 @@ ARCHFLAG_OLD/amd64 = -xarch=amd64
|
||||||
ARCHFLAG_NEW/amd64 = -m64
|
ARCHFLAG_NEW/amd64 = -m64
|
||||||
|
|
||||||
# Select the ARCHFLAGs and other SS12 (5.9) options
|
# Select the ARCHFLAGs and other SS12 (5.9) options
|
||||||
ifeq ($(shell expr $(COMPILER_REV) \>= 5.9), 1)
|
ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \>= 509), 1)
|
||||||
ARCHFLAG/sparc = $(ARCHFLAG_NEW/sparc)
|
ARCHFLAG/sparc = $(ARCHFLAG_NEW/sparc)
|
||||||
ARCHFLAG/sparcv9 = $(ARCHFLAG_NEW/sparcv9)
|
ARCHFLAG/sparcv9 = $(ARCHFLAG_NEW/sparcv9)
|
||||||
ARCHFLAG/i486 = $(ARCHFLAG_NEW/i486)
|
ARCHFLAG/i486 = $(ARCHFLAG_NEW/i486)
|
||||||
|
@ -150,7 +152,7 @@ OPT_CFLAGS/NOOPT=-xO1
|
||||||
# Begin current (>=5.6) Forte compiler options #
|
# Begin current (>=5.6) Forte compiler options #
|
||||||
#################################################
|
#################################################
|
||||||
|
|
||||||
ifeq ($(shell expr $(COMPILER_REV) \>= 5.6), 1)
|
ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \>= 506), 1)
|
||||||
|
|
||||||
ifeq ("${Platform_arch}", "sparc")
|
ifeq ("${Platform_arch}", "sparc")
|
||||||
|
|
||||||
|
@ -167,7 +169,7 @@ endif
|
||||||
# Begin current (>=5.5) Forte compiler options #
|
# Begin current (>=5.5) Forte compiler options #
|
||||||
#################################################
|
#################################################
|
||||||
|
|
||||||
ifeq ($(shell expr $(COMPILER_REV) \>= 5.5), 1)
|
ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \>= 505), 1)
|
||||||
|
|
||||||
CFLAGS += $(ARCHFLAG)
|
CFLAGS += $(ARCHFLAG)
|
||||||
AOUT_FLAGS += $(ARCHFLAG)
|
AOUT_FLAGS += $(ARCHFLAG)
|
||||||
|
@ -255,7 +257,7 @@ LFLAGS += -library=%none
|
||||||
|
|
||||||
LFLAGS += -mt
|
LFLAGS += -mt
|
||||||
|
|
||||||
endif # COMPILER_REV >= 5.5
|
endif # COMPILER_REV_NUMERIC >= 505
|
||||||
|
|
||||||
######################################
|
######################################
|
||||||
# End 5.5 Forte compiler options #
|
# End 5.5 Forte compiler options #
|
||||||
|
@ -265,7 +267,7 @@ endif # COMPILER_REV >= 5.5
|
||||||
# Begin 5.2 Forte compiler options #
|
# Begin 5.2 Forte compiler options #
|
||||||
######################################
|
######################################
|
||||||
|
|
||||||
ifeq ($(COMPILER_REV), 5.2)
|
ifeq ($(COMPILER_REV_NUMERIC), 502)
|
||||||
|
|
||||||
CFLAGS += $(ARCHFLAG)
|
CFLAGS += $(ARCHFLAG)
|
||||||
AOUT_FLAGS += $(ARCHFLAG)
|
AOUT_FLAGS += $(ARCHFLAG)
|
||||||
|
@ -324,7 +326,7 @@ PICFLAG/BYFILE = $(PICFLAG/$@)$(PICFLAG/DEFAULT$(PICFLAG/$@))
|
||||||
LFLAGS += -library=Crun
|
LFLAGS += -library=Crun
|
||||||
LIBS += -library=Crun -lCrun
|
LIBS += -library=Crun -lCrun
|
||||||
|
|
||||||
endif # COMPILER_REV == 5.2
|
endif # COMPILER_REV_NUMERIC == 502
|
||||||
|
|
||||||
##################################
|
##################################
|
||||||
# End 5.2 Forte compiler options #
|
# End 5.2 Forte compiler options #
|
||||||
|
@ -333,7 +335,7 @@ endif # COMPILER_REV == 5.2
|
||||||
##################################
|
##################################
|
||||||
# Begin old 5.1 compiler options #
|
# Begin old 5.1 compiler options #
|
||||||
##################################
|
##################################
|
||||||
ifeq ($(COMPILER_REV), 5.1)
|
ifeq ($(COMPILER_REV_NUMERIC), 501)
|
||||||
|
|
||||||
_JUNK_ := $(shell echo >&2 \
|
_JUNK_ := $(shell echo >&2 \
|
||||||
"*** ERROR: sparkWorks.make incomplete for 5.1 compiler")
|
"*** ERROR: sparkWorks.make incomplete for 5.1 compiler")
|
||||||
|
@ -347,7 +349,7 @@ endif
|
||||||
# Begin old 5.0 compiler options #
|
# Begin old 5.0 compiler options #
|
||||||
##################################
|
##################################
|
||||||
|
|
||||||
ifeq (${COMPILER_REV}, 5.0)
|
ifeq (${COMPILER_REV_NUMERIC}, 500)
|
||||||
|
|
||||||
# Had to hoist this higher apparently because of other changes. Must
|
# Had to hoist this higher apparently because of other changes. Must
|
||||||
# come before -xarch specification.
|
# come before -xarch specification.
|
||||||
|
@ -379,7 +381,7 @@ endif # sparc
|
||||||
|
|
||||||
ifeq ("${Platform_arch_model}", "x86_32")
|
ifeq ("${Platform_arch_model}", "x86_32")
|
||||||
OPT_CFLAGS=-xtarget=pentium $(EXTRA_OPT_CFLAGS)
|
OPT_CFLAGS=-xtarget=pentium $(EXTRA_OPT_CFLAGS)
|
||||||
ifeq ("${COMPILER_REV}", "5.0")
|
ifeq ("${COMPILER_REV_NUMERIC}", "500")
|
||||||
# SC5.0 tools on x86 are flakey at -xO4
|
# SC5.0 tools on x86 are flakey at -xO4
|
||||||
OPT_CFLAGS+=-xO3
|
OPT_CFLAGS+=-xO3
|
||||||
else
|
else
|
||||||
|
@ -405,13 +407,13 @@ PICFLAG/DEFAULT = $(PICFLAG)
|
||||||
PICFLAG/BETTER = $(PICFLAG/DEFAULT)
|
PICFLAG/BETTER = $(PICFLAG/DEFAULT)
|
||||||
PICFLAG/BYFILE = $(PICFLAG/$@)$(PICFLAG/DEFAULT$(PICFLAG/$@))
|
PICFLAG/BYFILE = $(PICFLAG/$@)$(PICFLAG/DEFAULT$(PICFLAG/$@))
|
||||||
|
|
||||||
endif # COMPILER_REV = 5.0
|
endif # COMPILER_REV_NUMERIC = 500
|
||||||
|
|
||||||
################################
|
################################
|
||||||
# End old 5.0 compiler options #
|
# End old 5.0 compiler options #
|
||||||
################################
|
################################
|
||||||
|
|
||||||
ifeq ("${COMPILER_REV}", "4.2")
|
ifeq ("${COMPILER_REV_NUMERIC}", "402")
|
||||||
# 4.2 COMPILERS SHOULD NO LONGER BE USED
|
# 4.2 COMPILERS SHOULD NO LONGER BE USED
|
||||||
_JUNK_ := $(shell echo >&2 \
|
_JUNK_ := $(shell echo >&2 \
|
||||||
"*** ERROR: SC4.2 compilers are not supported by this code base!")
|
"*** ERROR: SC4.2 compilers are not supported by this code base!")
|
||||||
|
@ -443,7 +445,7 @@ LINK_MODE/debug =
|
||||||
LINK_MODE/optimized = -Bsymbolic -znodefs
|
LINK_MODE/optimized = -Bsymbolic -znodefs
|
||||||
|
|
||||||
# Have thread local errnos
|
# Have thread local errnos
|
||||||
ifeq ($(shell expr $(COMPILER_REV) \>= 5.5), 1)
|
ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \>= 505), 1)
|
||||||
CFLAGS += -mt
|
CFLAGS += -mt
|
||||||
else
|
else
|
||||||
CFLAGS += -D_REENTRANT
|
CFLAGS += -D_REENTRANT
|
||||||
|
@ -460,7 +462,7 @@ FASTDEBUG_CFLAGS = -g0
|
||||||
# The -g0 setting allows the C++ frontend to inline, which is a big win.
|
# The -g0 setting allows the C++ frontend to inline, which is a big win.
|
||||||
|
|
||||||
# Special global options for SS12
|
# Special global options for SS12
|
||||||
ifeq ($(COMPILER_REV),5.9)
|
ifeq ($(COMPILER_REV_NUMERIC),509)
|
||||||
# There appears to be multiple issues with the new Dwarf2 debug format, so
|
# There appears to be multiple issues with the new Dwarf2 debug format, so
|
||||||
# we tell the compiler to use the older 'stabs' debug format all the time.
|
# we tell the compiler to use the older 'stabs' debug format all the time.
|
||||||
# Note that this needs to be used in optimized compiles too to be 100%.
|
# Note that this needs to be used in optimized compiles too to be 100%.
|
||||||
|
@ -479,8 +481,8 @@ endif
|
||||||
#DEBUG_CFLAGS += -Qoption ccfe -xglobalstatic
|
#DEBUG_CFLAGS += -Qoption ccfe -xglobalstatic
|
||||||
#FASTDEBUG_CFLAGS += -Qoption ccfe -xglobalstatic
|
#FASTDEBUG_CFLAGS += -Qoption ccfe -xglobalstatic
|
||||||
|
|
||||||
ifeq (${COMPILER_REV}, 5.2)
|
ifeq (${COMPILER_REV_NUMERIC}, 502)
|
||||||
COMPILER_DATE := $(shell $(CPP) -V 2>&1 | awk '{ print $$NF; }')
|
COMPILER_DATE := $(shell $(CPP) -V 2>&1 | sed -n '/^.*[ ]C++[ ]\([1-9]\.[0-9][0-9]*\)/p' | awk '{ print $$NF; }')
|
||||||
ifeq (${COMPILER_DATE}, 2001/01/31)
|
ifeq (${COMPILER_DATE}, 2001/01/31)
|
||||||
# disable -g0 in fastdebug since SC6.1 dated 2001/01/31 seems to be buggy
|
# disable -g0 in fastdebug since SC6.1 dated 2001/01/31 seems to be buggy
|
||||||
# use an innocuous value because it will get -g if it's empty
|
# use an innocuous value because it will get -g if it's empty
|
||||||
|
@ -493,7 +495,7 @@ endif
|
||||||
CFLAGS += $(CFLAGS_BROWSE)
|
CFLAGS += $(CFLAGS_BROWSE)
|
||||||
|
|
||||||
# ILD is gone as of SS11 (5.8), not supportted in SS10 (5.7)
|
# ILD is gone as of SS11 (5.8), not supportted in SS10 (5.7)
|
||||||
ifeq ($(shell expr $(COMPILER_REV) \< 5.7), 1)
|
ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \< 507), 1)
|
||||||
# use ild when debugging (but when optimizing we want reproducible results)
|
# use ild when debugging (but when optimizing we want reproducible results)
|
||||||
ILDFLAG = $(ILDFLAG/$(VERSION))
|
ILDFLAG = $(ILDFLAG/$(VERSION))
|
||||||
ILDFLAG/debug = -xildon
|
ILDFLAG/debug = -xildon
|
||||||
|
|
|
@ -26,7 +26,7 @@ Obj_Files += solaris_sparc.o
|
||||||
ASFLAGS += $(AS_ARCHFLAG)
|
ASFLAGS += $(AS_ARCHFLAG)
|
||||||
|
|
||||||
ifeq ("${Platform_compiler}", "sparcWorks")
|
ifeq ("${Platform_compiler}", "sparcWorks")
|
||||||
ifeq ($(shell expr $(COMPILER_REV) \< 5.5), 1)
|
ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \< 505), 1)
|
||||||
# When optimized fully, stubGenerator_sparc.cpp
|
# When optimized fully, stubGenerator_sparc.cpp
|
||||||
# has bogus code for the routine
|
# has bogus code for the routine
|
||||||
# StubGenerator::generate_flush_callers_register_windows()
|
# StubGenerator::generate_flush_callers_register_windows()
|
||||||
|
|
|
@ -83,9 +83,9 @@ Incremental_Lists =$(GENERATED)/$(Cached_db)
|
||||||
|
|
||||||
AD_Dir = $(GENERATED)/adfiles
|
AD_Dir = $(GENERATED)/adfiles
|
||||||
ADLC = $(AD_Dir)/adlc
|
ADLC = $(AD_Dir)/adlc
|
||||||
AD_Spec = $(GAMMADIR)/src/cpu/$(Platform_arch)/vm/$(Platform_arch).ad
|
AD_Spec = $(GAMMADIR)/src/cpu/$(Platform_arch)/vm/$(Platform_arch_model).ad
|
||||||
AD_Src = $(GAMMADIR)/src/share/vm/adlc
|
AD_Src = $(GAMMADIR)/src/share/vm/adlc
|
||||||
AD_Names = ad_$(Platform_arch).hpp ad_$(Platform_arch).cpp
|
AD_Names = ad_$(Platform_arch_model).hpp ad_$(Platform_arch_model).cpp
|
||||||
AD_Files = $(AD_Names:%=$(AD_Dir)/%)
|
AD_Files = $(AD_Names:%=$(AD_Dir)/%)
|
||||||
|
|
||||||
# AD_Files_If_Required/COMPILER1 = ad_stuff
|
# AD_Files_If_Required/COMPILER1 = ad_stuff
|
||||||
|
|
|
@ -101,7 +101,7 @@ LIBM=/usr/lib$(ISA_DIR)/libm.so.1
|
||||||
|
|
||||||
ifeq ("${Platform_compiler}", "sparcWorks")
|
ifeq ("${Platform_compiler}", "sparcWorks")
|
||||||
# The whole megilla:
|
# The whole megilla:
|
||||||
ifeq ($(shell expr $(COMPILER_REV) \>= 5.5), 1)
|
ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \>= 505), 1)
|
||||||
# Old Comment: List the libraries in the order the compiler was designed for
|
# Old Comment: List the libraries in the order the compiler was designed for
|
||||||
# Not sure what the 'designed for' comment is referring too above.
|
# Not sure what the 'designed for' comment is referring too above.
|
||||||
# The order may not be too significant anymore, but I have placed this
|
# The order may not be too significant anymore, but I have placed this
|
||||||
|
|
|
@ -102,6 +102,12 @@ GENERATED_NAMES_IN_INCL=\
|
||||||
adlc.exe: main.obj adlparse.obj archDesc.obj arena.obj dfa.obj dict2.obj filebuff.obj \
|
adlc.exe: main.obj adlparse.obj archDesc.obj arena.obj dfa.obj dict2.obj filebuff.obj \
|
||||||
forms.obj formsopt.obj formssel.obj opcodes.obj output_c.obj output_h.obj
|
forms.obj formsopt.obj formssel.obj opcodes.obj output_c.obj output_h.obj
|
||||||
$(LINK) $(LINK_FLAGS) /subsystem:console /out:$@ $**
|
$(LINK) $(LINK_FLAGS) /subsystem:console /out:$@ $**
|
||||||
|
!if "$(MT)" != ""
|
||||||
|
# The previous link command created a .manifest file that we want to
|
||||||
|
# insert into the linked artifact so we do not need to track it
|
||||||
|
# separately. Use ";#2" for .dll and ";#1" for .exe:
|
||||||
|
$(MT) /manifest $@.manifest /outputresource:$@;#1
|
||||||
|
!endif
|
||||||
|
|
||||||
$(GENERATED_NAMES_IN_INCL): $(Platform_arch_model).ad adlc.exe includeDB.current
|
$(GENERATED_NAMES_IN_INCL): $(Platform_arch_model).ad adlc.exe includeDB.current
|
||||||
rm -f $(GENERATED_NAMES)
|
rm -f $(GENERATED_NAMES)
|
||||||
|
|
|
@ -30,7 +30,7 @@ CPP=cl.exe
|
||||||
# /W3 Warning level 3
|
# /W3 Warning level 3
|
||||||
# /Zi Include debugging information
|
# /Zi Include debugging information
|
||||||
# /WX Treat any warning error as a fatal error
|
# /WX Treat any warning error as a fatal error
|
||||||
# /MD Use dynamic multi-threaded runtime (msvcrt.dll or msvc*71.dll)
|
# /MD Use dynamic multi-threaded runtime (msvcrt.dll or msvc*NN.dll)
|
||||||
# /MTd Use static multi-threaded runtime debug versions
|
# /MTd Use static multi-threaded runtime debug versions
|
||||||
# /O1 Optimize for size (/Os), skips /Oi
|
# /O1 Optimize for size (/Os), skips /Oi
|
||||||
# /O2 Optimize for speed (/Ot), adds /Oi to /O1
|
# /O2 Optimize for speed (/Ot), adds /Oi to /O1
|
||||||
|
@ -80,8 +80,10 @@ CPP_FLAGS=$(CPP_FLAGS) /D "IA32"
|
||||||
CPP=ARCH_ERROR
|
CPP=ARCH_ERROR
|
||||||
!endif
|
!endif
|
||||||
|
|
||||||
# MSC_VER is a 4 digit number that tells us what compiler is being used, it is
|
# MSC_VER is a 4 digit number that tells us what compiler is being used
|
||||||
# generated when the local.make file is created by the script gen_msc_ver.sh.
|
# and is generated when the local.make file is created by build.make
|
||||||
|
# via the script get_msc_ver.sh
|
||||||
|
#
|
||||||
# If MSC_VER is set, it overrides the above default setting.
|
# If MSC_VER is set, it overrides the above default setting.
|
||||||
# But it should be set.
|
# But it should be set.
|
||||||
# Possible values:
|
# Possible values:
|
||||||
|
@ -89,13 +91,14 @@ CPP=ARCH_ERROR
|
||||||
# 1300 and 1310 is VS2003 or VC7
|
# 1300 and 1310 is VS2003 or VC7
|
||||||
# 1399 is our fake number for the VS2005 compiler that really isn't 1400
|
# 1399 is our fake number for the VS2005 compiler that really isn't 1400
|
||||||
# 1400 is for VS2005
|
# 1400 is for VS2005
|
||||||
|
# 1500 is for VS2008
|
||||||
# Do not confuse this MSC_VER with the predefined macro _MSC_VER that the
|
# Do not confuse this MSC_VER with the predefined macro _MSC_VER that the
|
||||||
# compiler provides, when MSC_VER==1399, _MSC_VER will be 1400.
|
# compiler provides, when MSC_VER==1399, _MSC_VER will be 1400.
|
||||||
# Normally they are the same, but a pre-release of the VS2005 compilers
|
# Normally they are the same, but a pre-release of the VS2005 compilers
|
||||||
# in the Windows 64bit Platform SDK said it was 1400 when it was really
|
# in the Windows 64bit Platform SDK said it was 1400 when it was really
|
||||||
# closer to VS2003 in terms of option spellings, so we use 1399 for that
|
# closer to VS2003 in terms of option spellings, so we use 1399 for that
|
||||||
# 1400 version that really isn't 1400.
|
# 1400 version that really isn't 1400.
|
||||||
# See the file gen_msc_ver.sh for more info.
|
# See the file get_msc_ver.sh for more info.
|
||||||
!if "x$(MSC_VER)" == "x"
|
!if "x$(MSC_VER)" == "x"
|
||||||
COMPILER_NAME=$(DEFAULT_COMPILER_NAME)
|
COMPILER_NAME=$(DEFAULT_COMPILER_NAME)
|
||||||
!else
|
!else
|
||||||
|
@ -115,6 +118,9 @@ COMPILER_NAME=VS2003
|
||||||
!if "$(MSC_VER)" == "1400"
|
!if "$(MSC_VER)" == "1400"
|
||||||
COMPILER_NAME=VS2005
|
COMPILER_NAME=VS2005
|
||||||
!endif
|
!endif
|
||||||
|
!if "$(MSC_VER)" == "1500"
|
||||||
|
COMPILER_NAME=VS2008
|
||||||
|
!endif
|
||||||
!endif
|
!endif
|
||||||
|
|
||||||
# Add what version of the compiler we think this is to the compile line
|
# Add what version of the compiler we think this is to the compile line
|
||||||
|
@ -160,7 +166,25 @@ GX_OPTION = /EHsc
|
||||||
# externals at link time. Even with /GS-, you need bufferoverflowU.lib.
|
# externals at link time. Even with /GS-, you need bufferoverflowU.lib.
|
||||||
# NOTE: Currently we decided to not use /GS-
|
# NOTE: Currently we decided to not use /GS-
|
||||||
BUFFEROVERFLOWLIB = bufferoverflowU.lib
|
BUFFEROVERFLOWLIB = bufferoverflowU.lib
|
||||||
LINK_FLAGS = $(LINK_FLAGS) $(BUFFEROVERFLOWLIB)
|
LINK_FLAGS = /manifest $(LINK_FLAGS) $(BUFFEROVERFLOWLIB)
|
||||||
|
# Manifest Tool - used in VS2005 and later to adjust manifests stored
|
||||||
|
# as resources inside build artifacts.
|
||||||
|
MT=mt.exe
|
||||||
|
!if "$(BUILDARCH)" == "i486"
|
||||||
|
# VS2005 on x86 restricts the use of certain libc functions without this
|
||||||
|
CPP_FLAGS=$(CPP_FLAGS) /D _CRT_SECURE_NO_DEPRECATE
|
||||||
|
!endif
|
||||||
|
!endif
|
||||||
|
|
||||||
|
!if "$(COMPILER_NAME)" == "VS2008"
|
||||||
|
PRODUCT_OPT_OPTION = /O2 /Oy-
|
||||||
|
FASTDEBUG_OPT_OPTION = /O2 /Oy-
|
||||||
|
DEBUG_OPT_OPTION = /Od
|
||||||
|
GX_OPTION = /EHsc
|
||||||
|
LINK_FLAGS = /manifest $(LINK_FLAGS)
|
||||||
|
# Manifest Tool - used in VS2005 and later to adjust manifests stored
|
||||||
|
# as resources inside build artifacts.
|
||||||
|
MT=mt.exe
|
||||||
!if "$(BUILDARCH)" == "i486"
|
!if "$(BUILDARCH)" == "i486"
|
||||||
# VS2005 on x86 restricts the use of certain libc functions without this
|
# VS2005 on x86 restricts the use of certain libc functions without this
|
||||||
CPP_FLAGS=$(CPP_FLAGS) /D _CRT_SECURE_NO_DEPRECATE
|
CPP_FLAGS=$(CPP_FLAGS) /D _CRT_SECURE_NO_DEPRECATE
|
||||||
|
|
|
@ -50,6 +50,12 @@ $(AOUT): $(Res_Files) $(Obj_Files)
|
||||||
$(LINK) @<<
|
$(LINK) @<<
|
||||||
$(LINK_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
|
$(LINK_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
|
||||||
<<
|
<<
|
||||||
|
!if "$(MT)" != ""
|
||||||
|
# The previous link command created a .manifest file that we want to
|
||||||
|
# insert into the linked artifact so we do not need to track it
|
||||||
|
# separately. Use ";#2" for .dll and ";#1" for .exe:
|
||||||
|
$(MT) /manifest $@.manifest /outputresource:$@;#2
|
||||||
|
!endif
|
||||||
|
|
||||||
!include $(WorkSpace)/make/windows/makefiles/shared.make
|
!include $(WorkSpace)/make/windows/makefiles/shared.make
|
||||||
!include $(WorkSpace)/make/windows/makefiles/sa.make
|
!include $(WorkSpace)/make/windows/makefiles/sa.make
|
||||||
|
|
|
@ -50,6 +50,13 @@ $(AOUT): $(Res_Files) $(Obj_Files)
|
||||||
$(LINK) @<<
|
$(LINK) @<<
|
||||||
$(LINK_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
|
$(LINK_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
|
||||||
<<
|
<<
|
||||||
|
!if "$(MT)" != ""
|
||||||
|
# The previous link command created a .manifest file that we want to
|
||||||
|
# insert into the linked artifact so we do not need to track it
|
||||||
|
# separately. Use ";#2" for .dll and ";#1" for .exe:
|
||||||
|
$(MT) /manifest $@.manifest /outputresource:$@;#2
|
||||||
|
!endif
|
||||||
|
|
||||||
|
|
||||||
!include $(WorkSpace)/make/windows/makefiles/shared.make
|
!include $(WorkSpace)/make/windows/makefiles/shared.make
|
||||||
!include $(WorkSpace)/make/windows/makefiles/sa.make
|
!include $(WorkSpace)/make/windows/makefiles/sa.make
|
||||||
|
|
|
@ -61,6 +61,12 @@ $(AOUT): $(Res_Files) $(Obj_Files)
|
||||||
$(LINK_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
|
$(LINK_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
|
||||||
<<
|
<<
|
||||||
!endif
|
!endif
|
||||||
|
!if "$(MT)" != ""
|
||||||
|
# The previous link command created a .manifest file that we want to
|
||||||
|
# insert into the linked artifact so we do not need to track it
|
||||||
|
# separately. Use ";#2" for .dll and ";#1" for .exe:
|
||||||
|
$(MT) /manifest $@.manifest /outputresource:$@;#2
|
||||||
|
!endif
|
||||||
|
|
||||||
!include $(WorkSpace)/make/windows/makefiles/shared.make
|
!include $(WorkSpace)/make/windows/makefiles/shared.make
|
||||||
!include $(WorkSpace)/make/windows/makefiles/sa.make
|
!include $(WorkSpace)/make/windows/makefiles/sa.make
|
||||||
|
|
|
@ -92,13 +92,18 @@ SA_LINK_FLAGS = bufferoverflowU.lib
|
||||||
!else
|
!else
|
||||||
SA_CFLAGS = /nologo $(MS_RUNTIME_OPTION) /W3 /Gm $(GX_OPTION) /ZI /Od /D "WIN32" /D "_WINDOWS" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
SA_CFLAGS = /nologo $(MS_RUNTIME_OPTION) /W3 /Gm $(GX_OPTION) /ZI /Od /D "WIN32" /D "_WINDOWS" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||||
!endif
|
!endif
|
||||||
|
!if "$(MT)" != ""
|
||||||
|
SA_LINK_FLAGS = /manifest $(SA_LINK_FLAGS)
|
||||||
|
!endif
|
||||||
SASRCFILE = $(AGENT_DIR)/src/os/win32/windbg/sawindbg.cpp
|
SASRCFILE = $(AGENT_DIR)/src/os/win32/windbg/sawindbg.cpp
|
||||||
SA_LFLAGS = $(SA_LINK_FLAGS) /nologo /subsystem:console /map /debug /machine:$(MACHINE)
|
SA_LFLAGS = $(SA_LINK_FLAGS) /nologo /subsystem:console /map /debug /machine:$(MACHINE)
|
||||||
|
|
||||||
# Note that we do not keep sawindbj.obj around as it would then
|
# Note that we do not keep sawindbj.obj around as it would then
|
||||||
# get included in the dumpbin command in build_vm_def.sh
|
# get included in the dumpbin command in build_vm_def.sh
|
||||||
|
|
||||||
|
# In VS2005 or VS2008 the link command creates a .manifest file that we want
|
||||||
|
# to insert into the linked artifact so we do not need to track it separately.
|
||||||
|
# Use ";#2" for .dll and ";#1" for .exe in the MT command below:
|
||||||
$(SAWINDBG): $(SASRCFILE)
|
$(SAWINDBG): $(SASRCFILE)
|
||||||
set INCLUDE=$(SA_INCLUDE)$(INCLUDE)
|
set INCLUDE=$(SA_INCLUDE)$(INCLUDE)
|
||||||
$(CPP) @<<
|
$(CPP) @<<
|
||||||
|
@ -109,6 +114,9 @@ $(SAWINDBG): $(SASRCFILE)
|
||||||
<<
|
<<
|
||||||
set LIB=$(SA_LIB)$(LIB)
|
set LIB=$(SA_LIB)$(LIB)
|
||||||
$(LINK) /out:$@ /DLL sawindbg.obj dbgeng.lib $(SA_LFLAGS)
|
$(LINK) /out:$@ /DLL sawindbg.obj dbgeng.lib $(SA_LFLAGS)
|
||||||
|
!if "$(MT)" != ""
|
||||||
|
$(MT) /manifest $(@F).manifest /outputresource:$(@F);#2
|
||||||
|
!endif
|
||||||
-@rm -f sawindbg.obj
|
-@rm -f sawindbg.obj
|
||||||
|
|
||||||
cleanall :
|
cleanall :
|
||||||
|
|
|
@ -56,7 +56,8 @@ IncludeDBs_gc=$(HOTSPOTWORKSPACE)/src/share/vm/includeDB_gc_parallel \
|
||||||
$(HOTSPOTWORKSPACE)/src/share/vm/gc_implementation/includeDB_gc_shared \
|
$(HOTSPOTWORKSPACE)/src/share/vm/gc_implementation/includeDB_gc_shared \
|
||||||
$(HOTSPOTWORKSPACE)/src/share/vm/gc_implementation/includeDB_gc_parNew \
|
$(HOTSPOTWORKSPACE)/src/share/vm/gc_implementation/includeDB_gc_parNew \
|
||||||
$(HOTSPOTWORKSPACE)/src/share/vm/gc_implementation/includeDB_gc_parallelScavenge \
|
$(HOTSPOTWORKSPACE)/src/share/vm/gc_implementation/includeDB_gc_parallelScavenge \
|
||||||
$(HOTSPOTWORKSPACE)/src/share/vm/gc_implementation/includeDB_gc_concurrentMarkSweep
|
$(HOTSPOTWORKSPACE)/src/share/vm/gc_implementation/includeDB_gc_concurrentMarkSweep \
|
||||||
|
$(HOTSPOTWORKSPACE)/src/share/vm/gc_implementation/includeDB_gc_g1
|
||||||
|
|
||||||
|
|
||||||
IncludeDBs_kernel =$(IncludeDBs_base) \
|
IncludeDBs_kernel =$(IncludeDBs_base) \
|
||||||
|
|
|
@ -22,9 +22,6 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// make sure the defines don't screw up the declarations later on in this file
|
|
||||||
#define DONT_USE_REGISTER_DEFINES
|
|
||||||
|
|
||||||
#include "incls/_precompiled.incl"
|
#include "incls/_precompiled.incl"
|
||||||
#include "incls/_register_definitions_x86.cpp.incl"
|
#include "incls/_register_definitions_x86.cpp.incl"
|
||||||
|
|
||||||
|
|
|
@ -3756,7 +3756,6 @@ int set_lwp_priority (int ThreadID, int lwpid, int newPrio )
|
||||||
int maxClamped = MIN2(iaLimits.maxPrio, (int)iaInfo->ia_uprilim);
|
int maxClamped = MIN2(iaLimits.maxPrio, (int)iaInfo->ia_uprilim);
|
||||||
iaInfo->ia_upri = scale_to_lwp_priority(iaLimits.minPrio, maxClamped, newPrio);
|
iaInfo->ia_upri = scale_to_lwp_priority(iaLimits.minPrio, maxClamped, newPrio);
|
||||||
iaInfo->ia_uprilim = IA_NOCHANGE;
|
iaInfo->ia_uprilim = IA_NOCHANGE;
|
||||||
iaInfo->ia_nice = IA_NOCHANGE;
|
|
||||||
iaInfo->ia_mode = IA_NOCHANGE;
|
iaInfo->ia_mode = IA_NOCHANGE;
|
||||||
if (ThreadPriorityVerbose) {
|
if (ThreadPriorityVerbose) {
|
||||||
tty->print_cr ("IA: [%d...%d] %d->%d\n",
|
tty->print_cr ("IA: [%d...%d] %d->%d\n",
|
||||||
|
|
|
@ -212,9 +212,9 @@ ArchDesc::ArchDesc()
|
||||||
// Initialize I/O Files
|
// Initialize I/O Files
|
||||||
_ADL_file._name = NULL; _ADL_file._fp = NULL;
|
_ADL_file._name = NULL; _ADL_file._fp = NULL;
|
||||||
// Machine dependent output files
|
// Machine dependent output files
|
||||||
_DFA_file._name = "dfa_i486.cpp"; _DFA_file._fp = NULL;
|
_DFA_file._name = NULL; _DFA_file._fp = NULL;
|
||||||
_HPP_file._name = "ad_i486.hpp"; _HPP_file._fp = NULL;
|
_HPP_file._name = NULL; _HPP_file._fp = NULL;
|
||||||
_CPP_file._name = "ad_i486.cpp"; _CPP_file._fp = NULL;
|
_CPP_file._name = NULL; _CPP_file._fp = NULL;
|
||||||
_bug_file._name = "bugs.out"; _bug_file._fp = NULL;
|
_bug_file._name = "bugs.out"; _bug_file._fp = NULL;
|
||||||
|
|
||||||
// Initialize Register & Pipeline Form Pointers
|
// Initialize Register & Pipeline Form Pointers
|
||||||
|
|
|
@ -574,12 +574,23 @@ void ComputeLinearScanOrder::count_edges(BlockBegin* cur, BlockBegin* parent) {
|
||||||
TRACE_LINEAR_SCAN(3, tty->print_cr("backward branch"));
|
TRACE_LINEAR_SCAN(3, tty->print_cr("backward branch"));
|
||||||
assert(is_visited(cur), "block must be visisted when block is active");
|
assert(is_visited(cur), "block must be visisted when block is active");
|
||||||
assert(parent != NULL, "must have parent");
|
assert(parent != NULL, "must have parent");
|
||||||
assert(parent->number_of_sux() == 1, "loop end blocks must have one successor (critical edges are split)");
|
|
||||||
|
|
||||||
cur->set(BlockBegin::linear_scan_loop_header_flag);
|
cur->set(BlockBegin::linear_scan_loop_header_flag);
|
||||||
cur->set(BlockBegin::backward_branch_target_flag);
|
cur->set(BlockBegin::backward_branch_target_flag);
|
||||||
|
|
||||||
parent->set(BlockBegin::linear_scan_loop_end_flag);
|
parent->set(BlockBegin::linear_scan_loop_end_flag);
|
||||||
|
|
||||||
|
// When a loop header is also the start of an exception handler, then the backward branch is
|
||||||
|
// an exception edge. Because such edges are usually critical edges which cannot be split, the
|
||||||
|
// loop must be excluded here from processing.
|
||||||
|
if (cur->is_set(BlockBegin::exception_entry_flag)) {
|
||||||
|
// Make sure that dominators are correct in this weird situation
|
||||||
|
_iterative_dominators = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
assert(parent->number_of_sux() == 1 && parent->sux_at(0) == cur,
|
||||||
|
"loop end blocks must have one successor (critical edges are split)");
|
||||||
|
|
||||||
_loop_end_blocks.append(parent);
|
_loop_end_blocks.append(parent);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -484,12 +484,17 @@ ciConstant ciEnv::get_constant_by_index_impl(ciInstanceKlass* accessor,
|
||||||
} else if (tag.is_double()) {
|
} else if (tag.is_double()) {
|
||||||
return ciConstant((jdouble)cpool->double_at(index));
|
return ciConstant((jdouble)cpool->double_at(index));
|
||||||
} else if (tag.is_string() || tag.is_unresolved_string()) {
|
} else if (tag.is_string() || tag.is_unresolved_string()) {
|
||||||
oop string = cpool->string_at(index, THREAD);
|
oop string = NULL;
|
||||||
|
if (cpool->is_pseudo_string_at(index)) {
|
||||||
|
string = cpool->pseudo_string_at(index);
|
||||||
|
} else {
|
||||||
|
string = cpool->string_at(index, THREAD);
|
||||||
if (HAS_PENDING_EXCEPTION) {
|
if (HAS_PENDING_EXCEPTION) {
|
||||||
CLEAR_PENDING_EXCEPTION;
|
CLEAR_PENDING_EXCEPTION;
|
||||||
record_out_of_memory_failure();
|
record_out_of_memory_failure();
|
||||||
return ciConstant();
|
return ciConstant();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
ciObject* constant = get_object(string);
|
ciObject* constant = get_object(string);
|
||||||
assert (constant->is_instance(), "must be an instance, or not? ");
|
assert (constant->is_instance(), "must be an instance, or not? ");
|
||||||
return ciConstant(T_OBJECT, constant);
|
return ciConstant(T_OBJECT, constant);
|
||||||
|
|
|
@ -168,11 +168,23 @@ void ClassFileParser::parse_constant_pool_entries(constantPoolHandle cp, int len
|
||||||
// Got utf8 string, guarantee utf8_length+1 bytes, set stream position forward.
|
// Got utf8 string, guarantee utf8_length+1 bytes, set stream position forward.
|
||||||
cfs->guarantee_more(utf8_length+1, CHECK); // utf8 string, tag/access_flags
|
cfs->guarantee_more(utf8_length+1, CHECK); // utf8 string, tag/access_flags
|
||||||
cfs->skip_u1_fast(utf8_length);
|
cfs->skip_u1_fast(utf8_length);
|
||||||
|
|
||||||
// Before storing the symbol, make sure it's legal
|
// Before storing the symbol, make sure it's legal
|
||||||
if (_need_verify) {
|
if (_need_verify) {
|
||||||
verify_legal_utf8((unsigned char*)utf8_buffer, utf8_length, CHECK);
|
verify_legal_utf8((unsigned char*)utf8_buffer, utf8_length, CHECK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (AnonymousClasses && has_cp_patch_at(index)) {
|
||||||
|
Handle patch = clear_cp_patch_at(index);
|
||||||
|
guarantee_property(java_lang_String::is_instance(patch()),
|
||||||
|
"Illegal utf8 patch at %d in class file %s",
|
||||||
|
index, CHECK);
|
||||||
|
char* str = java_lang_String::as_utf8_string(patch());
|
||||||
|
// (could use java_lang_String::as_symbol instead, but might as well batch them)
|
||||||
|
utf8_buffer = (u1*) str;
|
||||||
|
utf8_length = (int) strlen(str);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int hash;
|
unsigned int hash;
|
||||||
symbolOop result = SymbolTable::lookup_only((char*)utf8_buffer, utf8_length, hash);
|
symbolOop result = SymbolTable::lookup_only((char*)utf8_buffer, utf8_length, hash);
|
||||||
if (result == NULL) {
|
if (result == NULL) {
|
||||||
|
@ -245,7 +257,7 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
|
||||||
int klass_ref_index = cp->klass_ref_index_at(index);
|
int klass_ref_index = cp->klass_ref_index_at(index);
|
||||||
int name_and_type_ref_index = cp->name_and_type_ref_index_at(index);
|
int name_and_type_ref_index = cp->name_and_type_ref_index_at(index);
|
||||||
check_property(valid_cp_range(klass_ref_index, length) &&
|
check_property(valid_cp_range(klass_ref_index, length) &&
|
||||||
cp->tag_at(klass_ref_index).is_klass_reference(),
|
is_klass_reference(cp, klass_ref_index),
|
||||||
"Invalid constant pool index %u in class file %s",
|
"Invalid constant pool index %u in class file %s",
|
||||||
klass_ref_index,
|
klass_ref_index,
|
||||||
CHECK_(nullHandle));
|
CHECK_(nullHandle));
|
||||||
|
@ -326,16 +338,46 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
|
||||||
} // end of switch
|
} // end of switch
|
||||||
} // end of for
|
} // end of for
|
||||||
|
|
||||||
|
if (_cp_patches != NULL) {
|
||||||
|
// need to treat this_class specially...
|
||||||
|
assert(AnonymousClasses, "");
|
||||||
|
int this_class_index;
|
||||||
|
{
|
||||||
|
cfs->guarantee_more(8, CHECK_(nullHandle)); // flags, this_class, super_class, infs_len
|
||||||
|
u1* mark = cfs->current();
|
||||||
|
u2 flags = cfs->get_u2_fast();
|
||||||
|
this_class_index = cfs->get_u2_fast();
|
||||||
|
cfs->set_current(mark); // revert to mark
|
||||||
|
}
|
||||||
|
|
||||||
|
for (index = 1; index < length; index++) { // Index 0 is unused
|
||||||
|
if (has_cp_patch_at(index)) {
|
||||||
|
guarantee_property(index != this_class_index,
|
||||||
|
"Illegal constant pool patch to self at %d in class file %s",
|
||||||
|
index, CHECK_(nullHandle));
|
||||||
|
patch_constant_pool(cp, index, cp_patch_at(index), CHECK_(nullHandle));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Ensure that all the patches have been used.
|
||||||
|
for (index = 0; index < _cp_patches->length(); index++) {
|
||||||
|
guarantee_property(!has_cp_patch_at(index),
|
||||||
|
"Unused constant pool patch at %d in class file %s",
|
||||||
|
index, CHECK_(nullHandle));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!_need_verify) {
|
if (!_need_verify) {
|
||||||
return cp;
|
return cp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// second verification pass - checks the strings are of the right format.
|
// second verification pass - checks the strings are of the right format.
|
||||||
|
// but not yet to the other entries
|
||||||
for (index = 1; index < length; index++) {
|
for (index = 1; index < length; index++) {
|
||||||
jbyte tag = cp->tag_at(index).value();
|
jbyte tag = cp->tag_at(index).value();
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
case JVM_CONSTANT_UnresolvedClass: {
|
case JVM_CONSTANT_UnresolvedClass: {
|
||||||
symbolHandle class_name(THREAD, cp->unresolved_klass_at(index));
|
symbolHandle class_name(THREAD, cp->unresolved_klass_at(index));
|
||||||
|
// check the name, even if _cp_patches will overwrite it
|
||||||
verify_legal_class_name(class_name, CHECK_(nullHandle));
|
verify_legal_class_name(class_name, CHECK_(nullHandle));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -378,6 +420,73 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ClassFileParser::patch_constant_pool(constantPoolHandle cp, int index, Handle patch, TRAPS) {
|
||||||
|
assert(AnonymousClasses, "");
|
||||||
|
BasicType patch_type = T_VOID;
|
||||||
|
switch (cp->tag_at(index).value()) {
|
||||||
|
|
||||||
|
case JVM_CONSTANT_UnresolvedClass :
|
||||||
|
// Patching a class means pre-resolving it.
|
||||||
|
// The name in the constant pool is ignored.
|
||||||
|
if (patch->klass() == SystemDictionary::class_klass()) { // %%% java_lang_Class::is_instance
|
||||||
|
guarantee_property(!java_lang_Class::is_primitive(patch()),
|
||||||
|
"Illegal class patch at %d in class file %s",
|
||||||
|
index, CHECK);
|
||||||
|
cp->klass_at_put(index, java_lang_Class::as_klassOop(patch()));
|
||||||
|
} else {
|
||||||
|
guarantee_property(java_lang_String::is_instance(patch()),
|
||||||
|
"Illegal class patch at %d in class file %s",
|
||||||
|
index, CHECK);
|
||||||
|
symbolHandle name = java_lang_String::as_symbol(patch(), CHECK);
|
||||||
|
cp->unresolved_klass_at_put(index, name());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JVM_CONSTANT_UnresolvedString :
|
||||||
|
// Patching a string means pre-resolving it.
|
||||||
|
// The spelling in the constant pool is ignored.
|
||||||
|
// The constant reference may be any object whatever.
|
||||||
|
// If it is not a real interned string, the constant is referred
|
||||||
|
// to as a "pseudo-string", and must be presented to the CP
|
||||||
|
// explicitly, because it may require scavenging.
|
||||||
|
cp->pseudo_string_at_put(index, patch());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JVM_CONSTANT_Integer : patch_type = T_INT; goto patch_prim;
|
||||||
|
case JVM_CONSTANT_Float : patch_type = T_FLOAT; goto patch_prim;
|
||||||
|
case JVM_CONSTANT_Long : patch_type = T_LONG; goto patch_prim;
|
||||||
|
case JVM_CONSTANT_Double : patch_type = T_DOUBLE; goto patch_prim;
|
||||||
|
patch_prim:
|
||||||
|
{
|
||||||
|
jvalue value;
|
||||||
|
BasicType value_type = java_lang_boxing_object::get_value(patch(), &value);
|
||||||
|
guarantee_property(value_type == patch_type,
|
||||||
|
"Illegal primitive patch at %d in class file %s",
|
||||||
|
index, CHECK);
|
||||||
|
switch (value_type) {
|
||||||
|
case T_INT: cp->int_at_put(index, value.i); break;
|
||||||
|
case T_FLOAT: cp->float_at_put(index, value.f); break;
|
||||||
|
case T_LONG: cp->long_at_put(index, value.j); break;
|
||||||
|
case T_DOUBLE: cp->double_at_put(index, value.d); break;
|
||||||
|
default: assert(false, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// %%% TODO: put method handles into CONSTANT_InterfaceMethodref, etc.
|
||||||
|
guarantee_property(!has_cp_patch_at(index),
|
||||||
|
"Illegal unexpected patch at %d in class file %s",
|
||||||
|
index, CHECK);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// On fall-through, mark the patch as used.
|
||||||
|
clear_cp_patch_at(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class NameSigHash: public ResourceObj {
|
class NameSigHash: public ResourceObj {
|
||||||
public:
|
public:
|
||||||
symbolOop _name; // name
|
symbolOop _name; // name
|
||||||
|
@ -448,11 +557,15 @@ objArrayHandle ClassFileParser::parse_interfaces(constantPoolHandle cp,
|
||||||
int index;
|
int index;
|
||||||
for (index = 0; index < length; index++) {
|
for (index = 0; index < length; index++) {
|
||||||
u2 interface_index = cfs->get_u2(CHECK_(nullHandle));
|
u2 interface_index = cfs->get_u2(CHECK_(nullHandle));
|
||||||
|
KlassHandle interf;
|
||||||
check_property(
|
check_property(
|
||||||
valid_cp_range(interface_index, cp->length()) &&
|
valid_cp_range(interface_index, cp->length()) &&
|
||||||
cp->tag_at(interface_index).is_unresolved_klass(),
|
is_klass_reference(cp, interface_index),
|
||||||
"Interface name has bad constant pool index %u in class file %s",
|
"Interface name has bad constant pool index %u in class file %s",
|
||||||
interface_index, CHECK_(nullHandle));
|
interface_index, CHECK_(nullHandle));
|
||||||
|
if (cp->tag_at(interface_index).is_klass()) {
|
||||||
|
interf = KlassHandle(THREAD, cp->resolved_klass_at(interface_index));
|
||||||
|
} else {
|
||||||
symbolHandle unresolved_klass (THREAD, cp->klass_name_at(interface_index));
|
symbolHandle unresolved_klass (THREAD, cp->klass_name_at(interface_index));
|
||||||
|
|
||||||
// Don't need to check legal name because it's checked when parsing constant pool.
|
// Don't need to check legal name because it's checked when parsing constant pool.
|
||||||
|
@ -465,9 +578,12 @@ objArrayHandle ClassFileParser::parse_interfaces(constantPoolHandle cp,
|
||||||
klassOop k = SystemDictionary::resolve_super_or_fail(class_name,
|
klassOop k = SystemDictionary::resolve_super_or_fail(class_name,
|
||||||
unresolved_klass, class_loader, protection_domain,
|
unresolved_klass, class_loader, protection_domain,
|
||||||
false, CHECK_(nullHandle));
|
false, CHECK_(nullHandle));
|
||||||
KlassHandle interf (THREAD, k);
|
interf = KlassHandle(THREAD, k);
|
||||||
vmtimer->resume();
|
vmtimer->resume();
|
||||||
|
|
||||||
|
cp->klass_at_put(interface_index, interf()); // eagerly resolve
|
||||||
|
}
|
||||||
|
|
||||||
if (!Klass::cast(interf())->is_interface()) {
|
if (!Klass::cast(interf())->is_interface()) {
|
||||||
THROW_MSG_(vmSymbols::java_lang_IncompatibleClassChangeError(), "Implementing class", nullHandle);
|
THROW_MSG_(vmSymbols::java_lang_IncompatibleClassChangeError(), "Implementing class", nullHandle);
|
||||||
}
|
}
|
||||||
|
@ -877,8 +993,7 @@ typeArrayHandle ClassFileParser::parse_exception_table(u4 code_length,
|
||||||
"Illegal exception table handler in class file %s", CHECK_(nullHandle));
|
"Illegal exception table handler in class file %s", CHECK_(nullHandle));
|
||||||
if (catch_type_index != 0) {
|
if (catch_type_index != 0) {
|
||||||
guarantee_property(valid_cp_range(catch_type_index, cp->length()) &&
|
guarantee_property(valid_cp_range(catch_type_index, cp->length()) &&
|
||||||
(cp->tag_at(catch_type_index).is_klass() ||
|
is_klass_reference(cp, catch_type_index),
|
||||||
cp->tag_at(catch_type_index).is_unresolved_klass()),
|
|
||||||
"Catch type in exception table has bad constant type in class file %s", CHECK_(nullHandle));
|
"Catch type in exception table has bad constant type in class file %s", CHECK_(nullHandle));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1117,7 +1232,7 @@ void ClassFileParser::parse_type_array(u2 array_length, u4 code_length, u4* u1_i
|
||||||
} else if (tag == ITEM_Object) {
|
} else if (tag == ITEM_Object) {
|
||||||
u2 class_index = u2_array[i2++] = cfs->get_u2(CHECK);
|
u2 class_index = u2_array[i2++] = cfs->get_u2(CHECK);
|
||||||
guarantee_property(valid_cp_range(class_index, cp->length()) &&
|
guarantee_property(valid_cp_range(class_index, cp->length()) &&
|
||||||
cp->tag_at(class_index).is_unresolved_klass(),
|
is_klass_reference(cp, class_index),
|
||||||
"Bad class index %u in StackMap in class file %s",
|
"Bad class index %u in StackMap in class file %s",
|
||||||
class_index, CHECK);
|
class_index, CHECK);
|
||||||
} else if (tag == ITEM_Uninitialized) {
|
} else if (tag == ITEM_Uninitialized) {
|
||||||
|
@ -1183,7 +1298,7 @@ u2* ClassFileParser::parse_checked_exceptions(u2* checked_exceptions_length,
|
||||||
checked_exception = cfs->get_u2_fast();
|
checked_exception = cfs->get_u2_fast();
|
||||||
check_property(
|
check_property(
|
||||||
valid_cp_range(checked_exception, cp->length()) &&
|
valid_cp_range(checked_exception, cp->length()) &&
|
||||||
cp->tag_at(checked_exception).is_klass_reference(),
|
is_klass_reference(cp, checked_exception),
|
||||||
"Exception name has bad type at constant pool %u in class file %s",
|
"Exception name has bad type at constant pool %u in class file %s",
|
||||||
checked_exception, CHECK_NULL);
|
checked_exception, CHECK_NULL);
|
||||||
}
|
}
|
||||||
|
@ -1918,7 +2033,7 @@ u2 ClassFileParser::parse_classfile_inner_classes_attribute(constantPoolHandle c
|
||||||
check_property(
|
check_property(
|
||||||
inner_class_info_index == 0 ||
|
inner_class_info_index == 0 ||
|
||||||
(valid_cp_range(inner_class_info_index, cp_size) &&
|
(valid_cp_range(inner_class_info_index, cp_size) &&
|
||||||
cp->tag_at(inner_class_info_index).is_klass_reference()),
|
is_klass_reference(cp, inner_class_info_index)),
|
||||||
"inner_class_info_index %u has bad constant type in class file %s",
|
"inner_class_info_index %u has bad constant type in class file %s",
|
||||||
inner_class_info_index, CHECK_0);
|
inner_class_info_index, CHECK_0);
|
||||||
// Outer class index
|
// Outer class index
|
||||||
|
@ -1926,7 +2041,7 @@ u2 ClassFileParser::parse_classfile_inner_classes_attribute(constantPoolHandle c
|
||||||
check_property(
|
check_property(
|
||||||
outer_class_info_index == 0 ||
|
outer_class_info_index == 0 ||
|
||||||
(valid_cp_range(outer_class_info_index, cp_size) &&
|
(valid_cp_range(outer_class_info_index, cp_size) &&
|
||||||
cp->tag_at(outer_class_info_index).is_klass_reference()),
|
is_klass_reference(cp, outer_class_info_index)),
|
||||||
"outer_class_info_index %u has bad constant type in class file %s",
|
"outer_class_info_index %u has bad constant type in class file %s",
|
||||||
outer_class_info_index, CHECK_0);
|
outer_class_info_index, CHECK_0);
|
||||||
// Inner class name
|
// Inner class name
|
||||||
|
@ -2088,7 +2203,7 @@ void ClassFileParser::parse_classfile_attributes(constantPoolHandle cp, instance
|
||||||
}
|
}
|
||||||
// Validate the constant pool indices and types
|
// Validate the constant pool indices and types
|
||||||
if (!cp->is_within_bounds(class_index) ||
|
if (!cp->is_within_bounds(class_index) ||
|
||||||
!cp->tag_at(class_index).is_klass_reference()) {
|
!is_klass_reference(cp, class_index)) {
|
||||||
classfile_parse_error("Invalid or out-of-bounds class index in EnclosingMethod attribute in class file %s", CHECK);
|
classfile_parse_error("Invalid or out-of-bounds class index in EnclosingMethod attribute in class file %s", CHECK);
|
||||||
}
|
}
|
||||||
if (method_index != 0 &&
|
if (method_index != 0 &&
|
||||||
|
@ -2349,6 +2464,7 @@ void ClassFileParser::java_lang_Class_fix_post(int* next_nonstatic_oop_offset_pt
|
||||||
instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
|
instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
|
||||||
Handle class_loader,
|
Handle class_loader,
|
||||||
Handle protection_domain,
|
Handle protection_domain,
|
||||||
|
GrowableArray<Handle>* cp_patches,
|
||||||
symbolHandle& parsed_name,
|
symbolHandle& parsed_name,
|
||||||
TRAPS) {
|
TRAPS) {
|
||||||
// So that JVMTI can cache class file in the state before retransformable agents
|
// So that JVMTI can cache class file in the state before retransformable agents
|
||||||
|
@ -2380,6 +2496,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_cp_patches = cp_patches;
|
||||||
|
|
||||||
instanceKlassHandle nullHandle;
|
instanceKlassHandle nullHandle;
|
||||||
|
|
||||||
|
@ -2510,14 +2627,22 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
|
||||||
CHECK_(nullHandle));
|
CHECK_(nullHandle));
|
||||||
} else {
|
} else {
|
||||||
check_property(valid_cp_range(super_class_index, cp_size) &&
|
check_property(valid_cp_range(super_class_index, cp_size) &&
|
||||||
cp->tag_at(super_class_index).is_unresolved_klass(),
|
is_klass_reference(cp, super_class_index),
|
||||||
"Invalid superclass index %u in class file %s",
|
"Invalid superclass index %u in class file %s",
|
||||||
super_class_index,
|
super_class_index,
|
||||||
CHECK_(nullHandle));
|
CHECK_(nullHandle));
|
||||||
// The class name should be legal because it is checked when parsing constant pool.
|
// The class name should be legal because it is checked when parsing constant pool.
|
||||||
// However, make sure it is not an array type.
|
// However, make sure it is not an array type.
|
||||||
|
bool is_array = false;
|
||||||
|
if (cp->tag_at(super_class_index).is_klass()) {
|
||||||
|
super_klass = instanceKlassHandle(THREAD, cp->resolved_klass_at(super_class_index));
|
||||||
|
if (_need_verify)
|
||||||
|
is_array = super_klass->oop_is_array();
|
||||||
|
} else if (_need_verify) {
|
||||||
|
is_array = (cp->unresolved_klass_at(super_class_index)->byte_at(0) == JVM_SIGNATURE_ARRAY);
|
||||||
|
}
|
||||||
if (_need_verify) {
|
if (_need_verify) {
|
||||||
guarantee_property(cp->unresolved_klass_at(super_class_index)->byte_at(0) != JVM_SIGNATURE_ARRAY,
|
guarantee_property(!is_array,
|
||||||
"Bad superclass name in class file %s", CHECK_(nullHandle));
|
"Bad superclass name in class file %s", CHECK_(nullHandle));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2557,7 +2682,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
|
||||||
objArrayHandle methods_default_annotations(THREAD, methods_default_annotations_oop);
|
objArrayHandle methods_default_annotations(THREAD, methods_default_annotations_oop);
|
||||||
|
|
||||||
// We check super class after class file is parsed and format is checked
|
// We check super class after class file is parsed and format is checked
|
||||||
if (super_class_index > 0) {
|
if (super_class_index > 0 && super_klass.is_null()) {
|
||||||
symbolHandle sk (THREAD, cp->klass_name_at(super_class_index));
|
symbolHandle sk (THREAD, cp->klass_name_at(super_class_index));
|
||||||
if (access_flags.is_interface()) {
|
if (access_flags.is_interface()) {
|
||||||
// Before attempting to resolve the superclass, check for class format
|
// Before attempting to resolve the superclass, check for class format
|
||||||
|
@ -2574,6 +2699,9 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
|
||||||
CHECK_(nullHandle));
|
CHECK_(nullHandle));
|
||||||
KlassHandle kh (THREAD, k);
|
KlassHandle kh (THREAD, k);
|
||||||
super_klass = instanceKlassHandle(THREAD, kh());
|
super_klass = instanceKlassHandle(THREAD, kh());
|
||||||
|
cp->klass_at_put(super_class_index, super_klass()); // eagerly resolve
|
||||||
|
}
|
||||||
|
if (super_klass.not_null()) {
|
||||||
if (super_klass->is_interface()) {
|
if (super_klass->is_interface()) {
|
||||||
ResourceMark rm(THREAD);
|
ResourceMark rm(THREAD);
|
||||||
Exceptions::fthrow(
|
Exceptions::fthrow(
|
||||||
|
@ -3000,6 +3128,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
|
||||||
this_klass->set_method_ordering(method_ordering());
|
this_klass->set_method_ordering(method_ordering());
|
||||||
this_klass->set_initial_method_idnum(methods->length());
|
this_klass->set_initial_method_idnum(methods->length());
|
||||||
this_klass->set_name(cp->klass_name_at(this_class_index));
|
this_klass->set_name(cp->klass_name_at(this_class_index));
|
||||||
|
cp->klass_at_put(this_class_index, this_klass()); // eagerly resolve
|
||||||
this_klass->set_protection_domain(protection_domain());
|
this_klass->set_protection_domain(protection_domain());
|
||||||
this_klass->set_fields_annotations(fields_annotations());
|
this_klass->set_fields_annotations(fields_annotations());
|
||||||
this_klass->set_methods_annotations(methods_annotations());
|
this_klass->set_methods_annotations(methods_annotations());
|
||||||
|
|
|
@ -33,6 +33,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
||||||
u2 _major_version;
|
u2 _major_version;
|
||||||
u2 _minor_version;
|
u2 _minor_version;
|
||||||
symbolHandle _class_name;
|
symbolHandle _class_name;
|
||||||
|
GrowableArray<Handle>* _cp_patches; // overrides for CP entries
|
||||||
|
|
||||||
bool _has_finalizer;
|
bool _has_finalizer;
|
||||||
bool _has_empty_finalizer;
|
bool _has_empty_finalizer;
|
||||||
|
@ -203,6 +204,35 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
||||||
char* skip_over_field_name(char* name, bool slash_ok, unsigned int length);
|
char* skip_over_field_name(char* name, bool slash_ok, unsigned int length);
|
||||||
char* skip_over_field_signature(char* signature, bool void_ok, unsigned int length, TRAPS);
|
char* skip_over_field_signature(char* signature, bool void_ok, unsigned int length, TRAPS);
|
||||||
|
|
||||||
|
bool has_cp_patch_at(int index) {
|
||||||
|
assert(AnonymousClasses, "");
|
||||||
|
assert(index >= 0, "oob");
|
||||||
|
return (_cp_patches != NULL
|
||||||
|
&& index < _cp_patches->length()
|
||||||
|
&& _cp_patches->adr_at(index)->not_null());
|
||||||
|
}
|
||||||
|
Handle cp_patch_at(int index) {
|
||||||
|
assert(has_cp_patch_at(index), "oob");
|
||||||
|
return _cp_patches->at(index);
|
||||||
|
}
|
||||||
|
Handle clear_cp_patch_at(int index) {
|
||||||
|
Handle patch = cp_patch_at(index);
|
||||||
|
_cp_patches->at_put(index, Handle());
|
||||||
|
assert(!has_cp_patch_at(index), "");
|
||||||
|
return patch;
|
||||||
|
}
|
||||||
|
void patch_constant_pool(constantPoolHandle cp, int index, Handle patch, TRAPS);
|
||||||
|
|
||||||
|
// Wrapper for constantTag.is_klass_[or_]reference.
|
||||||
|
// In older versions of the VM, klassOops cannot sneak into early phases of
|
||||||
|
// constant pool construction, but in later versions they can.
|
||||||
|
// %%% Let's phase out the old is_klass_reference.
|
||||||
|
bool is_klass_reference(constantPoolHandle cp, int index) {
|
||||||
|
return ((LinkWellKnownClasses || AnonymousClasses)
|
||||||
|
? cp->tag_at(index).is_klass_or_reference()
|
||||||
|
: cp->tag_at(index).is_klass_reference());
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Constructor
|
// Constructor
|
||||||
ClassFileParser(ClassFileStream* st) { set_stream(st); }
|
ClassFileParser(ClassFileStream* st) { set_stream(st); }
|
||||||
|
@ -218,6 +248,14 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
||||||
Handle class_loader,
|
Handle class_loader,
|
||||||
Handle protection_domain,
|
Handle protection_domain,
|
||||||
symbolHandle& parsed_name,
|
symbolHandle& parsed_name,
|
||||||
|
TRAPS) {
|
||||||
|
return parseClassFile(name, class_loader, protection_domain, NULL, parsed_name, THREAD);
|
||||||
|
}
|
||||||
|
instanceKlassHandle parseClassFile(symbolHandle name,
|
||||||
|
Handle class_loader,
|
||||||
|
Handle protection_domain,
|
||||||
|
GrowableArray<Handle>* cp_patches,
|
||||||
|
symbolHandle& parsed_name,
|
||||||
TRAPS);
|
TRAPS);
|
||||||
|
|
||||||
// Verifier checks
|
// Verifier checks
|
||||||
|
|
|
@ -937,6 +937,8 @@ klassOop SystemDictionary::parse_stream(symbolHandle class_name,
|
||||||
Handle class_loader,
|
Handle class_loader,
|
||||||
Handle protection_domain,
|
Handle protection_domain,
|
||||||
ClassFileStream* st,
|
ClassFileStream* st,
|
||||||
|
KlassHandle host_klass,
|
||||||
|
GrowableArray<Handle>* cp_patches,
|
||||||
TRAPS) {
|
TRAPS) {
|
||||||
symbolHandle parsed_name;
|
symbolHandle parsed_name;
|
||||||
|
|
||||||
|
@ -953,10 +955,10 @@ klassOop SystemDictionary::parse_stream(symbolHandle class_name,
|
||||||
instanceKlassHandle k = ClassFileParser(st).parseClassFile(class_name,
|
instanceKlassHandle k = ClassFileParser(st).parseClassFile(class_name,
|
||||||
class_loader,
|
class_loader,
|
||||||
protection_domain,
|
protection_domain,
|
||||||
|
cp_patches,
|
||||||
parsed_name,
|
parsed_name,
|
||||||
THREAD);
|
THREAD);
|
||||||
|
|
||||||
|
|
||||||
// We don't redefine the class, so we just need to clean up whether there
|
// We don't redefine the class, so we just need to clean up whether there
|
||||||
// was an error or not (don't want to modify any system dictionary
|
// was an error or not (don't want to modify any system dictionary
|
||||||
// data structures).
|
// data structures).
|
||||||
|
@ -973,6 +975,30 @@ klassOop SystemDictionary::parse_stream(symbolHandle class_name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (host_klass.not_null() && k.not_null()) {
|
||||||
|
assert(AnonymousClasses, "");
|
||||||
|
// If it's anonymous, initialize it now, since nobody else will.
|
||||||
|
k->set_host_klass(host_klass());
|
||||||
|
|
||||||
|
{
|
||||||
|
MutexLocker mu_r(Compile_lock, THREAD);
|
||||||
|
|
||||||
|
// Add to class hierarchy, initialize vtables, and do possible
|
||||||
|
// deoptimizations.
|
||||||
|
add_to_hierarchy(k, CHECK_NULL); // No exception, but can block
|
||||||
|
|
||||||
|
// But, do not add to system dictionary.
|
||||||
|
}
|
||||||
|
|
||||||
|
k->eager_initialize(THREAD);
|
||||||
|
|
||||||
|
// notify jvmti
|
||||||
|
if (JvmtiExport::should_post_class_load()) {
|
||||||
|
assert(THREAD->is_Java_thread(), "thread->is_Java_thread()");
|
||||||
|
JvmtiExport::post_class_load((JavaThread *) THREAD, k());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return k();
|
return k();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -228,6 +228,16 @@ public:
|
||||||
Handle class_loader,
|
Handle class_loader,
|
||||||
Handle protection_domain,
|
Handle protection_domain,
|
||||||
ClassFileStream* st,
|
ClassFileStream* st,
|
||||||
|
TRAPS) {
|
||||||
|
KlassHandle nullHandle;
|
||||||
|
return parse_stream(class_name, class_loader, protection_domain, st, nullHandle, NULL, THREAD);
|
||||||
|
}
|
||||||
|
static klassOop parse_stream(symbolHandle class_name,
|
||||||
|
Handle class_loader,
|
||||||
|
Handle protection_domain,
|
||||||
|
ClassFileStream* st,
|
||||||
|
KlassHandle host_klass,
|
||||||
|
GrowableArray<Handle>* cp_patches,
|
||||||
TRAPS);
|
TRAPS);
|
||||||
|
|
||||||
// Resolve from stream (called by jni_DefineClass and JVM_DefineClass)
|
// Resolve from stream (called by jni_DefineClass and JVM_DefineClass)
|
||||||
|
|
|
@ -1600,7 +1600,11 @@ void ClassVerifier::verify_ldc(
|
||||||
types = (1 << JVM_CONSTANT_Double) | (1 << JVM_CONSTANT_Long);
|
types = (1 << JVM_CONSTANT_Double) | (1 << JVM_CONSTANT_Long);
|
||||||
verify_cp_type(index, cp, types, CHECK_VERIFY(this));
|
verify_cp_type(index, cp, types, CHECK_VERIFY(this));
|
||||||
}
|
}
|
||||||
if (tag.is_string() || tag.is_unresolved_string()) {
|
if (tag.is_string() && cp->is_pseudo_string_at(index)) {
|
||||||
|
current_frame->push_stack(
|
||||||
|
VerificationType::reference_type(
|
||||||
|
vmSymbols::java_lang_Object()), CHECK_VERIFY(this));
|
||||||
|
} else if (tag.is_string() || tag.is_unresolved_string()) {
|
||||||
current_frame->push_stack(
|
current_frame->push_stack(
|
||||||
VerificationType::reference_type(
|
VerificationType::reference_type(
|
||||||
vmSymbols::java_lang_String()), CHECK_VERIFY(this));
|
vmSymbols::java_lang_String()), CHECK_VERIFY(this));
|
||||||
|
|
|
@ -1,314 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2001-2005 Sun Microsystems, Inc. All Rights Reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
|
||||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
|
||||||
* have any questions.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
// CopyrightVersion 1.2
|
|
||||||
|
|
||||||
# include "incls/_precompiled.incl"
|
|
||||||
# include "incls/_concurrentGCThread.cpp.incl"
|
|
||||||
|
|
||||||
bool ConcurrentGCThread::_should_terminate = false;
|
|
||||||
bool ConcurrentGCThread::_has_terminated = false;
|
|
||||||
int ConcurrentGCThread::_CGC_flag = CGC_nil;
|
|
||||||
|
|
||||||
SuspendibleThreadSet ConcurrentGCThread::_sts;
|
|
||||||
|
|
||||||
ConcurrentGCThread::ConcurrentGCThread() {
|
|
||||||
_sts.initialize();
|
|
||||||
};
|
|
||||||
|
|
||||||
void ConcurrentGCThread::stopWorldAndDo(VoidClosure* op) {
|
|
||||||
MutexLockerEx x(Heap_lock,
|
|
||||||
Mutex::_no_safepoint_check_flag);
|
|
||||||
// warning("CGC: about to try stopping world");
|
|
||||||
SafepointSynchronize::begin();
|
|
||||||
// warning("CGC: successfully stopped world");
|
|
||||||
op->do_void();
|
|
||||||
SafepointSynchronize::end();
|
|
||||||
// warning("CGC: successfully restarted world");
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConcurrentGCThread::safepoint_synchronize() {
|
|
||||||
_sts.suspend_all();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConcurrentGCThread::safepoint_desynchronize() {
|
|
||||||
_sts.resume_all();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConcurrentGCThread::create_and_start() {
|
|
||||||
if (os::create_thread(this, os::cgc_thread)) {
|
|
||||||
// XXX: need to set this to low priority
|
|
||||||
// unless "agressive mode" set; priority
|
|
||||||
// should be just less than that of VMThread.
|
|
||||||
os::set_priority(this, NearMaxPriority);
|
|
||||||
if (!_should_terminate && !DisableStartThread) {
|
|
||||||
os::start_thread(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConcurrentGCThread::initialize_in_thread() {
|
|
||||||
this->record_stack_base_and_size();
|
|
||||||
this->initialize_thread_local_storage();
|
|
||||||
this->set_active_handles(JNIHandleBlock::allocate_block());
|
|
||||||
// From this time Thread::current() should be working.
|
|
||||||
assert(this == Thread::current(), "just checking");
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConcurrentGCThread::wait_for_universe_init() {
|
|
||||||
MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
|
|
||||||
while (!is_init_completed() && !_should_terminate) {
|
|
||||||
CGC_lock->wait(Mutex::_no_safepoint_check_flag, 200);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConcurrentGCThread::terminate() {
|
|
||||||
// Signal that it is terminated
|
|
||||||
{
|
|
||||||
MutexLockerEx mu(Terminator_lock,
|
|
||||||
Mutex::_no_safepoint_check_flag);
|
|
||||||
_has_terminated = true;
|
|
||||||
Terminator_lock->notify();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Thread destructor usually does this..
|
|
||||||
ThreadLocalStorage::set_thread(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SuspendibleThreadSet::initialize_work() {
|
|
||||||
MutexLocker x(STS_init_lock);
|
|
||||||
if (!_initialized) {
|
|
||||||
_m = new Monitor(Mutex::leaf,
|
|
||||||
"SuspendibleThreadSetLock", true);
|
|
||||||
_async = 0;
|
|
||||||
_async_stop = false;
|
|
||||||
_async_stopped = 0;
|
|
||||||
_initialized = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SuspendibleThreadSet::join() {
|
|
||||||
initialize();
|
|
||||||
MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
|
|
||||||
while (_async_stop) _m->wait(Mutex::_no_safepoint_check_flag);
|
|
||||||
_async++;
|
|
||||||
assert(_async > 0, "Huh.");
|
|
||||||
}
|
|
||||||
|
|
||||||
void SuspendibleThreadSet::leave() {
|
|
||||||
assert(_initialized, "Must be initialized.");
|
|
||||||
MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
|
|
||||||
_async--;
|
|
||||||
assert(_async >= 0, "Huh.");
|
|
||||||
if (_async_stop) _m->notify_all();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SuspendibleThreadSet::yield(const char* id) {
|
|
||||||
assert(_initialized, "Must be initialized.");
|
|
||||||
if (_async_stop) {
|
|
||||||
MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
|
|
||||||
if (_async_stop) {
|
|
||||||
_async_stopped++;
|
|
||||||
assert(_async_stopped > 0, "Huh.");
|
|
||||||
if (_async_stopped == _async) {
|
|
||||||
if (ConcGCYieldTimeout > 0) {
|
|
||||||
double now = os::elapsedTime();
|
|
||||||
guarantee((now - _suspend_all_start) * 1000.0 <
|
|
||||||
(double)ConcGCYieldTimeout,
|
|
||||||
"Long delay; whodunit?");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_m->notify_all();
|
|
||||||
while (_async_stop) _m->wait(Mutex::_no_safepoint_check_flag);
|
|
||||||
_async_stopped--;
|
|
||||||
assert(_async >= 0, "Huh");
|
|
||||||
_m->notify_all();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SuspendibleThreadSet::suspend_all() {
|
|
||||||
initialize(); // If necessary.
|
|
||||||
if (ConcGCYieldTimeout > 0) {
|
|
||||||
_suspend_all_start = os::elapsedTime();
|
|
||||||
}
|
|
||||||
MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
|
|
||||||
assert(!_async_stop, "Only one at a time.");
|
|
||||||
_async_stop = true;
|
|
||||||
while (_async_stopped < _async) _m->wait(Mutex::_no_safepoint_check_flag);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SuspendibleThreadSet::resume_all() {
|
|
||||||
assert(_initialized, "Must be initialized.");
|
|
||||||
MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
|
|
||||||
assert(_async_stopped == _async, "Huh.");
|
|
||||||
_async_stop = false;
|
|
||||||
_m->notify_all();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _sltLoop(JavaThread* thread, TRAPS) {
|
|
||||||
SurrogateLockerThread* slt = (SurrogateLockerThread*)thread;
|
|
||||||
slt->loop();
|
|
||||||
}
|
|
||||||
|
|
||||||
SurrogateLockerThread::SurrogateLockerThread() :
|
|
||||||
JavaThread(&_sltLoop),
|
|
||||||
_monitor(Mutex::nonleaf, "SLTMonitor"),
|
|
||||||
_buffer(empty)
|
|
||||||
{}
|
|
||||||
|
|
||||||
SurrogateLockerThread* SurrogateLockerThread::make(TRAPS) {
|
|
||||||
klassOop k =
|
|
||||||
SystemDictionary::resolve_or_fail(vmSymbolHandles::java_lang_Thread(),
|
|
||||||
true, CHECK_NULL);
|
|
||||||
instanceKlassHandle klass (THREAD, k);
|
|
||||||
instanceHandle thread_oop = klass->allocate_instance_handle(CHECK_NULL);
|
|
||||||
|
|
||||||
const char thread_name[] = "Surrogate Locker Thread (CMS)";
|
|
||||||
Handle string = java_lang_String::create_from_str(thread_name, CHECK_NULL);
|
|
||||||
|
|
||||||
// Initialize thread_oop to put it into the system threadGroup
|
|
||||||
Handle thread_group (THREAD, Universe::system_thread_group());
|
|
||||||
JavaValue result(T_VOID);
|
|
||||||
JavaCalls::call_special(&result, thread_oop,
|
|
||||||
klass,
|
|
||||||
vmSymbolHandles::object_initializer_name(),
|
|
||||||
vmSymbolHandles::threadgroup_string_void_signature(),
|
|
||||||
thread_group,
|
|
||||||
string,
|
|
||||||
CHECK_NULL);
|
|
||||||
|
|
||||||
SurrogateLockerThread* res;
|
|
||||||
{
|
|
||||||
MutexLocker mu(Threads_lock);
|
|
||||||
res = new SurrogateLockerThread();
|
|
||||||
|
|
||||||
// At this point it may be possible that no osthread was created for the
|
|
||||||
// JavaThread due to lack of memory. We would have to throw an exception
|
|
||||||
// in that case. However, since this must work and we do not allow
|
|
||||||
// exceptions anyway, check and abort if this fails.
|
|
||||||
if (res == NULL || res->osthread() == NULL) {
|
|
||||||
vm_exit_during_initialization("java.lang.OutOfMemoryError",
|
|
||||||
"unable to create new native thread");
|
|
||||||
}
|
|
||||||
java_lang_Thread::set_thread(thread_oop(), res);
|
|
||||||
java_lang_Thread::set_priority(thread_oop(), NearMaxPriority);
|
|
||||||
java_lang_Thread::set_daemon(thread_oop());
|
|
||||||
|
|
||||||
res->set_threadObj(thread_oop());
|
|
||||||
Threads::add(res);
|
|
||||||
Thread::start(res);
|
|
||||||
}
|
|
||||||
os::yield(); // This seems to help with initial start-up of SLT
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SurrogateLockerThread::manipulatePLL(SLT_msg_type msg) {
|
|
||||||
MutexLockerEx x(&_monitor, Mutex::_no_safepoint_check_flag);
|
|
||||||
assert(_buffer == empty, "Should be empty");
|
|
||||||
assert(msg != empty, "empty message");
|
|
||||||
_buffer = msg;
|
|
||||||
while (_buffer != empty) {
|
|
||||||
_monitor.notify();
|
|
||||||
_monitor.wait(Mutex::_no_safepoint_check_flag);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ======= Surrogate Locker Thread =============
|
|
||||||
|
|
||||||
void SurrogateLockerThread::loop() {
|
|
||||||
BasicLock pll_basic_lock;
|
|
||||||
SLT_msg_type msg;
|
|
||||||
debug_only(unsigned int owned = 0;)
|
|
||||||
|
|
||||||
while (/* !isTerminated() */ 1) {
|
|
||||||
{
|
|
||||||
MutexLocker x(&_monitor);
|
|
||||||
// Since we are a JavaThread, we can't be here at a safepoint.
|
|
||||||
assert(!SafepointSynchronize::is_at_safepoint(),
|
|
||||||
"SLT is a JavaThread");
|
|
||||||
// wait for msg buffer to become non-empty
|
|
||||||
while (_buffer == empty) {
|
|
||||||
_monitor.notify();
|
|
||||||
_monitor.wait();
|
|
||||||
}
|
|
||||||
msg = _buffer;
|
|
||||||
}
|
|
||||||
switch(msg) {
|
|
||||||
case acquirePLL: {
|
|
||||||
instanceRefKlass::acquire_pending_list_lock(&pll_basic_lock);
|
|
||||||
debug_only(owned++;)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case releaseAndNotifyPLL: {
|
|
||||||
assert(owned > 0, "Don't have PLL");
|
|
||||||
instanceRefKlass::release_and_notify_pending_list_lock(&pll_basic_lock);
|
|
||||||
debug_only(owned--;)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case empty:
|
|
||||||
default: {
|
|
||||||
guarantee(false,"Unexpected message in _buffer");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
|
||||||
MutexLocker x(&_monitor);
|
|
||||||
// Since we are a JavaThread, we can't be here at a safepoint.
|
|
||||||
assert(!SafepointSynchronize::is_at_safepoint(),
|
|
||||||
"SLT is a JavaThread");
|
|
||||||
_buffer = empty;
|
|
||||||
_monitor.notify();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assert(!_monitor.owned_by_self(), "Should unlock before exit.");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ===== STS Access From Outside CGCT =====
|
|
||||||
|
|
||||||
void ConcurrentGCThread::stsYield(const char* id) {
|
|
||||||
assert( Thread::current()->is_ConcurrentGC_thread(),
|
|
||||||
"only a conc GC thread can call this" );
|
|
||||||
_sts.yield(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ConcurrentGCThread::stsShouldYield() {
|
|
||||||
assert( Thread::current()->is_ConcurrentGC_thread(),
|
|
||||||
"only a conc GC thread can call this" );
|
|
||||||
return _sts.should_yield();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConcurrentGCThread::stsJoin() {
|
|
||||||
assert( Thread::current()->is_ConcurrentGC_thread(),
|
|
||||||
"only a conc GC thread can call this" );
|
|
||||||
_sts.join();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConcurrentGCThread::stsLeave() {
|
|
||||||
assert( Thread::current()->is_ConcurrentGC_thread(),
|
|
||||||
"only a conc GC thread can call this" );
|
|
||||||
_sts.leave();
|
|
||||||
}
|
|
|
@ -1,167 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2001-2005 Sun Microsystems, Inc. All Rights Reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
|
||||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
|
||||||
* have any questions.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
class VoidClosure;
|
|
||||||
|
|
||||||
// A SuspendibleThreadSet is (obviously) a set of threads that can be
|
|
||||||
// suspended. A thread can join and later leave the set, and periodically
|
|
||||||
// yield. If some thread (not in the set) requests, via suspend_all, that
|
|
||||||
// the threads be suspended, then the requesting thread is blocked until
|
|
||||||
// all the threads in the set have yielded or left the set. (Threads may
|
|
||||||
// not enter the set when an attempted suspension is in progress.) The
|
|
||||||
// suspending thread later calls resume_all, allowing the suspended threads
|
|
||||||
// to continue.
|
|
||||||
|
|
||||||
class SuspendibleThreadSet {
|
|
||||||
Monitor* _m;
|
|
||||||
int _async;
|
|
||||||
bool _async_stop;
|
|
||||||
int _async_stopped;
|
|
||||||
bool _initialized;
|
|
||||||
double _suspend_all_start;
|
|
||||||
|
|
||||||
void initialize_work();
|
|
||||||
|
|
||||||
public:
|
|
||||||
SuspendibleThreadSet() : _initialized(false) {}
|
|
||||||
|
|
||||||
// Add the current thread to the set. May block if a suspension
|
|
||||||
// is in progress.
|
|
||||||
void join();
|
|
||||||
// Removes the current thread from the set.
|
|
||||||
void leave();
|
|
||||||
// Returns "true" iff an suspension is in progress.
|
|
||||||
bool should_yield() { return _async_stop; }
|
|
||||||
// Suspends the current thread if a suspension is in progress (for
|
|
||||||
// the duration of the suspension.)
|
|
||||||
void yield(const char* id);
|
|
||||||
// Return when all threads in the set are suspended.
|
|
||||||
void suspend_all();
|
|
||||||
// Allow suspended threads to resume.
|
|
||||||
void resume_all();
|
|
||||||
// Redundant initializations okay.
|
|
||||||
void initialize() {
|
|
||||||
// Double-check dirty read idiom.
|
|
||||||
if (!_initialized) initialize_work();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class ConcurrentGCThread: public NamedThread {
|
|
||||||
friend class VMStructs;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
static bool _should_terminate;
|
|
||||||
static bool _has_terminated;
|
|
||||||
|
|
||||||
enum CGC_flag_type {
|
|
||||||
CGC_nil = 0x0,
|
|
||||||
CGC_dont_suspend = 0x1,
|
|
||||||
CGC_CGC_safepoint = 0x2,
|
|
||||||
CGC_VM_safepoint = 0x4
|
|
||||||
};
|
|
||||||
|
|
||||||
static int _CGC_flag;
|
|
||||||
|
|
||||||
static bool CGC_flag_is_set(int b) { return (_CGC_flag & b) != 0; }
|
|
||||||
static int set_CGC_flag(int b) { return _CGC_flag |= b; }
|
|
||||||
static int reset_CGC_flag(int b) { return _CGC_flag &= ~b; }
|
|
||||||
|
|
||||||
void stopWorldAndDo(VoidClosure* op);
|
|
||||||
|
|
||||||
// All instances share this one set.
|
|
||||||
static SuspendibleThreadSet _sts;
|
|
||||||
|
|
||||||
// Create and start the thread (setting it's priority high.)
|
|
||||||
void create_and_start();
|
|
||||||
|
|
||||||
// Do initialization steps in the thread: record stack base and size,
|
|
||||||
// init thread local storage, set JNI handle block.
|
|
||||||
void initialize_in_thread();
|
|
||||||
|
|
||||||
// Wait until Universe::is_fully_initialized();
|
|
||||||
void wait_for_universe_init();
|
|
||||||
|
|
||||||
// Record that the current thread is terminating, and will do more
|
|
||||||
// concurrent work.
|
|
||||||
void terminate();
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Constructor
|
|
||||||
|
|
||||||
ConcurrentGCThread();
|
|
||||||
~ConcurrentGCThread() {} // Exists to call NamedThread destructor.
|
|
||||||
|
|
||||||
// Tester
|
|
||||||
bool is_ConcurrentGC_thread() const { return true; }
|
|
||||||
|
|
||||||
static void safepoint_synchronize();
|
|
||||||
static void safepoint_desynchronize();
|
|
||||||
|
|
||||||
// All overridings should probably do _sts::yield, but we allow
|
|
||||||
// overriding for distinguished debugging messages. Default is to do
|
|
||||||
// nothing.
|
|
||||||
virtual void yield() {}
|
|
||||||
|
|
||||||
bool should_yield() { return _sts.should_yield(); }
|
|
||||||
|
|
||||||
// they are prefixed by sts since there are already yield() and
|
|
||||||
// should_yield() (non-static) methods in this class and it was an
|
|
||||||
// easy way to differentiate them.
|
|
||||||
static void stsYield(const char* id);
|
|
||||||
static bool stsShouldYield();
|
|
||||||
static void stsJoin();
|
|
||||||
static void stsLeave();
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
// The SurrogateLockerThread is used by concurrent GC threads for
|
|
||||||
// manipulating Java monitors, in particular, currently for
|
|
||||||
// manipulating the pending_list_lock. XXX
|
|
||||||
class SurrogateLockerThread: public JavaThread {
|
|
||||||
friend class VMStructs;
|
|
||||||
public:
|
|
||||||
enum SLT_msg_type {
|
|
||||||
empty = 0, // no message
|
|
||||||
acquirePLL, // acquire pending list lock
|
|
||||||
releaseAndNotifyPLL // notify and release pending list lock
|
|
||||||
};
|
|
||||||
private:
|
|
||||||
// the following are shared with the CMSThread
|
|
||||||
SLT_msg_type _buffer; // communication buffer
|
|
||||||
Monitor _monitor; // monitor controlling buffer
|
|
||||||
BasicLock _basicLock; // used for PLL locking
|
|
||||||
|
|
||||||
public:
|
|
||||||
static SurrogateLockerThread* make(TRAPS);
|
|
||||||
|
|
||||||
SurrogateLockerThread();
|
|
||||||
|
|
||||||
bool is_hidden_from_external_view() const { return true; }
|
|
||||||
|
|
||||||
void loop(); // main method
|
|
||||||
|
|
||||||
void manipulatePLL(SLT_msg_type msg);
|
|
||||||
|
|
||||||
};
|
|
|
@ -30,7 +30,7 @@ PtrQueue::PtrQueue(PtrQueueSet* qset_, bool perm) :
|
||||||
_perm(perm), _lock(NULL)
|
_perm(perm), _lock(NULL)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
PtrQueue::~PtrQueue() {
|
void PtrQueue::flush() {
|
||||||
if (!_perm && _buf != NULL) {
|
if (!_perm && _buf != NULL) {
|
||||||
if (_index == _sz) {
|
if (_index == _sz) {
|
||||||
// No work to do.
|
// No work to do.
|
||||||
|
@ -41,8 +41,9 @@ PtrQueue::~PtrQueue() {
|
||||||
_buf[byte_index_to_index((int)i)] = NULL;
|
_buf[byte_index_to_index((int)i)] = NULL;
|
||||||
}
|
}
|
||||||
qset()->enqueue_complete_buffer(_buf);
|
qset()->enqueue_complete_buffer(_buf);
|
||||||
_buf = NULL;
|
|
||||||
}
|
}
|
||||||
|
_buf = NULL;
|
||||||
|
_index = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,9 @@ public:
|
||||||
// given PtrQueueSet.
|
// given PtrQueueSet.
|
||||||
PtrQueue(PtrQueueSet*, bool perm = false);
|
PtrQueue(PtrQueueSet*, bool perm = false);
|
||||||
// Release any contained resources.
|
// Release any contained resources.
|
||||||
~PtrQueue();
|
void flush();
|
||||||
|
// Calls flush() when destroyed.
|
||||||
|
~PtrQueue() { flush(); }
|
||||||
|
|
||||||
// Associate a lock with a ptr queue.
|
// Associate a lock with a ptr queue.
|
||||||
void set_lock(Mutex* lock) { _lock = lock; }
|
void set_lock(Mutex* lock) { _lock = lock; }
|
||||||
|
|
|
@ -90,10 +90,10 @@ void PSMarkSweepDecorator::precompact() {
|
||||||
*/
|
*/
|
||||||
bool skip_dead = ((PSMarkSweep::total_invocations() % MarkSweepAlwaysCompactCount) != 0);
|
bool skip_dead = ((PSMarkSweep::total_invocations() % MarkSweepAlwaysCompactCount) != 0);
|
||||||
|
|
||||||
ssize_t allowed_deadspace = 0;
|
size_t allowed_deadspace = 0;
|
||||||
if (skip_dead) {
|
if (skip_dead) {
|
||||||
int ratio = allowed_dead_ratio();
|
const size_t ratio = allowed_dead_ratio();
|
||||||
allowed_deadspace = (space()->capacity_in_bytes() * ratio / 100) / HeapWordSize;
|
allowed_deadspace = space()->capacity_in_words() * ratio / 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch the current destination decorator
|
// Fetch the current destination decorator
|
||||||
|
@ -271,10 +271,10 @@ void PSMarkSweepDecorator::precompact() {
|
||||||
dest->set_compaction_top(compact_top);
|
dest->set_compaction_top(compact_top);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PSMarkSweepDecorator::insert_deadspace(ssize_t& allowed_deadspace_words,
|
bool PSMarkSweepDecorator::insert_deadspace(size_t& allowed_deadspace_words,
|
||||||
HeapWord* q, size_t deadlength) {
|
HeapWord* q, size_t deadlength) {
|
||||||
|
if (allowed_deadspace_words >= deadlength) {
|
||||||
allowed_deadspace_words -= deadlength;
|
allowed_deadspace_words -= deadlength;
|
||||||
if (allowed_deadspace_words >= 0) {
|
|
||||||
oop(q)->set_mark(markOopDesc::prototype()->set_marked());
|
oop(q)->set_mark(markOopDesc::prototype()->set_marked());
|
||||||
const size_t aligned_min_int_array_size =
|
const size_t aligned_min_int_array_size =
|
||||||
align_object_size(typeArrayOopDesc::header_size(T_INT));
|
align_object_size(typeArrayOopDesc::header_size(T_INT));
|
||||||
|
|
|
@ -39,14 +39,16 @@ class PSMarkSweepDecorator: public CHeapObj {
|
||||||
HeapWord* _first_dead;
|
HeapWord* _first_dead;
|
||||||
HeapWord* _end_of_live;
|
HeapWord* _end_of_live;
|
||||||
HeapWord* _compaction_top;
|
HeapWord* _compaction_top;
|
||||||
unsigned int _allowed_dead_ratio;
|
size_t _allowed_dead_ratio;
|
||||||
|
|
||||||
bool insert_deadspace(ssize_t& allowed_deadspace_words, HeapWord* q, size_t word_len);
|
bool insert_deadspace(size_t& allowed_deadspace_words, HeapWord* q,
|
||||||
|
size_t word_len);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PSMarkSweepDecorator(MutableSpace* space, ObjectStartArray* start_array,
|
PSMarkSweepDecorator(MutableSpace* space, ObjectStartArray* start_array,
|
||||||
unsigned int allowed_dead_ratio) :
|
size_t allowed_dead_ratio) :
|
||||||
_space(space), _start_array(start_array), _allowed_dead_ratio(allowed_dead_ratio) { }
|
_space(space), _start_array(start_array),
|
||||||
|
_allowed_dead_ratio(allowed_dead_ratio) { }
|
||||||
|
|
||||||
// During a compacting collection, we need to collapse objects into
|
// During a compacting collection, we need to collapse objects into
|
||||||
// spaces in a given order. We want to fill space A, space B, and so
|
// spaces in a given order. We want to fill space A, space B, and so
|
||||||
|
@ -63,8 +65,8 @@ class PSMarkSweepDecorator: public CHeapObj {
|
||||||
HeapWord* compaction_top() { return _compaction_top; }
|
HeapWord* compaction_top() { return _compaction_top; }
|
||||||
void set_compaction_top(HeapWord* value) { _compaction_top = value; }
|
void set_compaction_top(HeapWord* value) { _compaction_top = value; }
|
||||||
|
|
||||||
unsigned int allowed_dead_ratio() { return _allowed_dead_ratio; }
|
size_t allowed_dead_ratio() { return _allowed_dead_ratio; }
|
||||||
void set_allowed_dead_ratio(unsigned int value) { _allowed_dead_ratio = value; }
|
void set_allowed_dead_ratio(size_t value) { _allowed_dead_ratio = value; }
|
||||||
|
|
||||||
// Work methods
|
// Work methods
|
||||||
void adjust_pointers();
|
void adjust_pointers();
|
||||||
|
|
|
@ -30,6 +30,12 @@ collectorPolicy.cpp cmsGCAdaptivePolicyCounters.hpp
|
||||||
|
|
||||||
compiledICHolderKlass.cpp oop.pcgc.inline.hpp
|
compiledICHolderKlass.cpp oop.pcgc.inline.hpp
|
||||||
|
|
||||||
|
constantPoolKlass.cpp cardTableRS.hpp
|
||||||
|
constantPoolKlass.cpp oop.pcgc.inline.hpp
|
||||||
|
constantPoolKlass.cpp psPromotionManager.inline.hpp
|
||||||
|
constantPoolKlass.cpp psScavenge.inline.hpp
|
||||||
|
constantPoolKlass.cpp parOopClosures.inline.hpp
|
||||||
|
|
||||||
genCollectedHeap.cpp concurrentMarkSweepThread.hpp
|
genCollectedHeap.cpp concurrentMarkSweepThread.hpp
|
||||||
genCollectedHeap.cpp vmCMSOperations.hpp
|
genCollectedHeap.cpp vmCMSOperations.hpp
|
||||||
|
|
||||||
|
|
|
@ -997,11 +997,11 @@ void OffsetTableContigSpace::serialize_block_offset_array_offsets(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int TenuredSpace::allowed_dead_ratio() const {
|
size_t TenuredSpace::allowed_dead_ratio() const {
|
||||||
return MarkSweepDeadRatio;
|
return MarkSweepDeadRatio;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int ContigPermSpace::allowed_dead_ratio() const {
|
size_t ContigPermSpace::allowed_dead_ratio() const {
|
||||||
return PermMarkSweepDeadRatio;
|
return PermMarkSweepDeadRatio;
|
||||||
}
|
}
|
||||||
|
|
|
@ -421,7 +421,7 @@ public:
|
||||||
|
|
||||||
// The maximum percentage of objects that can be dead in the compacted
|
// The maximum percentage of objects that can be dead in the compacted
|
||||||
// live part of a compacted space ("deadwood" support.)
|
// live part of a compacted space ("deadwood" support.)
|
||||||
virtual int allowed_dead_ratio() const { return 0; };
|
virtual size_t allowed_dead_ratio() const { return 0; };
|
||||||
|
|
||||||
// Some contiguous spaces may maintain some data structures that should
|
// Some contiguous spaces may maintain some data structures that should
|
||||||
// be updated whenever an allocation crosses a boundary. This function
|
// be updated whenever an allocation crosses a boundary. This function
|
||||||
|
@ -507,7 +507,7 @@ protected:
|
||||||
\
|
\
|
||||||
size_t allowed_deadspace = 0; \
|
size_t allowed_deadspace = 0; \
|
||||||
if (skip_dead) { \
|
if (skip_dead) { \
|
||||||
int ratio = allowed_dead_ratio(); \
|
const size_t ratio = allowed_dead_ratio(); \
|
||||||
allowed_deadspace = (capacity() * ratio / 100) / HeapWordSize; \
|
allowed_deadspace = (capacity() * ratio / 100) / HeapWordSize; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
|
@ -1079,7 +1079,7 @@ class TenuredSpace: public OffsetTableContigSpace {
|
||||||
friend class VMStructs;
|
friend class VMStructs;
|
||||||
protected:
|
protected:
|
||||||
// Mark sweep support
|
// Mark sweep support
|
||||||
int allowed_dead_ratio() const;
|
size_t allowed_dead_ratio() const;
|
||||||
public:
|
public:
|
||||||
// Constructor
|
// Constructor
|
||||||
TenuredSpace(BlockOffsetSharedArray* sharedOffsetArray,
|
TenuredSpace(BlockOffsetSharedArray* sharedOffsetArray,
|
||||||
|
@ -1094,7 +1094,7 @@ class ContigPermSpace: public OffsetTableContigSpace {
|
||||||
friend class VMStructs;
|
friend class VMStructs;
|
||||||
protected:
|
protected:
|
||||||
// Mark sweep support
|
// Mark sweep support
|
||||||
int allowed_dead_ratio() const;
|
size_t allowed_dead_ratio() const;
|
||||||
public:
|
public:
|
||||||
// Constructor
|
// Constructor
|
||||||
ContigPermSpace(BlockOffsetSharedArray* sharedOffsetArray, MemRegion mr) :
|
ContigPermSpace(BlockOffsetSharedArray* sharedOffsetArray, MemRegion mr) :
|
||||||
|
|
|
@ -73,7 +73,6 @@ class TenuredGeneration: public OneContigSpaceCardGeneration {
|
||||||
|
|
||||||
// Mark sweep support
|
// Mark sweep support
|
||||||
void compute_new_size();
|
void compute_new_size();
|
||||||
int allowed_dead_ratio() const;
|
|
||||||
|
|
||||||
virtual void gc_prologue(bool full);
|
virtual void gc_prologue(bool full);
|
||||||
virtual void gc_epilogue(bool full);
|
virtual void gc_epilogue(bool full);
|
||||||
|
|
|
@ -35,6 +35,7 @@ constantPoolOop constantPoolKlass::allocate(int length, TRAPS) {
|
||||||
c->set_tags(NULL);
|
c->set_tags(NULL);
|
||||||
c->set_cache(NULL);
|
c->set_cache(NULL);
|
||||||
c->set_pool_holder(NULL);
|
c->set_pool_holder(NULL);
|
||||||
|
c->set_flags(0);
|
||||||
// only set to non-zero if constant pool is merged by RedefineClasses
|
// only set to non-zero if constant pool is merged by RedefineClasses
|
||||||
c->set_orig_length(0);
|
c->set_orig_length(0);
|
||||||
// all fields are initialized; needed for GC
|
// all fields are initialized; needed for GC
|
||||||
|
@ -261,10 +262,32 @@ constantPoolKlass::oop_update_pointers(ParCompactionManager* cm, oop obj,
|
||||||
|
|
||||||
void constantPoolKlass::oop_copy_contents(PSPromotionManager* pm, oop obj) {
|
void constantPoolKlass::oop_copy_contents(PSPromotionManager* pm, oop obj) {
|
||||||
assert(obj->is_constantPool(), "should be constant pool");
|
assert(obj->is_constantPool(), "should be constant pool");
|
||||||
|
constantPoolOop cp = (constantPoolOop) obj;
|
||||||
|
if (AnonymousClasses && cp->has_pseudo_string() && cp->tags() != NULL) {
|
||||||
|
oop* base = (oop*)cp->base();
|
||||||
|
for (int i = 0; i < cp->length(); ++i, ++base) {
|
||||||
|
if (cp->tag_at(i).is_string()) {
|
||||||
|
if (PSScavenge::should_scavenge(base)) {
|
||||||
|
pm->claim_or_forward_breadth(base);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void constantPoolKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
|
void constantPoolKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
|
||||||
assert(obj->is_constantPool(), "should be constant pool");
|
assert(obj->is_constantPool(), "should be constant pool");
|
||||||
|
constantPoolOop cp = (constantPoolOop) obj;
|
||||||
|
if (AnonymousClasses && cp->has_pseudo_string() && cp->tags() != NULL) {
|
||||||
|
oop* base = (oop*)cp->base();
|
||||||
|
for (int i = 0; i < cp->length(); ++i, ++base) {
|
||||||
|
if (cp->tag_at(i).is_string()) {
|
||||||
|
if (PSScavenge::should_scavenge(base)) {
|
||||||
|
pm->claim_or_forward_depth(base);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif // SERIALGC
|
#endif // SERIALGC
|
||||||
|
|
||||||
|
@ -278,6 +301,11 @@ void constantPoolKlass::oop_print_on(oop obj, outputStream* st) {
|
||||||
assert(obj->is_constantPool(), "must be constantPool");
|
assert(obj->is_constantPool(), "must be constantPool");
|
||||||
Klass::oop_print_on(obj, st);
|
Klass::oop_print_on(obj, st);
|
||||||
constantPoolOop cp = constantPoolOop(obj);
|
constantPoolOop cp = constantPoolOop(obj);
|
||||||
|
if (cp->flags() != 0) {
|
||||||
|
st->print(" - flags : 0x%x", cp->flags());
|
||||||
|
if (cp->has_pseudo_string()) st->print(" has_pseudo_string");
|
||||||
|
st->cr();
|
||||||
|
}
|
||||||
|
|
||||||
// Temp. remove cache so we can do lookups with original indicies.
|
// Temp. remove cache so we can do lookups with original indicies.
|
||||||
constantPoolCacheHandle cache (THREAD, cp->cache());
|
constantPoolCacheHandle cache (THREAD, cp->cache());
|
||||||
|
@ -302,7 +330,11 @@ void constantPoolKlass::oop_print_on(oop obj, outputStream* st) {
|
||||||
break;
|
break;
|
||||||
case JVM_CONSTANT_UnresolvedString :
|
case JVM_CONSTANT_UnresolvedString :
|
||||||
case JVM_CONSTANT_String :
|
case JVM_CONSTANT_String :
|
||||||
|
if (cp->is_pseudo_string_at(index)) {
|
||||||
|
anObj = cp->pseudo_string_at(index);
|
||||||
|
} else {
|
||||||
anObj = cp->string_at(index, CATCH);
|
anObj = cp->string_at(index, CATCH);
|
||||||
|
}
|
||||||
anObj->print_value_on(st);
|
anObj->print_value_on(st);
|
||||||
st->print(" {0x%lx}", (address)anObj);
|
st->print(" {0x%lx}", (address)anObj);
|
||||||
break;
|
break;
|
||||||
|
@ -382,8 +414,12 @@ void constantPoolKlass::oop_verify_on(oop obj, outputStream* st) {
|
||||||
"should be symbol or instance");
|
"should be symbol or instance");
|
||||||
}
|
}
|
||||||
if (cp->tag_at(i).is_string()) {
|
if (cp->tag_at(i).is_string()) {
|
||||||
|
if (!cp->has_pseudo_string()) {
|
||||||
guarantee((*base)->is_perm(), "should be in permspace");
|
guarantee((*base)->is_perm(), "should be in permspace");
|
||||||
guarantee((*base)->is_instance(), "should be instance");
|
guarantee((*base)->is_instance(), "should be instance");
|
||||||
|
} else {
|
||||||
|
// can be non-perm, can be non-instance (array)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
base++;
|
base++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,18 @@
|
||||||
# include "incls/_precompiled.incl"
|
# include "incls/_precompiled.incl"
|
||||||
# include "incls/_constantPoolOop.cpp.incl"
|
# include "incls/_constantPoolOop.cpp.incl"
|
||||||
|
|
||||||
|
void constantPoolOopDesc::set_flag_at(FlagBit fb) {
|
||||||
|
const int MAX_STATE_CHANGES = 2;
|
||||||
|
for (int i = MAX_STATE_CHANGES + 10; i > 0; i--) {
|
||||||
|
int oflags = _flags;
|
||||||
|
int nflags = oflags | (1 << (int)fb);
|
||||||
|
if (Atomic::cmpxchg(nflags, &_flags, oflags) == oflags)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
assert(false, "failed to cmpxchg flags");
|
||||||
|
_flags |= (1 << (int)fb); // better than nothing
|
||||||
|
}
|
||||||
|
|
||||||
klassOop constantPoolOopDesc::klass_at_impl(constantPoolHandle this_oop, int which, TRAPS) {
|
klassOop constantPoolOopDesc::klass_at_impl(constantPoolHandle this_oop, int which, TRAPS) {
|
||||||
// A resolved constantPool entry will contain a klassOop, otherwise a symbolOop.
|
// A resolved constantPool entry will contain a klassOop, otherwise a symbolOop.
|
||||||
// It is not safe to rely on the tag bit's here, since we don't have a lock, and the entry and
|
// It is not safe to rely on the tag bit's here, since we don't have a lock, and the entry and
|
||||||
|
@ -333,8 +345,10 @@ char* constantPoolOopDesc::string_at_noresolve(int which) {
|
||||||
oop entry = *(obj_at_addr(which));
|
oop entry = *(obj_at_addr(which));
|
||||||
if (entry->is_symbol()) {
|
if (entry->is_symbol()) {
|
||||||
return ((symbolOop)entry)->as_C_string();
|
return ((symbolOop)entry)->as_C_string();
|
||||||
} else {
|
} else if (java_lang_String::is_instance(entry)) {
|
||||||
return java_lang_String::as_utf8_string(entry);
|
return java_lang_String::as_utf8_string(entry);
|
||||||
|
} else {
|
||||||
|
return (char*)"<pseudo-string>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -385,6 +399,19 @@ oop constantPoolOopDesc::string_at_impl(constantPoolHandle this_oop, int which,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool constantPoolOopDesc::is_pseudo_string_at(int which) {
|
||||||
|
oop entry = *(obj_at_addr(which));
|
||||||
|
if (entry->is_symbol())
|
||||||
|
// Not yet resolved, but it will resolve to a string.
|
||||||
|
return false;
|
||||||
|
else if (java_lang_String::is_instance(entry))
|
||||||
|
return false; // actually, it might be a non-interned or non-perm string
|
||||||
|
else
|
||||||
|
// truly pseudo
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool constantPoolOopDesc::klass_name_at_matches(instanceKlassHandle k,
|
bool constantPoolOopDesc::klass_name_at_matches(instanceKlassHandle k,
|
||||||
int which) {
|
int which) {
|
||||||
// Names are interned, so we can compare symbolOops directly
|
// Names are interned, so we can compare symbolOops directly
|
||||||
|
|
|
@ -41,6 +41,7 @@ class constantPoolOopDesc : public oopDesc {
|
||||||
typeArrayOop _tags; // the tag array describing the constant pool's contents
|
typeArrayOop _tags; // the tag array describing the constant pool's contents
|
||||||
constantPoolCacheOop _cache; // the cache holding interpreter runtime information
|
constantPoolCacheOop _cache; // the cache holding interpreter runtime information
|
||||||
klassOop _pool_holder; // the corresponding class
|
klassOop _pool_holder; // the corresponding class
|
||||||
|
int _flags; // a few header bits to describe contents for GC
|
||||||
int _length; // number of elements in the array
|
int _length; // number of elements in the array
|
||||||
// only set to non-zero if constant pool is merged by RedefineClasses
|
// only set to non-zero if constant pool is merged by RedefineClasses
|
||||||
int _orig_length;
|
int _orig_length;
|
||||||
|
@ -49,6 +50,16 @@ class constantPoolOopDesc : public oopDesc {
|
||||||
void tag_at_put(int which, jbyte t) { tags()->byte_at_put(which, t); }
|
void tag_at_put(int which, jbyte t) { tags()->byte_at_put(which, t); }
|
||||||
void release_tag_at_put(int which, jbyte t) { tags()->release_byte_at_put(which, t); }
|
void release_tag_at_put(int which, jbyte t) { tags()->release_byte_at_put(which, t); }
|
||||||
|
|
||||||
|
enum FlagBit {
|
||||||
|
FB_has_pseudo_string = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
int flags() const { return _flags; }
|
||||||
|
void set_flags(int f) { _flags = f; }
|
||||||
|
bool flag_at(FlagBit fb) const { return (_flags & (1 << (int)fb)) != 0; }
|
||||||
|
void set_flag_at(FlagBit fb);
|
||||||
|
// no clear_flag_at function; they only increase
|
||||||
|
|
||||||
private:
|
private:
|
||||||
intptr_t* base() const { return (intptr_t*) (((char*) this) + sizeof(constantPoolOopDesc)); }
|
intptr_t* base() const { return (intptr_t*) (((char*) this) + sizeof(constantPoolOopDesc)); }
|
||||||
oop* tags_addr() { return (oop*)&_tags; }
|
oop* tags_addr() { return (oop*)&_tags; }
|
||||||
|
@ -82,6 +93,9 @@ class constantPoolOopDesc : public oopDesc {
|
||||||
public:
|
public:
|
||||||
typeArrayOop tags() const { return _tags; }
|
typeArrayOop tags() const { return _tags; }
|
||||||
|
|
||||||
|
bool has_pseudo_string() const { return flag_at(FB_has_pseudo_string); }
|
||||||
|
void set_pseudo_string() { set_flag_at(FB_has_pseudo_string); }
|
||||||
|
|
||||||
// Klass holding pool
|
// Klass holding pool
|
||||||
klassOop pool_holder() const { return _pool_holder; }
|
klassOop pool_holder() const { return _pool_holder; }
|
||||||
void set_pool_holder(klassOop k) { oop_store_without_check((oop*)&_pool_holder, (oop) k); }
|
void set_pool_holder(klassOop k) { oop_store_without_check((oop*)&_pool_holder, (oop) k); }
|
||||||
|
@ -272,6 +286,27 @@ class constantPoolOopDesc : public oopDesc {
|
||||||
return string_at_impl(h_this, which, CHECK_NULL);
|
return string_at_impl(h_this, which, CHECK_NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A "pseudo-string" is an non-string oop that has found is way into
|
||||||
|
// a String entry.
|
||||||
|
// Under AnonymousClasses this can happen if the user patches a live
|
||||||
|
// object into a CONSTANT_String entry of an anonymous class.
|
||||||
|
// Method oops internally created for method handles may also
|
||||||
|
// use pseudo-strings to link themselves to related metaobjects.
|
||||||
|
|
||||||
|
bool is_pseudo_string_at(int which);
|
||||||
|
|
||||||
|
oop pseudo_string_at(int which) {
|
||||||
|
assert(tag_at(which).is_string(), "Corrupted constant pool");
|
||||||
|
return *obj_at_addr(which);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pseudo_string_at_put(int which, oop x) {
|
||||||
|
assert(AnonymousClasses, "");
|
||||||
|
set_pseudo_string(); // mark header
|
||||||
|
assert(tag_at(which).is_string() || tag_at(which).is_unresolved_string(), "Corrupted constant pool");
|
||||||
|
string_at_put(which, x); // this works just fine
|
||||||
|
}
|
||||||
|
|
||||||
// only called when we are sure a string entry is already resolved (via an
|
// only called when we are sure a string entry is already resolved (via an
|
||||||
// earlier string_at call.
|
// earlier string_at call.
|
||||||
oop resolved_string_at(int which) {
|
oop resolved_string_at(int which) {
|
||||||
|
@ -293,6 +328,7 @@ class constantPoolOopDesc : public oopDesc {
|
||||||
// UTF8 char* representation was chosen to avoid conversion of
|
// UTF8 char* representation was chosen to avoid conversion of
|
||||||
// java_lang_Strings at resolved entries into symbolOops
|
// java_lang_Strings at resolved entries into symbolOops
|
||||||
// or vice versa.
|
// or vice versa.
|
||||||
|
// Caller is responsible for checking for pseudo-strings.
|
||||||
char* string_at_noresolve(int which);
|
char* string_at_noresolve(int which);
|
||||||
|
|
||||||
jint name_and_type_at(int which) {
|
jint name_and_type_at(int which) {
|
||||||
|
|
|
@ -147,6 +147,10 @@ class instanceKlass: public Klass {
|
||||||
oop _class_loader;
|
oop _class_loader;
|
||||||
// Protection domain.
|
// Protection domain.
|
||||||
oop _protection_domain;
|
oop _protection_domain;
|
||||||
|
// Host class, which grants its access privileges to this class also.
|
||||||
|
// This is only non-null for an anonymous class (AnonymousClasses enabled).
|
||||||
|
// The host class is either named, or a previously loaded anonymous class.
|
||||||
|
klassOop _host_klass;
|
||||||
// Class signers.
|
// Class signers.
|
||||||
objArrayOop _signers;
|
objArrayOop _signers;
|
||||||
// Name of source file containing this klass, NULL if not specified.
|
// Name of source file containing this klass, NULL if not specified.
|
||||||
|
@ -375,6 +379,11 @@ class instanceKlass: public Klass {
|
||||||
oop protection_domain() { return _protection_domain; }
|
oop protection_domain() { return _protection_domain; }
|
||||||
void set_protection_domain(oop pd) { oop_store((oop*) &_protection_domain, pd); }
|
void set_protection_domain(oop pd) { oop_store((oop*) &_protection_domain, pd); }
|
||||||
|
|
||||||
|
// host class
|
||||||
|
oop host_klass() const { return _host_klass; }
|
||||||
|
void set_host_klass(oop host) { oop_store((oop*) &_host_klass, host); }
|
||||||
|
bool is_anonymous() const { return _host_klass != NULL; }
|
||||||
|
|
||||||
// signers
|
// signers
|
||||||
objArrayOop signers() const { return _signers; }
|
objArrayOop signers() const { return _signers; }
|
||||||
void set_signers(objArrayOop s) { oop_store((oop*) &_signers, oop(s)); }
|
void set_signers(objArrayOop s) { oop_store((oop*) &_signers, oop(s)); }
|
||||||
|
@ -709,6 +718,7 @@ private:
|
||||||
oop* adr_constants() const { return (oop*)&this->_constants;}
|
oop* adr_constants() const { return (oop*)&this->_constants;}
|
||||||
oop* adr_class_loader() const { return (oop*)&this->_class_loader;}
|
oop* adr_class_loader() const { return (oop*)&this->_class_loader;}
|
||||||
oop* adr_protection_domain() const { return (oop*)&this->_protection_domain;}
|
oop* adr_protection_domain() const { return (oop*)&this->_protection_domain;}
|
||||||
|
oop* adr_host_klass() const { return (oop*)&this->_host_klass;}
|
||||||
oop* adr_signers() const { return (oop*)&this->_signers;}
|
oop* adr_signers() const { return (oop*)&this->_signers;}
|
||||||
oop* adr_source_file_name() const { return (oop*)&this->_source_file_name;}
|
oop* adr_source_file_name() const { return (oop*)&this->_source_file_name;}
|
||||||
oop* adr_source_debug_extension() const { return (oop*)&this->_source_debug_extension;}
|
oop* adr_source_debug_extension() const { return (oop*)&this->_source_debug_extension;}
|
||||||
|
|
|
@ -81,6 +81,7 @@ void instanceKlassKlass::oop_follow_contents(oop obj) {
|
||||||
MarkSweep::mark_and_push(ik->adr_source_debug_extension());
|
MarkSweep::mark_and_push(ik->adr_source_debug_extension());
|
||||||
MarkSweep::mark_and_push(ik->adr_inner_classes());
|
MarkSweep::mark_and_push(ik->adr_inner_classes());
|
||||||
MarkSweep::mark_and_push(ik->adr_protection_domain());
|
MarkSweep::mark_and_push(ik->adr_protection_domain());
|
||||||
|
MarkSweep::mark_and_push(ik->adr_host_klass());
|
||||||
MarkSweep::mark_and_push(ik->adr_signers());
|
MarkSweep::mark_and_push(ik->adr_signers());
|
||||||
MarkSweep::mark_and_push(ik->adr_generic_signature());
|
MarkSweep::mark_and_push(ik->adr_generic_signature());
|
||||||
MarkSweep::mark_and_push(ik->adr_class_annotations());
|
MarkSweep::mark_and_push(ik->adr_class_annotations());
|
||||||
|
@ -120,6 +121,7 @@ void instanceKlassKlass::oop_follow_contents(ParCompactionManager* cm,
|
||||||
PSParallelCompact::mark_and_push(cm, ik->adr_source_debug_extension());
|
PSParallelCompact::mark_and_push(cm, ik->adr_source_debug_extension());
|
||||||
PSParallelCompact::mark_and_push(cm, ik->adr_inner_classes());
|
PSParallelCompact::mark_and_push(cm, ik->adr_inner_classes());
|
||||||
PSParallelCompact::mark_and_push(cm, ik->adr_protection_domain());
|
PSParallelCompact::mark_and_push(cm, ik->adr_protection_domain());
|
||||||
|
PSParallelCompact::mark_and_push(cm, ik->adr_host_klass());
|
||||||
PSParallelCompact::mark_and_push(cm, ik->adr_signers());
|
PSParallelCompact::mark_and_push(cm, ik->adr_signers());
|
||||||
PSParallelCompact::mark_and_push(cm, ik->adr_generic_signature());
|
PSParallelCompact::mark_and_push(cm, ik->adr_generic_signature());
|
||||||
PSParallelCompact::mark_and_push(cm, ik->adr_class_annotations());
|
PSParallelCompact::mark_and_push(cm, ik->adr_class_annotations());
|
||||||
|
@ -159,6 +161,7 @@ int instanceKlassKlass::oop_oop_iterate(oop obj, OopClosure* blk) {
|
||||||
blk->do_oop(ik->adr_constants());
|
blk->do_oop(ik->adr_constants());
|
||||||
blk->do_oop(ik->adr_class_loader());
|
blk->do_oop(ik->adr_class_loader());
|
||||||
blk->do_oop(ik->adr_protection_domain());
|
blk->do_oop(ik->adr_protection_domain());
|
||||||
|
blk->do_oop(ik->adr_host_klass());
|
||||||
blk->do_oop(ik->adr_signers());
|
blk->do_oop(ik->adr_signers());
|
||||||
blk->do_oop(ik->adr_source_file_name());
|
blk->do_oop(ik->adr_source_file_name());
|
||||||
blk->do_oop(ik->adr_source_debug_extension());
|
blk->do_oop(ik->adr_source_debug_extension());
|
||||||
|
@ -211,6 +214,8 @@ int instanceKlassKlass::oop_oop_iterate_m(oop obj, OopClosure* blk,
|
||||||
if (mr.contains(adr)) blk->do_oop(adr);
|
if (mr.contains(adr)) blk->do_oop(adr);
|
||||||
adr = ik->adr_protection_domain();
|
adr = ik->adr_protection_domain();
|
||||||
if (mr.contains(adr)) blk->do_oop(adr);
|
if (mr.contains(adr)) blk->do_oop(adr);
|
||||||
|
adr = ik->adr_host_klass();
|
||||||
|
if (mr.contains(adr)) blk->do_oop(adr);
|
||||||
adr = ik->adr_signers();
|
adr = ik->adr_signers();
|
||||||
if (mr.contains(adr)) blk->do_oop(adr);
|
if (mr.contains(adr)) blk->do_oop(adr);
|
||||||
adr = ik->adr_source_file_name();
|
adr = ik->adr_source_file_name();
|
||||||
|
@ -260,6 +265,7 @@ int instanceKlassKlass::oop_adjust_pointers(oop obj) {
|
||||||
MarkSweep::adjust_pointer(ik->adr_constants());
|
MarkSweep::adjust_pointer(ik->adr_constants());
|
||||||
MarkSweep::adjust_pointer(ik->adr_class_loader());
|
MarkSweep::adjust_pointer(ik->adr_class_loader());
|
||||||
MarkSweep::adjust_pointer(ik->adr_protection_domain());
|
MarkSweep::adjust_pointer(ik->adr_protection_domain());
|
||||||
|
MarkSweep::adjust_pointer(ik->adr_host_klass());
|
||||||
MarkSweep::adjust_pointer(ik->adr_signers());
|
MarkSweep::adjust_pointer(ik->adr_signers());
|
||||||
MarkSweep::adjust_pointer(ik->adr_source_file_name());
|
MarkSweep::adjust_pointer(ik->adr_source_file_name());
|
||||||
MarkSweep::adjust_pointer(ik->adr_source_debug_extension());
|
MarkSweep::adjust_pointer(ik->adr_source_debug_extension());
|
||||||
|
@ -295,6 +301,11 @@ void instanceKlassKlass::oop_copy_contents(PSPromotionManager* pm, oop obj) {
|
||||||
pm->claim_or_forward_breadth(pd_addr);
|
pm->claim_or_forward_breadth(pd_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
oop* hk_addr = ik->adr_host_klass();
|
||||||
|
if (PSScavenge::should_scavenge(hk_addr)) {
|
||||||
|
pm->claim_or_forward_breadth(hk_addr);
|
||||||
|
}
|
||||||
|
|
||||||
oop* sg_addr = ik->adr_signers();
|
oop* sg_addr = ik->adr_signers();
|
||||||
if (PSScavenge::should_scavenge(sg_addr)) {
|
if (PSScavenge::should_scavenge(sg_addr)) {
|
||||||
pm->claim_or_forward_breadth(sg_addr);
|
pm->claim_or_forward_breadth(sg_addr);
|
||||||
|
@ -318,6 +329,11 @@ void instanceKlassKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
|
||||||
pm->claim_or_forward_depth(pd_addr);
|
pm->claim_or_forward_depth(pd_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
oop* hk_addr = ik->adr_host_klass();
|
||||||
|
if (PSScavenge::should_scavenge(hk_addr)) {
|
||||||
|
pm->claim_or_forward_depth(hk_addr);
|
||||||
|
}
|
||||||
|
|
||||||
oop* sg_addr = ik->adr_signers();
|
oop* sg_addr = ik->adr_signers();
|
||||||
if (PSScavenge::should_scavenge(sg_addr)) {
|
if (PSScavenge::should_scavenge(sg_addr)) {
|
||||||
pm->claim_or_forward_depth(sg_addr);
|
pm->claim_or_forward_depth(sg_addr);
|
||||||
|
@ -421,6 +437,7 @@ klassOop instanceKlassKlass::allocate_instance_klass(int vtable_len, int itable_
|
||||||
ik->set_constants(NULL);
|
ik->set_constants(NULL);
|
||||||
ik->set_class_loader(NULL);
|
ik->set_class_loader(NULL);
|
||||||
ik->set_protection_domain(NULL);
|
ik->set_protection_domain(NULL);
|
||||||
|
ik->set_host_klass(NULL);
|
||||||
ik->set_signers(NULL);
|
ik->set_signers(NULL);
|
||||||
ik->set_source_file_name(NULL);
|
ik->set_source_file_name(NULL);
|
||||||
ik->set_source_debug_extension(NULL);
|
ik->set_source_debug_extension(NULL);
|
||||||
|
@ -526,6 +543,7 @@ void instanceKlassKlass::oop_print_on(oop obj, outputStream* st) {
|
||||||
st->print(" - constants: "); ik->constants()->print_value_on(st); st->cr();
|
st->print(" - constants: "); ik->constants()->print_value_on(st); st->cr();
|
||||||
st->print(" - class loader: "); ik->class_loader()->print_value_on(st); st->cr();
|
st->print(" - class loader: "); ik->class_loader()->print_value_on(st); st->cr();
|
||||||
st->print(" - protection domain: "); ik->protection_domain()->print_value_on(st); st->cr();
|
st->print(" - protection domain: "); ik->protection_domain()->print_value_on(st); st->cr();
|
||||||
|
st->print(" - host class: "); ik->host_klass()->print_value_on(st); st->cr();
|
||||||
st->print(" - signers: "); ik->signers()->print_value_on(st); st->cr();
|
st->print(" - signers: "); ik->signers()->print_value_on(st); st->cr();
|
||||||
if (ik->source_file_name() != NULL) {
|
if (ik->source_file_name() != NULL) {
|
||||||
st->print(" - source file: ");
|
st->print(" - source file: ");
|
||||||
|
@ -626,7 +644,7 @@ void instanceKlassKlass::oop_verify_on(oop obj, outputStream* st) {
|
||||||
ik->_verify_count = Universe::verify_count();
|
ik->_verify_count = Universe::verify_count();
|
||||||
#endif
|
#endif
|
||||||
// Verify that klass is present in SystemDictionary
|
// Verify that klass is present in SystemDictionary
|
||||||
if (ik->is_loaded()) {
|
if (ik->is_loaded() && !ik->is_anonymous()) {
|
||||||
symbolHandle h_name (thread, ik->name());
|
symbolHandle h_name (thread, ik->name());
|
||||||
Handle h_loader (thread, ik->class_loader());
|
Handle h_loader (thread, ik->class_loader());
|
||||||
Handle h_obj(thread, obj);
|
Handle h_obj(thread, obj);
|
||||||
|
@ -764,6 +782,9 @@ void instanceKlassKlass::oop_verify_on(oop obj, outputStream* st) {
|
||||||
if (ik->protection_domain() != NULL) {
|
if (ik->protection_domain() != NULL) {
|
||||||
guarantee(ik->protection_domain()->is_oop(), "should be oop");
|
guarantee(ik->protection_domain()->is_oop(), "should be oop");
|
||||||
}
|
}
|
||||||
|
if (ik->host_klass() != NULL) {
|
||||||
|
guarantee(ik->host_klass()->is_oop(), "should be oop");
|
||||||
|
}
|
||||||
if (ik->signers() != NULL) {
|
if (ik->signers() != NULL) {
|
||||||
guarantee(ik->signers()->is_objArray(), "should be obj array");
|
guarantee(ik->signers()->is_objArray(), "should be obj array");
|
||||||
}
|
}
|
||||||
|
|
|
@ -478,6 +478,24 @@ void Klass::with_array_klasses_do(void f(klassOop k)) {
|
||||||
|
|
||||||
|
|
||||||
const char* Klass::external_name() const {
|
const char* Klass::external_name() const {
|
||||||
|
if (oop_is_instance()) {
|
||||||
|
instanceKlass* ik = (instanceKlass*) this;
|
||||||
|
if (ik->is_anonymous()) {
|
||||||
|
assert(AnonymousClasses, "");
|
||||||
|
intptr_t hash = ik->java_mirror()->identity_hash();
|
||||||
|
char hash_buf[40];
|
||||||
|
sprintf(hash_buf, "/" UINTX_FORMAT, (uintx)hash);
|
||||||
|
size_t hash_len = strlen(hash_buf);
|
||||||
|
|
||||||
|
size_t result_len = name()->utf8_length();
|
||||||
|
char* result = NEW_RESOURCE_ARRAY(char, result_len + hash_len + 1);
|
||||||
|
name()->as_klass_external_name(result, (int) result_len + 1);
|
||||||
|
assert(strlen(result) == result_len, "");
|
||||||
|
strcpy(result + result_len, hash_buf);
|
||||||
|
assert(strlen(result) == result_len + hash_len, "");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
return name()->as_klass_external_name();
|
return name()->as_klass_external_name();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -256,10 +256,10 @@
|
||||||
develop(intx, PrintIdealGraphPort, 4444, \
|
develop(intx, PrintIdealGraphPort, 4444, \
|
||||||
"Ideal graph printer to network port") \
|
"Ideal graph printer to network port") \
|
||||||
\
|
\
|
||||||
develop(ccstr, PrintIdealGraphAddress, "127.0.0.1", \
|
notproduct(ccstr, PrintIdealGraphAddress, "127.0.0.1", \
|
||||||
"IP address to connect to visualizer") \
|
"IP address to connect to visualizer") \
|
||||||
\
|
\
|
||||||
develop(ccstr, PrintIdealGraphFile, NULL, \
|
notproduct(ccstr, PrintIdealGraphFile, NULL, \
|
||||||
"File to dump ideal graph to. If set overrides the " \
|
"File to dump ideal graph to. If set overrides the " \
|
||||||
"use of the network") \
|
"use of the network") \
|
||||||
\
|
\
|
||||||
|
|
|
@ -1673,7 +1673,6 @@ void PhaseMacroExpand::expand_lock_node(LockNode *lock) {
|
||||||
if (klass_node == NULL) {
|
if (klass_node == NULL) {
|
||||||
Node* k_adr = basic_plus_adr(obj, oopDesc::klass_offset_in_bytes());
|
Node* k_adr = basic_plus_adr(obj, oopDesc::klass_offset_in_bytes());
|
||||||
klass_node = transform_later( LoadKlassNode::make(_igvn, mem, k_adr, _igvn.type(k_adr)->is_ptr()) );
|
klass_node = transform_later( LoadKlassNode::make(_igvn, mem, k_adr, _igvn.type(k_adr)->is_ptr()) );
|
||||||
klass_node->init_req(0, ctrl);
|
|
||||||
}
|
}
|
||||||
Node *proto_node = make_load(ctrl, mem, klass_node, Klass::prototype_header_offset_in_bytes() + sizeof(oopDesc), TypeX_X, TypeX_X->basic_type());
|
Node *proto_node = make_load(ctrl, mem, klass_node, Klass::prototype_header_offset_in_bytes() + sizeof(oopDesc), TypeX_X, TypeX_X->basic_type());
|
||||||
|
|
||||||
|
|
|
@ -175,7 +175,7 @@ class Parse : public GraphKit {
|
||||||
bool is_SEL_backedge(Block* pred) const{ return is_SEL_head() && pred->rpo() >= rpo(); }
|
bool is_SEL_backedge(Block* pred) const{ return is_SEL_head() && pred->rpo() >= rpo(); }
|
||||||
bool is_invariant_local(uint i) const {
|
bool is_invariant_local(uint i) const {
|
||||||
const JVMState* jvms = start_map()->jvms();
|
const JVMState* jvms = start_map()->jvms();
|
||||||
if (!jvms->is_loc(i)) return false;
|
if (!jvms->is_loc(i) || flow()->outer()->has_irreducible_entry()) return false;
|
||||||
return flow()->is_invariant_local(i - jvms->locoff());
|
return flow()->is_invariant_local(i - jvms->locoff());
|
||||||
}
|
}
|
||||||
bool can_elide_SEL_phi(uint i) const { assert(is_SEL_head(),""); return is_invariant_local(i); }
|
bool can_elide_SEL_phi(uint i) const { assert(is_SEL_head(),""); return is_invariant_local(i); }
|
||||||
|
|
|
@ -744,6 +744,7 @@ static void is_lock_held_by_thread(Handle loader, PerfCounter* counter, TRAPS) {
|
||||||
|
|
||||||
// common code for JVM_DefineClass() and JVM_DefineClassWithSource()
|
// common code for JVM_DefineClass() and JVM_DefineClassWithSource()
|
||||||
static jclass jvm_define_class_common(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd, const char *source, TRAPS) {
|
static jclass jvm_define_class_common(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd, const char *source, TRAPS) {
|
||||||
|
if (source == NULL) source = "__JVM_DefineClass__";
|
||||||
|
|
||||||
// Since exceptions can be thrown, class initialization can take place
|
// Since exceptions can be thrown, class initialization can take place
|
||||||
// if name is NULL no check for class name in .class stream has to be made.
|
// if name is NULL no check for class name in .class stream has to be made.
|
||||||
|
@ -782,7 +783,7 @@ static jclass jvm_define_class_common(JNIEnv *env, const char *name, jobject loa
|
||||||
JVM_ENTRY(jclass, JVM_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd))
|
JVM_ENTRY(jclass, JVM_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd))
|
||||||
JVMWrapper2("JVM_DefineClass %s", name);
|
JVMWrapper2("JVM_DefineClass %s", name);
|
||||||
|
|
||||||
return jvm_define_class_common(env, name, loader, buf, len, pd, "__JVM_DefineClass__", THREAD);
|
return jvm_define_class_common(env, name, loader, buf, len, pd, NULL, THREAD);
|
||||||
JVM_END
|
JVM_END
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -422,6 +422,14 @@ JVM_DefineClassWithSource(JNIEnv *env, const char *name, jobject loader,
|
||||||
const jbyte *buf, jsize len, jobject pd,
|
const jbyte *buf, jsize len, jobject pd,
|
||||||
const char *source);
|
const char *source);
|
||||||
|
|
||||||
|
/* Define a class with a source (MLVM) */
|
||||||
|
JNIEXPORT jclass JNICALL
|
||||||
|
JVM_DefineClassWithCP(JNIEnv *env, const char *name, jobject loader,
|
||||||
|
const jbyte *buf, jsize len, jobject pd,
|
||||||
|
const char *source,
|
||||||
|
// same args as JVM_DefineClassWithSource to this point
|
||||||
|
jobjectArray constants);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reflection support functions
|
* Reflection support functions
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -837,6 +837,163 @@ UNSAFE_ENTRY(jclass, Unsafe_DefineClass1(JNIEnv *env, jobject unsafe, jstring na
|
||||||
}
|
}
|
||||||
UNSAFE_END
|
UNSAFE_END
|
||||||
|
|
||||||
|
#define DAC_Args CLS"[B["OBJ
|
||||||
|
// define a class but do not make it known to the class loader or system dictionary
|
||||||
|
// - host_class: supplies context for linkage, access control, protection domain, and class loader
|
||||||
|
// - data: bytes of a class file, a raw memory address (length gives the number of bytes)
|
||||||
|
// - cp_patches: where non-null entries exist, they replace corresponding CP entries in data
|
||||||
|
|
||||||
|
// When you load an anonymous class U, it works as if you changed its name just before loading,
|
||||||
|
// to a name that you will never use again. Since the name is lost, no other class can directly
|
||||||
|
// link to any member of U. Just after U is loaded, the only way to use it is reflectively,
|
||||||
|
// through java.lang.Class methods like Class.newInstance.
|
||||||
|
|
||||||
|
// Access checks for linkage sites within U continue to follow the same rules as for named classes.
|
||||||
|
// The package of an anonymous class is given by the package qualifier on the name under which it was loaded.
|
||||||
|
// An anonymous class also has special privileges to access any member of its host class.
|
||||||
|
// This is the main reason why this loading operation is unsafe. The purpose of this is to
|
||||||
|
// allow language implementations to simulate "open classes"; a host class in effect gets
|
||||||
|
// new code when an anonymous class is loaded alongside it. A less convenient but more
|
||||||
|
// standard way to do this is with reflection, which can also be set to ignore access
|
||||||
|
// restrictions.
|
||||||
|
|
||||||
|
// Access into an anonymous class is possible only through reflection. Therefore, there
|
||||||
|
// are no special access rules for calling into an anonymous class. The relaxed access
|
||||||
|
// rule for the host class is applied in the opposite direction: A host class reflectively
|
||||||
|
// access one of its anonymous classes.
|
||||||
|
|
||||||
|
// If you load the same bytecodes twice, you get two different classes. You can reload
|
||||||
|
// the same bytecodes with or without varying CP patches.
|
||||||
|
|
||||||
|
// By using the CP patching array, you can have a new anonymous class U2 refer to an older one U1.
|
||||||
|
// The bytecodes for U2 should refer to U1 by a symbolic name (doesn't matter what the name is).
|
||||||
|
// The CONSTANT_Class entry for that name can be patched to refer directly to U1.
|
||||||
|
|
||||||
|
// This allows, for example, U2 to use U1 as a superclass or super-interface, or as
|
||||||
|
// an outer class (so that U2 is an anonymous inner class of anonymous U1).
|
||||||
|
// It is not possible for a named class, or an older anonymous class, to refer by
|
||||||
|
// name (via its CP) to a newer anonymous class.
|
||||||
|
|
||||||
|
// CP patching may also be used to modify (i.e., hack) the names of methods, classes,
|
||||||
|
// or type descriptors used in the loaded anonymous class.
|
||||||
|
|
||||||
|
// Finally, CP patching may be used to introduce "live" objects into the constant pool,
|
||||||
|
// instead of "dead" strings. A compiled statement like println((Object)"hello") can
|
||||||
|
// be changed to println(greeting), where greeting is an arbitrary object created before
|
||||||
|
// the anonymous class is loaded. This is useful in dynamic languages, in which
|
||||||
|
// various kinds of metaobjects must be introduced as constants into bytecode.
|
||||||
|
// Note the cast (Object), which tells the verifier to expect an arbitrary object,
|
||||||
|
// not just a literal string. For such ldc instructions, the verifier uses the
|
||||||
|
// type Object instead of String, if the loaded constant is not in fact a String.
|
||||||
|
|
||||||
|
static oop
|
||||||
|
Unsafe_DefineAnonymousClass_impl(JNIEnv *env,
|
||||||
|
jclass host_class, jbyteArray data, jobjectArray cp_patches_jh,
|
||||||
|
HeapWord* *temp_alloc,
|
||||||
|
TRAPS) {
|
||||||
|
|
||||||
|
if (UsePerfData) {
|
||||||
|
ClassLoader::unsafe_defineClassCallCounter()->inc();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data == NULL) {
|
||||||
|
THROW_0(vmSymbols::java_lang_NullPointerException());
|
||||||
|
}
|
||||||
|
|
||||||
|
jint length = typeArrayOop(JNIHandles::resolve_non_null(data))->length();
|
||||||
|
jint word_length = (length + sizeof(HeapWord)-1) / sizeof(HeapWord);
|
||||||
|
HeapWord* body = NEW_C_HEAP_ARRAY(HeapWord, word_length);
|
||||||
|
if (body == NULL) {
|
||||||
|
THROW_0(vmSymbols::java_lang_OutOfMemoryError());
|
||||||
|
}
|
||||||
|
|
||||||
|
// caller responsible to free it:
|
||||||
|
(*temp_alloc) = body;
|
||||||
|
|
||||||
|
{
|
||||||
|
jbyte* array_base = typeArrayOop(JNIHandles::resolve_non_null(data))->byte_at_addr(0);
|
||||||
|
Copy::conjoint_words((HeapWord*) array_base, body, word_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
u1* class_bytes = (u1*) body;
|
||||||
|
int class_bytes_length = (int) length;
|
||||||
|
if (class_bytes_length < 0) class_bytes_length = 0;
|
||||||
|
if (class_bytes == NULL
|
||||||
|
|| host_class == NULL
|
||||||
|
|| length != class_bytes_length)
|
||||||
|
THROW_0(vmSymbols::java_lang_IllegalArgumentException());
|
||||||
|
|
||||||
|
objArrayHandle cp_patches_h;
|
||||||
|
if (cp_patches_jh != NULL) {
|
||||||
|
oop p = JNIHandles::resolve_non_null(cp_patches_jh);
|
||||||
|
if (!p->is_objArray())
|
||||||
|
THROW_0(vmSymbols::java_lang_IllegalArgumentException());
|
||||||
|
cp_patches_h = objArrayHandle(THREAD, (objArrayOop)p);
|
||||||
|
}
|
||||||
|
|
||||||
|
KlassHandle host_klass(THREAD, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(host_class)));
|
||||||
|
const char* host_source = host_klass->external_name();
|
||||||
|
Handle host_loader(THREAD, host_klass->class_loader());
|
||||||
|
Handle host_domain(THREAD, host_klass->protection_domain());
|
||||||
|
|
||||||
|
GrowableArray<Handle>* cp_patches = NULL;
|
||||||
|
if (cp_patches_h.not_null()) {
|
||||||
|
int alen = cp_patches_h->length();
|
||||||
|
for (int i = alen-1; i >= 0; i--) {
|
||||||
|
oop p = cp_patches_h->obj_at(i);
|
||||||
|
if (p != NULL) {
|
||||||
|
Handle patch(THREAD, p);
|
||||||
|
if (cp_patches == NULL)
|
||||||
|
cp_patches = new GrowableArray<Handle>(i+1, i+1, Handle());
|
||||||
|
cp_patches->at_put(i, patch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ClassFileStream st(class_bytes, class_bytes_length, (char*) host_source);
|
||||||
|
|
||||||
|
instanceKlassHandle anon_klass;
|
||||||
|
{
|
||||||
|
symbolHandle no_class_name;
|
||||||
|
klassOop anonk = SystemDictionary::parse_stream(no_class_name,
|
||||||
|
host_loader, host_domain,
|
||||||
|
&st, host_klass, cp_patches,
|
||||||
|
CHECK_NULL);
|
||||||
|
if (anonk == NULL) return NULL;
|
||||||
|
anon_klass = instanceKlassHandle(THREAD, anonk);
|
||||||
|
}
|
||||||
|
|
||||||
|
// let caller initialize it as needed...
|
||||||
|
|
||||||
|
return anon_klass->java_mirror();
|
||||||
|
}
|
||||||
|
|
||||||
|
UNSAFE_ENTRY(jclass, Unsafe_DefineAnonymousClass(JNIEnv *env, jobject unsafe, jclass host_class, jbyteArray data, jobjectArray cp_patches_jh))
|
||||||
|
{
|
||||||
|
UnsafeWrapper("Unsafe_DefineAnonymousClass");
|
||||||
|
ResourceMark rm(THREAD);
|
||||||
|
|
||||||
|
HeapWord* temp_alloc = NULL;
|
||||||
|
|
||||||
|
jobject res_jh = NULL;
|
||||||
|
|
||||||
|
{ oop res_oop = Unsafe_DefineAnonymousClass_impl(env,
|
||||||
|
host_class, data, cp_patches_jh,
|
||||||
|
&temp_alloc, THREAD);
|
||||||
|
if (res_oop != NULL)
|
||||||
|
res_jh = JNIHandles::make_local(env, res_oop);
|
||||||
|
}
|
||||||
|
|
||||||
|
// try/finally clause:
|
||||||
|
if (temp_alloc != NULL) {
|
||||||
|
FREE_C_HEAP_ARRAY(HeapWord, temp_alloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (jclass) res_jh;
|
||||||
|
}
|
||||||
|
UNSAFE_END
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
UNSAFE_ENTRY(void, Unsafe_MonitorEnter(JNIEnv *env, jobject unsafe, jobject jobj))
|
UNSAFE_ENTRY(void, Unsafe_MonitorEnter(JNIEnv *env, jobject unsafe, jobject jobj))
|
||||||
UnsafeWrapper("Unsafe_MonitorEnter");
|
UnsafeWrapper("Unsafe_MonitorEnter");
|
||||||
|
@ -1292,6 +1449,9 @@ JNINativeMethod memcopy_methods_15[] = {
|
||||||
{CC"copyMemory", CC"("ADR ADR"J)V", FN_PTR(Unsafe_CopyMemory)}
|
{CC"copyMemory", CC"("ADR ADR"J)V", FN_PTR(Unsafe_CopyMemory)}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
JNINativeMethod anonk_methods[] = {
|
||||||
|
{CC"defineAnonymousClass", CC"("DAC_Args")"CLS, FN_PTR(Unsafe_DefineAnonymousClass)},
|
||||||
|
};
|
||||||
|
|
||||||
#undef CC
|
#undef CC
|
||||||
#undef FN_PTR
|
#undef FN_PTR
|
||||||
|
@ -1354,6 +1514,15 @@ JVM_ENTRY(void, JVM_RegisterUnsafeMethods(JNIEnv *env, jclass unsafecls))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (AnonymousClasses) {
|
||||||
|
env->RegisterNatives(unsafecls, anonk_methods, sizeof(anonk_methods)/sizeof(JNINativeMethod));
|
||||||
|
if (env->ExceptionOccurred()) {
|
||||||
|
if (PrintMiscellaneous && (Verbose || WizardMode)) {
|
||||||
|
tty->print_cr("Warning: SDK 1.7 Unsafe.defineClass (anonymous version) not found.");
|
||||||
|
}
|
||||||
|
env->ExceptionClear();
|
||||||
|
}
|
||||||
|
}
|
||||||
int status = env->RegisterNatives(unsafecls, methods, sizeof(methods)/sizeof(JNINativeMethod));
|
int status = env->RegisterNatives(unsafecls, methods, sizeof(methods)/sizeof(JNINativeMethod));
|
||||||
if (env->ExceptionOccurred()) {
|
if (env->ExceptionOccurred()) {
|
||||||
if (PrintMiscellaneous && (Verbose || WizardMode)) {
|
if (PrintMiscellaneous && (Verbose || WizardMode)) {
|
||||||
|
|
|
@ -493,7 +493,7 @@ class CommandLineFlags {
|
||||||
develop(bool, DeoptimizeALot, false, \
|
develop(bool, DeoptimizeALot, false, \
|
||||||
"deoptimize at every exit from the runtime system") \
|
"deoptimize at every exit from the runtime system") \
|
||||||
\
|
\
|
||||||
develop(ccstrlist, DeoptimizeOnlyAt, "", \
|
notproduct(ccstrlist, DeoptimizeOnlyAt, "", \
|
||||||
"a comma separated list of bcis to deoptimize at") \
|
"a comma separated list of bcis to deoptimize at") \
|
||||||
\
|
\
|
||||||
product(bool, DeoptimizeRandom, false, \
|
product(bool, DeoptimizeRandom, false, \
|
||||||
|
@ -2792,7 +2792,7 @@ class CommandLineFlags {
|
||||||
product(intx, TargetSurvivorRatio, 50, \
|
product(intx, TargetSurvivorRatio, 50, \
|
||||||
"Desired percentage of survivor space used after scavenge") \
|
"Desired percentage of survivor space used after scavenge") \
|
||||||
\
|
\
|
||||||
product(intx, MarkSweepDeadRatio, 5, \
|
product(uintx, MarkSweepDeadRatio, 5, \
|
||||||
"Percentage (0-100) of the old gen allowed as dead wood." \
|
"Percentage (0-100) of the old gen allowed as dead wood." \
|
||||||
"Serial mark sweep treats this as both the min and max value." \
|
"Serial mark sweep treats this as both the min and max value." \
|
||||||
"CMS uses this value only if it falls back to mark sweep." \
|
"CMS uses this value only if it falls back to mark sweep." \
|
||||||
|
@ -2801,7 +2801,7 @@ class CommandLineFlags {
|
||||||
"either completely full or completely empty. Par compact also" \
|
"either completely full or completely empty. Par compact also" \
|
||||||
"has a smaller default value; see arguments.cpp.") \
|
"has a smaller default value; see arguments.cpp.") \
|
||||||
\
|
\
|
||||||
product(intx, PermMarkSweepDeadRatio, 20, \
|
product(uintx, PermMarkSweepDeadRatio, 20, \
|
||||||
"Percentage (0-100) of the perm gen allowed as dead wood." \
|
"Percentage (0-100) of the perm gen allowed as dead wood." \
|
||||||
"See MarkSweepDeadRatio for collector-specific comments.") \
|
"See MarkSweepDeadRatio for collector-specific comments.") \
|
||||||
\
|
\
|
||||||
|
@ -3230,6 +3230,9 @@ class CommandLineFlags {
|
||||||
"Skip assert() and verify() which page-in unwanted shared " \
|
"Skip assert() and verify() which page-in unwanted shared " \
|
||||||
"objects. ") \
|
"objects. ") \
|
||||||
\
|
\
|
||||||
|
product(bool, AnonymousClasses, false, \
|
||||||
|
"support sun.misc.Unsafe.defineAnonymousClass") \
|
||||||
|
\
|
||||||
product(bool, TaggedStackInterpreter, false, \
|
product(bool, TaggedStackInterpreter, false, \
|
||||||
"Insert tags in interpreter execution stack for oopmap generaion")\
|
"Insert tags in interpreter execution stack for oopmap generaion")\
|
||||||
\
|
\
|
||||||
|
|
|
@ -25,6 +25,14 @@
|
||||||
# include "incls/_precompiled.incl"
|
# include "incls/_precompiled.incl"
|
||||||
# include "incls/_perfMemory.cpp.incl"
|
# include "incls/_perfMemory.cpp.incl"
|
||||||
|
|
||||||
|
// Prefix of performance data file.
|
||||||
|
const char PERFDATA_NAME[] = "hsperfdata";
|
||||||
|
|
||||||
|
// Add 1 for the '_' character between PERFDATA_NAME and pid. The '\0' terminating
|
||||||
|
// character will be included in the sizeof(PERFDATA_NAME) operation.
|
||||||
|
static const size_t PERFDATA_FILENAME_LEN = sizeof(PERFDATA_NAME) +
|
||||||
|
UINT_CHARS + 1;
|
||||||
|
|
||||||
char* PerfMemory::_start = NULL;
|
char* PerfMemory::_start = NULL;
|
||||||
char* PerfMemory::_end = NULL;
|
char* PerfMemory::_end = NULL;
|
||||||
char* PerfMemory::_top = NULL;
|
char* PerfMemory::_top = NULL;
|
||||||
|
|
|
@ -95,7 +95,7 @@ typedef struct {
|
||||||
} PerfDataEntry;
|
} PerfDataEntry;
|
||||||
|
|
||||||
// Prefix of performance data file.
|
// Prefix of performance data file.
|
||||||
static const char PERFDATA_NAME[] = "hsperfdata";
|
extern const char PERFDATA_NAME[];
|
||||||
|
|
||||||
// UINT_CHARS contains the number of characters holding a process id
|
// UINT_CHARS contains the number of characters holding a process id
|
||||||
// (i.e. pid). pid is defined as unsigned "int" so the maximum possible pid value
|
// (i.e. pid). pid is defined as unsigned "int" so the maximum possible pid value
|
||||||
|
@ -103,11 +103,6 @@ static const char PERFDATA_NAME[] = "hsperfdata";
|
||||||
// string.
|
// string.
|
||||||
static const size_t UINT_CHARS = 10;
|
static const size_t UINT_CHARS = 10;
|
||||||
|
|
||||||
// Add 1 for the '_' character between PERFDATA_NAME and pid. The '\0' terminating
|
|
||||||
// character will be included in the sizeof(PERFDATA_NAME) operation.
|
|
||||||
static const size_t PERFDATA_FILENAME_LEN = sizeof(PERFDATA_NAME) +
|
|
||||||
UINT_CHARS + 1;
|
|
||||||
|
|
||||||
/* the PerfMemory class manages creation, destruction,
|
/* the PerfMemory class manages creation, destruction,
|
||||||
* and allocation of the PerfData region.
|
* and allocation of the PerfData region.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -456,10 +456,32 @@ bool Reflection::verify_class_access(klassOop current_class, klassOop new_class,
|
||||||
return can_relax_access_check_for(current_class, new_class, classloader_only);
|
return can_relax_access_check_for(current_class, new_class, classloader_only);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool under_host_klass(instanceKlass* ik, klassOop host_klass) {
|
||||||
|
DEBUG_ONLY(int inf_loop_check = 1000 * 1000 * 1000);
|
||||||
|
for (;;) {
|
||||||
|
klassOop hc = (klassOop) ik->host_klass();
|
||||||
|
if (hc == NULL) return false;
|
||||||
|
if (hc == host_klass) return true;
|
||||||
|
ik = instanceKlass::cast(hc);
|
||||||
|
|
||||||
|
// There's no way to make a host class loop short of patching memory.
|
||||||
|
// Therefore there cannot be a loop here unles there's another bug.
|
||||||
|
// Still, let's check for it.
|
||||||
|
assert(--inf_loop_check > 0, "no host_klass loop");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool Reflection::can_relax_access_check_for(
|
bool Reflection::can_relax_access_check_for(
|
||||||
klassOop accessor, klassOop accessee, bool classloader_only) {
|
klassOop accessor, klassOop accessee, bool classloader_only) {
|
||||||
instanceKlass* accessor_ik = instanceKlass::cast(accessor);
|
instanceKlass* accessor_ik = instanceKlass::cast(accessor);
|
||||||
instanceKlass* accessee_ik = instanceKlass::cast(accessee);
|
instanceKlass* accessee_ik = instanceKlass::cast(accessee);
|
||||||
|
|
||||||
|
// If either is on the other's host_klass chain, access is OK,
|
||||||
|
// because one is inside the other.
|
||||||
|
if (under_host_klass(accessor_ik, accessee) ||
|
||||||
|
under_host_klass(accessee_ik, accessor))
|
||||||
|
return true;
|
||||||
|
|
||||||
if (RelaxAccessControlCheck ||
|
if (RelaxAccessControlCheck ||
|
||||||
(accessor_ik->major_version() < JAVA_1_5_VERSION &&
|
(accessor_ik->major_version() < JAVA_1_5_VERSION &&
|
||||||
accessee_ik->major_version() < JAVA_1_5_VERSION)) {
|
accessee_ik->major_version() < JAVA_1_5_VERSION)) {
|
||||||
|
|
|
@ -1422,6 +1422,7 @@ static void ensure_join(JavaThread* thread) {
|
||||||
thread->clear_pending_exception();
|
thread->clear_pending_exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// For any new cleanup additions, please check to see if they need to be applied to
|
// For any new cleanup additions, please check to see if they need to be applied to
|
||||||
// cleanup_failed_attach_current_thread as well.
|
// cleanup_failed_attach_current_thread as well.
|
||||||
void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
|
void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
|
||||||
|
@ -1592,12 +1593,27 @@ void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
|
||||||
JvmtiExport::cleanup_thread(this);
|
JvmtiExport::cleanup_thread(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef SERIALGC
|
||||||
|
// We must flush G1-related buffers before removing a thread from
|
||||||
|
// the list of active threads.
|
||||||
|
if (UseG1GC) {
|
||||||
|
flush_barrier_queues();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Remove from list of active threads list, and notify VM thread if we are the last non-daemon thread
|
// Remove from list of active threads list, and notify VM thread if we are the last non-daemon thread
|
||||||
Threads::remove(this);
|
Threads::remove(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JavaThread::cleanup_failed_attach_current_thread() {
|
#ifndef SERIALGC
|
||||||
|
// Flush G1-related queues.
|
||||||
|
void JavaThread::flush_barrier_queues() {
|
||||||
|
satb_mark_queue().flush();
|
||||||
|
dirty_card_queue().flush();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void JavaThread::cleanup_failed_attach_current_thread() {
|
||||||
if (get_thread_profiler() != NULL) {
|
if (get_thread_profiler() != NULL) {
|
||||||
get_thread_profiler()->disengage();
|
get_thread_profiler()->disengage();
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
|
@ -1620,11 +1636,19 @@ void JavaThread::cleanup_failed_attach_current_thread() {
|
||||||
tlab().make_parsable(true); // retire TLAB, if any
|
tlab().make_parsable(true); // retire TLAB, if any
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef SERIALGC
|
||||||
|
if (UseG1GC) {
|
||||||
|
flush_barrier_queues();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
Threads::remove(this);
|
Threads::remove(this);
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
JavaThread* JavaThread::active() {
|
JavaThread* JavaThread::active() {
|
||||||
Thread* thread = ThreadLocalStorage::thread();
|
Thread* thread = ThreadLocalStorage::thread();
|
||||||
assert(thread != NULL, "just checking");
|
assert(thread != NULL, "just checking");
|
||||||
|
|
|
@ -793,6 +793,8 @@ class JavaThread: public Thread {
|
||||||
DirtyCardQueue _dirty_card_queue; // Thread-local log for dirty cards.
|
DirtyCardQueue _dirty_card_queue; // Thread-local log for dirty cards.
|
||||||
// Set of all such queues.
|
// Set of all such queues.
|
||||||
static DirtyCardQueueSet _dirty_card_queue_set;
|
static DirtyCardQueueSet _dirty_card_queue_set;
|
||||||
|
|
||||||
|
void flush_barrier_queues();
|
||||||
#endif // !SERIALGC
|
#endif // !SERIALGC
|
||||||
|
|
||||||
friend class VMThread;
|
friend class VMThread;
|
||||||
|
|
|
@ -40,11 +40,18 @@ class ResourceArray: public ResourceObj {
|
||||||
_length = 0;
|
_length = 0;
|
||||||
_data = NULL;
|
_data = NULL;
|
||||||
DEBUG_ONLY(init_nesting();)
|
DEBUG_ONLY(init_nesting();)
|
||||||
|
// client may call initialize, at most once
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ResourceArray(size_t esize, int length) {
|
ResourceArray(size_t esize, int length) {
|
||||||
|
DEBUG_ONLY(_data = NULL);
|
||||||
|
initialize(esize, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
void initialize(size_t esize, int length) {
|
||||||
assert(length >= 0, "illegal length");
|
assert(length >= 0, "illegal length");
|
||||||
|
assert(_data == NULL, "must be new object");
|
||||||
_length = length;
|
_length = length;
|
||||||
_data = resource_allocate_bytes(esize * length);
|
_data = resource_allocate_bytes(esize * length);
|
||||||
DEBUG_ONLY(init_nesting();)
|
DEBUG_ONLY(init_nesting();)
|
||||||
|
@ -111,7 +118,10 @@ class CHeapArray: public CHeapObj {
|
||||||
/* creation */ \
|
/* creation */ \
|
||||||
array_name() : base_class() {} \
|
array_name() : base_class() {} \
|
||||||
array_name(const int length) : base_class(esize, length) {} \
|
array_name(const int length) : base_class(esize, length) {} \
|
||||||
array_name(const int length, const etype fx) : base_class(esize, length) { \
|
array_name(const int length, const etype fx) { initialize(length, fx); } \
|
||||||
|
void initialize(const int length) { base_class::initialize(esize, length); } \
|
||||||
|
void initialize(const int length, const etype fx) { \
|
||||||
|
initialize(length); \
|
||||||
for (int i = 0; i < length; i++) ((etype*)_data)[i] = fx; \
|
for (int i = 0; i < length; i++) ((etype*)_data)[i] = fx; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
|
@ -158,15 +168,28 @@ class CHeapArray: public CHeapObj {
|
||||||
public: \
|
public: \
|
||||||
/* creation */ \
|
/* creation */ \
|
||||||
stack_name() : array_name() { _size = 0; } \
|
stack_name() : array_name() { _size = 0; } \
|
||||||
stack_name(const int size) : array_name(size){ _length = 0; _size = size; } \
|
stack_name(const int size) { initialize(size); } \
|
||||||
stack_name(const int size, const etype fx) : array_name(size, fx) { _size = size; } \
|
stack_name(const int size, const etype fx) { initialize(size, fx); } \
|
||||||
|
void initialize(const int size, const etype fx) { \
|
||||||
|
_size = size; \
|
||||||
|
array_name::initialize(size, fx); \
|
||||||
|
/* _length == size, allocation and size are the same */ \
|
||||||
|
} \
|
||||||
|
void initialize(const int size) { \
|
||||||
|
_size = size; \
|
||||||
|
array_name::initialize(size); \
|
||||||
|
_length = 0; /* reset length to zero; _size records the allocation */ \
|
||||||
|
} \
|
||||||
\
|
\
|
||||||
/* standard operations */ \
|
/* standard operations */ \
|
||||||
int size() const { return _size; } \
|
int size() const { return _size; } \
|
||||||
\
|
\
|
||||||
void push(const etype x) { \
|
int push(const etype x) { \
|
||||||
if (length() >= size()) expand(esize, length(), _size); \
|
int len = length(); \
|
||||||
((etype*)_data)[_length++] = x; \
|
if (len >= size()) expand(esize, len, _size); \
|
||||||
|
((etype*)_data)[len] = x; \
|
||||||
|
_length = len+1; \
|
||||||
|
return len; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
etype pop() { \
|
etype pop() { \
|
||||||
|
@ -235,7 +258,7 @@ class CHeapArray: public CHeapObj {
|
||||||
int capacity() const { return size(); } \
|
int capacity() const { return size(); } \
|
||||||
void clear() { truncate(0); } \
|
void clear() { truncate(0); } \
|
||||||
void trunc_to(const int length) { truncate(length); } \
|
void trunc_to(const int length) { truncate(length); } \
|
||||||
void append(const etype x) { push(x); } \
|
int append(const etype x) { return push(x); } \
|
||||||
void appendAll(const stack_name* stack) { push_all(stack); } \
|
void appendAll(const stack_name* stack) { push_all(stack); } \
|
||||||
etype last() const { return top(); } \
|
etype last() const { return top(); } \
|
||||||
}; \
|
}; \
|
||||||
|
|
|
@ -71,6 +71,7 @@ class constantTag VALUE_OBJ_CLASS_SPEC {
|
||||||
bool is_string_index() const { return _tag == JVM_CONSTANT_StringIndex; }
|
bool is_string_index() const { return _tag == JVM_CONSTANT_StringIndex; }
|
||||||
|
|
||||||
bool is_klass_reference() const { return is_klass_index() || is_unresolved_klass(); }
|
bool is_klass_reference() const { return is_klass_index() || is_unresolved_klass(); }
|
||||||
|
bool is_klass_or_reference() const{ return is_klass() || is_klass_reference(); }
|
||||||
bool is_field_or_method() const { return is_field() || is_method() || is_interface_method(); }
|
bool is_field_or_method() const { return is_field() || is_method() || is_interface_method(); }
|
||||||
bool is_symbol() const { return is_utf8(); }
|
bool is_symbol() const { return is_utf8(); }
|
||||||
|
|
||||||
|
|
|
@ -595,7 +595,7 @@ static void find(intptr_t x, bool print_pc) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Universe::heap()->is_in_reserved(addr)) {
|
if (Universe::heap()->is_in(addr)) {
|
||||||
HeapWord* p = Universe::heap()->block_start(addr);
|
HeapWord* p = Universe::heap()->block_start(addr);
|
||||||
bool print = false;
|
bool print = false;
|
||||||
// If we couldn't find it it just may mean that heap wasn't parseable
|
// If we couldn't find it it just may mean that heap wasn't parseable
|
||||||
|
@ -621,7 +621,11 @@ static void find(intptr_t x, bool print_pc) {
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
} else if (Universe::heap()->is_in_reserved(addr)) {
|
||||||
|
tty->print_cr(INTPTR_FORMAT " is an unallocated location in the heap", addr);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (JNIHandles::is_global_handle((jobject) addr)) {
|
if (JNIHandles::is_global_handle((jobject) addr)) {
|
||||||
tty->print_cr(INTPTR_FORMAT " is a global jni handle", addr);
|
tty->print_cr(INTPTR_FORMAT " is a global jni handle", addr);
|
||||||
return;
|
return;
|
||||||
|
@ -636,9 +640,9 @@ static void find(intptr_t x, bool print_pc) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for(JavaThread *thread = Threads::first(); thread; thread = thread->next()) {
|
for(JavaThread *thread = Threads::first(); thread; thread = thread->next()) {
|
||||||
// Check for priviledge stack
|
// Check for privilege stack
|
||||||
if (thread->privileged_stack_top() != NULL && thread->privileged_stack_top()->contains(addr)) {
|
if (thread->privileged_stack_top() != NULL && thread->privileged_stack_top()->contains(addr)) {
|
||||||
tty->print_cr(INTPTR_FORMAT "is pointing into the priviledge stack for thread: " INTPTR_FORMAT, addr, thread);
|
tty->print_cr(INTPTR_FORMAT " is pointing into the privilege stack for thread: " INTPTR_FORMAT, addr, thread);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// If the addr is a java thread print information about that.
|
// If the addr is a java thread print information about that.
|
||||||
|
|
|
@ -111,6 +111,12 @@ class GenericGrowableArray : public ResourceObj {
|
||||||
}
|
}
|
||||||
|
|
||||||
void* raw_allocate(int elementSize);
|
void* raw_allocate(int elementSize);
|
||||||
|
|
||||||
|
// some uses pass the Thread explicitly for speed (4990299 tuning)
|
||||||
|
void* raw_allocate(Thread* thread, int elementSize) {
|
||||||
|
assert(on_stack(), "fast ResourceObj path only");
|
||||||
|
return (void*)resource_allocate_bytes(thread, elementSize * _max);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class E> class GrowableArray : public GenericGrowableArray {
|
template<class E> class GrowableArray : public GenericGrowableArray {
|
||||||
|
@ -121,6 +127,11 @@ template<class E> class GrowableArray : public GenericGrowableArray {
|
||||||
void raw_at_put_grow(int i, const E& p, const E& fill);
|
void raw_at_put_grow(int i, const E& p, const E& fill);
|
||||||
void clear_and_deallocate();
|
void clear_and_deallocate();
|
||||||
public:
|
public:
|
||||||
|
GrowableArray(Thread* thread, int initial_size) : GenericGrowableArray(initial_size, 0, false) {
|
||||||
|
_data = (E*)raw_allocate(thread, sizeof(E));
|
||||||
|
for (int i = 0; i < _max; i++) ::new ((void*)&_data[i]) E();
|
||||||
|
}
|
||||||
|
|
||||||
GrowableArray(int initial_size, bool C_heap = false) : GenericGrowableArray(initial_size, 0, C_heap) {
|
GrowableArray(int initial_size, bool C_heap = false) : GenericGrowableArray(initial_size, 0, C_heap) {
|
||||||
_data = (E*)raw_allocate(sizeof(E));
|
_data = (E*)raw_allocate(sizeof(E));
|
||||||
for (int i = 0; i < _max; i++) ::new ((void*)&_data[i]) E();
|
for (int i = 0; i < _max; i++) ::new ((void*)&_data[i]) E();
|
||||||
|
@ -159,10 +170,12 @@ template<class E> class GrowableArray : public GenericGrowableArray {
|
||||||
|
|
||||||
void print();
|
void print();
|
||||||
|
|
||||||
void append(const E& elem) {
|
int append(const E& elem) {
|
||||||
check_nesting();
|
check_nesting();
|
||||||
if (_len == _max) grow(_len);
|
if (_len == _max) grow(_len);
|
||||||
_data[_len++] = elem;
|
int idx = _len++;
|
||||||
|
_data[idx] = elem;
|
||||||
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void append_if_missing(const E& elem) {
|
void append_if_missing(const E& elem) {
|
||||||
|
|
|
@ -43,9 +43,11 @@ BasicHashtableEntry* BasicHashtable::new_entry(unsigned int hashValue) {
|
||||||
entry = _free_list;
|
entry = _free_list;
|
||||||
_free_list = _free_list->next();
|
_free_list = _free_list->next();
|
||||||
} else {
|
} else {
|
||||||
const int block_size = 500;
|
if (_first_free_entry + _entry_size >= _end_block) {
|
||||||
if (_first_free_entry == _end_block) {
|
int block_size = MIN2(512, MAX2((int)_table_size / 2, (int)_number_of_entries));
|
||||||
int len = _entry_size * block_size;
|
int len = _entry_size * block_size;
|
||||||
|
len = 1 << log2_intptr(len); // round down to power of 2
|
||||||
|
assert(len >= _entry_size, "");
|
||||||
_first_free_entry = NEW_C_HEAP_ARRAY(char, len);
|
_first_free_entry = NEW_C_HEAP_ARRAY(char, len);
|
||||||
_end_block = _first_free_entry + len;
|
_end_block = _first_free_entry + len;
|
||||||
}
|
}
|
||||||
|
@ -53,6 +55,7 @@ BasicHashtableEntry* BasicHashtable::new_entry(unsigned int hashValue) {
|
||||||
_first_free_entry += _entry_size;
|
_first_free_entry += _entry_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(_entry_size % HeapWordSize == 0, "");
|
||||||
entry->set_hash(hashValue);
|
entry->set_hash(hashValue);
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,3 +14,4 @@ c84ca638db42a8b6b227b4e3b63bca192c5ca634 jdk7-b36
|
||||||
af49591bc486d82aa04b832257de0d18adc9af52 jdk7-b37
|
af49591bc486d82aa04b832257de0d18adc9af52 jdk7-b37
|
||||||
e9f750f0a3a00413a7b77028b2ecdabb7129ae32 jdk7-b38
|
e9f750f0a3a00413a7b77028b2ecdabb7129ae32 jdk7-b38
|
||||||
831b80be6cea8e7d7da197ccdac5fd4c701a5033 jdk7-b39
|
831b80be6cea8e7d7da197ccdac5fd4c701a5033 jdk7-b39
|
||||||
|
54946f466e2c047c44c903f1bec400b685c2508e jdk7-b40
|
||||||
|
|
|
@ -14,3 +14,4 @@ cf4894b78ceb966326e93bf221db0c2d14d59218 jdk7-b35
|
||||||
14f50aee4989b75934d385c56a83da0c23d2f68b jdk7-b37
|
14f50aee4989b75934d385c56a83da0c23d2f68b jdk7-b37
|
||||||
cc5f810b5af8a3a83b0df5a29d9e24d7a0ff8086 jdk7-b38
|
cc5f810b5af8a3a83b0df5a29d9e24d7a0ff8086 jdk7-b38
|
||||||
4e51997582effa006dde5c6d8b8820b2045b9c7f jdk7-b39
|
4e51997582effa006dde5c6d8b8820b2045b9c7f jdk7-b39
|
||||||
|
2201dad60231a3c3e0346e3a0250d69ca3b71fd4 jdk7-b40
|
||||||
|
|
|
@ -69,9 +69,9 @@ public class ServiceName {
|
||||||
/**
|
/**
|
||||||
* The version of the JMX specification implemented by this product.
|
* The version of the JMX specification implemented by this product.
|
||||||
* <BR>
|
* <BR>
|
||||||
* The value is <CODE>1.4</CODE>.
|
* The value is <CODE>2.0</CODE>.
|
||||||
*/
|
*/
|
||||||
public static final String JMX_SPEC_VERSION = "1.4";
|
public static final String JMX_SPEC_VERSION = "2.0";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The vendor of the JMX specification implemented by this product.
|
* The vendor of the JMX specification implemented by this product.
|
||||||
|
|
|
@ -41,7 +41,7 @@ public class EventParams {
|
||||||
|
|
||||||
@SuppressWarnings("cast") // cast for jdk 1.5
|
@SuppressWarnings("cast") // cast for jdk 1.5
|
||||||
public static long getLeaseTimeout() {
|
public static long getLeaseTimeout() {
|
||||||
long timeout = EventClient.DEFAULT_LEASE_TIMEOUT;
|
long timeout = EventClient.DEFAULT_REQUESTED_LEASE_TIME;
|
||||||
try {
|
try {
|
||||||
final GetPropertyAction act =
|
final GetPropertyAction act =
|
||||||
new GetPropertyAction(DEFAULT_LEASE_TIMEOUT);
|
new GetPropertyAction(DEFAULT_LEASE_TIMEOUT);
|
||||||
|
|
|
@ -29,6 +29,7 @@ import com.sun.jmx.remote.util.ClassLogger;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.ScheduledFuture;
|
||||||
|
import java.util.concurrent.ThreadFactory;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -143,9 +144,10 @@ public class LeaseManager {
|
||||||
private final Runnable callback;
|
private final Runnable callback;
|
||||||
private ScheduledFuture<?> scheduled; // If null, the lease has expired.
|
private ScheduledFuture<?> scheduled; // If null, the lease has expired.
|
||||||
|
|
||||||
|
private static final ThreadFactory threadFactory =
|
||||||
|
new DaemonThreadFactory("JMX LeaseManager %d");
|
||||||
private final ScheduledExecutorService executor
|
private final ScheduledExecutorService executor
|
||||||
= Executors.newScheduledThreadPool(1,
|
= Executors.newScheduledThreadPool(1, threadFactory);
|
||||||
new DaemonThreadFactory("JMX LeaseManager %d"));
|
|
||||||
|
|
||||||
private static final ClassLogger logger =
|
private static final ClassLogger logger =
|
||||||
new ClassLogger("javax.management.event", "LeaseManager");
|
new ClassLogger("javax.management.event", "LeaseManager");
|
||||||
|
|
|
@ -55,9 +55,19 @@ import javax.management.namespace.JMXNamespaces;
|
||||||
import javax.management.namespace.MBeanServerSupport;
|
import javax.management.namespace.MBeanServerSupport;
|
||||||
import javax.management.remote.IdentityMBeanServerForwarder;
|
import javax.management.remote.IdentityMBeanServerForwarder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>An {@link MBeanServerForwarder} that simulates the existence of a
|
||||||
|
* given MBean. Requests for that MBean, call it X, are intercepted by the
|
||||||
|
* forwarder, and requests for any other MBean are forwarded to the next
|
||||||
|
* forwarder in the chain. Requests such as queryNames which can span both the
|
||||||
|
* X and other MBeans are handled by merging the results for X with the results
|
||||||
|
* from the next forwarder, unless the "visible" parameter is false, in which
|
||||||
|
* case X is invisible to such requests.</p>
|
||||||
|
*/
|
||||||
public class SingleMBeanForwarder extends IdentityMBeanServerForwarder {
|
public class SingleMBeanForwarder extends IdentityMBeanServerForwarder {
|
||||||
|
|
||||||
private final ObjectName mbeanName;
|
private final ObjectName mbeanName;
|
||||||
|
private final boolean visible;
|
||||||
private DynamicMBean mbean;
|
private DynamicMBean mbean;
|
||||||
|
|
||||||
private MBeanServer mbeanMBS = new MBeanServerSupport() {
|
private MBeanServer mbeanMBS = new MBeanServerSupport() {
|
||||||
|
@ -85,10 +95,20 @@ public class SingleMBeanForwarder extends IdentityMBeanServerForwarder {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This will only be called if mbeanName has an empty domain.
|
||||||
|
// In that case a getAttribute (e.g.) of that name will have the
|
||||||
|
// domain replaced by MBeanServerSupport with the default domain,
|
||||||
|
// so we must be sure that the default domain is empty too.
|
||||||
|
@Override
|
||||||
|
public String getDefaultDomain() {
|
||||||
|
return mbeanName.getDomain();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public SingleMBeanForwarder(ObjectName mbeanName, DynamicMBean mbean) {
|
public SingleMBeanForwarder(
|
||||||
|
ObjectName mbeanName, DynamicMBean mbean, boolean visible) {
|
||||||
this.mbeanName = mbeanName;
|
this.mbeanName = mbeanName;
|
||||||
|
this.visible = visible;
|
||||||
setSingleMBean(mbean);
|
setSingleMBean(mbean);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,8 +233,10 @@ public class SingleMBeanForwarder extends IdentityMBeanServerForwarder {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getDomains() {
|
public String[] getDomains() {
|
||||||
TreeSet<String> domainSet =
|
String[] domains = super.getDomains();
|
||||||
new TreeSet<String>(Arrays.asList(super.getDomains()));
|
if (!visible)
|
||||||
|
return domains;
|
||||||
|
TreeSet<String> domainSet = new TreeSet<String>(Arrays.asList(domains));
|
||||||
domainSet.add(mbeanName.getDomain());
|
domainSet.add(mbeanName.getDomain());
|
||||||
return domainSet.toArray(new String[domainSet.size()]);
|
return domainSet.toArray(new String[domainSet.size()]);
|
||||||
}
|
}
|
||||||
|
@ -222,7 +244,7 @@ public class SingleMBeanForwarder extends IdentityMBeanServerForwarder {
|
||||||
@Override
|
@Override
|
||||||
public Integer getMBeanCount() {
|
public Integer getMBeanCount() {
|
||||||
Integer count = super.getMBeanCount();
|
Integer count = super.getMBeanCount();
|
||||||
if (!super.isRegistered(mbeanName))
|
if (visible && !super.isRegistered(mbeanName))
|
||||||
count++;
|
count++;
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
@ -284,7 +306,7 @@ public class SingleMBeanForwarder extends IdentityMBeanServerForwarder {
|
||||||
*/
|
*/
|
||||||
private boolean applies(ObjectName pattern) {
|
private boolean applies(ObjectName pattern) {
|
||||||
// we know pattern is not null.
|
// we know pattern is not null.
|
||||||
if (!pattern.apply(mbeanName))
|
if (!visible || !pattern.apply(mbeanName))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
final String dompat = pattern.getDomain();
|
final String dompat = pattern.getDomain();
|
||||||
|
@ -306,22 +328,26 @@ public class SingleMBeanForwarder extends IdentityMBeanServerForwarder {
|
||||||
@Override
|
@Override
|
||||||
public Set<ObjectInstance> queryMBeans(ObjectName name, QueryExp query) {
|
public Set<ObjectInstance> queryMBeans(ObjectName name, QueryExp query) {
|
||||||
Set<ObjectInstance> names = super.queryMBeans(name, query);
|
Set<ObjectInstance> names = super.queryMBeans(name, query);
|
||||||
|
if (visible) {
|
||||||
if (name == null || applies(name) ) {
|
if (name == null || applies(name) ) {
|
||||||
// Don't assume mbs.queryNames returns a writable set.
|
// Don't assume mbs.queryNames returns a writable set.
|
||||||
names = Util.cloneSet(names);
|
names = Util.cloneSet(names);
|
||||||
names.addAll(mbeanMBS.queryMBeans(name, query));
|
names.addAll(mbeanMBS.queryMBeans(name, query));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<ObjectName> queryNames(ObjectName name, QueryExp query) {
|
public Set<ObjectName> queryNames(ObjectName name, QueryExp query) {
|
||||||
Set<ObjectName> names = super.queryNames(name, query);
|
Set<ObjectName> names = super.queryNames(name, query);
|
||||||
|
if (visible) {
|
||||||
if (name == null || applies(name)) {
|
if (name == null || applies(name)) {
|
||||||
// Don't assume mbs.queryNames returns a writable set.
|
// Don't assume mbs.queryNames returns a writable set.
|
||||||
names = Util.cloneSet(names);
|
names = Util.cloneSet(names);
|
||||||
names.addAll(mbeanMBS.queryNames(name, query));
|
names.addAll(mbeanMBS.queryNames(name, query));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -122,7 +122,7 @@ public final class JmxMBeanServer
|
||||||
* {@link javax.management.MBeanServerFactory#newMBeanServer(java.lang.String)}
|
* {@link javax.management.MBeanServerFactory#newMBeanServer(java.lang.String)}
|
||||||
* instead.
|
* instead.
|
||||||
* <p>
|
* <p>
|
||||||
* By default, {@link MBeanServerInterceptor} are disabled. Use
|
* By default, interceptors are disabled. Use
|
||||||
* {@link #JmxMBeanServer(java.lang.String,javax.management.MBeanServer,javax.management.MBeanServerDelegate,boolean)} to enable them.
|
* {@link #JmxMBeanServer(java.lang.String,javax.management.MBeanServer,javax.management.MBeanServerDelegate,boolean)} to enable them.
|
||||||
* </ul>
|
* </ul>
|
||||||
* @param domain The default domain name used by this MBeanServer.
|
* @param domain The default domain name used by this MBeanServer.
|
||||||
|
@ -239,7 +239,7 @@ public final class JmxMBeanServer
|
||||||
this.mBeanServerDelegateObject = delegate;
|
this.mBeanServerDelegateObject = delegate;
|
||||||
this.outerShell = outer;
|
this.outerShell = outer;
|
||||||
|
|
||||||
final Repository repository = new Repository(domain,fairLock);
|
final Repository repository = new Repository(domain);
|
||||||
this.mbsInterceptor =
|
this.mbsInterceptor =
|
||||||
new NamespaceDispatchInterceptor(outer, delegate, instantiator,
|
new NamespaceDispatchInterceptor(outer, delegate, instantiator,
|
||||||
repository);
|
repository);
|
||||||
|
|
|
@ -1,354 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Sun designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Sun in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
|
||||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
|
||||||
* have any questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.sun.jmx.namespace;
|
|
||||||
|
|
||||||
import com.sun.jmx.defaults.JmxProperties;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.WeakHashMap;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
import javax.management.ListenerNotFoundException;
|
|
||||||
import javax.management.MBeanServerConnection;
|
|
||||||
import javax.management.NotificationFilter;
|
|
||||||
import javax.management.NotificationListener;
|
|
||||||
import javax.management.event.EventClient;
|
|
||||||
import javax.management.event.EventClientDelegateMBean;
|
|
||||||
import javax.management.namespace.JMXNamespace;
|
|
||||||
import javax.management.namespace.JMXNamespaces;
|
|
||||||
import javax.management.remote.JMXAddressable;
|
|
||||||
import javax.management.remote.JMXConnector;
|
|
||||||
import javax.management.remote.JMXServiceURL;
|
|
||||||
import javax.security.auth.Subject;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A collection of methods that provide JMXConnector wrappers for
|
|
||||||
* JMXRemoteNamepaces underlying connectors.
|
|
||||||
* <p><b>
|
|
||||||
* This API is a Sun internal API and is subject to changes without notice.
|
|
||||||
* </b></p>
|
|
||||||
* @since 1.7
|
|
||||||
*/
|
|
||||||
public final class JMXNamespaceUtils {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A logger for this class.
|
|
||||||
**/
|
|
||||||
private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER;
|
|
||||||
|
|
||||||
|
|
||||||
private static <K,V> Map<K,V> newWeakHashMap() {
|
|
||||||
return new WeakHashMap<K,V>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** There are no instances of this class */
|
|
||||||
private JMXNamespaceUtils() {
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns un unmodifiable view of a map.
|
|
||||||
public static <K,V> Map<K,V> unmodifiableMap(Map<K,V> aMap) {
|
|
||||||
if (aMap == null || aMap.isEmpty())
|
|
||||||
return Collections.emptyMap();
|
|
||||||
return Collections.unmodifiableMap(aMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A base class that helps writing JMXConnectors that return
|
|
||||||
* MBeanServerConnection wrappers.
|
|
||||||
* This base class wraps an inner JMXConnector (the source), and preserve
|
|
||||||
* its caching policy. If a connection is cached in the source, its wrapper
|
|
||||||
* will be cached in this connector too.
|
|
||||||
* Author's note: rewriting this with java.lang.reflect.Proxy could be
|
|
||||||
* envisaged. It would avoid the combinatory sub-classing introduced by
|
|
||||||
* JMXAddressable.
|
|
||||||
* <p>
|
|
||||||
* Note: all the standard JMXConnector implementations are serializable.
|
|
||||||
* This implementation here is not. Should it be?
|
|
||||||
* I believe it must not be serializable unless it becomes
|
|
||||||
* part of a public API (either standard or officially exposed
|
|
||||||
* and supported in a documented com.sun package)
|
|
||||||
**/
|
|
||||||
static class JMXCachingConnector
|
|
||||||
implements JMXConnector {
|
|
||||||
|
|
||||||
// private static final long serialVersionUID = -2279076110599707875L;
|
|
||||||
|
|
||||||
final JMXConnector source;
|
|
||||||
|
|
||||||
// if this object is made serializable, then the variable below
|
|
||||||
// needs to become volatile transient and be lazyly-created...
|
|
||||||
private final
|
|
||||||
Map<MBeanServerConnection,MBeanServerConnection> connectionMap;
|
|
||||||
|
|
||||||
|
|
||||||
public JMXCachingConnector(JMXConnector source) {
|
|
||||||
this.source = checkNonNull(source, "source");
|
|
||||||
connectionMap = newWeakHashMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
private MBeanServerConnection
|
|
||||||
getCached(MBeanServerConnection inner) {
|
|
||||||
return connectionMap.get(inner);
|
|
||||||
}
|
|
||||||
|
|
||||||
private MBeanServerConnection putCached(final MBeanServerConnection inner,
|
|
||||||
final MBeanServerConnection wrapper) {
|
|
||||||
if (inner == wrapper) return wrapper;
|
|
||||||
synchronized (this) {
|
|
||||||
final MBeanServerConnection concurrent =
|
|
||||||
connectionMap.get(inner);
|
|
||||||
if (concurrent != null) return concurrent;
|
|
||||||
connectionMap.put(inner,wrapper);
|
|
||||||
}
|
|
||||||
return wrapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addConnectionNotificationListener(NotificationListener
|
|
||||||
listener, NotificationFilter filter, Object handback) {
|
|
||||||
source.addConnectionNotificationListener(listener,filter,handback);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void close() throws IOException {
|
|
||||||
source.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void connect() throws IOException {
|
|
||||||
source.connect();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void connect(Map<String,?> env) throws IOException {
|
|
||||||
source.connect(env);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getConnectionId() throws IOException {
|
|
||||||
return source.getConnectionId();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Preserve caching policy of the underlying connector.
|
|
||||||
**/
|
|
||||||
public MBeanServerConnection
|
|
||||||
getMBeanServerConnection() throws IOException {
|
|
||||||
final MBeanServerConnection inner =
|
|
||||||
source.getMBeanServerConnection();
|
|
||||||
final MBeanServerConnection cached = getCached(inner);
|
|
||||||
if (cached != null) return cached;
|
|
||||||
final MBeanServerConnection wrapper = wrap(inner);
|
|
||||||
return putCached(inner,wrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
public MBeanServerConnection
|
|
||||||
getMBeanServerConnection(Subject delegationSubject)
|
|
||||||
throws IOException {
|
|
||||||
final MBeanServerConnection wrapped =
|
|
||||||
source.getMBeanServerConnection(delegationSubject);
|
|
||||||
synchronized (this) {
|
|
||||||
final MBeanServerConnection cached = getCached(wrapped);
|
|
||||||
if (cached != null) return cached;
|
|
||||||
final MBeanServerConnection wrapper =
|
|
||||||
wrapWithSubject(wrapped,delegationSubject);
|
|
||||||
return putCached(wrapped,wrapper);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeConnectionNotificationListener(
|
|
||||||
NotificationListener listener)
|
|
||||||
throws ListenerNotFoundException {
|
|
||||||
source.removeConnectionNotificationListener(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeConnectionNotificationListener(
|
|
||||||
NotificationListener l, NotificationFilter f,
|
|
||||||
Object handback) throws ListenerNotFoundException {
|
|
||||||
source.removeConnectionNotificationListener(l,f,handback);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is the method that subclass will redefine. This method
|
|
||||||
* is called by {@code this.getMBeanServerConnection()}.
|
|
||||||
* {@code inner} is the connection returned by
|
|
||||||
* {@code source.getMBeanServerConnection()}.
|
|
||||||
**/
|
|
||||||
protected MBeanServerConnection wrap(MBeanServerConnection inner)
|
|
||||||
throws IOException {
|
|
||||||
return inner;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Subclass may also want to redefine this method.
|
|
||||||
* By default it calls wrap(inner). This method
|
|
||||||
* is called by {@code this.getMBeanServerConnection(Subject)}.
|
|
||||||
* {@code inner} is the connection returned by
|
|
||||||
* {@code source.getMBeanServerConnection(Subject)}.
|
|
||||||
**/
|
|
||||||
protected MBeanServerConnection wrapWithSubject(
|
|
||||||
MBeanServerConnection inner, Subject delegationSubject)
|
|
||||||
throws IOException {
|
|
||||||
return wrap(inner);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
if (source instanceof JMXAddressable) {
|
|
||||||
final JMXServiceURL address =
|
|
||||||
((JMXAddressable)source).getAddress();
|
|
||||||
if (address != null)
|
|
||||||
return address.toString();
|
|
||||||
}
|
|
||||||
return source.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name space connector can do 'cd'
|
|
||||||
**/
|
|
||||||
static class JMXNamespaceConnector extends JMXCachingConnector {
|
|
||||||
|
|
||||||
// private static final long serialVersionUID = -4813611540843020867L;
|
|
||||||
|
|
||||||
private final String toDir;
|
|
||||||
private final boolean closeable;
|
|
||||||
|
|
||||||
public JMXNamespaceConnector(JMXConnector source, String toDir,
|
|
||||||
boolean closeable) {
|
|
||||||
super(source);
|
|
||||||
this.toDir = toDir;
|
|
||||||
this.closeable = closeable;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() throws IOException {
|
|
||||||
if (!closeable)
|
|
||||||
throw new UnsupportedOperationException("close");
|
|
||||||
else super.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected MBeanServerConnection wrap(MBeanServerConnection wrapped)
|
|
||||||
throws IOException {
|
|
||||||
if (LOG.isLoggable(Level.FINER))
|
|
||||||
LOG.finer("Creating name space proxy connection for source: "+
|
|
||||||
"namespace="+toDir);
|
|
||||||
return JMXNamespaces.narrowToNamespace(wrapped,toDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "JMXNamespaces.narrowToNamespace("+
|
|
||||||
super.toString()+
|
|
||||||
", \""+toDir+"\")";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static class JMXEventConnector extends JMXCachingConnector {
|
|
||||||
|
|
||||||
// private static final long serialVersionUID = 4742659236340242785L;
|
|
||||||
|
|
||||||
JMXEventConnector(JMXConnector wrapped) {
|
|
||||||
super(wrapped);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected MBeanServerConnection wrap(MBeanServerConnection inner)
|
|
||||||
throws IOException {
|
|
||||||
return EventClient.getEventClientConnection(inner);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "EventClient.withEventClient("+super.toString()+")";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static class JMXAddressableEventConnector extends JMXEventConnector
|
|
||||||
implements JMXAddressable {
|
|
||||||
|
|
||||||
// private static final long serialVersionUID = -9128520234812124712L;
|
|
||||||
|
|
||||||
JMXAddressableEventConnector(JMXConnector wrapped) {
|
|
||||||
super(wrapped);
|
|
||||||
}
|
|
||||||
|
|
||||||
public JMXServiceURL getAddress() {
|
|
||||||
return ((JMXAddressable)source).getAddress();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a connector whose MBeamServerConnection will point to the
|
|
||||||
* given sub name space inside the source connector.
|
|
||||||
* @see JMXNamespace
|
|
||||||
**/
|
|
||||||
public static JMXConnector cd(final JMXConnector source,
|
|
||||||
final String toNamespace,
|
|
||||||
final boolean closeable)
|
|
||||||
throws IOException {
|
|
||||||
|
|
||||||
checkNonNull(source, "JMXConnector");
|
|
||||||
|
|
||||||
if (toNamespace == null || toNamespace.equals(""))
|
|
||||||
return source;
|
|
||||||
|
|
||||||
return new JMXNamespaceConnector(source,toNamespace,closeable);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a JMX Connector that will use an {@link EventClient}
|
|
||||||
* to subscribe for notifications. If the server doesn't have
|
|
||||||
* an {@link EventClientDelegateMBean}, then the connector will
|
|
||||||
* use the legacy notification mechanism instead.
|
|
||||||
*
|
|
||||||
* @param source The underlying JMX Connector wrapped by the returned
|
|
||||||
* connector.
|
|
||||||
* @return A JMX Connector that will uses an {@link EventClient}, if
|
|
||||||
* available.
|
|
||||||
* @see EventClient#getEventClientConnection(MBeanServerConnection)
|
|
||||||
*/
|
|
||||||
public static JMXConnector withEventClient(final JMXConnector source) {
|
|
||||||
checkNonNull(source, "JMXConnector");
|
|
||||||
if (source instanceof JMXAddressable)
|
|
||||||
return new JMXAddressableEventConnector(source);
|
|
||||||
else
|
|
||||||
return new JMXEventConnector(source);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T checkNonNull(T parameter, String name) {
|
|
||||||
if (parameter == null)
|
|
||||||
throw new IllegalArgumentException(name+" must not be null");
|
|
||||||
return parameter;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -49,11 +49,6 @@ public class ObjectNameRouter {
|
||||||
final int tlen;
|
final int tlen;
|
||||||
final boolean identity;
|
final boolean identity;
|
||||||
|
|
||||||
|
|
||||||
public ObjectNameRouter(String targetDirName) {
|
|
||||||
this(targetDirName,null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Creates a new instance of ObjectNameRouter */
|
/** Creates a new instance of ObjectNameRouter */
|
||||||
public ObjectNameRouter(final String remove, final String add) {
|
public ObjectNameRouter(final String remove, final String add) {
|
||||||
this.targetPrefix = (remove==null?"":remove);
|
this.targetPrefix = (remove==null?"":remove);
|
||||||
|
@ -186,6 +181,4 @@ public class ObjectNameRouter {
|
||||||
b.append(NAMESPACE_SEPARATOR);
|
b.append(NAMESPACE_SEPARATOR);
|
||||||
return b.toString();
|
return b.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,6 @@ import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.management.MBeanServerConnection;
|
import javax.management.MBeanServerConnection;
|
||||||
import javax.management.namespace.JMXNamespaces;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -57,22 +56,14 @@ public class RoutingConnectionProxy
|
||||||
private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER;
|
private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER;
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new instance of RoutingConnectionProxy
|
|
||||||
*/
|
|
||||||
public RoutingConnectionProxy(MBeanServerConnection source,
|
|
||||||
String sourceDir) {
|
|
||||||
this(source,sourceDir,"",false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance of RoutingConnectionProxy
|
* Creates a new instance of RoutingConnectionProxy
|
||||||
*/
|
*/
|
||||||
public RoutingConnectionProxy(MBeanServerConnection source,
|
public RoutingConnectionProxy(MBeanServerConnection source,
|
||||||
String sourceDir,
|
String sourceDir,
|
||||||
String targetDir,
|
String targetDir,
|
||||||
boolean forwardsContext) {
|
boolean probe) {
|
||||||
super(source,sourceDir,targetDir,forwardsContext);
|
super(source, sourceDir, targetDir, probe);
|
||||||
|
|
||||||
if (LOG.isLoggable(Level.FINER))
|
if (LOG.isLoggable(Level.FINER))
|
||||||
LOG.finer("RoutingConnectionProxy for " + getSourceNamespace() +
|
LOG.finer("RoutingConnectionProxy for " + getSourceNamespace() +
|
||||||
|
@ -85,15 +76,13 @@ public class RoutingConnectionProxy
|
||||||
final String sourceNs = getSourceNamespace();
|
final String sourceNs = getSourceNamespace();
|
||||||
String wrapped = String.valueOf(source());
|
String wrapped = String.valueOf(source());
|
||||||
if ("".equals(targetNs)) {
|
if ("".equals(targetNs)) {
|
||||||
if (forwardsContext)
|
|
||||||
wrapped = "ClientContext.withDynamicContext("+wrapped+")";
|
|
||||||
return "JMXNamespaces.narrowToNamespace("+
|
return "JMXNamespaces.narrowToNamespace("+
|
||||||
wrapped+", \""+
|
wrapped+", \""+
|
||||||
sourceNs+"\")";
|
sourceNs+"\")";
|
||||||
}
|
}
|
||||||
return this.getClass().getSimpleName()+"("+wrapped+", \""+
|
return this.getClass().getSimpleName()+"("+wrapped+", \""+
|
||||||
sourceNs+"\", \""+
|
sourceNs+"\", \""+
|
||||||
targetNs+"\", "+forwardsContext+")";
|
targetNs+"\")";
|
||||||
}
|
}
|
||||||
|
|
||||||
static final RoutingProxyFactory
|
static final RoutingProxyFactory
|
||||||
|
@ -102,22 +91,16 @@ public class RoutingConnectionProxy
|
||||||
<MBeanServerConnection,RoutingConnectionProxy>() {
|
<MBeanServerConnection,RoutingConnectionProxy>() {
|
||||||
|
|
||||||
public RoutingConnectionProxy newInstance(MBeanServerConnection source,
|
public RoutingConnectionProxy newInstance(MBeanServerConnection source,
|
||||||
String sourcePath, String targetPath,
|
String sourcePath, String targetPath, boolean probe) {
|
||||||
boolean forwardsContext) {
|
|
||||||
return new RoutingConnectionProxy(source,sourcePath,
|
return new RoutingConnectionProxy(source,sourcePath,
|
||||||
targetPath,forwardsContext);
|
targetPath, probe);
|
||||||
}
|
|
||||||
|
|
||||||
public RoutingConnectionProxy newInstance(
|
|
||||||
MBeanServerConnection source, String sourcePath) {
|
|
||||||
return new RoutingConnectionProxy(source,sourcePath);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static MBeanServerConnection cd(MBeanServerConnection source,
|
public static MBeanServerConnection cd(
|
||||||
String sourcePath) {
|
MBeanServerConnection source, String sourcePath, boolean probe) {
|
||||||
return RoutingProxy.cd(RoutingConnectionProxy.class, FACTORY,
|
return RoutingProxy.cd(RoutingConnectionProxy.class, FACTORY,
|
||||||
source, sourcePath);
|
source, sourcePath, probe);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ import java.io.IOException;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import javax.management.InstanceNotFoundException;
|
||||||
import javax.management.MBeanException;
|
import javax.management.MBeanException;
|
||||||
import javax.management.MBeanRegistrationException;
|
import javax.management.MBeanRegistrationException;
|
||||||
|
|
||||||
|
@ -90,17 +91,9 @@ import javax.management.namespace.JMXNamespaces;
|
||||||
// targetNs=<encoded-context> // context must be removed from object name
|
// targetNs=<encoded-context> // context must be removed from object name
|
||||||
// sourceNs="" // nothing to add...
|
// sourceNs="" // nothing to add...
|
||||||
//
|
//
|
||||||
// RoutingProxies can also be used on the client side to implement
|
|
||||||
// "withClientContext" operations. In that case, the boolean parameter
|
|
||||||
// 'forwards context' is set to true, targetNs is "", and sourceNS may
|
|
||||||
// also be "". When forwardsContext is true, the RoutingProxy dynamically
|
|
||||||
// creates an ObjectNameRouter for each operation - in order to dynamically add
|
|
||||||
// the context attached to the thread to the routing ObjectName. This is
|
|
||||||
// performed in the getObjectNameRouter() method.
|
|
||||||
//
|
|
||||||
// Finally, in order to avoid too many layers of wrapping,
|
// Finally, in order to avoid too many layers of wrapping,
|
||||||
// RoutingConnectionProxy and RoutingServerProxy can be created through a
|
// RoutingConnectionProxy and RoutingServerProxy can be created through a
|
||||||
// factory method that can concatenate namespace pathes in order to
|
// factory method that can concatenate namespace paths in order to
|
||||||
// return a single RoutingProxy - rather than wrapping a RoutingProxy inside
|
// return a single RoutingProxy - rather than wrapping a RoutingProxy inside
|
||||||
// another RoutingProxy. See RoutingConnectionProxy.cd and
|
// another RoutingProxy. See RoutingConnectionProxy.cd and
|
||||||
// RoutingServerProxy.cd
|
// RoutingServerProxy.cd
|
||||||
|
@ -146,16 +139,18 @@ public abstract class RoutingProxy<T extends MBeanServerConnection>
|
||||||
private final T source;
|
private final T source;
|
||||||
|
|
||||||
// The name space we're narrowing to (usually some name space in
|
// The name space we're narrowing to (usually some name space in
|
||||||
// the source MBeanServerConnection
|
// the source MBeanServerConnection), e.g. "a" for the namespace
|
||||||
|
// "a//". This is empty in the case of ClientContext described above.
|
||||||
private final String sourceNs;
|
private final String sourceNs;
|
||||||
|
|
||||||
// The name space we pretend to be mounted in (usually "")
|
// The name space we pretend to be mounted in. This is empty except
|
||||||
|
// in the case of ClientContext described above (where it will be
|
||||||
|
// something like "jmx.context//foo=bar".
|
||||||
private final String targetNs;
|
private final String targetNs;
|
||||||
|
|
||||||
// The name of the JMXNamespace that handles the source name space
|
// The name of the JMXNamespace that handles the source name space
|
||||||
private final ObjectName handlerName;
|
private final ObjectName handlerName;
|
||||||
private final ObjectNameRouter router;
|
private final ObjectNameRouter router;
|
||||||
final boolean forwardsContext;
|
|
||||||
private volatile String defaultDomain = null;
|
private volatile String defaultDomain = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -164,7 +159,7 @@ public abstract class RoutingProxy<T extends MBeanServerConnection>
|
||||||
protected RoutingProxy(T source,
|
protected RoutingProxy(T source,
|
||||||
String sourceNs,
|
String sourceNs,
|
||||||
String targetNs,
|
String targetNs,
|
||||||
boolean forwardsContext) {
|
boolean probe) {
|
||||||
if (source == null) throw new IllegalArgumentException("null");
|
if (source == null) throw new IllegalArgumentException("null");
|
||||||
this.sourceNs = JMXNamespaces.normalizeNamespaceName(sourceNs);
|
this.sourceNs = JMXNamespaces.normalizeNamespaceName(sourceNs);
|
||||||
|
|
||||||
|
@ -177,21 +172,24 @@ public abstract class RoutingProxy<T extends MBeanServerConnection>
|
||||||
// System.err.println("sourceNs: "+sourceNs);
|
// System.err.println("sourceNs: "+sourceNs);
|
||||||
this.handlerName =
|
this.handlerName =
|
||||||
JMXNamespaces.getNamespaceObjectName(this.sourceNs);
|
JMXNamespaces.getNamespaceObjectName(this.sourceNs);
|
||||||
|
if (probe) {
|
||||||
try {
|
try {
|
||||||
// System.err.println("handlerName: "+handlerName);
|
if (!source.isRegistered(handlerName)) {
|
||||||
if (!source.isRegistered(handlerName))
|
InstanceNotFoundException infe =
|
||||||
|
new InstanceNotFoundException(handlerName);
|
||||||
throw new IllegalArgumentException(sourceNs +
|
throw new IllegalArgumentException(sourceNs +
|
||||||
": no such name space");
|
": no such name space", infe);
|
||||||
|
}
|
||||||
} catch (IOException x) {
|
} catch (IOException x) {
|
||||||
throw new IllegalArgumentException("source stale: "+x,x);
|
throw new IllegalArgumentException("source stale: "+x,x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
this.source = source;
|
this.source = source;
|
||||||
this.targetNs = (targetNs==null?"":
|
this.targetNs = (targetNs==null?"":
|
||||||
JMXNamespaces.normalizeNamespaceName(targetNs));
|
JMXNamespaces.normalizeNamespaceName(targetNs));
|
||||||
this.router =
|
this.router =
|
||||||
new ObjectNameRouter(this.targetNs,this.sourceNs);
|
new ObjectNameRouter(this.targetNs,this.sourceNs);
|
||||||
this.forwardsContext = forwardsContext;
|
|
||||||
|
|
||||||
if (LOG.isLoggable(Level.FINER))
|
if (LOG.isLoggable(Level.FINER))
|
||||||
LOG.finer("RoutingProxy for " + this.sourceNs + " created");
|
LOG.finer("RoutingProxy for " + this.sourceNs + " created");
|
||||||
|
@ -200,14 +198,6 @@ public abstract class RoutingProxy<T extends MBeanServerConnection>
|
||||||
@Override
|
@Override
|
||||||
public T source() { return source; }
|
public T source() { return source; }
|
||||||
|
|
||||||
ObjectNameRouter getObjectNameRouter() {
|
|
||||||
// TODO: uncomment this when contexts are added
|
|
||||||
// if (forwardsContext)
|
|
||||||
// return ObjectNameRouter.wrapWithContext(router);
|
|
||||||
// else
|
|
||||||
return router;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObjectName toSource(ObjectName targetName)
|
public ObjectName toSource(ObjectName targetName)
|
||||||
throws MalformedObjectNameException {
|
throws MalformedObjectNameException {
|
||||||
|
@ -222,8 +212,7 @@ public abstract class RoutingProxy<T extends MBeanServerConnection>
|
||||||
if (defaultDomain != null)
|
if (defaultDomain != null)
|
||||||
targetName = targetName.withDomain(defaultDomain);
|
targetName = targetName.withDomain(defaultDomain);
|
||||||
}
|
}
|
||||||
final ObjectNameRouter r = getObjectNameRouter();
|
return router.toSourceContext(targetName,true);
|
||||||
return r.toSourceContext(targetName,true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -243,8 +232,7 @@ public abstract class RoutingProxy<T extends MBeanServerConnection>
|
||||||
public ObjectName toTarget(ObjectName sourceName)
|
public ObjectName toTarget(ObjectName sourceName)
|
||||||
throws MalformedObjectNameException {
|
throws MalformedObjectNameException {
|
||||||
if (sourceName == null) return null;
|
if (sourceName == null) return null;
|
||||||
final ObjectNameRouter r = getObjectNameRouter();
|
return router.toTargetContext(sourceName,false);
|
||||||
return r.toTargetContext(sourceName,false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object getAttributeFromHandler(String attributeName)
|
private Object getAttributeFromHandler(String attributeName)
|
||||||
|
@ -357,11 +345,8 @@ public abstract class RoutingProxy<T extends MBeanServerConnection>
|
||||||
// instance.
|
// instance.
|
||||||
static interface RoutingProxyFactory<T extends MBeanServerConnection,
|
static interface RoutingProxyFactory<T extends MBeanServerConnection,
|
||||||
R extends RoutingProxy<T>> {
|
R extends RoutingProxy<T>> {
|
||||||
R newInstance(T source,
|
public R newInstance(
|
||||||
String sourcePath, String targetPath,
|
T source, String sourcePath, String targetPath, boolean probe);
|
||||||
boolean forwardsContext);
|
|
||||||
R newInstance(T source,
|
|
||||||
String sourcePath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Performs a narrowDownToNamespace operation.
|
// Performs a narrowDownToNamespace operation.
|
||||||
|
@ -377,7 +362,7 @@ public abstract class RoutingProxy<T extends MBeanServerConnection>
|
||||||
static <T extends MBeanServerConnection, R extends RoutingProxy<T>>
|
static <T extends MBeanServerConnection, R extends RoutingProxy<T>>
|
||||||
R cd(Class<R> routingProxyClass,
|
R cd(Class<R> routingProxyClass,
|
||||||
RoutingProxyFactory<T,R> factory,
|
RoutingProxyFactory<T,R> factory,
|
||||||
T source, String sourcePath) {
|
T source, String sourcePath, boolean probe) {
|
||||||
if (source == null) throw new IllegalArgumentException("null");
|
if (source == null) throw new IllegalArgumentException("null");
|
||||||
if (source.getClass().equals(routingProxyClass)) {
|
if (source.getClass().equals(routingProxyClass)) {
|
||||||
// cast is OK here, but findbugs complains unless we use class.cast
|
// cast is OK here, but findbugs complains unless we use class.cast
|
||||||
|
@ -400,14 +385,13 @@ public abstract class RoutingProxy<T extends MBeanServerConnection>
|
||||||
final String path =
|
final String path =
|
||||||
JMXNamespaces.concat(other.getSourceNamespace(),
|
JMXNamespaces.concat(other.getSourceNamespace(),
|
||||||
sourcePath);
|
sourcePath);
|
||||||
return factory.newInstance(other.source(),path,"",
|
return factory.newInstance(other.source(), path, "", probe);
|
||||||
other.forwardsContext);
|
|
||||||
}
|
}
|
||||||
// Note: we could do possibly something here - but it would involve
|
// Note: we could do possibly something here - but it would involve
|
||||||
// removing part of targetDir, and possibly adding
|
// removing part of targetDir, and possibly adding
|
||||||
// something to sourcePath.
|
// something to sourcePath.
|
||||||
// Too complex to bother! => simply default to stacking...
|
// Too complex to bother! => simply default to stacking...
|
||||||
}
|
}
|
||||||
return factory.newInstance(source,sourcePath);
|
return factory.newInstance(source, sourcePath, "", probe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,6 @@ import javax.management.OperationsException;
|
||||||
import javax.management.QueryExp;
|
import javax.management.QueryExp;
|
||||||
import javax.management.ReflectionException;
|
import javax.management.ReflectionException;
|
||||||
import javax.management.loading.ClassLoaderRepository;
|
import javax.management.loading.ClassLoaderRepository;
|
||||||
import javax.management.namespace.JMXNamespaces;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A RoutingServerProxy is an MBeanServer proxy that proxies a
|
* A RoutingServerProxy is an MBeanServer proxy that proxies a
|
||||||
|
@ -76,19 +75,11 @@ public class RoutingServerProxy
|
||||||
extends RoutingProxy<MBeanServer>
|
extends RoutingProxy<MBeanServer>
|
||||||
implements MBeanServer {
|
implements MBeanServer {
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new instance of RoutingServerProxy
|
|
||||||
*/
|
|
||||||
public RoutingServerProxy(MBeanServer source,
|
|
||||||
String sourceNs) {
|
|
||||||
this(source,sourceNs,"",false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public RoutingServerProxy(MBeanServer source,
|
public RoutingServerProxy(MBeanServer source,
|
||||||
String sourceNs,
|
String sourceNs,
|
||||||
String targetNs,
|
String targetNs,
|
||||||
boolean forwardsContext) {
|
boolean probe) {
|
||||||
super(source,sourceNs,targetNs,forwardsContext);
|
super(source, sourceNs, targetNs, probe);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -571,20 +562,15 @@ public class RoutingServerProxy
|
||||||
FACTORY = new RoutingProxyFactory<MBeanServer,RoutingServerProxy>() {
|
FACTORY = new RoutingProxyFactory<MBeanServer,RoutingServerProxy>() {
|
||||||
|
|
||||||
public RoutingServerProxy newInstance(MBeanServer source,
|
public RoutingServerProxy newInstance(MBeanServer source,
|
||||||
String sourcePath, String targetPath,
|
String sourcePath, String targetPath, boolean probe) {
|
||||||
boolean forwardsContext) {
|
return new RoutingServerProxy(
|
||||||
return new RoutingServerProxy(source,sourcePath,
|
source, sourcePath, targetPath, probe);
|
||||||
targetPath,forwardsContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
public RoutingServerProxy newInstance(
|
|
||||||
MBeanServer source, String sourcePath) {
|
|
||||||
return new RoutingServerProxy(source,sourcePath);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static MBeanServer cd(MBeanServer source, String sourcePath) {
|
public static MBeanServer cd(
|
||||||
|
MBeanServer source, String sourcePath, boolean probe) {
|
||||||
return RoutingProxy.cd(RoutingServerProxy.class, FACTORY,
|
return RoutingProxy.cd(RoutingServerProxy.class, FACTORY,
|
||||||
source, sourcePath);
|
source, sourcePath, probe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -430,13 +430,11 @@ public class EventClientConnection implements InvocationHandler,
|
||||||
* The {@code EventClient} is created lazily, when it is needed
|
* The {@code EventClient} is created lazily, when it is needed
|
||||||
* for the first time. If null, a default factory will be used
|
* for the first time. If null, a default factory will be used
|
||||||
* (see {@link #createEventClient}).
|
* (see {@link #createEventClient}).
|
||||||
* @return the
|
* @return the MBeanServerConnection.
|
||||||
**/
|
**/
|
||||||
public static MBeanServerConnection getEventConnectionFor(
|
public static MBeanServerConnection getEventConnectionFor(
|
||||||
MBeanServerConnection connection,
|
MBeanServerConnection connection,
|
||||||
Callable<EventClient> eventClientFactory) {
|
Callable<EventClient> eventClientFactory) {
|
||||||
// if c already uses an EventClient no need to create a new one.
|
|
||||||
//
|
|
||||||
if (connection instanceof EventClientFactory
|
if (connection instanceof EventClientFactory
|
||||||
&& eventClientFactory != null)
|
&& eventClientFactory != null)
|
||||||
throw new IllegalArgumentException("connection already uses EventClient");
|
throw new IllegalArgumentException("connection already uses EventClient");
|
||||||
|
|
|
@ -497,6 +497,10 @@ public class HttpsURLConnectionOldImpl
|
||||||
delegate.setFixedLengthStreamingMode(contentLength);
|
delegate.setFixedLengthStreamingMode(contentLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setFixedLengthStreamingMode(long contentLength) {
|
||||||
|
delegate.setFixedLengthStreamingMode(contentLength);
|
||||||
|
}
|
||||||
|
|
||||||
public void setChunkedStreamingMode (int chunklen) {
|
public void setChunkedStreamingMode (int chunklen) {
|
||||||
delegate.setChunkedStreamingMode(chunklen);
|
delegate.setChunkedStreamingMode(chunklen);
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,6 +86,8 @@ import sun.misc.HexDumpEncoder;
|
||||||
* the principal name from the configuration is used. In the
|
* the principal name from the configuration is used. In the
|
||||||
* case where the principal property is not set and the principal
|
* case where the principal property is not set and the principal
|
||||||
* entry also does not exist, the user is prompted for the name.
|
* entry also does not exist, the user is prompted for the name.
|
||||||
|
* When this property of entry is set, and <code>useTicketCache</code>
|
||||||
|
* is set to true, only TGT belonging to this principal is used.
|
||||||
*
|
*
|
||||||
* <p> The following is a list of configuration options supported
|
* <p> The following is a list of configuration options supported
|
||||||
* for <code>Krb5LoginModule</code>:
|
* for <code>Krb5LoginModule</code>:
|
||||||
|
@ -101,18 +103,19 @@ import sun.misc.HexDumpEncoder;
|
||||||
* to false if you do not want this module to use the ticket cache.
|
* to false if you do not want this module to use the ticket cache.
|
||||||
* (Default is False).
|
* (Default is False).
|
||||||
* This module will
|
* This module will
|
||||||
* search for the tickect
|
* search for the ticket
|
||||||
* cache in the following locations:
|
* cache in the following locations:
|
||||||
* For Windows 2000, it will use Local Security Authority (LSA) API
|
* On Solaris and Linux
|
||||||
* to get the TGT. On Solaris and Linux
|
|
||||||
* it will look for the ticket cache in /tmp/krb5cc_<code>uid</code>
|
* it will look for the ticket cache in /tmp/krb5cc_<code>uid</code>
|
||||||
* where the uid is numeric user
|
* where the uid is numeric user
|
||||||
* identifier. If the ticket cache is
|
* identifier. If the ticket cache is
|
||||||
* not available in either of the above locations, or if we are on a
|
* not available in the above location, or if we are on a
|
||||||
* different Windows platform, it will look for the cache as
|
* Windows platform, it will look for the cache as
|
||||||
* {user.home}{file.separator}krb5cc_{user.name}.
|
* {user.home}{file.separator}krb5cc_{user.name}.
|
||||||
* You can override the ticket cache location by using
|
* You can override the ticket cache location by using
|
||||||
* <code>ticketCache</code>
|
* <code>ticketCache</code>.
|
||||||
|
* For Windows, if a ticket cannot be retrieved from the file ticket cache,
|
||||||
|
* it will use Local Security Authority (LSA) API to get the TGT.
|
||||||
* <P>
|
* <P>
|
||||||
* <dt><b><code>ticketCache</code></b>:</dt>
|
* <dt><b><code>ticketCache</code></b>:</dt>
|
||||||
* <dd>Set this to the name of the ticket
|
* <dd>Set this to the name of the ticket
|
||||||
|
@ -129,20 +132,20 @@ import sun.misc.HexDumpEncoder;
|
||||||
* <dt><b><code>doNotPrompt</code></b>:</dt>
|
* <dt><b><code>doNotPrompt</code></b>:</dt>
|
||||||
* <dd>Set this to true if you do not want to be
|
* <dd>Set this to true if you do not want to be
|
||||||
* prompted for the password
|
* prompted for the password
|
||||||
* if credentials can
|
* if credentials can not be obtained from the cache, the keytab,
|
||||||
* not be obtained from the cache or keytab.(Default is false)
|
* or through shared state.(Default is false)
|
||||||
* If set to true authentication will fail if credentials can
|
* If set to true, credential must be obtained through cache, keytab,
|
||||||
* not be obtained from the cache or keytab.</dd>
|
* or shared state. Otherwise, authentication will fail.</dd>
|
||||||
* <P>
|
* <P>
|
||||||
* <dt><b><code>useKeyTab</code></b>:</dt>
|
* <dt><b><code>useKeyTab</code></b>:</dt>
|
||||||
* <dd>Set this to true if you
|
* <dd>Set this to true if you
|
||||||
* want the module to get the principal's key from the
|
* want the module to get the principal's key from the
|
||||||
* the keytab.(default value is False)
|
* the keytab.(default value is False)
|
||||||
* If <code>keyatb</code>
|
* If <code>keytab</code>
|
||||||
* is not set then
|
* is not set then
|
||||||
* the module will locate the keytab from the
|
* the module will locate the keytab from the
|
||||||
* Kerberos configuration file.</dd>
|
* Kerberos configuration file.
|
||||||
* If it is not specifed in the Kerberos configuration file
|
* If it is not specified in the Kerberos configuration file
|
||||||
* then it will look for the file
|
* then it will look for the file
|
||||||
* <code>{user.home}{file.separator}</code>krb5.keytab.</dd>
|
* <code>{user.home}{file.separator}</code>krb5.keytab.</dd>
|
||||||
* <P>
|
* <P>
|
||||||
|
@ -210,20 +213,34 @@ import sun.misc.HexDumpEncoder;
|
||||||
* exist for the username and password in the shared
|
* exist for the username and password in the shared
|
||||||
* state, or if authentication fails.
|
* state, or if authentication fails.
|
||||||
*
|
*
|
||||||
* clearPass if, true, this <code>LoginModule</code> clears the
|
* clearPass if, true, this LoginModule clears the
|
||||||
* username and password stored in the module's shared
|
* username and password stored in the module's shared
|
||||||
* state after both phases of authentication
|
* state after both phases of authentication
|
||||||
* (login and commit) have completed.
|
* (login and commit) have completed.
|
||||||
* </pre>
|
* </pre>
|
||||||
|
* <p>If the principal system property or key is already provided, the value of
|
||||||
|
* "javax.security.auth.login.name" in the shared state is ignored.
|
||||||
|
* <p>When multiple mechanisms to retrieve a ticket or key is provided, the
|
||||||
|
* preference order looks like this:
|
||||||
|
* <ol>
|
||||||
|
* <li>ticket cache
|
||||||
|
* <li>keytab
|
||||||
|
* <li>shared state
|
||||||
|
* <li>user prompt
|
||||||
|
* </ol>
|
||||||
|
* <p>Note that if any step fails, it will fallback to the next step.
|
||||||
|
* There's only one exception, it the shared state step fails and
|
||||||
|
* <code>useFirstPass</code>=true, no user prompt is made.
|
||||||
* <p>Examples of some configuration values for Krb5LoginModule in
|
* <p>Examples of some configuration values for Krb5LoginModule in
|
||||||
* JAAS config file and the results are:
|
* JAAS config file and the results are:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <p> <code>doNotPrompt</code>=true;
|
* <p> <code>doNotPrompt</code>=true;
|
||||||
* </ul>
|
* </ul>
|
||||||
* <p> This is an illegal combination since <code>useTicketCache</code>
|
* <p> This is an illegal combination since none of <code>useTicketCache</code>,
|
||||||
* is not set and the user can not be prompted for the password.
|
* <code>useKeyTab</code>, <code>useFirstPass</code> and <code>tryFirstPass</code>
|
||||||
|
* is set and the user can not be prompted for the password.
|
||||||
*<ul>
|
*<ul>
|
||||||
* <p> <code>ticketCache</code> = < filename >;
|
* <p> <code>ticketCache</code> = <filename>;
|
||||||
*</ul>
|
*</ul>
|
||||||
* <p> This is an illegal combination since <code>useTicketCache</code>
|
* <p> This is an illegal combination since <code>useTicketCache</code>
|
||||||
* is not set to true and the ticketCache is set. A configuration error
|
* is not set to true and the ticketCache is set. A configuration error
|
||||||
|
@ -240,9 +257,9 @@ import sun.misc.HexDumpEncoder;
|
||||||
*</ul>
|
*</ul>
|
||||||
* <p> This is an illegal combination since <code>storeKey</code> is set to
|
* <p> This is an illegal combination since <code>storeKey</code> is set to
|
||||||
* true but the key can not be obtained either by prompting the user or from
|
* true but the key can not be obtained either by prompting the user or from
|
||||||
* the keytab.A configuration error will occur.
|
* the keytab, or from the shared state. A configuration error will occur.
|
||||||
* <ul>
|
* <ul>
|
||||||
* <p> <code>keyTab</code> = < filename > <code>doNotPrompt</code>=true ;
|
* <p> <code>keyTab</code> = <filename> <code>doNotPrompt</code>=true ;
|
||||||
* </ul>
|
* </ul>
|
||||||
* <p>This is an illegal combination since useKeyTab is not set to true and
|
* <p>This is an illegal combination since useKeyTab is not set to true and
|
||||||
* the keyTab is set. A configuration error will occur.
|
* the keyTab is set. A configuration error will occur.
|
||||||
|
@ -260,7 +277,7 @@ import sun.misc.HexDumpEncoder;
|
||||||
* with the principal and TGT. If the TGT is not available,
|
* with the principal and TGT. If the TGT is not available,
|
||||||
* do not prompt the user, instead fail the authentication.
|
* do not prompt the user, instead fail the authentication.
|
||||||
* <ul>
|
* <ul>
|
||||||
* <p><code>principal</code>=< name ><code>useTicketCache</code> = true
|
* <p><code>principal</code>=<name><code>useTicketCache</code> = true
|
||||||
* <code>doNotPrompt</code>=true;
|
* <code>doNotPrompt</code>=true;
|
||||||
*</ul>
|
*</ul>
|
||||||
* <p> Get the TGT from the default cache for the principal and populate the
|
* <p> Get the TGT from the default cache for the principal and populate the
|
||||||
|
@ -269,9 +286,9 @@ import sun.misc.HexDumpEncoder;
|
||||||
* authentication will fail.
|
* authentication will fail.
|
||||||
* <ul>
|
* <ul>
|
||||||
* <p> <code>useTicketCache</code> = true
|
* <p> <code>useTicketCache</code> = true
|
||||||
* <code>ticketCache</code>=< file name ><code>useKeyTab</code> = true
|
* <code>ticketCache</code>=<file name><code>useKeyTab</code> = true
|
||||||
* <code> keyTab</code>=< keytab filename >
|
* <code> keyTab</code>=<keytab filename>
|
||||||
* <code>principal</code> = < principal name >
|
* <code>principal</code> = <principal name>
|
||||||
* <code>doNotPrompt</code>=true;
|
* <code>doNotPrompt</code>=true;
|
||||||
*</ul>
|
*</ul>
|
||||||
* <p> Search the cache for the principal's TGT. If it is not available
|
* <p> Search the cache for the principal's TGT. If it is not available
|
||||||
|
@ -281,7 +298,7 @@ import sun.misc.HexDumpEncoder;
|
||||||
* If the key is not available or valid then authentication will fail.
|
* If the key is not available or valid then authentication will fail.
|
||||||
* <ul>
|
* <ul>
|
||||||
* <p><code>useTicketCache</code> = true
|
* <p><code>useTicketCache</code> = true
|
||||||
* <code>ticketCache</code>=< file name >
|
* <code>ticketCache</code>=<file name>
|
||||||
*</ul>
|
*</ul>
|
||||||
* <p> The TGT will be obtained from the cache specified.
|
* <p> The TGT will be obtained from the cache specified.
|
||||||
* The Kerberos principal name used will be the principal name in
|
* The Kerberos principal name used will be the principal name in
|
||||||
|
@ -292,8 +309,8 @@ import sun.misc.HexDumpEncoder;
|
||||||
* The Subject will be populated with the TGT.
|
* The Subject will be populated with the TGT.
|
||||||
*<ul>
|
*<ul>
|
||||||
* <p> <code>useKeyTab</code> = true
|
* <p> <code>useKeyTab</code> = true
|
||||||
* <code>keyTab</code>=< keytab filename >
|
* <code>keyTab</code>=<keytab filename>
|
||||||
* <code>principal</code>= < principal name >
|
* <code>principal</code>= <principal name>
|
||||||
* <code>storeKey</code>=true;
|
* <code>storeKey</code>=true;
|
||||||
*</ul>
|
*</ul>
|
||||||
* <p> The key for the principal will be retrieved from the keytab.
|
* <p> The key for the principal will be retrieved from the keytab.
|
||||||
|
@ -303,7 +320,7 @@ import sun.misc.HexDumpEncoder;
|
||||||
* password entered.
|
* password entered.
|
||||||
* <ul>
|
* <ul>
|
||||||
* <p> <code>useKeyTab</code> = true
|
* <p> <code>useKeyTab</code> = true
|
||||||
* <code>keyTab</code>=< keytabname >
|
* <code>keyTab</code>=<keytabname>
|
||||||
* <code>storeKey</code>=true
|
* <code>storeKey</code>=true
|
||||||
* <code>doNotPrompt</code>=true;
|
* <code>doNotPrompt</code>=true;
|
||||||
*</ul>
|
*</ul>
|
||||||
|
@ -316,21 +333,23 @@ import sun.misc.HexDumpEncoder;
|
||||||
* Subject's private credentials set. Otherwise the authentication will
|
* Subject's private credentials set. Otherwise the authentication will
|
||||||
* fail.
|
* fail.
|
||||||
*<ul>
|
*<ul>
|
||||||
* <p><code>useKeyTab</code> = true
|
* <p>
|
||||||
* <code>keyTab</code>=< file name > <code>storeKey</code>=true
|
|
||||||
* <code>principal</code>= < principal name >
|
|
||||||
* <code>useTicketCache</code>=true
|
* <code>useTicketCache</code>=true
|
||||||
* <code>ticketCache</code>=< file name >;
|
* <code>ticketCache</code>=<file name>;
|
||||||
|
* <code>useKeyTab</code> = true
|
||||||
|
* <code>keyTab</code>=<file name> <code>storeKey</code>=true
|
||||||
|
* <code>principal</code>= <principal name>
|
||||||
*</ul>
|
*</ul>
|
||||||
* <p>The principal's key will be retrieved from the keytab and added
|
* <p>
|
||||||
* to the <code>Subject</code>'s private credentials. If the key
|
* The client's TGT will be retrieved from the ticket cache and added to the
|
||||||
* is not available, the
|
|
||||||
* user will be prompted for the password; the key derived from the password
|
|
||||||
* will be added to the Subject's private credentials set. The
|
|
||||||
* client's TGT will be retrieved from the ticket cache and added to the
|
|
||||||
* <code>Subject</code>'s private credentials. If the TGT is not available
|
* <code>Subject</code>'s private credentials. If the TGT is not available
|
||||||
* in the ticket cache, it will be obtained using the authentication
|
* in the ticket cache, or the TGT's client name does not match the principal
|
||||||
|
* name, Java will use a secret key to obtain the TGT using the authentication
|
||||||
* exchange and added to the Subject's private credentials.
|
* exchange and added to the Subject's private credentials.
|
||||||
|
* This secret key will be first retrieved from the keytab. If the key
|
||||||
|
* is not available, the user will be prompted for the password. In either
|
||||||
|
* case, the key derived from the password will be added to the
|
||||||
|
* Subject's private credentials set.
|
||||||
* <ul>
|
* <ul>
|
||||||
* <p><code>isInitiator</code> = false
|
* <p><code>isInitiator</code> = false
|
||||||
*</ul>
|
*</ul>
|
||||||
|
@ -856,11 +875,13 @@ public class Krb5LoginModule implements LoginModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateConfiguration() throws LoginException {
|
private void validateConfiguration() throws LoginException {
|
||||||
if (doNotPrompt && !useTicketCache && !useKeyTab)
|
if (doNotPrompt && !useTicketCache && !useKeyTab
|
||||||
|
&& !tryFirstPass && !useFirstPass)
|
||||||
throw new LoginException
|
throw new LoginException
|
||||||
("Configuration Error"
|
("Configuration Error"
|
||||||
+ " - either doNotPrompt should be "
|
+ " - either doNotPrompt should be "
|
||||||
+ " false or useTicketCache/useKeyTab "
|
+ " false or at least one of useTicketCache, "
|
||||||
|
+ " useKeyTab, tryFirstPass and useFirstPass"
|
||||||
+ " should be true");
|
+ " should be true");
|
||||||
if (ticketCacheName != null && !useTicketCache)
|
if (ticketCacheName != null && !useTicketCache)
|
||||||
throw new LoginException
|
throw new LoginException
|
||||||
|
@ -872,11 +893,12 @@ public class Krb5LoginModule implements LoginModule {
|
||||||
throw new LoginException
|
throw new LoginException
|
||||||
("Configuration Error - useKeyTab should be set to true "
|
("Configuration Error - useKeyTab should be set to true "
|
||||||
+ "to use the keytab" + keyTabName);
|
+ "to use the keytab" + keyTabName);
|
||||||
if (storeKey && doNotPrompt && !useKeyTab)
|
if (storeKey && doNotPrompt && !useKeyTab
|
||||||
|
&& !tryFirstPass && !useFirstPass)
|
||||||
throw new LoginException
|
throw new LoginException
|
||||||
("Configuration Error - either doNotPrompt "
|
("Configuration Error - either doNotPrompt should be set to "
|
||||||
+ "should be set to false or "
|
+ " false or at least one of tryFirstPass, useFirstPass "
|
||||||
+ "useKeyTab must be set to true for storeKey option");
|
+ "or useKeyTab must be set to true for storeKey option");
|
||||||
if (renewTGT && !useTicketCache)
|
if (renewTGT && !useTicketCache)
|
||||||
throw new LoginException
|
throw new LoginException
|
||||||
("Configuration Error"
|
("Configuration Error"
|
||||||
|
|
|
@ -73,10 +73,23 @@ abstract public class HttpURLConnection extends URLConnection {
|
||||||
* The fixed content-length when using fixed-length streaming mode.
|
* The fixed content-length when using fixed-length streaming mode.
|
||||||
* A value of <code>-1</code> means fixed-length streaming mode is disabled
|
* A value of <code>-1</code> means fixed-length streaming mode is disabled
|
||||||
* for output.
|
* for output.
|
||||||
|
*
|
||||||
|
* <P> <B>NOTE:</B> {@link #fixedContentLengthLong} is recommended instead
|
||||||
|
* of this field, as it allows larger content lengths to be set.
|
||||||
|
*
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
protected int fixedContentLength = -1;
|
protected int fixedContentLength = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The fixed content-length when using fixed-length streaming mode.
|
||||||
|
* A value of {@code -1} means fixed-length streaming mode is disabled
|
||||||
|
* for output.
|
||||||
|
*
|
||||||
|
* @since 1.7
|
||||||
|
*/
|
||||||
|
protected long fixedContentLengthLong = -1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the key for the <code>n</code><sup>th</sup> header field.
|
* Returns the key for the <code>n</code><sup>th</sup> header field.
|
||||||
* Some implementations may treat the <code>0</code><sup>th</sup>
|
* Some implementations may treat the <code>0</code><sup>th</sup>
|
||||||
|
@ -109,6 +122,9 @@ abstract public class HttpURLConnection extends URLConnection {
|
||||||
* This exception can be queried for the details of the error.
|
* This exception can be queried for the details of the error.
|
||||||
* <p>
|
* <p>
|
||||||
* This method must be called before the URLConnection is connected.
|
* This method must be called before the URLConnection is connected.
|
||||||
|
* <p>
|
||||||
|
* <B>NOTE:</B> {@link #setFixedLengthStreamingMode(long)} is recommended
|
||||||
|
* instead of this method as it allows larger content lengths to be set.
|
||||||
*
|
*
|
||||||
* @param contentLength The number of bytes which will be written
|
* @param contentLength The number of bytes which will be written
|
||||||
* to the OutputStream.
|
* to the OutputStream.
|
||||||
|
@ -135,6 +151,52 @@ abstract public class HttpURLConnection extends URLConnection {
|
||||||
fixedContentLength = contentLength;
|
fixedContentLength = contentLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is used to enable streaming of a HTTP request body
|
||||||
|
* without internal buffering, when the content length is known in
|
||||||
|
* advance.
|
||||||
|
*
|
||||||
|
* <P> An exception will be thrown if the application attempts to write
|
||||||
|
* more data than the indicated content-length, or if the application
|
||||||
|
* closes the OutputStream before writing the indicated amount.
|
||||||
|
*
|
||||||
|
* <P> When output streaming is enabled, authentication and redirection
|
||||||
|
* cannot be handled automatically. A {@linkplain HttpRetryException} will
|
||||||
|
* be thrown when reading the response if authentication or redirection
|
||||||
|
* are required. This exception can be queried for the details of the
|
||||||
|
* error.
|
||||||
|
*
|
||||||
|
* <P> This method must be called before the URLConnection is connected.
|
||||||
|
*
|
||||||
|
* <P> The content length set by invoking this method takes precedence
|
||||||
|
* over any value set by {@link #setFixedLengthStreamingMode(int)}.
|
||||||
|
*
|
||||||
|
* @param contentLength
|
||||||
|
* The number of bytes which will be written to the OutputStream.
|
||||||
|
*
|
||||||
|
* @throws IllegalStateException
|
||||||
|
* if URLConnection is already connected or if a different
|
||||||
|
* streaming mode is already enabled.
|
||||||
|
*
|
||||||
|
* @throws IllegalArgumentException
|
||||||
|
* if a content length less than zero is specified.
|
||||||
|
*
|
||||||
|
* @since 1.7
|
||||||
|
*/
|
||||||
|
public void setFixedLengthStreamingMode(long contentLength) {
|
||||||
|
if (connected) {
|
||||||
|
throw new IllegalStateException("Already connected");
|
||||||
|
}
|
||||||
|
if (chunkLength != -1) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"Chunked encoding streaming mode set");
|
||||||
|
}
|
||||||
|
if (contentLength < 0) {
|
||||||
|
throw new IllegalArgumentException("invalid content length");
|
||||||
|
}
|
||||||
|
fixedContentLengthLong = contentLength;
|
||||||
|
}
|
||||||
|
|
||||||
/* Default chunk size (including chunk header) if not specified;
|
/* Default chunk size (including chunk header) if not specified;
|
||||||
* we want to keep this in sync with the one defined in
|
* we want to keep this in sync with the one defined in
|
||||||
* sun.net.www.http.ChunkedOutputStream
|
* sun.net.www.http.ChunkedOutputStream
|
||||||
|
@ -170,7 +232,7 @@ abstract public class HttpURLConnection extends URLConnection {
|
||||||
if (connected) {
|
if (connected) {
|
||||||
throw new IllegalStateException ("Can't set streaming mode: already connected");
|
throw new IllegalStateException ("Can't set streaming mode: already connected");
|
||||||
}
|
}
|
||||||
if (fixedContentLength != -1) {
|
if (fixedContentLength != -1 || fixedContentLengthLong != -1) {
|
||||||
throw new IllegalStateException ("Fixed length streaming mode set");
|
throw new IllegalStateException ("Fixed length streaming mode set");
|
||||||
}
|
}
|
||||||
chunkLength = chunklen <=0? DEFAULT_CHUNK_SIZE : chunklen;
|
chunkLength = chunklen <=0? DEFAULT_CHUNK_SIZE : chunklen;
|
||||||
|
|
|
@ -113,7 +113,7 @@ public class CertPathValidatorException extends GeneralSecurityException {
|
||||||
* permitted, and indicates that the cause is nonexistent or unknown.)
|
* permitted, and indicates that the cause is nonexistent or unknown.)
|
||||||
*/
|
*/
|
||||||
public CertPathValidatorException(Throwable cause) {
|
public CertPathValidatorException(Throwable cause) {
|
||||||
this(null, cause);
|
this((cause == null ? null : cause.toString()), cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 1999-2005 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -27,17 +27,23 @@ package javax.management;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a list of values for attributes of an MBean. The methods
|
* <p>Represents a list of values for attributes of an MBean. See the
|
||||||
* used for the insertion of {@link javax.management.Attribute
|
* {@link MBeanServerConnection#getAttributes getAttributes} and
|
||||||
* Attribute} objects in the <CODE>AttributeList</CODE> overrides the
|
* {@link MBeanServerConnection#setAttributes setAttributes} methods of
|
||||||
* corresponding methods in the superclass
|
* {@link MBeanServer} and {@link MBeanServerConnection}.</p>
|
||||||
* <CODE>ArrayList</CODE>. This is needed in order to insure that the
|
*
|
||||||
* objects contained in the <CODE>AttributeList</CODE> are only
|
* <p id="type-safe">For compatibility reasons, it is possible, though
|
||||||
* <CODE>Attribute</CODE> objects. This avoids getting an exception
|
* highly discouraged, to add objects to an {@code AttributeList} that are
|
||||||
* when retrieving elements from the <CODE>AttributeList</CODE>.
|
* not instances of {@code Attribute}. However, an {@code AttributeList}
|
||||||
|
* can be made <em>type-safe</em>, which means that an attempt to add
|
||||||
|
* an object that is not an {@code Attribute} will produce an {@code
|
||||||
|
* IllegalArgumentException}. An {@code AttributeList} becomes type-safe
|
||||||
|
* when the method {@link #asList()} is called on it.</p>
|
||||||
*
|
*
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
|
@ -58,8 +64,8 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
public class AttributeList extends ArrayList<Object> {
|
public class AttributeList extends ArrayList<Object> {
|
||||||
|
|
||||||
private transient boolean typeSafe;
|
private transient volatile boolean typeSafe;
|
||||||
private transient boolean tainted;
|
private transient volatile boolean tainted;
|
||||||
|
|
||||||
/* Serial version */
|
/* Serial version */
|
||||||
private static final long serialVersionUID = -4077085769279709076L;
|
private static final long serialVersionUID = -4077085769279709076L;
|
||||||
|
@ -124,13 +130,63 @@ public class AttributeList extends ArrayList<Object> {
|
||||||
|
|
||||||
// Check for non-Attribute objects
|
// Check for non-Attribute objects
|
||||||
//
|
//
|
||||||
checkTypeSafe(list);
|
adding(list);
|
||||||
|
|
||||||
// Build the List<Attribute>
|
// Build the List<Attribute>
|
||||||
//
|
//
|
||||||
super.addAll(list);
|
super.addAll(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Constructs an {@code AttributeList} containing the elements of
|
||||||
|
* the {@code Map} specified, in the order in which they appear in the
|
||||||
|
* {@code Map}'s {@link Map#entrySet entrySet}. For each <em>{@code
|
||||||
|
* key}</em> and <em>{@code value}</em> in the {@code Map}, the constructed
|
||||||
|
* {@code AttributeList} will contain {@link Attribute#Attribute
|
||||||
|
* Attribute(<em>key</em>, <em>value</em>)}.</p>
|
||||||
|
*
|
||||||
|
* @param map the {@code Map} defining the elements of the new
|
||||||
|
* {@code AttributeList}.
|
||||||
|
*/
|
||||||
|
public AttributeList(Map<String, ?> map) {
|
||||||
|
for (Map.Entry<String, ?> entry : map.entrySet())
|
||||||
|
add(new Attribute(entry.getKey(), entry.getValue()));
|
||||||
|
typeSafe = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Return a {@code Map} that is a snapshot of the values in this
|
||||||
|
* {@code AttributeList}. Each key in the {@code Map} is the {@linkplain
|
||||||
|
* Attribute#getName() name} of an {@code Attribute} in the list, and each
|
||||||
|
* value is the corresponding {@linkplain Attribute#getValue() value} of
|
||||||
|
* that {@code Attribute}. The {@code AttributeList} and the {@code Map}
|
||||||
|
* are unrelated after the call, that is, changes to one do not affect the
|
||||||
|
* other.</p>
|
||||||
|
*
|
||||||
|
* <p>If the {@code AttributeList} contains more than one {@code Attribute}
|
||||||
|
* with the same name, then the {@code Map} will contain an entry
|
||||||
|
* for that name where the value is that of the last of those {@code
|
||||||
|
* Attribute}s.</p>
|
||||||
|
*
|
||||||
|
* @return the new {@code Map}.
|
||||||
|
*
|
||||||
|
* @throws IllegalArgumentException if this {@code AttributeList} contains
|
||||||
|
* an element that is not an {@code Attribute}.
|
||||||
|
*/
|
||||||
|
public Map<String, Object> toMap() {
|
||||||
|
Map<String, Object> map = new LinkedHashMap<String, Object>();
|
||||||
|
|
||||||
|
// We can't call adding(this) because we're not necessarily typeSafe
|
||||||
|
if (tainted)
|
||||||
|
throw new IllegalArgumentException("AttributeList contains non-Attribute");
|
||||||
|
|
||||||
|
for (Object x : this) {
|
||||||
|
Attribute a = (Attribute) x;
|
||||||
|
map.put(a.getName(), a.getValue());
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a view of this list as a {@code List<Attribute>}.
|
* Return a view of this list as a {@code List<Attribute>}.
|
||||||
* Changes to the returned value are reflected by changes
|
* Changes to the returned value are reflected by changes
|
||||||
|
@ -154,11 +210,9 @@ public class AttributeList extends ArrayList<Object> {
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public List<Attribute> asList() {
|
public List<Attribute> asList() {
|
||||||
if (!typeSafe) {
|
|
||||||
if (tainted)
|
|
||||||
checkTypeSafe(this);
|
|
||||||
typeSafe = true;
|
typeSafe = true;
|
||||||
}
|
if (tainted)
|
||||||
|
adding((Collection<?>) this); // will throw IllegalArgumentException
|
||||||
return (List<Attribute>) (List<?>) this;
|
return (List<Attribute>) (List<?>) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,7 +229,7 @@ public class AttributeList extends ArrayList<Object> {
|
||||||
* Inserts the attribute specified as an element at the position specified.
|
* Inserts the attribute specified as an element at the position specified.
|
||||||
* Elements with an index greater than or equal to the current position are
|
* Elements with an index greater than or equal to the current position are
|
||||||
* shifted up. If the index is out of range (index < 0 || index >
|
* shifted up. If the index is out of range (index < 0 || index >
|
||||||
* size() a RuntimeOperationsException should be raised, wrapping the
|
* size()) a RuntimeOperationsException should be raised, wrapping the
|
||||||
* java.lang.IndexOutOfBoundsException thrown.
|
* java.lang.IndexOutOfBoundsException thrown.
|
||||||
*
|
*
|
||||||
* @param object The <CODE>Attribute</CODE> object to be inserted.
|
* @param object The <CODE>Attribute</CODE> object to be inserted.
|
||||||
|
@ -245,8 +299,7 @@ public class AttributeList extends ArrayList<Object> {
|
||||||
public boolean addAll(int index, AttributeList list) {
|
public boolean addAll(int index, AttributeList list) {
|
||||||
try {
|
try {
|
||||||
return super.addAll(index, list);
|
return super.addAll(index, list);
|
||||||
}
|
} catch (IndexOutOfBoundsException e) {
|
||||||
catch (IndexOutOfBoundsException e) {
|
|
||||||
throw new RuntimeOperationsException(e,
|
throw new RuntimeOperationsException(e,
|
||||||
"The specified index is out of range");
|
"The specified index is out of range");
|
||||||
}
|
}
|
||||||
|
@ -258,96 +311,77 @@ public class AttributeList extends ArrayList<Object> {
|
||||||
* been called on this instance.
|
* been called on this instance.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @throws IllegalArgumentException if this {@code AttributeList} is
|
||||||
|
* <a href="#type-safe">type-safe</a> and {@code element} is not an
|
||||||
|
* {@code Attribute}.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean add(Object o) {
|
public boolean add(Object element) {
|
||||||
if (!tainted)
|
adding(element);
|
||||||
tainted = isTainted(o);
|
return super.add(element);
|
||||||
if (typeSafe)
|
|
||||||
checkTypeSafe(o);
|
|
||||||
return super.add(o);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @throws IllegalArgumentException if this {@code AttributeList} is
|
||||||
|
* <a href="#type-safe">type-safe</a> and {@code element} is not an
|
||||||
|
* {@code Attribute}.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void add(int index, Object element) {
|
public void add(int index, Object element) {
|
||||||
if (!tainted)
|
adding(element);
|
||||||
tainted = isTainted(element);
|
|
||||||
if (typeSafe)
|
|
||||||
checkTypeSafe(element);
|
|
||||||
super.add(index, element);
|
super.add(index, element);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @throws IllegalArgumentException if this {@code AttributeList} is
|
||||||
|
* <a href="#type-safe">type-safe</a> and {@code c} contains an
|
||||||
|
* element that is not an {@code Attribute}.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean addAll(Collection<?> c) {
|
public boolean addAll(Collection<?> c) {
|
||||||
if (!tainted)
|
adding(c);
|
||||||
tainted = isTainted(c);
|
|
||||||
if (typeSafe)
|
|
||||||
checkTypeSafe(c);
|
|
||||||
return super.addAll(c);
|
return super.addAll(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @throws IllegalArgumentException if this {@code AttributeList} is
|
||||||
|
* <a href="#type-safe">type-safe</a> and {@code c} contains an
|
||||||
|
* element that is not an {@code Attribute}.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean addAll(int index, Collection<?> c) {
|
public boolean addAll(int index, Collection<?> c) {
|
||||||
if (!tainted)
|
adding(c);
|
||||||
tainted = isTainted(c);
|
|
||||||
if (typeSafe)
|
|
||||||
checkTypeSafe(c);
|
|
||||||
return super.addAll(index, c);
|
return super.addAll(index, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @throws IllegalArgumentException if this {@code AttributeList} is
|
||||||
|
* <a href="#type-safe">type-safe</a> and {@code element} is not an
|
||||||
|
* {@code Attribute}.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Object set(int index, Object element) {
|
public Object set(int index, Object element) {
|
||||||
if (!tainted)
|
adding(element);
|
||||||
tainted = isTainted(element);
|
|
||||||
if (typeSafe)
|
|
||||||
checkTypeSafe(element);
|
|
||||||
return super.set(index, element);
|
return super.set(index, element);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private void adding(Object x) {
|
||||||
* IllegalArgumentException if o is a non-Attribute object.
|
if (x == null || x instanceof Attribute)
|
||||||
*/
|
return;
|
||||||
private static void checkTypeSafe(Object o) {
|
if (typeSafe)
|
||||||
try {
|
throw new IllegalArgumentException("Not an Attribute: " + x);
|
||||||
o = (Attribute) o;
|
else
|
||||||
} catch (ClassCastException e) {
|
tainted = true;
|
||||||
throw new IllegalArgumentException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private void adding(Collection<?> c) {
|
||||||
* IllegalArgumentException if c contains any non-Attribute objects.
|
for (Object x : c)
|
||||||
*/
|
adding(x);
|
||||||
private static void checkTypeSafe(Collection<?> c) {
|
|
||||||
try {
|
|
||||||
Attribute a;
|
|
||||||
for (Object o : c)
|
|
||||||
a = (Attribute) o;
|
|
||||||
} catch (ClassCastException e) {
|
|
||||||
throw new IllegalArgumentException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if o is a non-Attribute object.
|
|
||||||
*/
|
|
||||||
private static boolean isTainted(Object o) {
|
|
||||||
try {
|
|
||||||
checkTypeSafe(o);
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if c contains any non-Attribute objects.
|
|
||||||
*/
|
|
||||||
private static boolean isTainted(Collection<?> c) {
|
|
||||||
try {
|
|
||||||
checkTypeSafe(c);
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
1091
jdk/src/share/classes/javax/management/ClientContext.java
Normal file
1091
jdk/src/share/classes/javax/management/ClientContext.java
Normal file
File diff suppressed because it is too large
Load diff
|
@ -35,8 +35,8 @@ import java.io.Serializable;
|
||||||
// Javadoc imports:
|
// Javadoc imports:
|
||||||
import java.lang.management.MemoryUsage;
|
import java.lang.management.MemoryUsage;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
import javax.management.openmbean.CompositeData;
|
import javax.management.openmbean.CompositeData;
|
||||||
import javax.management.openmbean.MXBeanMappingFactory;
|
import javax.management.openmbean.MXBeanMappingFactory;
|
||||||
import javax.management.openmbean.OpenMBeanAttributeInfoSupport;
|
import javax.management.openmbean.OpenMBeanAttributeInfoSupport;
|
||||||
|
@ -118,19 +118,22 @@ import javax.management.openmbean.OpenType;
|
||||||
* deprecation, for example {@code "1.3 Replaced by the Capacity
|
* deprecation, for example {@code "1.3 Replaced by the Capacity
|
||||||
* attribute"}.</td>
|
* attribute"}.</td>
|
||||||
*
|
*
|
||||||
* <tr id="descriptionResourceBundleBaseName">
|
* <tr><td id="descriptionResourceBundleBaseName"><i>descriptionResource<br>
|
||||||
* <td>descriptionResource<br>BundleBaseName</td><td>String</td><td>Any</td>
|
* BundleBaseName</i></td><td>String</td><td>Any</td>
|
||||||
*
|
*
|
||||||
* <td>The base name for the {@link ResourceBundle} in which the key given in
|
* <td>The base name for the {@link ResourceBundle} in which the key given in
|
||||||
* the {@code descriptionResourceKey} field can be found, for example
|
* the {@code descriptionResourceKey} field can be found, for example
|
||||||
* {@code "com.example.myapp.MBeanResources"}.</td>
|
* {@code "com.example.myapp.MBeanResources"}. See
|
||||||
|
* {@link MBeanInfo#localizeDescriptions MBeanInfo.localizeDescriptions}.</td>
|
||||||
*
|
*
|
||||||
* <tr id="descriptionResourceKey">
|
* <tr><td id="descriptionResourceKey"><i>descriptionResourceKey</i></td>
|
||||||
* <td>descriptionResourceKey</td><td>String</td><td>Any</td>
|
* <td>String</td><td>Any</td>
|
||||||
*
|
*
|
||||||
* <td>A resource key for the description of this element. In
|
* <td>A resource key for the description of this element. In
|
||||||
* conjunction with the {@code descriptionResourceBundleBaseName},
|
* conjunction with the {@code descriptionResourceBundleBaseName},
|
||||||
* this can be used to find a localized version of the description.</td>
|
* this can be used to find a localized version of the description.
|
||||||
|
* See {@link MBeanInfo#localizeDescriptions MBeanInfo.localizeDescriptions}.
|
||||||
|
* </td>
|
||||||
*
|
*
|
||||||
* <tr><td>enabled</td><td>String</td>
|
* <tr><td>enabled</td><td>String</td>
|
||||||
* <td>MBeanAttributeInfo<br>MBeanNotificationInfo<br>MBeanOperationInfo</td>
|
* <td>MBeanAttributeInfo<br>MBeanNotificationInfo<br>MBeanOperationInfo</td>
|
||||||
|
@ -157,11 +160,11 @@ import javax.management.openmbean.OpenType;
|
||||||
* href="MBeanInfo.html#info-changed">{@code "jmx.mbean.info.changed"}</a>
|
* href="MBeanInfo.html#info-changed">{@code "jmx.mbean.info.changed"}</a>
|
||||||
* notification.</td>
|
* notification.</td>
|
||||||
*
|
*
|
||||||
* <tr><td>infoTimeout</td><td>String<br>Long</td><td>MBeanInfo</td>
|
* <tr id="infoTimeout"><td>infoTimeout</td><td>String<br>Long</td><td>MBeanInfo</td>
|
||||||
*
|
*
|
||||||
* <td id="infoTimeout">The time in milli-seconds that the MBeanInfo can
|
* <td>The time in milli-seconds that the MBeanInfo can reasonably be
|
||||||
* reasonably be expected to be unchanged. The value can be a {@code Long}
|
* expected to be unchanged. The value can be a {@code Long} or a
|
||||||
* or a decimal string. This provides a hint from a DynamicMBean or any
|
* decimal string. This provides a hint from a DynamicMBean or any
|
||||||
* MBean that does not define {@code immutableInfo} as {@code true}
|
* MBean that does not define {@code immutableInfo} as {@code true}
|
||||||
* that the MBeanInfo is not likely to change within this period and
|
* that the MBeanInfo is not likely to change within this period and
|
||||||
* therefore can be cached. When this field is missing or has the
|
* therefore can be cached. When this field is missing or has the
|
||||||
|
@ -185,6 +188,13 @@ import javax.management.openmbean.OpenType;
|
||||||
* <td>Legal values for an attribute or parameter. See
|
* <td>Legal values for an attribute or parameter. See
|
||||||
* {@link javax.management.openmbean}.</td>
|
* {@link javax.management.openmbean}.</td>
|
||||||
*
|
*
|
||||||
|
* <tr id="locale"><td><i>locale</i></td>
|
||||||
|
* <td>String</td><td>Any</td>
|
||||||
|
*
|
||||||
|
* <td>The {@linkplain Locale locale} of the description in this
|
||||||
|
* {@code MBeanInfo}, {@code MBeanAttributeInfo}, etc, as returned
|
||||||
|
* by {@link Locale#toString()}.</td>
|
||||||
|
*
|
||||||
* <tr id="maxValue"><td><i>maxValue</i><td>Object</td>
|
* <tr id="maxValue"><td><i>maxValue</i><td>Object</td>
|
||||||
* <td>MBeanAttributeInfo<br>MBeanParameterInfo</td>
|
* <td>MBeanAttributeInfo<br>MBeanParameterInfo</td>
|
||||||
*
|
*
|
||||||
|
|
|
@ -30,6 +30,7 @@ import com.sun.jmx.mbeanserver.MBeanInjector;
|
||||||
import com.sun.jmx.remote.util.ClassLogger;
|
import com.sun.jmx.remote.util.ClassLogger;
|
||||||
import java.beans.BeanInfo;
|
import java.beans.BeanInfo;
|
||||||
import java.beans.PropertyDescriptor;
|
import java.beans.PropertyDescriptor;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.lang.reflect.InvocationHandler;
|
import java.lang.reflect.InvocationHandler;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
@ -37,6 +38,7 @@ import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Proxy;
|
import java.lang.reflect.Proxy;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
import javax.management.namespace.JMXNamespaces;
|
||||||
import javax.management.openmbean.MXBeanMappingFactory;
|
import javax.management.openmbean.MXBeanMappingFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -60,6 +62,21 @@ public class JMX {
|
||||||
*/
|
*/
|
||||||
public static final String DEFAULT_VALUE_FIELD = "defaultValue";
|
public static final String DEFAULT_VALUE_FIELD = "defaultValue";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the <a
|
||||||
|
* href="Descriptor.html#descriptionResourceBundleBaseName">{@code
|
||||||
|
* descriptionResourceBundleBaseName}</a> field.
|
||||||
|
*/
|
||||||
|
public static final String DESCRIPTION_RESOURCE_BUNDLE_BASE_NAME_FIELD =
|
||||||
|
"descriptionResourceBundleBaseName";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the <a href="Descriptor.html#descriptionResourceKey">{@code
|
||||||
|
* descriptionResourceKey}</a> field.
|
||||||
|
*/
|
||||||
|
public static final String DESCRIPTION_RESOURCE_KEY_FIELD =
|
||||||
|
"descriptionResourceKey";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of the <a href="Descriptor.html#immutableInfo">{@code
|
* The name of the <a href="Descriptor.html#immutableInfo">{@code
|
||||||
* immutableInfo}</a> field.
|
* immutableInfo}</a> field.
|
||||||
|
@ -78,6 +95,12 @@ public class JMX {
|
||||||
*/
|
*/
|
||||||
public static final String LEGAL_VALUES_FIELD = "legalValues";
|
public static final String LEGAL_VALUES_FIELD = "legalValues";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the <a href="Descriptor.html#locale">{@code locale}</a>
|
||||||
|
* field.
|
||||||
|
*/
|
||||||
|
public static final String LOCALE_FIELD = "locale";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of the <a href="Descriptor.html#maxValue">{@code
|
* The name of the <a href="Descriptor.html#maxValue">{@code
|
||||||
* maxValue}</a> field.
|
* maxValue}</a> field.
|
||||||
|
@ -120,13 +143,12 @@ public class JMX {
|
||||||
* <p>Options to apply to an MBean proxy or to an instance of {@link
|
* <p>Options to apply to an MBean proxy or to an instance of {@link
|
||||||
* StandardMBean}.</p>
|
* StandardMBean}.</p>
|
||||||
*
|
*
|
||||||
* <p>For example, to specify a custom {@link MXBeanMappingFactory}
|
* <p>For example, to specify the "wrapped object visible" option for a
|
||||||
* for a {@code StandardMBean}, you might write this:</p>
|
* {@code StandardMBean}, you might write this:</p>
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* MXBeanMappingFactory factory = new MyMXBeanMappingFactory();
|
* StandardMBean.Options opts = new StandardMBean.Options();
|
||||||
* JMX.MBeanOptions opts = new JMX.MBeanOptions();
|
* opts.setWrappedObjectVisible(true);
|
||||||
* opts.setMXBeanMappingFactory(factory);
|
|
||||||
* StandardMBean mbean = new StandardMBean(impl, intf, opts);
|
* StandardMBean mbean = new StandardMBean(impl, intf, opts);
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -808,4 +830,80 @@ public class JMX {
|
||||||
((DynamicWrapperMBean) mbean).getWrappedObject() : mbean;
|
((DynamicWrapperMBean) mbean).getWrappedObject() : mbean;
|
||||||
return (MBeanInjector.injectsSendNotification(resource));
|
return (MBeanInjector.injectsSendNotification(resource));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Return the version of the JMX specification that a (possibly remote)
|
||||||
|
* MBean Server is using. The JMX specification described in this
|
||||||
|
* documentation is version 2.0. The earlier versions that might be
|
||||||
|
* reported by this method are 1.0, 1.1, 1.2, and 1.4. (There is no 1.3.)
|
||||||
|
* All of these versions and all future versions can be compared using
|
||||||
|
* {@link String#compareTo(String)}. So, for example, to tell if
|
||||||
|
* {@code mbsc} is running at least version 2.0 you can write:</p>
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* String version = JMX.getSpecificationVersion(mbsc, null);
|
||||||
|
* boolean atLeast2dot0 = (version.compareTo("2.0") >= 0);
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* <p>A remote MBean Server might be running an earlier version of the
|
||||||
|
* JMX API, and in that case <a href="package-summary.html#interop">certain
|
||||||
|
* features</a> might not be available in it.</p>
|
||||||
|
*
|
||||||
|
* <p>The version of the MBean Server {@code mbsc} is not necessarily
|
||||||
|
* the version of all namespaces within that MBean Server, for example
|
||||||
|
* if some of them use {@link javax.management.namespace.JMXRemoteNamespace
|
||||||
|
* JMXRemoteNamespace}. To determine the version of the namespace
|
||||||
|
* that a particular MBean is in, give its name as the {@code mbeanName}
|
||||||
|
* parameter.</p>
|
||||||
|
*
|
||||||
|
* @param mbsc a connection to an MBean Server.
|
||||||
|
*
|
||||||
|
* @param mbeanName the name of an MBean within that MBean Server, or null.
|
||||||
|
* If non-null, the namespace of this name, as determined by
|
||||||
|
* {@link JMXNamespaces#getContainingNamespace
|
||||||
|
* JMXNamespaces.getContainingNamespace}, is the one whose specification
|
||||||
|
* version will be returned.
|
||||||
|
*
|
||||||
|
* @return the JMX specification version reported by that MBean Server.
|
||||||
|
*
|
||||||
|
* @throws IllegalArgumentException if {@code mbsc} is null, or if
|
||||||
|
* {@code mbeanName} includes a wildcard character ({@code *} or {@code ?})
|
||||||
|
* in its namespace.
|
||||||
|
*
|
||||||
|
* @throws IOException if the version cannot be obtained, either because
|
||||||
|
* there is a communication problem or because the remote MBean Server
|
||||||
|
* does not have the appropriate {@linkplain
|
||||||
|
* MBeanServerDelegateMBean#getSpecificationVersion() attribute}.
|
||||||
|
*
|
||||||
|
* @see <a href="package-summary.html#interop">Interoperability between
|
||||||
|
* versions of the JMX specification</a>
|
||||||
|
* @see MBeanServerDelegateMBean#getSpecificationVersion
|
||||||
|
*/
|
||||||
|
public static String getSpecificationVersion(
|
||||||
|
MBeanServerConnection mbsc, ObjectName mbeanName)
|
||||||
|
throws IOException {
|
||||||
|
if (mbsc == null)
|
||||||
|
throw new IllegalArgumentException("Null MBeanServerConnection");
|
||||||
|
|
||||||
|
String namespace;
|
||||||
|
if (mbeanName == null)
|
||||||
|
namespace = "";
|
||||||
|
else
|
||||||
|
namespace = JMXNamespaces.getContainingNamespace(mbeanName);
|
||||||
|
if (namespace.contains("*") || namespace.contains("?")) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"ObjectName contains namespace wildcard: " + mbeanName);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (namespace.length() > 0)
|
||||||
|
mbsc = JMXNamespaces.narrowToNamespace(mbsc, namespace);
|
||||||
|
return (String) mbsc.getAttribute(
|
||||||
|
MBeanServerDelegate.DELEGATE_NAME, "SpecificationVersion");
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw e;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IOException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
package javax.management;
|
package javax.management;
|
||||||
|
|
||||||
|
import com.sun.jmx.mbeanserver.Util;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.StreamCorruptedException;
|
import java.io.StreamCorruptedException;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
@ -37,6 +38,12 @@ import java.util.WeakHashMap;
|
||||||
import java.security.AccessController;
|
import java.security.AccessController;
|
||||||
import java.security.PrivilegedAction;
|
import java.security.PrivilegedAction;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.MissingResourceException;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
import static javax.management.ImmutableDescriptor.nonNullDescriptor;
|
import static javax.management.ImmutableDescriptor.nonNullDescriptor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -290,6 +297,7 @@ public class MBeanInfo implements Cloneable, Serializable, DescriptorRead {
|
||||||
* <p>Since this class is immutable, the clone method is chiefly of
|
* <p>Since this class is immutable, the clone method is chiefly of
|
||||||
* interest to subclasses.</p>
|
* interest to subclasses.</p>
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public Object clone () {
|
public Object clone () {
|
||||||
try {
|
try {
|
||||||
return super.clone() ;
|
return super.clone() ;
|
||||||
|
@ -474,6 +482,7 @@ public class MBeanInfo implements Cloneable, Serializable, DescriptorRead {
|
||||||
return (Descriptor) nonNullDescriptor(descriptor).clone();
|
return (Descriptor) nonNullDescriptor(descriptor).clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return
|
return
|
||||||
getClass().getName() + "[" +
|
getClass().getName() + "[" +
|
||||||
|
@ -505,6 +514,7 @@ public class MBeanInfo implements Cloneable, Serializable, DescriptorRead {
|
||||||
* @return true if and only if <code>o</code> is an MBeanInfo that is equal
|
* @return true if and only if <code>o</code> is an MBeanInfo that is equal
|
||||||
* to this one according to the rules above.
|
* to this one according to the rules above.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (o == this)
|
if (o == this)
|
||||||
return true;
|
return true;
|
||||||
|
@ -524,6 +534,7 @@ public class MBeanInfo implements Cloneable, Serializable, DescriptorRead {
|
||||||
Arrays.equals(p.fastGetNotifications(), fastGetNotifications()));
|
Arrays.equals(p.fastGetNotifications(), fastGetNotifications()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
/* Since computing the hashCode is quite expensive, we cache it.
|
/* Since computing the hashCode is quite expensive, we cache it.
|
||||||
If by some terrible misfortune the computed value is 0, the
|
If by some terrible misfortune the computed value is 0, the
|
||||||
|
@ -747,4 +758,377 @@ public class MBeanInfo implements Cloneable, Serializable, DescriptorRead {
|
||||||
throw new StreamCorruptedException("Got unexpected byte.");
|
throw new StreamCorruptedException("Got unexpected byte.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Return an {@code MBeanInfo} object that is the same as this one
|
||||||
|
* except that its descriptions are localized in the given locale.
|
||||||
|
* This means the text returned by {@link MBeanInfo#getDescription}
|
||||||
|
* (the description of the MBean itself), and the text returned by the
|
||||||
|
* {@link MBeanFeatureInfo#getDescription getDescription()} method
|
||||||
|
* for every {@linkplain MBeanAttributeInfo attribute}, {@linkplain
|
||||||
|
* MBeanOperationInfo operation}, {@linkplain MBeanConstructorInfo
|
||||||
|
* constructor}, and {@linkplain MBeanNotificationInfo notification}
|
||||||
|
* contained in the {@code MBeanInfo}.</p>
|
||||||
|
*
|
||||||
|
* <p>Here is how the description {@code this.getDescription()} is
|
||||||
|
* localized.</p>
|
||||||
|
*
|
||||||
|
* <p>First, if the {@linkplain #getDescriptor() descriptor}
|
||||||
|
* of this {@code MBeanInfo} contains a field <code><a
|
||||||
|
* href="Descriptor.html#locale">"locale"</a></code>, and the value of
|
||||||
|
* the field is the same as {@code locale.toString()}, then this {@code
|
||||||
|
* MBeanInfo} is returned. Otherwise, localization proceeds as follows,
|
||||||
|
* and the {@code "locale"} field in the returned {@code MBeanInfo} will
|
||||||
|
* be {@code locale.toString()}.
|
||||||
|
*
|
||||||
|
* <p>A <em>{@code className}</em> is determined. If this
|
||||||
|
* {@code MBeanInfo} contains a descriptor with the field
|
||||||
|
* <a href="Descriptor.html#interfaceClassName">{@code
|
||||||
|
* "interfaceClassName"}</a>, then the value of that field is the
|
||||||
|
* {@code className}. Otherwise, it is {@link #getClassName()}.
|
||||||
|
* Everything before the last period (.) in the {@code className} is
|
||||||
|
* the <em>{@code package}</em>, and everything after is the <em>{@code
|
||||||
|
* simpleClassName}</em>. (If there is no period, then the {@code package}
|
||||||
|
* is empty and the {@code simpleClassName} is the same as the {@code
|
||||||
|
* className}.)</p>
|
||||||
|
*
|
||||||
|
* <p>A <em>{@code resourceKey}</em> is determined. If this {@code
|
||||||
|
* MBeanInfo} contains a {@linkplain MBeanInfo#getDescriptor() descriptor}
|
||||||
|
* with a field {@link JMX#DESCRIPTION_RESOURCE_KEY_FIELD
|
||||||
|
* "descriptionResourceKey"}, the value of the field is
|
||||||
|
* the {@code resourceKey}. Otherwise, the {@code resourceKey} is {@code
|
||||||
|
* simpleClassName + ".mbean"}.</p>
|
||||||
|
*
|
||||||
|
* <p>A <em>{@code resourceBundleBaseName}</em> is determined. If
|
||||||
|
* this {@code MBeanInfo} contains a descriptor with a field {@link
|
||||||
|
* JMX#DESCRIPTION_RESOURCE_BUNDLE_BASE_NAME_FIELD
|
||||||
|
* "descriptionResourceBundleBaseName"}, the value of the field
|
||||||
|
* is the {@code resourceBundleBaseName}. Otherwise, the {@code
|
||||||
|
* resourceBundleBaseName} is {@code package + ".MBeanDescriptions"}.
|
||||||
|
*
|
||||||
|
* <p>Then, a {@link java.util.ResourceBundle ResourceBundle} is
|
||||||
|
* determined, using<br> {@link java.util.ResourceBundle#getBundle(String,
|
||||||
|
* Locale, ClassLoader) ResourceBundle.getBundle(resourceBundleBaseName,
|
||||||
|
* locale, loader)}. If this succeeds, and if {@link
|
||||||
|
* java.util.ResourceBundle#getString(String) getString(resourceKey)}
|
||||||
|
* returns a string, then that string is the localized description.
|
||||||
|
* Otherwise, the original description is unchanged.</p>
|
||||||
|
*
|
||||||
|
* <p>A localized description for an {@code MBeanAttributeInfo} is
|
||||||
|
* obtained similarly. The default {@code resourceBundleBaseName}
|
||||||
|
* is the same as above. The default description and the
|
||||||
|
* descriptor fields {@code "descriptionResourceKey"} and {@code
|
||||||
|
* "descriptionResourceBundleBaseName"} come from the {@code
|
||||||
|
* MBeanAttributeInfo} rather than the {@code MBeanInfo}. If the
|
||||||
|
* attribute's {@linkplain MBeanFeatureInfo#getName() name} is {@code
|
||||||
|
* Foo} then its default {@code resourceKey} is {@code simpleClassName +
|
||||||
|
* ".attribute.Foo"}.</p>
|
||||||
|
*
|
||||||
|
* <p>Similar rules apply for operations, constructors, and notifications.
|
||||||
|
* If the name of the operation, constructor, or notification is {@code
|
||||||
|
* Foo} then the default {@code resourceKey} is respectively {@code
|
||||||
|
* simpleClassName + ".operation.Foo"}, {@code simpleClassName +
|
||||||
|
* ".constructor.Foo"}, or {@code simpleClassName + ".notification.Foo"}.
|
||||||
|
* If two operations or constructors have the same name (overloading) then
|
||||||
|
* they have the same default {@code resourceKey}; if different localized
|
||||||
|
* descriptions are needed then a non-default key must be supplied using
|
||||||
|
* {@code "descriptionResourceKey"}.</p>
|
||||||
|
*
|
||||||
|
* <p>Similar rules also apply for descriptions of parameters ({@link
|
||||||
|
* MBeanParameterInfo}). The default {@code resourceKey} for a parameter
|
||||||
|
* whose {@linkplain MBeanFeatureInfo#getName() name} is {@code
|
||||||
|
* Bar} in an operation or constructor called {@code Foo} is {@code
|
||||||
|
* simpleClassName + ".operation.Foo.Bar"} or {@code simpleClassName +
|
||||||
|
* ".constructor.Foo.Bar"} respectively.</p>
|
||||||
|
*
|
||||||
|
* <h4>Example</h4>
|
||||||
|
*
|
||||||
|
* <p>Suppose you have an MBean defined by these two Java source files:</p>
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* // ConfigurationMBean.java
|
||||||
|
* package com.example;
|
||||||
|
* public interface ConfigurationMBean {
|
||||||
|
* public String getName();
|
||||||
|
* public void save(String fileName);
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // Configuration.java
|
||||||
|
* package com.example;
|
||||||
|
* public class Configuration implements ConfigurationMBean {
|
||||||
|
* public Configuration(String defaultName) {
|
||||||
|
* ...
|
||||||
|
* }
|
||||||
|
* ...
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* <p>Then you could define the default descriptions for the MBean, by
|
||||||
|
* including a resource bundle called {@code com/example/MBeanDescriptions}
|
||||||
|
* with the compiled classes. Most often this is done by creating a file
|
||||||
|
* {@code MBeanDescriptions.properties} in the same directory as {@code
|
||||||
|
* ConfigurationMBean.java}. Make sure that this file is copied into the
|
||||||
|
* same place as the compiled classes; in typical build environments that
|
||||||
|
* will be true by default.</p>
|
||||||
|
*
|
||||||
|
* <p>The file {@code com/example/MBeanDescriptions.properties} might
|
||||||
|
* look like this:</p>
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* # Description of the MBean
|
||||||
|
* ConfigurationMBean.mbean = Configuration manager
|
||||||
|
*
|
||||||
|
* # Description of the Name attribute
|
||||||
|
* ConfigurationMBean.attribute.Name = The name of the configuration
|
||||||
|
*
|
||||||
|
* # Description of the save operation
|
||||||
|
* ConfigurationMBean.operation.save = Save the configuration to a file
|
||||||
|
*
|
||||||
|
* # Description of the parameter to the save operation.
|
||||||
|
* # Parameter names from the original Java source are not available,
|
||||||
|
* # so the default names are p1, p2, etc. If the names were available,
|
||||||
|
* # this would be ConfigurationMBean.operation.save.fileName
|
||||||
|
* ConfigurationMBean.operation.save.p1 = The name of the file
|
||||||
|
*
|
||||||
|
* # Description of the constructor. The default name of a constructor is
|
||||||
|
* # its fully-qualified class name.
|
||||||
|
* ConfigurationMBean.constructor.com.example.Configuration = <!--
|
||||||
|
* -->Constructor with name of default file
|
||||||
|
* # Description of the constructor parameter.
|
||||||
|
* ConfigurationMBean.constructor.com.example.Configuration.p1 = <!--
|
||||||
|
* -->Name of the default file
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* <p>Starting with this file, you could create descriptions for the French
|
||||||
|
* locale by creating {@code com/example/MBeanDescriptions_fr.properties}.
|
||||||
|
* The keys in this file are the same as before but the text has been
|
||||||
|
* translated:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* ConfigurationMBean.mbean = Gestionnaire de configuration
|
||||||
|
*
|
||||||
|
* ConfigurationMBean.attribute.Name = Le nom de la configuration
|
||||||
|
*
|
||||||
|
* ConfigurationMBean.operation.save = Sauvegarder la configuration <!--
|
||||||
|
* -->dans un fichier
|
||||||
|
*
|
||||||
|
* ConfigurationMBean.operation.save.p1 = Le nom du fichier
|
||||||
|
*
|
||||||
|
* ConfigurationMBean.constructor.com.example.Configuration = <!--
|
||||||
|
* -->Constructeur avec nom du fichier par défaut
|
||||||
|
* ConfigurationMBean.constructor.com.example.Configuration.p1 = <!--
|
||||||
|
* -->Nom du fichier par défaut
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* <p>The descriptions in {@code MBeanDescriptions.properties} and
|
||||||
|
* {@code MBeanDescriptions_fr.properties} will only be consulted if
|
||||||
|
* {@code localizeDescriptions} is called, perhaps because the
|
||||||
|
* MBean Server has been wrapped by {@link
|
||||||
|
* ClientContext#newLocalizeMBeanInfoForwarder} or because the
|
||||||
|
* connector server has been created with the {@link
|
||||||
|
* javax.management.remote.JMXConnectorServer#LOCALIZE_MBEAN_INFO_FORWARDER
|
||||||
|
* LOCALIZE_MBEAN_INFO_FORWARDER} option. If you want descriptions
|
||||||
|
* even when there is no localization step, then you should consider
|
||||||
|
* using {@link Description @Description} annotations. Annotations
|
||||||
|
* provide descriptions by default but are overridden if {@code
|
||||||
|
* localizeDescriptions} is called.</p>
|
||||||
|
*
|
||||||
|
* @param locale the target locale for descriptions. Cannot be null.
|
||||||
|
*
|
||||||
|
* @param loader the {@code ClassLoader} to use for looking up resource
|
||||||
|
* bundles.
|
||||||
|
*
|
||||||
|
* @return an {@code MBeanInfo} with descriptions appropriately localized.
|
||||||
|
*
|
||||||
|
* @throws NullPointerException if {@code locale} is null.
|
||||||
|
*/
|
||||||
|
public MBeanInfo localizeDescriptions(Locale locale, ClassLoader loader) {
|
||||||
|
if (locale == null)
|
||||||
|
throw new NullPointerException("locale");
|
||||||
|
Descriptor d = getDescriptor();
|
||||||
|
String mbiLocaleString = (String) d.getFieldValue(JMX.LOCALE_FIELD);
|
||||||
|
if (locale.toString().equals(mbiLocaleString))
|
||||||
|
return this;
|
||||||
|
return new Rewriter(this, locale, loader).getMBeanInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Rewriter {
|
||||||
|
private final MBeanInfo mbi;
|
||||||
|
private final ClassLoader loader;
|
||||||
|
private final Locale locale;
|
||||||
|
private final String packageName;
|
||||||
|
private final String simpleClassNamePlusDot;
|
||||||
|
private ResourceBundle defaultBundle;
|
||||||
|
private boolean defaultBundleLoaded;
|
||||||
|
|
||||||
|
// ResourceBundle.getBundle throws NullPointerException
|
||||||
|
// if the loader is null, even though that is perfectly
|
||||||
|
// valid and means the bootstrap loader. So we work
|
||||||
|
// around with a ClassLoader that is equivalent to the
|
||||||
|
// bootstrap loader but is not null.
|
||||||
|
private static final ClassLoader bootstrapLoader =
|
||||||
|
new ClassLoader(null) {};
|
||||||
|
|
||||||
|
Rewriter(MBeanInfo mbi, Locale locale, ClassLoader loader) {
|
||||||
|
this.mbi = mbi;
|
||||||
|
this.locale = locale;
|
||||||
|
if (loader == null)
|
||||||
|
loader = bootstrapLoader;
|
||||||
|
this.loader = loader;
|
||||||
|
|
||||||
|
String intfName = (String)
|
||||||
|
mbi.getDescriptor().getFieldValue("interfaceClassName");
|
||||||
|
if (intfName == null)
|
||||||
|
intfName = mbi.getClassName();
|
||||||
|
int lastDot = intfName.lastIndexOf('.');
|
||||||
|
this.packageName = intfName.substring(0, lastDot + 1);
|
||||||
|
this.simpleClassNamePlusDot = intfName.substring(lastDot + 1) + ".";
|
||||||
|
// Inner classes show up as Outer$Inner so won't match the dot.
|
||||||
|
// When there is no dot, lastDot is -1,
|
||||||
|
// packageName is empty, and simpleClassNamePlusDot is intfName.
|
||||||
|
}
|
||||||
|
|
||||||
|
MBeanInfo getMBeanInfo() {
|
||||||
|
MBeanAttributeInfo[] mbais =
|
||||||
|
rewrite(mbi.getAttributes(), "attribute.");
|
||||||
|
MBeanOperationInfo[] mbois =
|
||||||
|
rewrite(mbi.getOperations(), "operation.");
|
||||||
|
MBeanConstructorInfo[] mbcis =
|
||||||
|
rewrite(mbi.getConstructors(), "constructor.");
|
||||||
|
MBeanNotificationInfo[] mbnis =
|
||||||
|
rewrite(mbi.getNotifications(), "notification.");
|
||||||
|
Descriptor d = mbi.getDescriptor();
|
||||||
|
d = changeLocale(d);
|
||||||
|
String description = getDescription(d, "mbean", "");
|
||||||
|
if (description == null)
|
||||||
|
description = mbi.getDescription();
|
||||||
|
return new MBeanInfo(
|
||||||
|
mbi.getClassName(), description,
|
||||||
|
mbais, mbcis, mbois, mbnis, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Descriptor changeLocale(Descriptor d) {
|
||||||
|
if (d.getFieldValue(JMX.LOCALE_FIELD) != null) {
|
||||||
|
Map<String, Object> map = new HashMap<String, Object>();
|
||||||
|
for (String field : d.getFieldNames())
|
||||||
|
map.put(field, d.getFieldValue(field));
|
||||||
|
map.remove(JMX.LOCALE_FIELD);
|
||||||
|
d = new ImmutableDescriptor(map);
|
||||||
|
}
|
||||||
|
return ImmutableDescriptor.union(
|
||||||
|
d, new ImmutableDescriptor(JMX.LOCALE_FIELD + "=" + locale));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getDescription(
|
||||||
|
Descriptor d, String defaultPrefix, String defaultSuffix) {
|
||||||
|
ResourceBundle bundle = bundleFromDescriptor(d);
|
||||||
|
if (bundle == null)
|
||||||
|
return null;
|
||||||
|
String key =
|
||||||
|
(String) d.getFieldValue(JMX.DESCRIPTION_RESOURCE_KEY_FIELD);
|
||||||
|
if (key == null)
|
||||||
|
key = simpleClassNamePlusDot + defaultPrefix + defaultSuffix;
|
||||||
|
return descriptionFromResource(bundle, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T extends MBeanFeatureInfo> T[] rewrite(
|
||||||
|
T[] features, String resourcePrefix) {
|
||||||
|
for (int i = 0; i < features.length; i++) {
|
||||||
|
T feature = features[i];
|
||||||
|
Descriptor d = feature.getDescriptor();
|
||||||
|
String description =
|
||||||
|
getDescription(d, resourcePrefix, feature.getName());
|
||||||
|
if (description != null &&
|
||||||
|
!description.equals(feature.getDescription())) {
|
||||||
|
features[i] = setDescription(feature, description);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return features;
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T extends MBeanFeatureInfo> T setDescription(
|
||||||
|
T feature, String description) {
|
||||||
|
|
||||||
|
Object newf;
|
||||||
|
String name = feature.getName();
|
||||||
|
Descriptor d = feature.getDescriptor();
|
||||||
|
|
||||||
|
if (feature instanceof MBeanAttributeInfo) {
|
||||||
|
MBeanAttributeInfo mbai = (MBeanAttributeInfo) feature;
|
||||||
|
newf = new MBeanAttributeInfo(
|
||||||
|
name, mbai.getType(), description,
|
||||||
|
mbai.isReadable(), mbai.isWritable(), mbai.isIs(),
|
||||||
|
d);
|
||||||
|
} else if (feature instanceof MBeanOperationInfo) {
|
||||||
|
MBeanOperationInfo mboi = (MBeanOperationInfo) feature;
|
||||||
|
MBeanParameterInfo[] sig = rewrite(
|
||||||
|
mboi.getSignature(), "operation." + name + ".");
|
||||||
|
newf = new MBeanOperationInfo(
|
||||||
|
name, description, sig,
|
||||||
|
mboi.getReturnType(), mboi.getImpact(), d);
|
||||||
|
} else if (feature instanceof MBeanConstructorInfo) {
|
||||||
|
MBeanConstructorInfo mbci = (MBeanConstructorInfo) feature;
|
||||||
|
MBeanParameterInfo[] sig = rewrite(
|
||||||
|
mbci.getSignature(), "constructor." + name + ".");
|
||||||
|
newf = new MBeanConstructorInfo(
|
||||||
|
name, description, sig, d);
|
||||||
|
} else if (feature instanceof MBeanNotificationInfo) {
|
||||||
|
MBeanNotificationInfo mbni = (MBeanNotificationInfo) feature;
|
||||||
|
newf = new MBeanNotificationInfo(
|
||||||
|
mbni.getNotifTypes(), name, description, d);
|
||||||
|
} else if (feature instanceof MBeanParameterInfo) {
|
||||||
|
MBeanParameterInfo mbpi = (MBeanParameterInfo) feature;
|
||||||
|
newf = new MBeanParameterInfo(
|
||||||
|
name, mbpi.getType(), description, d);
|
||||||
|
} else {
|
||||||
|
logger().log(Level.FINE, "Unknown feature type: " +
|
||||||
|
feature.getClass());
|
||||||
|
newf = feature;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Util.<T>cast(newf);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResourceBundle bundleFromDescriptor(Descriptor d) {
|
||||||
|
String bundleName = (String) d.getFieldValue(
|
||||||
|
JMX.DESCRIPTION_RESOURCE_BUNDLE_BASE_NAME_FIELD);
|
||||||
|
|
||||||
|
if (bundleName != null)
|
||||||
|
return getBundle(bundleName);
|
||||||
|
|
||||||
|
if (defaultBundleLoaded)
|
||||||
|
return defaultBundle;
|
||||||
|
|
||||||
|
bundleName = packageName + "MBeanDescriptions";
|
||||||
|
defaultBundle = getBundle(bundleName);
|
||||||
|
defaultBundleLoaded = true;
|
||||||
|
return defaultBundle;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String descriptionFromResource(
|
||||||
|
ResourceBundle bundle, String key) {
|
||||||
|
try {
|
||||||
|
return bundle.getString(key);
|
||||||
|
} catch (MissingResourceException e) {
|
||||||
|
logger().log(Level.FINEST, "No resource for " + key, e);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger().log(Level.FINE, "Bad resource for " + key, e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResourceBundle getBundle(String name) {
|
||||||
|
try {
|
||||||
|
return ResourceBundle.getBundle(name, locale, loader);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger().log(Level.FINE,
|
||||||
|
"Could not load ResourceBundle " + name, e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Logger logger() {
|
||||||
|
return Logger.getLogger("javax.management.locale");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -532,8 +532,30 @@ public interface MBeanServerConnection extends NotificationManager {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables the values of several attributes of a named MBean. The MBean
|
* <p>Retrieves the values of several attributes of a named MBean. The MBean
|
||||||
* is identified by its object name.
|
* is identified by its object name.</p>
|
||||||
|
*
|
||||||
|
* <p>If one or more attributes cannot be retrieved for some reason, they
|
||||||
|
* will be omitted from the returned {@code AttributeList}. The caller
|
||||||
|
* should check that the list is the same size as the {@code attributes}
|
||||||
|
* array. To discover what problem prevented a given attribute from being
|
||||||
|
* retrieved, call {@link #getAttribute getAttribute} for that attribute.</p>
|
||||||
|
*
|
||||||
|
* <p>Here is an example of calling this method and checking that it
|
||||||
|
* succeeded in retrieving all the requested attributes:</p>
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* String[] attrNames = ...;
|
||||||
|
* AttributeList list = mbeanServerConnection.getAttributes(objectName, attrNames);
|
||||||
|
* if (list.size() == attrNames.length)
|
||||||
|
* System.out.println("All attributes were retrieved successfully");
|
||||||
|
* else {
|
||||||
|
* {@code List<String>} missing = new {@code ArrayList<String>}(<!--
|
||||||
|
* -->{@link java.util.Arrays#asList Arrays.asList}(attrNames));
|
||||||
|
* missing.removeAll(list.toMap().keySet());
|
||||||
|
* System.out.println("Did not retrieve: " + missing);
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
*
|
*
|
||||||
* @param name The object name of the MBean from which the
|
* @param name The object name of the MBean from which the
|
||||||
* attributes are retrieved.
|
* attributes are retrieved.
|
||||||
|
@ -557,6 +579,7 @@ public interface MBeanServerConnection extends NotificationManager {
|
||||||
throws InstanceNotFoundException, ReflectionException,
|
throws InstanceNotFoundException, ReflectionException,
|
||||||
IOException;
|
IOException;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the value of a specific attribute of a named MBean. The MBean
|
* Sets the value of a specific attribute of a named MBean. The MBean
|
||||||
* is identified by its object name.
|
* is identified by its object name.
|
||||||
|
@ -592,10 +615,36 @@ public interface MBeanServerConnection extends NotificationManager {
|
||||||
ReflectionException, IOException;
|
ReflectionException, IOException;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the values of several attributes of a named MBean. The MBean is
|
* <p>Sets the values of several attributes of a named MBean. The MBean is
|
||||||
* identified by its object name.
|
* identified by its object name.</p>
|
||||||
|
*
|
||||||
|
* <p>If one or more attributes cannot be set for some reason, they will be
|
||||||
|
* omitted from the returned {@code AttributeList}. The caller should check
|
||||||
|
* that the input {@code AttributeList} is the same size as the output one.
|
||||||
|
* To discover what problem prevented a given attribute from being retrieved,
|
||||||
|
* it will usually be possible to call {@link #setAttribute setAttribute}
|
||||||
|
* for that attribute, although this is not guaranteed to work. (For
|
||||||
|
* example, the values of two attributes may have been rejected because
|
||||||
|
* they were inconsistent with each other. Setting one of them alone might
|
||||||
|
* be allowed.)<p>
|
||||||
|
*
|
||||||
|
* <p>Here is an example of calling this method and checking that it
|
||||||
|
* succeeded in setting all the requested attributes:</p>
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* AttributeList inputAttrs = ...;
|
||||||
|
* AttributeList outputAttrs = mbeanServerConnection.setAttributes(<!--
|
||||||
|
* -->objectName, inputAttrs);
|
||||||
|
* if (inputAttrs.size() == outputAttrs.size())
|
||||||
|
* System.out.println("All attributes were set successfully");
|
||||||
|
* else {
|
||||||
|
* {@code List<String>} missing = new {@code ArrayList<String>}(<!--
|
||||||
|
* -->inputAttrs.toMap().keySet());
|
||||||
|
* missing.removeAll(outputAttrs.toMap().keySet());
|
||||||
|
* System.out.println("Did not set: " + missing);
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
*
|
*
|
||||||
* @param name The object name of the MBean within which the
|
* @param name The object name of the MBean within which the
|
||||||
* attributes are to be set.
|
* attributes are to be set.
|
||||||
|
@ -622,7 +671,39 @@ public interface MBeanServerConnection extends NotificationManager {
|
||||||
throws InstanceNotFoundException, ReflectionException, IOException;
|
throws InstanceNotFoundException, ReflectionException, IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invokes an operation on an MBean.
|
* <p>Invokes an operation on an MBean.</p>
|
||||||
|
*
|
||||||
|
* <p>Because of the need for a {@code signature} to differentiate
|
||||||
|
* possibly-overloaded operations, it is much simpler to invoke operations
|
||||||
|
* through an {@linkplain JMX#newMBeanProxy(MBeanServerConnection, ObjectName,
|
||||||
|
* Class) MBean proxy} where possible. For example, suppose you have a
|
||||||
|
* Standard MBean interface like this:</p>
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* public interface FooMBean {
|
||||||
|
* public int countMatches(String[] patterns, boolean ignoreCase);
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* <p>The {@code countMatches} operation can be invoked as follows:</p>
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* String[] myPatterns = ...;
|
||||||
|
* int count = (Integer) mbeanServerConnection.invoke(
|
||||||
|
* objectName,
|
||||||
|
* "countMatches",
|
||||||
|
* new Object[] {myPatterns, true},
|
||||||
|
* new String[] {String[].class.getName(), boolean.class.getName()});
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* <p>Alternatively, it can be invoked through a proxy as follows:</p>
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* String[] myPatterns = ...;
|
||||||
|
* FooMBean fooProxy = JMX.newMBeanProxy(
|
||||||
|
* mbeanServerConnection, objectName, FooMBean.class);
|
||||||
|
* int count = fooProxy.countMatches(myPatterns, true);
|
||||||
|
* </pre>
|
||||||
*
|
*
|
||||||
* @param name The object name of the MBean on which the method is
|
* @param name The object name of the MBean on which the method is
|
||||||
* to be invoked.
|
* to be invoked.
|
||||||
|
@ -630,7 +711,8 @@ public interface MBeanServerConnection extends NotificationManager {
|
||||||
* @param params An array containing the parameters to be set when
|
* @param params An array containing the parameters to be set when
|
||||||
* the operation is invoked
|
* the operation is invoked
|
||||||
* @param signature An array containing the signature of the
|
* @param signature An array containing the signature of the
|
||||||
* operation. The class objects will be loaded using the same
|
* operation, an array of class names in the format returned by
|
||||||
|
* {@link Class#getName()}. The class objects will be loaded using the same
|
||||||
* class loader as the one used for loading the MBean on which the
|
* class loader as the one used for loading the MBean on which the
|
||||||
* operation was invoked.
|
* operation was invoked.
|
||||||
*
|
*
|
||||||
|
|
|
@ -27,15 +27,70 @@ package javax.management;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a notification emitted by the MBean server through the MBeanServerDelegate MBean.
|
* Represents a notification emitted by the MBean Server through the MBeanServerDelegate MBean.
|
||||||
* The MBean Server emits the following types of notifications: MBean registration, MBean
|
* The MBean Server emits the following types of notifications: MBean registration, MBean
|
||||||
* de-registration.
|
* unregistration.
|
||||||
* <P>
|
* <P>
|
||||||
* To receive to MBeanServerNotifications, you need to be declared as listener to
|
* To receive MBeanServerNotifications, you need to register a listener with
|
||||||
* the {@link javax.management.MBeanServerDelegate javax.management.MBeanServerDelegate} MBean
|
* the {@link MBeanServerDelegate MBeanServerDelegate} MBean
|
||||||
* that represents the MBeanServer. The ObjectName of the MBeanServerDelegate is:
|
* that represents the MBeanServer. The ObjectName of the MBeanServerDelegate is
|
||||||
|
* {@link MBeanServerDelegate#DELEGATE_NAME}, which is
|
||||||
* <CODE>JMImplementation:type=MBeanServerDelegate</CODE>.
|
* <CODE>JMImplementation:type=MBeanServerDelegate</CODE>.
|
||||||
*
|
*
|
||||||
|
* <p>The following code prints a message every time an MBean is registered
|
||||||
|
* or unregistered in the MBean Server {@code mbeanServer}:</p>
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* private static final NotificationListener printListener = new NotificationListener() {
|
||||||
|
* public void handleNotification(Notification n, Object handback) {
|
||||||
|
* if (!(n instanceof MBeanServerNotification)) {
|
||||||
|
* System.out.println("Ignored notification of class " + n.getClass().getName());
|
||||||
|
* return;
|
||||||
|
* }
|
||||||
|
* MBeanServerNotification mbsn = (MBeanServerNotification) n;
|
||||||
|
* String what;
|
||||||
|
* if (n.getType().equals(MBeanServerNotification.REGISTRATION_NOTIFICATION))
|
||||||
|
* what = "MBean registered";
|
||||||
|
* else if (n.getType().equals(MBeanServerNotification.UNREGISTRATION_NOTIFICATION))
|
||||||
|
* what = "MBean unregistered";
|
||||||
|
* else
|
||||||
|
* what = "Unknown type " + n.getType();
|
||||||
|
* System.out.println("Received MBean Server notification: " + what + ": " +
|
||||||
|
* mbsn.getMBeanName());
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* ...
|
||||||
|
* mbeanServer.addNotificationListener(
|
||||||
|
* MBeanServerDelegate.DELEGATE_NAME, printListener, null, null);
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* <p>The following code prints a message every time an MBean is registered
|
||||||
|
* or unregistered in the MBean Server {@code mbeanServer}:</p>
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* private static final NotificationListener printListener = new NotificationListener() {
|
||||||
|
* public void handleNotification(Notification n, Object handback) {
|
||||||
|
* if (!(n instanceof MBeanServerNotification)) {
|
||||||
|
* System.out.println("Ignored notification of class " + n.getClass().getName());
|
||||||
|
* return;
|
||||||
|
* }
|
||||||
|
* MBeanServerNotification mbsn = (MBeanServerNotification) n;
|
||||||
|
* String what;
|
||||||
|
* if (n.getType().equals(MBeanServerNotification.REGISTRATION_NOTIFICATION))
|
||||||
|
* what = "MBean registered";
|
||||||
|
* else if (n.getType().equals(MBeanServerNotification.UNREGISTRATION_NOTIFICATION))
|
||||||
|
* what = "MBean unregistered";
|
||||||
|
* else
|
||||||
|
* what = "Unknown type " + n.getType();
|
||||||
|
* System.out.println("Received MBean Server notification: " + what + ": " +
|
||||||
|
* mbsn.getMBeanName());
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* ...
|
||||||
|
* mbeanServer.addNotificationListener(
|
||||||
|
* MBeanServerDelegate.DELEGATE_NAME, printListener, null, null);
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public class MBeanServerNotification extends Notification {
|
public class MBeanServerNotification extends Notification {
|
||||||
|
|
|
@ -54,7 +54,7 @@ import com.sun.jmx.mbeanserver.GetPropertyAction;
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("serial") // serialVersionUID is not constant
|
@SuppressWarnings("serial") // serialVersionUID is not constant
|
||||||
public class Notification extends EventObject {
|
public class Notification extends EventObject implements Cloneable {
|
||||||
|
|
||||||
// Serialization compatibility stuff:
|
// Serialization compatibility stuff:
|
||||||
// Two serial forms are supported in this class. The selected form depends
|
// Two serial forms are supported in this class. The selected form depends
|
||||||
|
@ -243,6 +243,26 @@ public class Notification extends EventObject {
|
||||||
this.message = message ;
|
this.message = message ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Creates and returns a copy of this object. The copy is created as
|
||||||
|
* described for {@link Object#clone()}. This means, first, that the
|
||||||
|
* class of the object will be the same as the class of this object, and,
|
||||||
|
* second, that the copy is a "shallow copy". Fields of this notification
|
||||||
|
* are not themselves copied. In particular, the {@linkplain
|
||||||
|
* #getUserData user data} of the copy is the same object as the
|
||||||
|
* original.</p>
|
||||||
|
*
|
||||||
|
* @return a copy of this object.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Object clone() {
|
||||||
|
try {
|
||||||
|
return super.clone();
|
||||||
|
} catch (CloneNotSupportedException e) {
|
||||||
|
throw new AssertionError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the source.
|
* Sets the source.
|
||||||
*
|
*
|
||||||
|
@ -285,8 +305,10 @@ public class Notification extends EventObject {
|
||||||
/**
|
/**
|
||||||
* Get the notification type.
|
* Get the notification type.
|
||||||
*
|
*
|
||||||
* @return The notification type. It's a string expressed in a dot notation similar
|
* @return The notification type. It's a string expressed in a dot notation
|
||||||
* to Java properties. An example of a notification type is network.alarm.router .
|
* similar to Java properties. It is recommended that the notification type
|
||||||
|
* should follow the reverse-domain-name convention used by Java package
|
||||||
|
* names. An example of a notification type is com.example.alarm.router.
|
||||||
*/
|
*/
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return type ;
|
return type ;
|
||||||
|
@ -317,14 +339,25 @@ public class Notification extends EventObject {
|
||||||
/**
|
/**
|
||||||
* Get the notification message.
|
* Get the notification message.
|
||||||
*
|
*
|
||||||
* @return The message string of this notification object. It contains in a string,
|
* @return The message string of this notification object.
|
||||||
* which could be the explanation of the notification for displaying to a user
|
|
||||||
*
|
*
|
||||||
|
* @see #setMessage
|
||||||
*/
|
*/
|
||||||
public String getMessage() {
|
public String getMessage() {
|
||||||
return message ;
|
return message ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the notification message.
|
||||||
|
*
|
||||||
|
* @param message the new notification message.
|
||||||
|
*
|
||||||
|
* @see #getMessage
|
||||||
|
*/
|
||||||
|
public void setMessage(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the user data.
|
* Get the user data.
|
||||||
*
|
*
|
||||||
|
@ -355,6 +388,7 @@ public class Notification extends EventObject {
|
||||||
*
|
*
|
||||||
* @return A String representation of this notification.
|
* @return A String representation of this notification.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return super.toString()+"[type="+type+"][message="+message+"]";
|
return super.toString()+"[type="+type+"][message="+message+"]";
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
package javax.management;
|
package javax.management;
|
||||||
|
|
||||||
import com.sun.jmx.mbeanserver.NotificationMBeanSupport;
|
import com.sun.jmx.mbeanserver.NotificationMBeanSupport;
|
||||||
import com.sun.jmx.mbeanserver.Util;
|
|
||||||
import java.lang.reflect.InvocationHandler;
|
import java.lang.reflect.InvocationHandler;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
@ -43,6 +42,11 @@ import java.util.Set;
|
||||||
* on both the client and the server in the remote case, so using this class
|
* on both the client and the server in the remote case, so using this class
|
||||||
* instead is recommended where possible.</p>
|
* instead is recommended where possible.</p>
|
||||||
*
|
*
|
||||||
|
* <p>Because this class was introduced in version 2.0 of the JMX API,
|
||||||
|
* it may not be present on a remote JMX agent that is running an earlier
|
||||||
|
* version. The method {@link JMX#getSpecificationVersion
|
||||||
|
* JMX.getSpecificationVersion} can be used to determine the remote version.</p>
|
||||||
|
*
|
||||||
* <p>This class uses the {@linkplain Query Query API} to specify the
|
* <p>This class uses the {@linkplain Query Query API} to specify the
|
||||||
* filtering logic. For example, to select only notifications where the
|
* filtering logic. For example, to select only notifications where the
|
||||||
* {@linkplain Notification#getType() type} is {@code "com.example.mytype"},
|
* {@linkplain Notification#getType() type} is {@code "com.example.mytype"},
|
||||||
|
|
|
@ -29,7 +29,6 @@ import com.sun.jmx.event.DaemonThreadFactory;
|
||||||
import com.sun.jmx.event.LeaseRenewer;
|
import com.sun.jmx.event.LeaseRenewer;
|
||||||
import com.sun.jmx.event.ReceiverBuffer;
|
import com.sun.jmx.event.ReceiverBuffer;
|
||||||
import com.sun.jmx.event.RepeatedSingletonJob;
|
import com.sun.jmx.event.RepeatedSingletonJob;
|
||||||
import com.sun.jmx.namespace.JMXNamespaceUtils;
|
|
||||||
import com.sun.jmx.mbeanserver.PerThreadGroupPool;
|
import com.sun.jmx.mbeanserver.PerThreadGroupPool;
|
||||||
import com.sun.jmx.remote.util.ClassLogger;
|
import com.sun.jmx.remote.util.ClassLogger;
|
||||||
|
|
||||||
|
@ -58,7 +57,6 @@ import javax.management.NotificationBroadcasterSupport;
|
||||||
import javax.management.NotificationFilter;
|
import javax.management.NotificationFilter;
|
||||||
import javax.management.NotificationListener;
|
import javax.management.NotificationListener;
|
||||||
import javax.management.ObjectName;
|
import javax.management.ObjectName;
|
||||||
import javax.management.remote.JMXConnector;
|
|
||||||
import javax.management.remote.NotificationResult;
|
import javax.management.remote.NotificationResult;
|
||||||
import javax.management.remote.TargetedNotification;
|
import javax.management.remote.TargetedNotification;
|
||||||
|
|
||||||
|
@ -129,11 +127,12 @@ public class EventClient implements EventConsumer, NotificationManager {
|
||||||
public static final String NOTIFS_LOST = "jmx.event.service.notifs.lost";
|
public static final String NOTIFS_LOST = "jmx.event.service.notifs.lost";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default lease time, {@value}, in milliseconds.
|
* The default lease time that EventClient instances will request, in
|
||||||
|
* milliseconds. This value is {@value}.
|
||||||
*
|
*
|
||||||
* @see EventClientDelegateMBean#lease
|
* @see EventClientDelegateMBean#lease
|
||||||
*/
|
*/
|
||||||
public static final long DEFAULT_LEASE_TIMEOUT = 300000;
|
public static final long DEFAULT_REQUESTED_LEASE_TIME = 300000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Constructs a default {@code EventClient} object.</p>
|
* <p>Constructs a default {@code EventClient} object.</p>
|
||||||
|
@ -173,7 +172,7 @@ public class EventClient implements EventConsumer, NotificationManager {
|
||||||
*/
|
*/
|
||||||
public EventClient(EventClientDelegateMBean delegate)
|
public EventClient(EventClientDelegateMBean delegate)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
this(delegate, null, null, null, DEFAULT_LEASE_TIMEOUT);
|
this(delegate, null, null, null, DEFAULT_REQUESTED_LEASE_TIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -196,7 +195,7 @@ public class EventClient implements EventConsumer, NotificationManager {
|
||||||
* If {@code null}, a default scheduler will be used.
|
* If {@code null}, a default scheduler will be used.
|
||||||
* @param requestedLeaseTime The lease time used to keep this client alive
|
* @param requestedLeaseTime The lease time used to keep this client alive
|
||||||
* in the {@link EventClientDelegateMBean}. A value of zero is equivalent
|
* in the {@link EventClientDelegateMBean}. A value of zero is equivalent
|
||||||
* to the {@linkplain #DEFAULT_LEASE_TIMEOUT default value}.
|
* to the {@linkplain #DEFAULT_REQUESTED_LEASE_TIME default value}.
|
||||||
*
|
*
|
||||||
* @throws IllegalArgumentException If {@code delegate} is null.
|
* @throws IllegalArgumentException If {@code delegate} is null.
|
||||||
* @throws IOException If an I/O error occurs when communicating with the
|
* @throws IOException If an I/O error occurs when communicating with the
|
||||||
|
@ -213,7 +212,7 @@ public class EventClient implements EventConsumer, NotificationManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (requestedLeaseTime == 0)
|
if (requestedLeaseTime == 0)
|
||||||
requestedLeaseTime = DEFAULT_LEASE_TIMEOUT;
|
requestedLeaseTime = DEFAULT_REQUESTED_LEASE_TIME;
|
||||||
else if (requestedLeaseTime < 0) {
|
else if (requestedLeaseTime < 0) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Negative lease time: " + requestedLeaseTime);
|
"Negative lease time: " + requestedLeaseTime);
|
||||||
|
@ -269,7 +268,13 @@ public class EventClient implements EventConsumer, NotificationManager {
|
||||||
new ScheduledThreadPoolExecutor(20, daemonThreadFactory);
|
new ScheduledThreadPoolExecutor(20, daemonThreadFactory);
|
||||||
executor.setKeepAliveTime(1, TimeUnit.SECONDS);
|
executor.setKeepAliveTime(1, TimeUnit.SECONDS);
|
||||||
executor.allowCoreThreadTimeOut(true);
|
executor.allowCoreThreadTimeOut(true);
|
||||||
executor.setRemoveOnCancelPolicy(true);
|
if (setRemoveOnCancelPolicy != null) {
|
||||||
|
try {
|
||||||
|
setRemoveOnCancelPolicy.invoke(executor, true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.trace("setRemoveOnCancelPolicy", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
// By default, a ScheduledThreadPoolExecutor will keep jobs
|
// By default, a ScheduledThreadPoolExecutor will keep jobs
|
||||||
// in its queue even after they have been cancelled. They
|
// in its queue even after they have been cancelled. They
|
||||||
// will only be removed when their scheduled time arrives.
|
// will only be removed when their scheduled time arrives.
|
||||||
|
@ -277,12 +282,25 @@ public class EventClient implements EventConsumer, NotificationManager {
|
||||||
// this EventClient, this can lead to a moderately large number
|
// this EventClient, this can lead to a moderately large number
|
||||||
// of objects remaining referenced until the renewal time
|
// of objects remaining referenced until the renewal time
|
||||||
// arrives. Hence the above call, which removes the job from
|
// arrives. Hence the above call, which removes the job from
|
||||||
// the queue as soon as it is cancelled.
|
// the queue as soon as it is cancelled. Since the call is
|
||||||
|
// new with JDK 7, we invoke it via reflection to make it
|
||||||
|
// easier to use this code on JDK 6.
|
||||||
return executor;
|
return executor;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return leaseRenewerThreadPool.getThreadPoolExecutor(create);
|
return leaseRenewerThreadPool.getThreadPoolExecutor(create);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Method setRemoveOnCancelPolicy;
|
||||||
|
static {
|
||||||
|
Method m;
|
||||||
|
try {
|
||||||
|
m = ScheduledThreadPoolExecutor.class.getMethod(
|
||||||
|
"setRemoveOnCancelPolicy", boolean.class);
|
||||||
|
} catch (Exception e) {
|
||||||
|
m = null;
|
||||||
|
}
|
||||||
|
setRemoveOnCancelPolicy = m;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1042,7 +1060,7 @@ public class EventClient implements EventConsumer, NotificationManager {
|
||||||
final public EventClient call() throws Exception {
|
final public EventClient call() throws Exception {
|
||||||
EventClientDelegateMBean ecd = EventClientDelegate.getProxy(conn);
|
EventClientDelegateMBean ecd = EventClientDelegate.getProxy(conn);
|
||||||
return new EventClient(ecd, eventRelay, null, null,
|
return new EventClient(ecd, eventRelay, null, null,
|
||||||
DEFAULT_LEASE_TIMEOUT);
|
DEFAULT_REQUESTED_LEASE_TIME);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1080,24 +1098,6 @@ public class EventClient implements EventConsumer, NotificationManager {
|
||||||
return clientId;
|
return clientId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a JMX Connector that will use an {@link EventClient}
|
|
||||||
* to subscribe for notifications. If the server doesn't have
|
|
||||||
* an {@link EventClientDelegateMBean}, then the connector will
|
|
||||||
* use the legacy notification mechanism instead.
|
|
||||||
*
|
|
||||||
* @param wrapped The underlying JMX Connector wrapped by the returned
|
|
||||||
* connector.
|
|
||||||
*
|
|
||||||
* @return A JMX Connector that will uses an {@link EventClient}, if
|
|
||||||
* available.
|
|
||||||
*
|
|
||||||
* @see EventClient#getEventClientConnection(MBeanServerConnection)
|
|
||||||
*/
|
|
||||||
public static JMXConnector withEventClient(final JMXConnector wrapped) {
|
|
||||||
return JMXNamespaceUtils.withEventClient(wrapped);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final PerThreadGroupPool<ScheduledThreadPoolExecutor>
|
private static final PerThreadGroupPool<ScheduledThreadPoolExecutor>
|
||||||
leaseRenewerThreadPool = PerThreadGroupPool.make();
|
leaseRenewerThreadPool = PerThreadGroupPool.make();
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,6 +149,7 @@ public class EventClientDelegate implements EventClientDelegateMBean {
|
||||||
// of a setMBeanServer on some other forwarder later in the chain.
|
// of a setMBeanServer on some other forwarder later in the chain.
|
||||||
|
|
||||||
private static class Forwarder extends SingleMBeanForwarder {
|
private static class Forwarder extends SingleMBeanForwarder {
|
||||||
|
private MBeanServer loopMBS;
|
||||||
|
|
||||||
private static class UnsupportedInvocationHandler
|
private static class UnsupportedInvocationHandler
|
||||||
implements InvocationHandler {
|
implements InvocationHandler {
|
||||||
|
@ -173,7 +174,11 @@ public class EventClientDelegate implements EventClientDelegateMBean {
|
||||||
private volatile boolean madeECD;
|
private volatile boolean madeECD;
|
||||||
|
|
||||||
Forwarder() {
|
Forwarder() {
|
||||||
super(OBJECT_NAME, makeUnsupportedECD());
|
super(OBJECT_NAME, makeUnsupportedECD(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized void setLoopMBS(MBeanServer loopMBS) {
|
||||||
|
this.loopMBS = loopMBS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -186,7 +191,7 @@ public class EventClientDelegate implements EventClientDelegateMBean {
|
||||||
AccessController.doPrivileged(
|
AccessController.doPrivileged(
|
||||||
new PrivilegedAction<EventClientDelegate>() {
|
new PrivilegedAction<EventClientDelegate>() {
|
||||||
public EventClientDelegate run() {
|
public EventClientDelegate run() {
|
||||||
return getEventClientDelegate(Forwarder.this);
|
return getEventClientDelegate(loopMBS);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
DynamicMBean mbean = new StandardMBean(
|
DynamicMBean mbean = new StandardMBean(
|
||||||
|
@ -208,11 +213,46 @@ public class EventClientDelegate implements EventClientDelegateMBean {
|
||||||
* that are targeted for that MBean and handles them itself. All other
|
* that are targeted for that MBean and handles them itself. All other
|
||||||
* requests are forwarded to the next element in the forwarder chain.</p>
|
* requests are forwarded to the next element in the forwarder chain.</p>
|
||||||
*
|
*
|
||||||
|
* @param nextMBS the next {@code MBeanServer} in the chain of forwarders,
|
||||||
|
* which might be another {@code MBeanServerForwarder} or a plain {@code
|
||||||
|
* MBeanServer}. This is the object to which {@code MBeanServer} requests
|
||||||
|
* that do not concern the {@code EventClientDelegateMBean} are sent.
|
||||||
|
* It will be the value of {@link MBeanServerForwarder#getMBeanServer()
|
||||||
|
* getMBeanServer()} on the returned object, and can be changed with {@link
|
||||||
|
* MBeanServerForwarder#setMBeanServer setMBeanServer}. It can be null but
|
||||||
|
* must be set to a non-null value before any {@code MBeanServer} requests
|
||||||
|
* arrive.
|
||||||
|
*
|
||||||
|
* @param loopMBS the {@code MBeanServer} to which requests from the
|
||||||
|
* {@code EventClientDelegateMBean} should be sent. For example,
|
||||||
|
* when you invoke the {@link EventClientDelegateMBean#addListener
|
||||||
|
* addListener} operation on the {@code EventClientDelegateMBean}, it will
|
||||||
|
* result in a call to {@link
|
||||||
|
* MBeanServer#addNotificationListener(ObjectName, NotificationListener,
|
||||||
|
* NotificationFilter, Object) addNotificationListener} on this object.
|
||||||
|
* If this parameter is null, then these requests will be sent to the
|
||||||
|
* newly-created {@code MBeanServerForwarder}. Usually the parameter will
|
||||||
|
* either be null or will be the result of {@link
|
||||||
|
* javax.management.remote.JMXConnectorServer#getSystemMBeanServerForwarder()
|
||||||
|
* getSystemMBeanServerForwarder()} for the connector server in which
|
||||||
|
* this forwarder will be installed.
|
||||||
|
*
|
||||||
* @return a new {@code MBeanServerForwarder} that simulates the existence
|
* @return a new {@code MBeanServerForwarder} that simulates the existence
|
||||||
* of an {@code EventClientDelegateMBean}.
|
* of an {@code EventClientDelegateMBean}.
|
||||||
|
*
|
||||||
|
* @see javax.management.remote.JMXConnectorServer#installStandardForwarders
|
||||||
*/
|
*/
|
||||||
public static MBeanServerForwarder newForwarder() {
|
public static MBeanServerForwarder newForwarder(
|
||||||
return new Forwarder();
|
MBeanServer nextMBS, MBeanServer loopMBS) {
|
||||||
|
Forwarder mbsf = new Forwarder();
|
||||||
|
// We must setLoopMBS before setMBeanServer, because when we
|
||||||
|
// setMBeanServer that will call getEventClientDelegate(loopMBS).
|
||||||
|
if (loopMBS == null)
|
||||||
|
loopMBS = mbsf;
|
||||||
|
mbsf.setLoopMBS(loopMBS);
|
||||||
|
if (nextMBS != null)
|
||||||
|
mbsf.setMBeanServer(nextMBS);
|
||||||
|
return mbsf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -437,10 +477,9 @@ public class EventClientDelegate implements EventClientDelegateMBean {
|
||||||
// private classes
|
// private classes
|
||||||
// ------------------------------------
|
// ------------------------------------
|
||||||
private class ClientInfo {
|
private class ClientInfo {
|
||||||
String clientId;
|
final String clientId;
|
||||||
EventBuffer buffer;
|
final NotificationListener clientListener;
|
||||||
NotificationListener clientListener;
|
final Map<Integer, AddedListener> listenerInfoMap =
|
||||||
Map<Integer, AddedListener> listenerInfoMap =
|
|
||||||
new HashMap<Integer, AddedListener>();
|
new HashMap<Integer, AddedListener>();
|
||||||
|
|
||||||
ClientInfo(String clientId, EventForwarder forwarder) {
|
ClientInfo(String clientId, EventForwarder forwarder) {
|
||||||
|
@ -703,7 +742,8 @@ public class EventClientDelegate implements EventClientDelegateMBean {
|
||||||
clientInfo = clientInfoMap.get(clientId);
|
clientInfo = clientInfoMap.get(clientId);
|
||||||
|
|
||||||
if (clientInfo == null) {
|
if (clientInfo == null) {
|
||||||
throw new EventClientNotFoundException("The client is not found.");
|
throw new EventClientNotFoundException(
|
||||||
|
"Client not found (id " + clientId + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
return clientInfo;
|
return clientInfo;
|
||||||
|
|
|
@ -51,7 +51,8 @@ import javax.management.remote.NotificationResult;
|
||||||
* and the MBean Server, that will intercept accesses to the Event Client
|
* and the MBean Server, that will intercept accesses to the Event Client
|
||||||
* Delegate MBean and treat them as the real MBean would. This forwarder is
|
* Delegate MBean and treat them as the real MBean would. This forwarder is
|
||||||
* inserted by default with the standard RMI Connector Server, and can also
|
* inserted by default with the standard RMI Connector Server, and can also
|
||||||
* be created explicitly using {@link EventClientDelegate#newForwarder()}.
|
* be created explicitly using {@link EventClientDelegate#newForwarder
|
||||||
|
* EventClientDelegate.newForwarder}.
|
||||||
*
|
*
|
||||||
* <li><p>A variant on the above is to replace the MBean Server that is
|
* <li><p>A variant on the above is to replace the MBean Server that is
|
||||||
* used locally with a forwarder as described above. Since
|
* used locally with a forwarder as described above. Since
|
||||||
|
@ -61,9 +62,7 @@ import javax.management.remote.NotificationResult;
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); // or whatever
|
* MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); // or whatever
|
||||||
* MBeanServerForwarder mbsf = EventClientDelegate.newForwarder();
|
* mbs = EventClientDelegate.newForwarder(mbs, null);
|
||||||
* mbsf.setMBeanServer(mbs);
|
|
||||||
* mbs = mbsf;
|
|
||||||
* // now use mbs just as you did before, but it will have an EventClientDelegate
|
* // now use mbs just as you did before, but it will have an EventClientDelegate
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
|
|
@ -27,7 +27,6 @@ package javax.management.event;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.concurrent.Executors; // for javadoc
|
import java.util.concurrent.Executors; // for javadoc
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This interface is used to specify a way to receive
|
* This interface is used to specify a way to receive
|
||||||
|
|
|
@ -83,8 +83,8 @@
|
||||||
* javax.management.event.EventClientDelegateMBean EventClientDelegateMBean}
|
* javax.management.event.EventClientDelegateMBean EventClientDelegateMBean}
|
||||||
* must be registered in the MBean Server, or the connector server must
|
* must be registered in the MBean Server, or the connector server must
|
||||||
* be configured to simulate the existence of this MBean, for example
|
* be configured to simulate the existence of this MBean, for example
|
||||||
* using {@link javax.management.event.EventClientDelegate#newForwarder()
|
* using {@link javax.management.event.EventClientDelegate#newForwarder
|
||||||
* EventClientDelegate.newForwarder()}. The standard RMI connector is so
|
* EventClientDelegate.newForwarder}. The standard RMI connector is so
|
||||||
* configured by default. The {@code EventClientDelegateMBean} documentation
|
* configured by default. The {@code EventClientDelegateMBean} documentation
|
||||||
* has further details.</p>
|
* has further details.</p>
|
||||||
*
|
*
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue