changeset 4259:b41995ac0c17

Merge
author lana
date Thu, 15 Oct 2009 16:37:55 -0700
parents 50b23b28d857 4e7661eaa211
children 913d5ec97629
files jaxp/make/build.properties jaxp/make/build.xml jaxp/make/tools/StripProperties/StripProperties.java jaxp/make/tools/StripProperties/StripPropertiesTask.java jaxws/make/build.properties jaxws/make/build.xml jaxws/make/tools/StripProperties/StripProperties.java jaxws/make/tools/StripProperties/StripPropertiesTask.java jdk/src/share/classes/java/awt/Component.java jdk/src/share/classes/java/awt/Container.java jdk/src/share/classes/sun/net/www/protocol/http/InMemoryCookieStore.java jdk/src/share/native/sun/security/ec/ec.c jdk/src/share/native/sun/security/ec/ec.h jdk/src/share/native/sun/security/ec/ec2.h jdk/src/share/native/sun/security/ec/ec2_163.c jdk/src/share/native/sun/security/ec/ec2_193.c jdk/src/share/native/sun/security/ec/ec2_233.c jdk/src/share/native/sun/security/ec/ec2_aff.c jdk/src/share/native/sun/security/ec/ec2_mont.c jdk/src/share/native/sun/security/ec/ec_naf.c jdk/src/share/native/sun/security/ec/ecc_impl.h jdk/src/share/native/sun/security/ec/ecdecode.c jdk/src/share/native/sun/security/ec/ecl-curve.h jdk/src/share/native/sun/security/ec/ecl-exp.h jdk/src/share/native/sun/security/ec/ecl-priv.h jdk/src/share/native/sun/security/ec/ecl.c jdk/src/share/native/sun/security/ec/ecl.h jdk/src/share/native/sun/security/ec/ecl_curve.c jdk/src/share/native/sun/security/ec/ecl_gf.c jdk/src/share/native/sun/security/ec/ecl_mult.c jdk/src/share/native/sun/security/ec/ecp.h jdk/src/share/native/sun/security/ec/ecp_192.c jdk/src/share/native/sun/security/ec/ecp_224.c jdk/src/share/native/sun/security/ec/ecp_256.c jdk/src/share/native/sun/security/ec/ecp_384.c jdk/src/share/native/sun/security/ec/ecp_521.c jdk/src/share/native/sun/security/ec/ecp_aff.c jdk/src/share/native/sun/security/ec/ecp_jac.c jdk/src/share/native/sun/security/ec/ecp_jm.c jdk/src/share/native/sun/security/ec/ecp_mont.c jdk/src/share/native/sun/security/ec/logtab.h jdk/src/share/native/sun/security/ec/mp_gf2m-priv.h jdk/src/share/native/sun/security/ec/mp_gf2m.c jdk/src/share/native/sun/security/ec/mp_gf2m.h jdk/src/share/native/sun/security/ec/mpi-config.h jdk/src/share/native/sun/security/ec/mpi-priv.h jdk/src/share/native/sun/security/ec/mpi.c jdk/src/share/native/sun/security/ec/mpi.h jdk/src/share/native/sun/security/ec/mplogic.c jdk/src/share/native/sun/security/ec/mplogic.h jdk/src/share/native/sun/security/ec/mpmontg.c jdk/src/share/native/sun/security/ec/mpprime.h jdk/src/share/native/sun/security/ec/oid.c jdk/src/share/native/sun/security/ec/secitem.c jdk/src/share/native/sun/security/ec/secoidt.h jdk/src/solaris/classes/sun/awt/X11/XDropTargetRegistry.java jdk/src/solaris/classes/sun/awt/X11/XWindow.java jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java langtools/src/share/classes/com/sun/tools/javac/file/Old199.java langtools/src/share/classes/com/sun/tools/javah/MainDoclet.java langtools/src/share/classes/com/sun/tools/javah/resources/Linux_ppc.properties langtools/src/share/classes/com/sun/tools/javah/resources/Linux_sparc.properties langtools/src/share/classes/com/sun/tools/javah/resources/SunOS_sparc.properties langtools/src/share/classes/com/sun/tools/javah/resources/SunOS_sparcv9.properties langtools/src/share/classes/com/sun/tools/javah/resources/win32_x86.properties
diffstat 976 files changed, 52370 insertions(+), 36481 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Wed Oct 14 19:23:15 2009 +0400
+++ b/.hgtags	Thu Oct 15 16:37:55 2009 -0700
@@ -46,3 +46,5 @@
 1b662b1ed14eb4ae31d5138a36c433b13d941dc5 jdk7-b69
 207f694795c448c17753eff1a2f50363106960c2 jdk7-b70
 c5d39b6be65cba0effb5f466ea48fe43764d0e0c jdk7-b71
+df4bcd06e1d0ab306efa5a44f24a409dc0c0c742 jdk7-b72
+ce74bd35ce948d629a356e168797f44b593b1578 jdk7-b73
--- a/.hgtags-top-repo	Wed Oct 14 19:23:15 2009 +0400
+++ b/.hgtags-top-repo	Thu Oct 15 16:37:55 2009 -0700
@@ -46,3 +46,5 @@
 82e6c820c51ac27882b77755d42efefdbf1dcda0 jdk7-b69
 175cb3fe615998d1004c6d3fd96e6d2e86b6772d jdk7-b70
 4c36e9853dda27bdac5ef4839a610509fbe31d34 jdk7-b71
+0d7e03b426df27c21dcc44ffb9178eacd1b04f10 jdk7-b72
+3ac6dcf7823205546fbbc3d4ea59f37358d0b0d4 jdk7-b73
--- a/README-builds.html	Wed Oct 14 19:23:15 2009 +0400
+++ b/README-builds.html	Thu Oct 15 16:37:55 2009 -0700
@@ -38,12 +38,17 @@
             <ul>
                 <li><a href="#introduction">Introduction</a></li>
                 <li><a href="#MBE">Minimum Build Environments</a></li>
-                <li><a href="#SDBE">Specific Developer Build Environments</a></li>
+                <li><a href="#SDBE">Specific Developer Build Environments</a>
                     <ul>
                         <li><a href="#fedora">Fedora Linux</a> </li>
                         <li><a href="#centos">CentOS Linux</a> </li>
-                        <li><a href="#ubuntu">Ubuntu Linux</a> </li>
+		        <li><a href="#debian">Debian GNU/Linux</a></li>
+			<li><a href="#ubuntu">Ubuntu Linux</a> </li>
+		        <li><a href="#opensuse">OpenSUSE</a></li>
+		        <li><a href="#mandriva">Mandriva</a></li>
+		        <li><a href="#opensolaris">OpenSolaris</a></li>
                     </ul>
+		</li>
                 <li><a href="#directories">Source Directory Structure</a> </li>
                 <li><a href="#building">Build Information</a>
                     <ul>
@@ -209,24 +214,59 @@
             we will try to provide what information we have available to us.
         </blockquote>
         <!-- ------------------------------------------------------ -->
-        <h3><a name="fedora">Fedora 9</a></h3>
+        <h3><a name="fedora">Fedora</a></h3>
         <blockquote>
-            After installing
-            <a href="http://www.fedoraproject.org/">Fedora 9</a>
-            you need to make sure you have
-            the "Software Development" bundle installed, plus the
-            following packages:
-            <blockquote>
-                <ul>
-                    <li>cups devel: Cups Development Package</li>
-                    <li>freetype 2.3+ devel: Freetype 2.3 Development Package</li>
-                    <li>hg: Mercurial, if you need to clone or manage source repositories</li>
-                    <li>ksh: May be needed when using <tt>webrev</tt></li>
-                </ul>
+	  <h4>Fedora 9</h4>
+	  <p>
+	    <blockquote>
+              After installing <a href="http://fedoraproject.org">Fedora</a> 9 
+	      you need to install several build dependencies. The simplest
+	      way to do it is to execute the following commands as user 
+	      <tt>root</tt>:
+	      <p/>
+	      <code>yum-builddep java-openjdk</code>
+	      <p/>
+	      <code>yum install gcc gcc-c++</code>
+	      <p/>
+	      In addition, it's necessary to set a few environment variables for the build:
+
+	      <p/>
+	      <code>export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-openjdk</code>
             </blockquote>
-            <p>
-            Always a good idea to do a complete Software Update/Refresh
-            after you get all the packages installed.
+	  <h4>Fedora 10</h4>
+	  <p>
+	    <blockquote>
+              After installing <a href="http://fedoraproject.org">Fedora</a> 10 
+	      you need to install several build dependencies. The simplest
+	      way to do it is to execute the following commands as user 
+	      <tt>root</tt>:
+	      <p/>
+	      <code>yum-builddep java-1.6.0-openjdk</code>
+	      <p/>
+	      <code>yum install gcc gcc-c++</code>
+	      <p/>
+	      In addition, it's necessary to set a few environment variables for the build:
+
+	      <p/>
+	      <code>export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-openjdk</code>
+            </blockquote>
+	  <h4>Fedora 11</h4>
+	  <p>
+	    <blockquote>
+              After installing <a href="http://fedoraproject.org">Fedora</a> 11 
+	      you need to install several build dependencies. The simplest
+	      way to do it is to execute the following commands as user 
+	      <tt>root</tt>:
+	      <p/>
+	      <code>yum-builddep java-1.6.0-openjdk</code>
+	      <p/>
+	      <code>yum install gcc gcc-c++</code>
+	      <p/>
+	      In addition, it's necessary to set a few environment variables for the build:
+
+	      <p/>
+	      <code>export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-openjdk</code>
+             </blockquote>
         </blockquote>
         <!-- ------------------------------------------------------ -->
         <h3><a name="centos">CentOS 5.2</a></h3>
@@ -269,145 +309,146 @@
             it's needed.
         </blockquote>
         <!-- ------------------------------------------------------ -->
-        <h3><a name="ubuntu">Ubuntu</a></h3>
+        <h3><a name="debian">Debian</a></h3>
         <blockquote>
-            In addition to needing the Bootstrap JDK and the Binary Plugs, 
-            when building on Ubuntu you will need to
-            make sure certain packages are installed.
-            In particular, certain X11 packages, make, m4, gawk, gcc 4, 
-            binutils, cups, freetype
-            and alsa.
-            <!-- ------------------------------------------------------ -->
-            <h4>Ubuntu 6.06</h4>
+            <h4>Debian 5.0 (Lenny)</h4>
             <p>
-            The following list of packages for Ubuntu 6.06 is a working set that
-            does appear to work. 
+	      <blockquote>
+		After installing <a href="http://debian.org">Debian</a> 5 
+		you need to install several build dependencies. 
+		The simplest way to install the build dependencies is to 
+		execute the following commands as user <tt>root</tt>:
+		<p/>
+		<code>aptitude build-dep openjdk-6</code>
+		<p/>
+		<code>aptitude install openjdk-6-jdk libmotif-dev</code>
+		<p/>
+		In addition, it's necessary to set a few environment variables for the build:
+		<p/>
+		<code>export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-6-openjdk</code>
+	      </blockquote>
+        </blockquote>
+        <!-- ====================================================== -->
+	<h3><a name="ubuntu">Ubuntu</a></h3>
+        <blockquote>
+            <h4>Ubuntu 8.04</h4>
             <p>
-            <b>Note that it's quite possible that some of these
-                packages are not required, so anyone discovering that some of the
-                packages listed below are NOT required,
-                please let the
-                OpenJDK
-            team know.</b>
+	      <blockquote>
+		After installing <a href="http://ubuntu.org">Ubuntu</a> 8.04 
+		you need to install several build dependencies. 
+		<p/>
+		First, you need to enable the universe repository in the 
+		Software Sources application and reload the repository 
+		information. The Software Sources application is available 
+		under the System/Administration menu. 
+		<p/>
+		The simplest way to install the build dependencies is to 
+		execute the following commands:
+		<p/>
+		<code>sudo aptitude build-dep openjdk-6</code>
+		<p/>
+		<code>sudo aptitude install openjdk-6-jdk</code>
+		<p/>
+		In addition, it's necessary to set a few environment variables for the build:
+		<p/>
+		<code>export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-6-openjdk</code>
+              </blockquote>
+           <h4>Ubuntu 8.10</h4>
             <p>
-            All the packages below can be installed with the
-            Synaptic Package manager provided with the base Ubuntu 6.06 release.
-            <blockquote>
-                <ul>
-                    <li>binutils (2.16.1cvs20060117-1ubuntu2.1)</li>
-                    <li>cpp (4:4.0.3-1)</li>
-                    <li>cpp-4.0 (4.0.3-1ubuntu5)</li>
-                    <li>libfreetype6-dev</li>
-                    <li>g++ (4:4.0.3-1)</li>
-                    <li>g++-4.0 (4.0.3-1ubuntu5)</li>
-                    <li>gawk (1:3.1.5-2build1)</li>
-                    <li>gcc (4:4.0.3-1)</li>
-                    <li>gcc-4.0 (4.0.3-1ubuntu5)</li>
-                    <li>libasound2-dev (1.0.10-2ubuntu4)</li>
-                    <li>libc6 (2.3.6-0ubuntu20) to 2.3.6-0ubuntu20.4</li>
-                    <li>libc6-dev (2.3.6-0ubuntu20.4)</li>
-                    <li>libc6-i686 (2.3.6-0ubuntu20) to 2.3.6-0ubuntu20.4</li>
-                    <li>libcupsys2-dev (1.2.2-0ubuntu0.6.06)</li>
-                    <li>libgcrypt11-dev (1.2.2-1)</li>
-                    <li>libgnutls-dev (1.2.9-2ubuntu1.1)</li>
-                    <li>libgnutls12 (1.2.9-2ubuntu1) to 1.2.9-2ubuntu1.1</li>
-                    <li>libgpg-error-dev (1.1-4)</li>
-                    <li>libice-dev (2:1.0.0-0ubuntu2)</li>
-                    <li>liblockfile1 (1.06.1)</li>
-                    <li>libopencdk8-dev (0.5.7-2)</li>
-                    <li>libpopt-dev (1.7-5)</li>
-                    <li>libsm-dev (2:1.0.0-0ubuntu2)</li>
-                    <li>libstdc++6-4.0-dev (4.0.3-1ubuntu5)</li>
-                    <li>libtasn1-2-dev (0.2.17-1ubuntu1)</li>
-                    <li>libx11-dev (2:1.0.0-0ubuntu9)</li>
-                    <li>libxau-dev (1:1.0.0-0ubuntu4)</li>
-                    <li>libxaw-headers (2:1.0.1-0ubuntu3)</li>
-                    <li>libxaw7-dev (2:1.0.1-0ubuntu3)</li>
-                    <li>libxdmcp-dev (1:1.0.0-0ubuntu2)</li>
-                    <li>libxext-dev (2:1.0.0-0ubuntu4)</li>
-                    <li>libxi-dev (2:1.0.0-0ubuntu3) </li>
-                    <li>libxmu-dev (2:1.0.0-0ubuntu3)</li>
-                    <li>libxmu-headers (2:1.0.0-0ubuntu3)</li>
-                    <li>libxmuu-dev (2:1.0.0-0ubuntu3)</li>
-                    <li>libxp-dev (6.8.2-11ubuntu2)</li>
-                    <li>libxpm-dev (1:3.5.4.2-0ubuntu3)</li>
-                    <li>libxrandr-dev (1:1.1.0.2-0ubuntu4)</li>
-                    <li>libxt-dev (1:1.0.0-0ubuntu3)</li>
-                    <li>libxtrap-dev (2:1.0.0-0ubuntu2)</li>
-                    <li>libxtst-dev (2:1.0.1-0ubuntu2)</li>
-                    <li>libxv-dev (2:1.0.1-0ubuntu3)</li>
-                    <li>linux-kernel-headers (2.6.11.2-0ubuntu18)</li>
-                    <li>m4 (1.4.4-1)</li>
-                    <li>make (3.80+3.81.b4-1)</li>
-                    <li>ssl-cert (1.0.13)</li>
-                    <li>x-dev (7.0.4-0ubuntu2)</li>
-                    <li>x11proto-core-dev (7.0.4-0ubuntu2)</li>
-                    <li>x11proto-input-dev (1.3.2-0ubuntu2)</li>
-                    <li>x11proto-kb-dev (1.0.2-0ubuntu2)</li>
-                    <li>x11proto-randr-dev (1.1.2-0ubuntu2)</li>
-                    <li>x11proto-record-dev (1.13.2-0ubuntu2)</li>
-                    <li>x11proto-trap-dev (3.4.3-0ubuntu2)</li>
-                    <li>x11proto-video-dev (2.2.2-0ubuntu2)</li>
-                    <li>x11proto-xext-dev (7.0.2-0ubuntu2)</li>
-                    <li>xlibs-dev (7.0.0-0ubuntu45)</li>
-                    <li>zlib1g-dev (1:1.2.3-6ubuntu4)</li>
-                </ul>
-            </blockquote>
-            <!-- ------------------------------------------------------ -->
-            <h4>Ubuntu 7.04</h4>
+	      <blockquote>
+		After installing <a href="http://ubuntu.org">Ubuntu</a> 8.10 
+		you need to install several build dependencies. The simplest
+		way to do it is to execute the following commands:
+		<p/>
+		<code>sudo aptitude build-dep openjdk-6</code>
+		<p/>
+		<code>sudo aptitude install openjdk-6-jdk</code>
+		<p/>
+		In addition, it's necessary to set a few environment variables for the build:
+		<p/>
+		<code>export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-6-openjdk</code>
+             </blockquote>
+           <h4>Ubuntu 9.04</h4>
             <p>
-            Using the Synaptic Package Manager, download the following
-            packages (double indented packages are automatically aquired
-            due to package dependencies):
-            <blockquote>
-                <ul>
-                    <li>build-essential</li>
-                    <ul>
-                        <li>dpkg-dev</li>
-                        <li>g++</li>
-                        <li>g++-4.1</li>
-                        <li>libc6-dev</li>
-                        <li>libstdc++6.4.1-dev</li>
-                        <li>linux-libc-dev</li>
-                    </ul>
-                    <li>gawk</li>
-                    <li>m4</li>
-                    <li>libasound2-dev</li>
-                    <li>libcupsys2-dev</li>
-                    <ul>
-                        <li>libgcrypt11-dev</li>
-                        <li>lgnutls-dev</li>
-                        <li>libgpg-error-dev</li>
-                        <li>liblzo-dev</li>
-                        <li>libopencdk8-dev</li>
-                        <li>libpopt-dev</li>
-                        <li>libtasn1-3-dev</li>
-                        <li>zlib1g-dev</li>
-                    </ul>
-                    <li>sun-java6-jdk</li>
-                    <ul>
-                        <li>java-common</li>
-                        <li>libltdl3</li>
-                        <li>odbcinst1debian1</li>
-                        <li>sun-java6-bin</li>
-                        <li>sun-java6-jre</li>
-                        <li>unixodbc</li>
-                    </ul>
-                    <li>xlibs-dev</li>
-                    <ul>
-                        <li>(many)</li>
-                    </ul>
-                    <li>x11proto-print-dev</li>
-                    <li>libxaw7-dev</li>
-                    <ul>
-                        <li>libxaw-headers</li>
-                    </ul>
-                    <li>libxp-dev</li>
-                    <li>libfreetype6-dev</li>
-                </ul>
-            </blockquote>
+	      <blockquote>
+		After installing <a href="http://ubuntu.org">Ubuntu</a> 9.04 
+		you need to install several build dependencies. The simplest
+		way to do it is to execute the following commands:
+		<p/>
+		<code>sudo aptitude build-dep openjdk-6</code>
+		<p/>
+		<code>sudo aptitude install openjdk-6-jdk</code>
+		<p/>
+		In addition, it's necessary to set a few environment variables for the build:
+		<p/>
+		<code>export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-6-openjdk</code>
+             </blockquote>
         </blockquote>
-        <!-- ------------------------------------------------------ -->
+        <!-- ====================================================== -->
+        <h3><a name="opensuse">OpenSUSE</a></h3>
+        <blockquote>
+            <h4>OpenSUSE 11.1</h4>
+            <p>
+	      <blockquote>
+		After installing <a href="http://opensuse.org">OpenSUSE</a> 11.1 
+		you need to install several build dependencies. 
+		The simplest way to install the build dependencies is to 
+		execute the following commands:
+		<p/>
+		<code>sudo zypper source-install -d java-1_6_0-openjdk</code>
+		<p/>
+		<code>sudo zypper install make</code>
+		<p/>
+		In addition, it is necessary to set a few environment variables for the build:
+		<p/>
+		<code>export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-1.6.0-openjdk</code>
+		<p/>
+		Finally, you need to unset the <code>JAVA_HOME</code> environment variable:
+		<p/>
+		<code>export -n JAVA_HOME</code>
+	      </blockquote>
+	</blockquote>
+        <!-- ====================================================== -->
+        <h3><a name="mandriva">Mandriva</a></h3>
+        <blockquote>
+            <h4>Mandriva Linux One 2009 Spring</h4>
+            <p>
+	      <blockquote>
+		After installing <a href="http://mandriva.org">Mandriva</a> Linux One 2009 Spring 
+		you need to install several build dependencies. 
+		The simplest way to install the build dependencies is to 
+		execute the following commands as user <tt>root</tt>:
+		<p/>
+		<code>urpmi java-1.6.0-openjdk-devel ant make gcc gcc-c++ freetype-devel zip unzip libcups2-devel libxrender1-devel libalsa2-devel libstc++-static-devel libxtst6-devel libxi-devel</code>
+                <p/>
+		In addition, it is necessary to set a few environment variables for the build:
+		<p/>
+		<code>export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-1.6.0-openjdk</code>
+	      </blockquote>
+        </blockquote>
+        <!-- ====================================================== -->
+        <h3><a name="opensolaris">OpenSolaris</a></h3>
+        <blockquote>
+            <h4>OpenSolaris 2009.06</h4>
+            <p>
+	      <blockquote>
+		After installing <a href="http://opensolaris.org">OpenSolaris</a> 2009.06 
+		you need to install several build dependencies. 
+		The simplest way to install the build dependencies is to 
+		execute the following commands:
+		<p/>
+		<code>pfexec pkg install SUNWgmake SUNWj6dev SUNWant sunstudioexpress SUNWcups SUNWzip SUNWunzip SUNWxwhl SUNWxorg-headers SUNWaudh SUNWfreetype2</code>
+                <p/>
+		In addition, it is necessary to set a few environment variables for the build:
+		<p/>
+		<code>export LANG=C ALT_COMPILER_PATH=/opt/SunStudioExpress/bin/ ALT_CUPS_HEADERS_PATH=/usr/include/</code>
+		<p/>
+		Finally, you need to make sure that the build process can find the Sun Studio compilers:
+		<p/>
+		<code>export PATH=$PATH:/opt/SunStudioExpress/bin/</code>
+	      </blockquote>
+        </blockquote>
+        <!-- ------------------------------------------------------ -->  
         <hr>
         <h2><a name="directories">Source Directory Structure</a></h2>
         <blockquote>
--- a/corba/.hgtags	Wed Oct 14 19:23:15 2009 +0400
+++ b/corba/.hgtags	Thu Oct 15 16:37:55 2009 -0700
@@ -46,3 +46,5 @@
 8120d308ec4e805c5588b8d9372844d781c4112d jdk7-b69
 175bd68779546078dbdb6dacd7f0aced79ed22b1 jdk7-b70
 3f1ef7f899ea2aec189c4fb67e5c8fa374437c50 jdk7-b71
+c793a31209263fbb867c23c752599d85c21abb73 jdk7-b72
+b751c528c55560cf2adeaeef24b39ca1f4d1cbf7 jdk7-b73
--- a/corba/make/Makefile	Wed Oct 14 19:23:15 2009 +0400
+++ b/corba/make/Makefile	Thu Oct 15 16:37:55 2009 -0700
@@ -141,12 +141,12 @@
 
 #----- src.zip
 
-SRC_ZIP_FILES = $(shell $(FIND) $(SRC_CLASSES_DIR) \( -name SCCS -o -name \*-template \) -prune -o -type f -print )
+SRC_ZIP_FILES = $(shell $(FIND) $(SRC_CLASSES_DIR) \( -name \*-template \) -prune -o -type f -print )
 
 SRC_ZIP = $(LIB_DIR)/src.zip
 $(SRC_ZIP): $(SRC_ZIP_FILES)
 	abs_src_zip=`cd $(@D) ; pwd`/$(@F) ; \
-	( cd $(SRC_CLASSES_DIR) ; $(FIND) . \( -name SCCS -o -name \*-template \) -prune -o -type f -print | $(ZIP) -q $$abs_src_zip -@ ) ; \
+	( cd $(SRC_CLASSES_DIR) ; $(FIND) . \( -name \*-template \) -prune -o -type f -print | $(ZIP) -q $$abs_src_zip -@ ) ; \
 	( cd $(GENSRC_DIR) ; $(FIND) . -type f -print | $(ZIP) -q $$abs_src_zip -@ ) ;
 
 #----- bin.zip
--- a/corba/make/common/BuildToolJar.gmk	Wed Oct 14 19:23:15 2009 +0400
+++ b/corba/make/common/BuildToolJar.gmk	Thu Oct 15 16:37:55 2009 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright 1998-2005 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 1998-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -24,22 +24,29 @@
 #
 
 # Input: BUILDDIR PACKAGE PKGDIR PROGRAM BUILDTOOL_SOURCE_ROOT BUILDTOOL_MAIN
- 
+
+# All subdirectories under the package root for the tool (max depth 4)
+_WC_DIRS          = * */* */*/* */*/*/*
+
 BUILDTOOL_MAIN_SOURCE_FILE = $(BUILDTOOL_SOURCE_ROOT)/$(BUILDTOOL_MAIN)
 BUILDTOOL_MANIFEST_FILE    = $(BUILDTOOLCLASSDIR)/$(PROGRAM)_manifest.mf
 BUILDTOOL_JAR_FILE         = $(BUILDTOOLJARDIR)/$(PROGRAM).jar
-BUILDTOOL_ALL_FILES       := $(shell $(CD) $(BUILDTOOL_SOURCE_ROOT) \
-    && $(FIND) $(PKGDIR) $(SCM_DIRS_prune) -o -type f -print)
-BUILTTOOL_MAINCLASS = $(subst /,.,$(BUILDTOOL_MAIN:%.java=%))
+BUILTTOOL_MAINCLASS        = $(subst /,.,$(BUILDTOOL_MAIN:%.java=%))
 
-all build: $(BUILDTOOL_JAR_FILE) tool_info
+# Wildcard patterns that find all the sources for this build tool
+BUILDTOOL_WC_PATTERNS      = $(BUILDTOOL_SOURCE_ROOT)/$(PKGDIR)/*.java \
+    $(patsubst %, $(BUILDTOOL_SOURCE_ROOT)/$(PKGDIR)/%/*.java, $(_WC_DIRS))
+
+# Wildcard expansion that finds all the files
+BUILDTOOL_SRC_FILES       := $(wildcard $(BUILDTOOL_WC_PATTERNS))
+
+all build: $(BUILDTOOL_JAR_FILE)
 
 $(BUILDTOOL_MANIFEST_FILE): $(BUILDTOOL_MAIN_SOURCE_FILE)
 	@$(prep-target)
 	$(ECHO) "Main-Class: $(BUILTTOOL_MAINCLASS)" > $@
 
-$(BUILDTOOL_JAR_FILE): $(BUILDTOOL_MANIFEST_FILE) \
-    $(BUILDTOOL_ALL_FILES:%=$(BUILDTOOL_SOURCE_ROOT)/%)
+$(BUILDTOOL_JAR_FILE): $(BUILDTOOL_MANIFEST_FILE) $(BUILDTOOL_SRC_FILES)
 	@$(prep-target)
 	@$(MKDIR) -p $(BUILDTOOLCLASSDIR)
 	$(BOOT_JAVAC_CMD) -d $(BUILDTOOLCLASSDIR) \
@@ -49,23 +56,8 @@
 	    $(JAR_JFLAGS) || $(RM) $@
 	@$(java-vm-cleanup)
 
-# Printing out a build tool information line
-define printBuildToolSetting
-if [ "$2" != "" ] ; then $(PRINTF) "%-25s %s\n" "$1:" "$2"; fi
-endef
+clean clobber::
+	$(RM) -r $(BUILDTOOLCLASSDIR)/$(PKGDIR) \
+                 $(BUILDTOOL_MANIFEST_FILE) \
+                 $(BUILDTOOL_JAR_FILE)
 
-# Print out the build tool information
-tool_info:
-	@$(ECHO) "========================================================="
-	@$(call printBuildToolSetting,BUILDTOOL,$(PROGRAM))
-	@$(call printBuildToolSetting,PACKAGE,$(PACKAGE))
-	@$(call printBuildToolSetting,BUILDTOOL_SOURCE_ROOT,$(BUILDTOOL_SOURCE_ROOT))
-	@$(call printBuildToolSetting,BUILTTOOL_MAINCLASS,$(BUILTTOOL_MAINCLASS))
-	@$(call printBuildToolSetting,BUILDTOOL_JAR_FILE,$(BUILDTOOL_JAR_FILE))
-	@$(ECHO) "========================================================="
-
-clean clobber::
-	$(RM) -r $(BUILDTOOLCLASSDIR)/$(PKGDIR)
-	$(RM) $(BUILDTOOL_MANIFEST_FILE)
-	$(RM) $(BUILDTOOL_JAR_FILE)
-
--- a/corba/make/common/CancelImplicits.gmk	Wed Oct 14 19:23:15 2009 +0400
+++ b/corba/make/common/CancelImplicits.gmk	Thu Oct 15 16:37:55 2009 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright 1998-1999 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 1998-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -56,11 +56,3 @@
 %: %.sh
 endif
 
-#
-# If you are using RCS, you must set the variable USE_RCS at the make
-# command line. Otherwise we disable RCS.
-#
-ifndef USE_RCS
-%:: %,v
-%:: RCS/%,v
-endif
--- a/corba/make/common/Defs.gmk	Wed Oct 14 19:23:15 2009 +0400
+++ b/corba/make/common/Defs.gmk	Thu Oct 15 16:37:55 2009 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright 1995-2007 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 1995-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -310,125 +310,32 @@
 SUBDIRS_MAKEFLAGS-clobber = INCREMENTAL_BUILD=false
 SUBDIRS_MAKEFLAGS-clean   = INCREMENTAL_BUILD=false
 
-# Current directory
-CURRENT_DIRECTORY := $(shell $(PWD))
-
-# If no timing wanted, we need to define these as empty
-ifdef NO_TIMING
-
-TIMING_ID:=NA
-
-define TIMING_start
-t=0:0:0:0
-endef
-
-define TIMING_end
-time_used=0
-endef
-
-else # NO_TIMING
-
-# Default timing id
-TIMING_ID:=$(shell $(BASENAME) $(CURRENT_DIRECTORY))
-
-# Timing start (must be used in same shell, e.g. same command line)
-#    Defines the shell variable $1 to have the start time.
-define TIMING_start
-$1=`$(DATE) +%j:%H:%M:%S`
-endef
-
-# Timing end (must be used in same shell, e.g. same command line)
-#    Expects shell variable $1 to have been defined as the start time.
-#    Expects shell variable $2 to have timing id string
-#    Sets total_seconds shell variable as the total seconds used.
-#    Sets time_used shell variable to contain format "%dh%dm%ds"
-define TIMING_end
-begTime="$${$1}"; \
-timing_id="$${$2}"; \
-endTime=`$(DATE) +%j:%H:%M:%S`; \
-d1=`$(ECHO) $${begTime} | $(CUT) -d':' -f1 | $(SED) -e 's@^0*@@'`; \
-if [ "$${d1}" = "" ] ; then d1=0; fi; \
-h1=`$(ECHO) $${begTime} | $(CUT) -d':' -f2 | $(SED) -e 's@^0*@@'`; \
-if [ "$${h1}" = "" ] ; then h1=0; fi; \
-m1=`$(ECHO) $${begTime} | $(CUT) -d':' -f3 | $(SED) -e 's@^0*@@'`; \
-if [ "$${m1}" = "" ] ; then m1=0; fi; \
-s1=`$(ECHO) $${begTime} | $(CUT) -d':' -f4 | $(SED) -e 's@^0*@@'`; \
-if [ "$${s1}" = "" ] ; then s1=0; fi; \
-d2=`$(ECHO) $${endTime} | $(CUT) -d':' -f1 | $(SED) -e 's@^0*@@'`; \
-if [ "$${d2}" = "" ] ; then d2=0; fi; \
-h2=`$(ECHO) $${endTime} | $(CUT) -d':' -f2 | $(SED) -e 's@^0*@@'`; \
-if [ "$${h2}" = "" ] ; then h2=0; fi; \
-m2=`$(ECHO) $${endTime} | $(CUT) -d':' -f3 | $(SED) -e 's@^0*@@'`; \
-if [ "$${m2}" = "" ] ; then m2=0; fi; \
-s2=`$(ECHO) $${endTime} | $(CUT) -d':' -f4 | $(SED) -e 's@^0*@@'`; \
-if [ "$${s2}" = "" ] ; then s2=0; fi; \
-t1_secs=`$(EXPR) $${d1} '*' 60 '*' 60 '*' 24 '+' $${h1} '*' 60 '*' 60 \
-		 '+' $${m1} '*' 60 '+' $${s1}`; \
-t2_secs=`$(EXPR) $${d2} '*' 60 '*' 60 '*' 24 '+' $${h2} '*' 60 '*' 60 \
-		 '+' $${m2} '*' 60 '+' $${s2}`; \
-total_seconds=`$(EXPR) $${t2_secs} '-' $${t1_secs}`; \
-if [ "$${total_seconds}" -lt 0 ] ; then total_seconds=0; fi; \
-t_hour=`$(EXPR) $${total_seconds} '/' '(' 60 '*' 60 ')'`h; \
-t_min=`$(EXPR) '(' $${total_seconds} '%' '(' 60 '*' 60 ')' ')' '/' 60`m; \
-t_sec=`$(EXPR) $${total_seconds} '%' 60`s; \
-time_used=$${t_sec}; \
-if [ "$${t_hour}" != "0h" ] ; then \
-time_used=$${t_hour}$${t_min}$${t_sec}; \
-elif [ "$${t_min}" != "0m" ] ; then \
-time_used=$${t_min}$${t_sec}; \
-else \
-time_used=$${t_sec}; \
-fi; \
-$(PRINTF) "  Timing: %05d seconds or %s for %s\n" \
-    $${total_seconds} $${time_used} $${timing_id}
-endef
-
-endif # NO_TIMING
-
 # Given a SUBDIRS list, cd into them and make them
 #   SUBDIRS_MAKEFLAGS      Make settings for a subdir make
 #   SUBDIRS_MAKEFLAGS-$@   Make settings specific to this target
 define SUBDIRS-loop
-@$(ECHO) "Begin Processing SUBDIRS: $(SUBDIRS)"
 @for i in DUMMY $(SUBDIRS) ; do \
   if [ "$$i" != "DUMMY" ] ; then \
-    $(ECHO) ">>>Recursively making "$$i" "$@" @ `$(DATE)` ..."; \
-    timing_id="$(TIMING_ID)-`$(BASENAME) $${i}`"; \
-    $(call TIMING_start,startTime); \
-    curDir=$(CURRENT_DIRECTORY); \
-    $(CD) $$i; $(MAKE) $@ TIMING_ID=$${timing_id} \
-			  $(SUBDIRS_MAKEFLAGS) \
-			  $(SUBDIRS_MAKEFLAGS-$@) \
-			  FULL_VERSION=$(FULL_VERSION) \
-			  RELEASE=$(RELEASE) || exit 1; \
-	       $(CD) $${curDir}; \
-    $(call TIMING_end,startTime,timing_id); \
-    $(ECHO) "<<<Finished Recursively making "$$i" "$@" @ `$(DATE)`." ; \
+    $(MAKE) -C $${i} $@ \
+          $(SUBDIRS_MAKEFLAGS) \
+          $(SUBDIRS_MAKEFLAGS-$@) \
+          FULL_VERSION=$(FULL_VERSION) \
+          RELEASE=$(RELEASE) || exit 1; \
   fi ; \
 done
-@$(ECHO) "Done Processing SUBDIRS: $(SUBDIRS)"
 endef
 
 # Given a OTHERSUBDIRS list, cd into them and make them (extra loop define)
 #   OTHERSUBDIRS_MAKEFLAGS      Make settings for a subdir make
 define OTHERSUBDIRS-loop
-@$(ECHO) "Begin Processing OTHERSUBDIRS: $(OTHERSUBDIRS)"
 @for i in DUMMY $(OTHERSUBDIRS) ; do \
   if [ "$$i" != "DUMMY" ] ; then \
-    $(ECHO) ">>>Recursively making "$$i" "$@" @ `$(DATE)` ..."; \
-    timing_id="$(TIMING_ID)-`$(BASENAME) $${i}`"; \
-    $(call TIMING_start,startTime); \
-    curDir=$(CURRENT_DIRECTORY); \
-    $(CD) $$i; $(MAKE) $@ TIMING_ID=$${timing_id} \
-		          $(OTHERSUBDIRS_MAKEFLAGS) \
-			  FULL_VERSION=$(FULL_VERSION) \
-			  RELEASE=$(RELEASE) || exit 1; \
-	       $(CD) $${curDir}; \
-    $(call TIMING_end,startTime,timing_id); \
-    $(ECHO) "<<<Finished Recursively making "$$i" "$@" @ `$(DATE)`." ; \
+    $(MAKE) -C $${i} $@ \
+          $(OTHERSUBDIRS_MAKEFLAGS) \
+          FULL_VERSION=$(FULL_VERSION) \
+          RELEASE=$(RELEASE) || exit 1; \
   fi ; \
 done
-@$(ECHO) "Done Processing OTHERSUBDIRS: $(OTHERSUBDIRS)"
 endef
 
 #
@@ -460,46 +367,23 @@
   VERSION_DEFINES = -DRELEASE='"$(RELEASE)"'
 endif
 
-# Note: As a rule, GNU Make rules should not appear in any of the 
-# Defs*.gmk files. These were added for Kestrel-Solaris and do address
-# a TeamWare bug. They should be moved elsewhere for Merlin.
-# 
-#  Override gnumake built-in rules which do sccs get operations badly.
-#  (They put the checked out code in the current directory, not in the
-#  directory of the original file.) 
-# Since this is a symptom of a teamware failure, complain and die on the spot.
+# Prevent the use of many default suffix rules we do not need
+.SUFFIXES:
+.SUFFIXES: .c .o .h .obj .cpp .hpp .java .class
 
-# This message immediately goes to stdout and the build terminates.
-define SCCS-trouble
-$(error  \
-"ERROR: File $@ referenced while building in $(CURRENT_DIRECTORY) \
- is out of date with respect to its SCCS file $<. \
- This can happen from an unresolved Teamware conflict, a file movement, or \
- a failure in which SCCS files are updated but the 'sccs get' was not done. \
- You should double check for other out of date files in your workspace. \
- Or run: cd $(TOPDIR) && $(MAKE) sccs_get")
-endef
-
-%:: s.%
-	@$(SCCS-trouble)
-%:: SCCS/s.%
-	@$(SCCS-trouble)
-	@$(ECHO) "         is out of date with respect to its SCCS file." >> $(WARNING_FILE)
-	@$(ECHO) "         This file may be from an unresolved Teamware conflict." >> $(WARNING_FILE)
-	@$(ECHO) "         This is also a symptom of a Teamware bringover/putback failure" >> $(WARNING_FILE)
-	@$(ECHO) "         in which SCCS files are updated but not checked out." >> $(WARNING_FILE)
-	@$(ECHO) "         Check for other out of date files in your workspace." >> $(WARNING_FILE)
-	@$(ECHO) "" >> $(WARNING_FILE)
-	@#exit 666
-
+# Make sure we are all insane
 ifdef INSANE
   export INSANE
 endif
 
-ifdef ALT_COPYRIGHT_YEAR
-  COPYRIGHT_YEAR = $(ALT_COPYRIGHT_YEAR)
-else
-  COPYRIGHT_YEAR = $(shell $(DATE) '+%Y')
+# Make sure we have the current year
+ifndef COPYRIGHT_YEAR
+  ifdef ALT_COPYRIGHT_YEAR
+    COPYRIGHT_YEAR := $(ALT_COPYRIGHT_YEAR)
+  else
+    COPYRIGHT_YEAR := $(shell $(DATE) '+%Y')
+  endif
+  export COPYRIGHT_YEAR
 endif
 
 # Install of imported file (JDK_IMPORT_PATH, or some other external location)
--- a/corba/make/common/Rules.gmk	Wed Oct 14 19:23:15 2009 +0400
+++ b/corba/make/common/Rules.gmk	Thu Oct 15 16:37:55 2009 -0700
@@ -27,17 +27,6 @@
 #
 # Rules shared by all Java makefiles.
 #
-# Used to apply to source file $<, checks code conventions, issues warnings.
-define check-conventions
-  if [ "$(CONVENTION_WATCH)" = "true" ] ; then \
-    if [ "`$(CAT) -n -v -t $< | $(EGREP) -v '\@\(\#\)' | $(EGREP) '\^[MLI]'`" != "" ] ; then \
-      $(ECHO) "WARNING: File contains tabs, ^M, or ^L characters: $<"; \
-      if [ "$(CONVENTION_DETAILS)" = "true" ] ; then \
-        $(CAT) -n -v -t $< | $(EGREP) -v '\@\(\#\)' | $(EGREP) '\^[MLI]' ; \
-      fi; \
-    fi; \
-  fi
-endef
 
 # Make sure the default rule is all
 rules_default_rule: all
@@ -162,7 +151,6 @@
 # Add a java source to the list
 define add-java-file
 $(ECHO) "$?" >> $(JAVA_SOURCE_LIST)
-$(check-conventions)
 endef
 
 $(CLASSDESTDIR)/%.class: $(GENSRCDIR)/%.java
@@ -197,11 +185,8 @@
 
 .compile.classlist : $(JAVA_SOURCE_LIST)
 	@$(MKDIR) -p $(CLASSDESTDIR)
-	@if [ `$(CAT) $(JAVA_SOURCE_LIST) | $(WC) -l` -ge 1 ] ; then \
-	  $(ECHO) "# Java sources to be compiled: (listed in file $(JAVA_SOURCE_LIST))"; \
+	if [ -s $(JAVA_SOURCE_LIST) ] ; then \
 	  $(CAT) $(JAVA_SOURCE_LIST); \
-	  $(ECHO) "# Running javac:"; \
-	  $(ECHO) $(JAVAC_CMD) $(JAVAC_PREFER_SOURCE) -sourcepath "$(SOURCEPATH)" -d $(CLASSDESTDIR) @$(JAVA_SOURCE_LIST); \
 	  $(JAVAC_CMD) $(JAVAC_PREFER_SOURCE) -sourcepath "$(SOURCEPATH)" -d $(CLASSDESTDIR) @$(JAVA_SOURCE_LIST); \
 	fi
 	@$(java-vm-cleanup)
@@ -220,10 +205,7 @@
 packages.clean:
 ifeq ($(DONT_CLOBBER_CLASSES),false)
   ifdef AUTO_FILES_JAVA_DIRS
-	@for sdir in $(AUTO_FILES_JAVA_DIRS); do \
-	  $(ECHO) "$(RM) -r $(CLASSDESTDIR)/$$sdir"; \
-	  $(RM) -r $(CLASSDESTDIR)/$$sdir; \
-        done
+	$(RM) -r $(patsubst %, $(CLASSDESTDIR)/%, $(AUTO_FILES_JAVA_DIRS))
   else
 	$(RM) -r $(CLASSDESTDIR)/$(PKGDIR)
   endif
@@ -259,15 +241,13 @@
 
 $(CLASSHDR_DOTFILE): $(CLASSES_export)
 	$(prep-target)
-	@$(ECHO) "# Running javah:"
 	$(JAVAH_CMD) -d $(CLASSHDRDIR)/ \
 		$(CLASSES.export) $(subst $$,\$$,$(EXPORTED_inner))
 	@$(java-vm-cleanup)
 	@$(TOUCH) $@
 
 classheaders.clean:
-	$(RM) $(CLASSHDR_DOTFILE)
-	$(RM) -r $(CLASSHDRDIR)
+	$(RM) -r $(CLASSHDRDIR) $(CLASSHDR_DOTFILE)
 
 else # FILES_export
 
--- a/corba/make/common/shared/Compiler-msvc.gmk	Wed Oct 14 19:23:15 2009 +0400
+++ b/corba/make/common/shared/Compiler-msvc.gmk	Thu Oct 15 16:37:55 2009 -0700
@@ -48,11 +48,17 @@
   NMAKE          = MFLAGS= MAKEFLAGS= $(COMPILER_PATH)nmake -nologo
 
   # Compiler version and type (Always get word after "Version")
-  CC_VER  := $(shell $(CC) 2>&1 | $(HEAD) -n 1 | $(SED) 's/.*\(Version.*\)/\1/' | $(NAWK) '{print $$2}')
-  
+  ifndef CC_VER
+    CC_VER  := $(shell $(CC) 2>&1 | $(HEAD) -n 1 | $(SED) 's/.*\(Version.*\)/\1/' | $(NAWK) '{print $$2}')
+    export CC_VER
+  endif
+
   # SDK-64 and MSVC6 put REBASE.EXE in a different places - go figure...
   ifeq ($(ARCH_DATA_MODEL), 32)
-    LINK_VER := $(shell $(LINK) | $(HEAD) -n 1 | $(NAWK) '{print $$6}')
+    ifndef LINK_VER
+      LINK_VER := $(shell $(LINK) | $(HEAD) -n 1 | $(NAWK) '{print $$6}')
+      export LINK_VER
+    endif
     CC_MAJORVER :=$(call MajorVersion,$(CC_VER))
     ifeq ($(CC_MAJORVER), 13)
       # This should be: CC_VER=13.10.3077 LINK_VER=7.10.3077
@@ -93,7 +99,10 @@
     endif
   else
     # else ARCH_DATA_MODEL is 64
-    LINK_VER := $(shell $(LINK) | $(HEAD) -n 1 | $(NAWK) '{print $$6}')
+    ifndef LINK_VER
+      LINK_VER := $(shell $(LINK) | $(HEAD) -n 1 | $(NAWK) '{print $$6}')
+      export LINK_VER
+    endif
     CC_MAJORVER :=$(call MajorVersion,$(CC_VER))
     CC_MINORVER :=$(call MinorVersion,$(CC_VER))
     CC_MICROVER :=$(call MicroVersion,$(CC_VER))
--- a/corba/make/common/shared/Defs-utils.gmk	Wed Oct 14 19:23:15 2009 +0400
+++ b/corba/make/common/shared/Defs-utils.gmk	Thu Oct 15 16:37:55 2009 -0700
@@ -116,7 +116,6 @@
 RMDIR          = $(UTILS_COMMAND_PATH)rmdir
 RPM            = $(UTILS_COMMAND_PATH)rpm
 RPMBUILD       = $(UTILS_COMMAND_PATH)rpmbuild
-SCCS           = $(UTILS_CCS_BIN_PATH)sccs
 SED            = $(UTILS_COMMAND_PATH)sed
 SH             = $(UTILS_COMMAND_PATH)sh
 SHOWREV        = $(UTILS_USR_BIN_PATH)showrev
--- a/corba/make/common/shared/Defs-windows.gmk	Wed Oct 14 19:23:15 2009 +0400
+++ b/corba/make/common/shared/Defs-windows.gmk	Thu Oct 15 16:37:55 2009 -0700
@@ -113,32 +113,38 @@
 
 # UNIXCOMMAND_PATH: path to where the most common Unix commands are.
 #  NOTE: Must end with / so that it could be empty, allowing PATH usage.
-ifdef ALT_UNIXCOMMAND_PATH
-  xALT_UNIXCOMMAND_PATH  :="$(subst \,/,$(ALT_UNIXCOMMAND_PATH))"
-  fxALT_UNIXCOMMAND_PATH :=$(call FullPath,$(xALT_UNIXCOMMAND_PATH))
-  UNIXCOMMAND_PATH       :=$(call PrefixPath,$(fxALT_UNIXCOMMAND_PATH))
-else
-  ifdef USING_CYGWIN
-    UNIXCOMMAND_PATH :=$(call PrefixPath,/usr/bin)
+ifndef UNIXCOMMAND_PATH
+  ifdef ALT_UNIXCOMMAND_PATH
+    xALT_UNIXCOMMAND_PATH  :="$(subst \,/,$(ALT_UNIXCOMMAND_PATH))"
+    fxALT_UNIXCOMMAND_PATH :=$(call FullPath,$(xALT_UNIXCOMMAND_PATH))
+    UNIXCOMMAND_PATH       :=$(call PrefixPath,$(fxALT_UNIXCOMMAND_PATH))
   else
-    ifdef ROOTDIR
-      xROOTDIR :="$(subst \,/,$(ROOTDIR))"
-      _rootdir :=$(call FullPath,$(xROOTDIR))
+    ifdef USING_CYGWIN
+      UNIXCOMMAND_PATH :=$(call PrefixPath,/usr/bin)
     else
-      xROOTDIR :="$(_system_drive)/mksnt"
-      _rootdir :=$(call FullPath,$(xROOTDIR))
-    endif
-    ifneq ($(_rootdir),)
-      UNIXCOMMAND_PATH :=$(call PrefixPath,$(_rootdir)/mksnt)
+      ifdef ROOTDIR
+        xROOTDIR :="$(subst \,/,$(ROOTDIR))"
+        _rootdir :=$(call FullPath,$(xROOTDIR))
+      else
+        xROOTDIR :="$(_system_drive)/mksnt"
+        _rootdir :=$(call FullPath,$(xROOTDIR))
+      endif
+      ifneq ($(_rootdir),)
+        UNIXCOMMAND_PATH :=$(call PrefixPath,$(_rootdir)/mksnt)
+      endif
     endif
   endif
+  UNIXCOMMAND_PATH:=$(call AltCheckSpaces,UNIXCOMMAND_PATH)
+  export UNIXCOMMAND_PATH
 endif
-UNIXCOMMAND_PATH:=$(call AltCheckSpaces,UNIXCOMMAND_PATH)
 
 # Get version of MKS or CYGWIN
 ifdef USING_CYGWIN
-_CYGWIN_VER :=$(shell $(UNAME))
-CYGWIN_VER  :=$(call GetVersion,$(_CYGWIN_VER))
+  ifndef CYGWIN_VER
+    _CYGWIN_VER :=$(shell $(UNAME))
+    CYGWIN_VER  :=$(call GetVersion,$(_CYGWIN_VER))
+    export CYGWIN_VER
+  endif
 else # MKS
 _MKS_VER :=$(shell $(MKSINFO) 2>&1 | $(GREP) Release | $(TAIL) -1 | $(SED) -e 's@.*\(Release.*\)@\1@')
 MKS_VER  :=$(call GetVersion,$(_MKS_VER))
@@ -168,235 +174,234 @@
 
 # Process Windows values into FullPath values, these paths may have \ chars
 
-# System root
-ifdef SYSTEMROOT
-  xSYSTEMROOT  :="$(subst \,/,$(SYSTEMROOT))"
-  _system_root :=$(call FullPath,$(xSYSTEMROOT))
-else
-  ifdef SystemRoot
-     xSYSTEMROOT :="$(subst \,/,$(SystemRoot))"
-    _system_root :=$(call FullPath,$(xSYSTEMROOT))
+# Program Files directory
+ifndef SHORTPROGRAMFILES
+  ifdef PROGRAMFILES
+    xPROGRAMFILES      :="$(subst \,/,$(PROGRAMFILES))"
   else
-    ifdef WINDIR
-      xWINDIR      :="$(subst \,/,$(WINDIR))"
-      _system_root :=$(call FullPath,$(xWINDIR))
+    ifeq ($(ARCH_DATA_MODEL), 32)
+      xPROGRAMFILES    :="$(_system_drive)/Program Files"
     else
-      ifdef windir
-        xWINDIR      :="$(subst \,/,$(windir))"
-        _system_root :=$(call FullPath,$(xWINDIR))
-      endif
+      xPROGRAMFILES    :="$(_system_drive)/Program Files (x86)"
     endif
   endif
-endif
-_system_root:=$(call CheckValue,_system_root,$(_system_drive)/WINNT)
-
-# Program Files directory
-ifdef PROGRAMFILES
-  xPROGRAMFILES      :="$(subst \,/,$(PROGRAMFILES))"
-else
   ifeq ($(ARCH_DATA_MODEL), 32)
-    xPROGRAMFILES    :="$(_system_drive)/Program Files"
+    SHORTPROGRAMFILES  :=$(call FullPath,$(xPROGRAMFILES))
   else
-    xPROGRAMFILES    :="$(_system_drive)/Program Files (x86)"
+    ifdef PROGRAMW6432
+      xPROGRAMW6432    :="$(subst \,/,$(PROGRAMW6432))"
+    else
+      xPROGRAMW6432    :="$(_system_drive)/Program Files"
+    endif
+    SHORTPROGRAMFILES  :=$(call FullPath,$(xPROGRAMW6432))
   endif
-endif
-ifeq ($(ARCH_DATA_MODEL), 32)
-  _program_files     :=$(call FullPath,$(xPROGRAMFILES))
-else
-  ifdef PROGRAMW6432
-    xPROGRAMW6432    :="$(subst \,/,$(PROGRAMW6432))"
-  else
-    xPROGRAMW6432    :="$(_system_drive)/Program Files"
+  ifneq ($(word 1,$(SHORTPROGRAMFILES)),$(SHORTPROGRAMFILES))
+    SHORTPROGRAMFILES  :=
   endif
-  _program_files     :=$(call FullPath,$(xPROGRAMW6432))
-  _program_files32   :=$(call FullPath,$(xPROGRAMFILES))
-  ifneq ($(word 1,$(_program_files32)),$(_program_files32))
-    _program_files32:=
-  endif
-endif
-ifneq ($(word 1,$(_program_files)),$(_program_files))
-  _program_files:=
+  export SHORTPROGRAMFILES
 endif
 
 # Compilers, SDK, and Visual Studio (MSDEV) [32bit is different from 64bit]
 ifeq ($(ARCH_DATA_MODEL), 32)
-  # Try looking in MSVCDIR or MSVCDir area first (set by vcvars32.bat)
-  ifdef MSVCDIR
-    xMSVCDIR  :="$(subst \,/,$(MSVCDIR))"
-    _msvc_dir :=$(call FullPath,$(xMSVCDIR))
-  else
-    ifdef MSVCDir
-      xMSVCDIR  :="$(subst \,/,$(MSVCDir))"
-      _msvc_dir :=$(call FullPath,$(xMSVCDIR))
+  ifndef SHORTMSVCDIR
+    # Try looking in MSVCDIR or MSVCDir area first (set by vcvars32.bat)
+    ifdef MSVCDIR
+      xMSVCDIR         :="$(subst \,/,$(MSVCDIR))"
+      SHORTMSVCDIR     :=$(call FullPath,$(xMSVCDIR))
     else
-      ifneq ($(_program_files),)
-        xMSVCDIR  :="$(_program_files)/Microsoft Visual Studio .NET 2003/Vc7"
-        _msvc_dir :=$(call FullPath,$(xMSVCDIR))
+      ifdef MSVCDir
+        xMSVCDIR       :="$(subst \,/,$(MSVCDir))"
+        SHORTMSVCDIR   :=$(call FullPath,$(xMSVCDIR))
+      else
+        ifneq ($(SHORTPROGRAMFILES),)
+          xMSVCDIR     :="$(SHORTPROGRAMFILES)/Microsoft Visual Studio .NET 2003/Vc7"
+          SHORTMSVCDIR :=$(call FullPath,$(xMSVCDIR))
+        endif
       endif
     endif
+    ifneq ($(subst MSDev98,OLDOLDOLD,$(SHORTMSVCDIR)),$(SHORTMSVCDIR))
+      SHORTMSVCDIR     :=
+    endif
+    # If we still don't have it, look for VS71COMNTOOLS, setup by installer?
+    ifeq ($(SHORTMSVCDIR),)
+      ifdef VS71COMNTOOLS  # /Common/Tools directory, use ../../Vc7
+        xVS71COMNTOOLS :="$(subst \,/,$(VS71COMNTOOLS))"
+        _vs71tools     :=$(call FullPath,$(xVS71COMNTOOLS))
+      endif
+      ifneq ($(_vs71tools),)
+        SHORTMSVCDIR   :=$(_vs71tools)/../../Vc7
+      endif
+    endif
+    export SHORTMSVCDIR
   endif
-  ifneq ($(subst MSDev98,OLDOLDOLD,$(_msvc_dir)),$(_msvc_dir))
-    _msvc_dir :=
-  endif
-  # If we still don't have it, look for VS71COMNTOOLS, setup by installer?
-  ifeq ($(_msvc_dir),)
-    ifdef VS71COMNTOOLS  # /Common/Tools directory, use ../../Vc7
-      xVS71COMNTOOLS :="$(subst \,/,$(VS71COMNTOOLS))"
-      _vs71tools     :=$(call FullPath,$(xVS71COMNTOOLS))
-    endif
-    ifneq ($(_vs71tools),)
-      _msvc_dir :=$(_vs71tools)/../../Vc7
-    endif
-  endif
-  ifneq ($(_msvc_dir),)
-    _compiler_bin :=$(_msvc_dir)/Bin
-    _redist_sdk   :=$(_msvc_dir)/../SDK/v1.1/Bin
-    _ms_sdk       :=$(_msvc_dir)/PlatformSDK
+  ifneq ($(SHORTMSVCDIR),)
+    SHORTCOMPILERBIN   :=$(SHORTMSVCDIR)/Bin
+    SHORTPSDK          :=$(SHORTMSVCDIR)/PlatformSDK
+    export SHORTCOMPILERBIN
+    export SHORTPSDK
   endif
 endif
 
 # The Microsoft Platform SDK installed by itself
-ifneq ($(_program_files),)
-  xPSDK  :="$(_program_files)/Microsoft Platform SDK"
-  _psdk  :=$(call FullPath,$(xPSDK))
-  ifeq ($(_psdk),)
-    xPSDK  :="$(_program_files)/Microsoft SDK"
-    _psdk :=$(call FullPath,$(xMSSDK))
+ifneq ($(SHORTPROGRAMFILES),)
+  ifndef SHORTPSDK
+    xPSDK       :="$(SHORTPROGRAMFILES)/Microsoft Platform SDK"
+    SHORTPSDK   :=$(call FullPath,$(xPSDK))
+    ifeq ($(SHORTPSDK),)
+      xPSDK     :="$(SHORTPROGRAMFILES)/Microsoft SDK"
+      SHORTPSDK :=$(call FullPath,$(xMSSDK))
+    endif
+    export SHORTPSDK
   endif
 endif
 
 # If no SDK found yet, look in other places
-ifeq ($(_ms_sdk),)
+ifndef SHORTPSDK
   ifdef MSSDK
-    xMSSDK  :="$(subst \,/,$(MSSDK))"
-    _ms_sdk :=$(call FullPath,$(xMSSDK))
+    xMSSDK      :="$(subst \,/,$(MSSDK))"
+    SHORTPSDK   :=$(call FullPath,$(xMSSDK))
   else
     ifdef MSSdk
-      xMSSDK  :="$(subst \,/,$(MSSdk))"
-      _ms_sdk :=$(call FullPath,$(xMSSDK))
-    else
-      _ms_sdk :=$(_psdk)
+      xMSSDK    :="$(subst \,/,$(MSSdk))"
+      SHORTPSDK :=$(call FullPath,$(xMSSDK))
     endif
   endif
+  export SHORTPSDK
 endif
 
 # Compilers for 64bit are from SDK
 ifeq ($(ARCH_DATA_MODEL), 64)
-  xMSSDK61 :="C:/Program Files/Microsoft SDKs/Windows/v6.1/"
-  MSSDK61 :=$(call FullPath,$(xMSSDK61))
-  xVS2008 :="C:/Program Files (x86)/Microsoft Visual Studio 9.0/"
-  _vs2008 :=$(call FullPath,$(xVS2008))
-  ifneq ($(_vs2008),)
-    ifeq ($(ARCH), ia64)
-      _compiler_bin :=$(_vs2008)/VC/Bin/x86_ia64
-    endif
-    ifeq ($(ARCH), amd64)
-      _compiler_bin :=$(_vs2008)/VC/Bin/$(ARCH)
-      _redist_sdk   :=$(MSSDK61)/VC/redist
-    endif
-  else
-    ifneq ($(_ms_sdk),)
+  ifndef SHORTCOMPILERBIN
+    xMSSDK61 :="C:/Program Files/Microsoft SDKs/Windows/v6.1/"
+    MSSDK61 :=$(call FullPath,$(xMSSDK61))
+    xVS2008 :="C:/Program Files (x86)/Microsoft Visual Studio 9.0/"
+    _vs2008 :=$(call FullPath,$(xVS2008))
+    ifneq ($(_vs2008),)
       ifeq ($(ARCH), ia64)
-        _compiler_bin :=$(_ms_sdk)/Bin/Win64
+        SHORTCOMPILERBIN :=$(_vs2008)/VC/Bin/x86_ia64
       endif
       ifeq ($(ARCH), amd64)
-        _compiler_bin :=$(_ms_sdk)/Bin/Win64/x86/$(ARCH)
-        _redist_sdk   :=$(_ms_sdk)/redist/win64/AMD64
+        SHORTCOMPILERBIN :=$(_vs2008)/VC/Bin/$(ARCH)
+      endif
+    else
+      ifneq ($(SHORTPSDK),)
+        ifeq ($(ARCH), ia64)
+          SHORTCOMPILERBIN :=$(SHORTPSDK)/Bin/Win64
+        endif
+        ifeq ($(ARCH), amd64)
+          SHORTCOMPILERBIN :=$(SHORTPSDK)/Bin/Win64/x86/$(ARCH)
+        endif
       endif
     endif
+    export SHORTCOMPILERBIN
   endif
 endif
 
 # Location on system where jdk installs might be
-ifneq ($(_program_files),)
-  USRJDKINSTANCES_PATH =$(_program_files)/Java
+ifneq ($(SHORTPROGRAMFILES),)
+  USRJDKINSTANCES_PATH =$(SHORTPROGRAMFILES)/Java
 else
   USRJDKINSTANCES_PATH =$(_system_drive)/
 endif
 
 # SLASH_JAVA: location of all network accessable files
-ifdef ALT_SLASH_JAVA
-  xALT_SLASH_JAVA :="$(subst \,/,$(ALT_SLASH_JAVA))"
-  SLASH_JAVA      :=$(call FullPath,$(xALT_SLASH_JAVA))
-else
-  ifdef ALT_JDK_JAVA_DRIVE
-    SLASH_JAVA  =$(JDK_JAVA_DRIVE)
+ifndef SLASH_JAVA
+  ifdef ALT_SLASH_JAVA
+    xALT_SLASH_JAVA :="$(subst \,/,$(ALT_SLASH_JAVA))"
+    SLASH_JAVA      :=$(call FullPath,$(xALT_SLASH_JAVA))
   else
-    SLASH_JAVA  =J:
+    ifdef ALT_JDK_JAVA_DRIVE
+      SLASH_JAVA  =$(JDK_JAVA_DRIVE)
+    else
+      SLASH_JAVA  =J:
+    endif
   endif
+  SLASH_JAVA:=$(call AltCheckSpaces,SLASH_JAVA)
+  SLASH_JAVA:=$(call AltCheckValue,SLASH_JAVA)
+  export SLASH_JAVA
 endif
-SLASH_JAVA:=$(call AltCheckSpaces,SLASH_JAVA)
-SLASH_JAVA:=$(call AltCheckValue,SLASH_JAVA)
 
 # JDK_DEVTOOLS_DIR: common path for all the java devtools
-ifdef ALT_JDK_DEVTOOLS_DIR
-  xALT_JDK_DEVTOOLS_DIR :="$(subst \,/,$(ALT_JDK_DEVTOOLS_DIR))"
-  JDK_DEVTOOLS_DIR      :=$(call FullPath,$(xALT_JDK_DEVTOOLS_DIR))
-else
-  JDK_DEVTOOLS_DIR =$(SLASH_JAVA)/devtools
+ifndef JDK_DEVTOOLS_DIR
+  ifdef ALT_JDK_DEVTOOLS_DIR
+    xALT_JDK_DEVTOOLS_DIR :="$(subst \,/,$(ALT_JDK_DEVTOOLS_DIR))"
+    JDK_DEVTOOLS_DIR      :=$(call FullPath,$(xALT_JDK_DEVTOOLS_DIR))
+  else
+    JDK_DEVTOOLS_DIR =$(SLASH_JAVA)/devtools
+  endif
+  JDK_DEVTOOLS_DIR:=$(call AltCheckSpaces,JDK_DEVTOOLS_DIR)
+  JDK_DEVTOOLS_DIR:=$(call AltCheckValue,JDK_DEVTOOLS_DIR)
+  export JDK_DEVTOOLS_DIR
 endif
-JDK_DEVTOOLS_DIR:=$(call AltCheckSpaces,JDK_DEVTOOLS_DIR)
-JDK_DEVTOOLS_DIR:=$(call AltCheckValue,JDK_DEVTOOLS_DIR)
 
 # COMPILER_PATH: path to where the compiler and tools are installed.
 #  NOTE: Must end with / so that it could be empty, allowing PATH usage.
-ifdef ALT_COMPILER_PATH
-  xALT_COMPILER_PATH  :="$(subst \,/,$(ALT_COMPILER_PATH))"
-  fxALT_COMPILER_PATH :=$(call FullPath,$(xALT_COMPILER_PATH))
-  COMPILER_PATH       :=$(call PrefixPath,$(fxALT_COMPILER_PATH))
-else
-  COMPILER_PATH :=$(call PrefixPath,$(_compiler_bin))
+ifndef COMPILER_PATH
+  ifdef ALT_COMPILER_PATH
+    xALT_COMPILER_PATH  :="$(subst \,/,$(ALT_COMPILER_PATH))"
+    fxALT_COMPILER_PATH :=$(call FullPath,$(xALT_COMPILER_PATH))
+    COMPILER_PATH       :=$(call PrefixPath,$(fxALT_COMPILER_PATH))
+  else
+    COMPILER_PATH :=$(call PrefixPath,$(SHORTCOMPILERBIN))
+  endif
+  COMPILER_PATH :=$(call AltCheckSpaces,COMPILER_PATH)
+  export COMPILER_PATH
 endif
-COMPILER_PATH :=$(call AltCheckSpaces,COMPILER_PATH)
 
 # MSDEVTOOLS_PATH: path to where the additional MS Compiler tools are.
 #  NOTE: Must end with / so that it could be empty, allowing PATH usage.
-ifdef ALT_MSDEVTOOLS_PATH
-  xALT_MSDEVTOOLS_PATH  :="$(subst \,/,$(ALT_MSDEVTOOLS_PATH))"
-  fxALT_MSDEVTOOLS_PATH :=$(call FullPath,$(xALT_MSDEVTOOLS_PATH))
-  MSDEVTOOLS_PATH       :=$(call PrefixPath,$(fxALT_MSDEVTOOLS_PATH))
-else
-  ifeq ($(ARCH_DATA_MODEL), 64)
-    ifdef MSTOOLS
-      xMSTOOLS  :="$(subst \,/,$(MSTOOLS))"
-      _ms_tools :=$(call FullPath,$(xMSTOOLS))
-    else
-      ifdef Mstools
-        xMSTOOLS  :="$(subst \,/,$(Mstools))"
+ifndef MSDEVTOOLS_PATH
+  ifdef ALT_MSDEVTOOLS_PATH
+    xALT_MSDEVTOOLS_PATH  :="$(subst \,/,$(ALT_MSDEVTOOLS_PATH))"
+    fxALT_MSDEVTOOLS_PATH :=$(call FullPath,$(xALT_MSDEVTOOLS_PATH))
+    MSDEVTOOLS_PATH       :=$(call PrefixPath,$(fxALT_MSDEVTOOLS_PATH))
+  else
+    ifeq ($(ARCH_DATA_MODEL), 64)
+      ifdef MSTOOLS
+        xMSTOOLS  :="$(subst \,/,$(MSTOOLS))"
         _ms_tools :=$(call FullPath,$(xMSTOOLS))
       else
-        _ms_tools :=
+        ifdef Mstools
+          xMSTOOLS  :="$(subst \,/,$(Mstools))"
+          _ms_tools :=$(call FullPath,$(xMSTOOLS))
+        else
+          _ms_tools :=
+        endif
       endif
+      ifneq ($(_ms_tools),)
+        _ms_tools_bin :=$(_ms_tools)/Bin
+      else
+        # Assumes compiler bin is .../Bin/win64/x86/AMD64, rc.exe is 3 levels up
+        _ms_tools_bin :=$(SHORTCOMPILERBIN)/../../..
+      endif
+    else
+      _ms_tools_bin :=$(SHORTCOMPILERBIN)
     endif
-    ifneq ($(_ms_tools),)
-      _ms_tools_bin :=$(_ms_tools)/Bin
-    else
-      # Assumes compiler bin is .../Bin/win64/x86/AMD64, rc.exe is 3 levels up
-      _ms_tools_bin :=$(_compiler_bin)/../../..
-    endif
-  else
-    _ms_tools_bin :=$(_compiler_bin)
+    MSDEVTOOLS_PATH :=$(call PrefixPath,$(_ms_tools_bin))
   endif
-  MSDEVTOOLS_PATH :=$(call PrefixPath,$(_ms_tools_bin))
+  MSDEVTOOLS_PATH:=$(call AltCheckSpaces,MSDEVTOOLS_PATH)
+  export MSDEVTOOLS_PATH
 endif
-MSDEVTOOLS_PATH:=$(call AltCheckSpaces,MSDEVTOOLS_PATH)
 
 # DEVTOOLS_PATH: for other tools required for building (such as zip, etc.)
 #  NOTE: Must end with / so that it could be empty, allowing PATH usage.
-ifdef ALT_DEVTOOLS_PATH
-  xALT_DEVTOOLS_PATH  :="$(subst \,/,$(ALT_DEVTOOLS_PATH))"
-  fxALT_DEVTOOLS_PATH :=$(call FullPath,$(xALT_DEVTOOLS_PATH))
-  DEVTOOLS_PATH       :=$(call PrefixPath,$(fxALT_DEVTOOLS_PATH))
-else
-  ifdef USING_CYGWIN
-    DEVTOOLS_PATH :=$(UNIXCOMMAND_PATH)
+ifndef DEVTOOLS_PATH
+  ifdef ALT_DEVTOOLS_PATH
+    xALT_DEVTOOLS_PATH  :="$(subst \,/,$(ALT_DEVTOOLS_PATH))"
+    fxALT_DEVTOOLS_PATH :=$(call FullPath,$(xALT_DEVTOOLS_PATH))
+    DEVTOOLS_PATH       :=$(call PrefixPath,$(fxALT_DEVTOOLS_PATH))
   else
-    xDEVTOOLS_PATH  :="$(_system_drive)/utils"
-    fxDEVTOOLS_PATH :=$(call FullPath,$(xDEVTOOLS_PATH))
-    DEVTOOLS_PATH  :=$(call PrefixPath,$(fxDEVTOOLS_PATH))
+    ifdef USING_CYGWIN
+      DEVTOOLS_PATH :=$(UNIXCOMMAND_PATH)
+    else
+      xDEVTOOLS_PATH  :="$(_system_drive)/utils"
+      fxDEVTOOLS_PATH :=$(call FullPath,$(xDEVTOOLS_PATH))
+      DEVTOOLS_PATH  :=$(call PrefixPath,$(fxDEVTOOLS_PATH))
+    endif
   endif
+  DEVTOOLS_PATH:=$(call AltCheckSpaces,DEVTOOLS_PATH)
+  export DEVTOOLS_PATH
 endif
-DEVTOOLS_PATH:=$(call AltCheckSpaces,DEVTOOLS_PATH)
 
 # _BOOTDIR1: First choice for a Bootstrap JDK, previous released JDK.
 # _BOOTDIR2: Second choice
@@ -410,20 +415,26 @@
 
 # BUILD_JDK_IMPORT_PATH: location of JDK install trees to import for
 #   multiple platforms, e.g. windows-i586, solaris-sparc, linux-586, etc.
-ifdef ALT_BUILD_JDK_IMPORT_PATH
-  BUILD_JDK_IMPORT_PATH  :=$(call FullPath,$(ALT_BUILD_JDK_IMPORT_PATH))
-else
-  BUILD_JDK_IMPORT_PATH   = $(PROMOTED_BUILD_BINARIES)
+ifndef BUILD_JDK_IMPORT_PATH
+  ifdef ALT_BUILD_JDK_IMPORT_PATH
+    BUILD_JDK_IMPORT_PATH  :=$(call FullPath,$(ALT_BUILD_JDK_IMPORT_PATH))
+  else
+    BUILD_JDK_IMPORT_PATH   = $(PROMOTED_BUILD_BINARIES)
+  endif
+  BUILD_JDK_IMPORT_PATH:=$(call AltCheckSpaces,BUILD_JDK_IMPORT_PATH)
+  BUILD_JDK_IMPORT_PATH:=$(call AltCheckValue,BUILD_JDK_IMPORT_PATH)
+  export BUILD_JDK_IMPORT_PATH
 endif
-BUILD_JDK_IMPORT_PATH:=$(call AltCheckSpaces,BUILD_JDK_IMPORT_PATH)
-BUILD_JDK_IMPORT_PATH:=$(call AltCheckValue,BUILD_JDK_IMPORT_PATH)
 
 # JDK_IMPORT_PATH: location of previously built JDK (this version) to import
-ifdef ALT_JDK_IMPORT_PATH
-  JDK_IMPORT_PATH  :=$(call FullPath,$(ALT_JDK_IMPORT_PATH))
-else
-  JDK_IMPORT_PATH   = $(BUILD_JDK_IMPORT_PATH)/$(PLATFORM)-$(ARCH)$(_JDK_IMPORT_VARIANT)
+ifndef JDK_IMPORT_PATH
+  ifdef ALT_JDK_IMPORT_PATH
+    JDK_IMPORT_PATH  :=$(call FullPath,$(ALT_JDK_IMPORT_PATH))
+  else
+    JDK_IMPORT_PATH   = $(BUILD_JDK_IMPORT_PATH)/$(PLATFORM)-$(ARCH)$(_JDK_IMPORT_VARIANT)
+  endif
+  JDK_IMPORT_PATH:=$(call AltCheckSpaces,JDK_IMPORT_PATH)
+  JDK_IMPORT_PATH:=$(call AltCheckValue,JDK_IMPORT_PATH)
+  export JDK_IMPORT_PATH
 endif
-JDK_IMPORT_PATH:=$(call AltCheckSpaces,JDK_IMPORT_PATH)
-JDK_IMPORT_PATH:=$(call AltCheckValue,JDK_IMPORT_PATH)
 
--- a/corba/make/common/shared/Defs.gmk	Wed Oct 14 19:23:15 2009 +0400
+++ b/corba/make/common/shared/Defs.gmk	Thu Oct 15 16:37:55 2009 -0700
@@ -228,12 +228,15 @@
 endif
 
 # FULL_VERSION is RELEASE and -BUILD_NUMBER if BUILD_NUMBER is set
-ifdef BUILD_NUMBER
-  FULL_VERSION = $(RELEASE)-$(BUILD_NUMBER)
-else
-  BUILD_NUMBER = b00
-  USER_RELEASE_SUFFIX := $(shell echo $(USER)_`date '+%d_%b_%Y_%H_%M' | tr "A-Z" "a-z"`)
-  FULL_VERSION = $(RELEASE)-$(USER_RELEASE_SUFFIX)-$(BUILD_NUMBER)
+ifndef FULL_VERSION
+  ifdef BUILD_NUMBER
+    FULL_VERSION = $(RELEASE)-$(BUILD_NUMBER)
+  else
+    BUILD_NUMBER = b00
+    USER_RELEASE_SUFFIX := $(shell echo $(USER)_`date '+%d_%b_%Y_%H_%M' | tr "A-Z" "a-z"`)
+    FULL_VERSION = $(RELEASE)-$(USER_RELEASE_SUFFIX)-$(BUILD_NUMBER)
+  endif
+  export FULL_VERSION
 endif
 
 # Promoted build location
--- a/corba/make/common/shared/Platform.gmk	Wed Oct 14 19:23:15 2009 +0400
+++ b/corba/make/common/shared/Platform.gmk	Thu Oct 15 16:37:55 2009 -0700
@@ -84,21 +84,14 @@
 #     REQUIRED_LINUX_VER          linux only: required version of linux
 #     REQUIRED_LINUX_FULLVER      linux only: required full version of linux
 
-SYSTEM_UNAME := $(shell uname)
+ifndef SYSTEM_UNAME
+  SYSTEM_UNAME := $(shell uname)
+  export SYSTEM_UNAME
+endif
 
 # Normal boot jdk is previous release, but a hard requirement is a 1.5 boot
 REQUIRED_BOOT_VER = 1.5
 
-#
-# Prune out all known SCM (Source Code Management) directories
-# so they will not be included when copying directory trees
-# or packaging up .jar files, etc.  This applies to all workspaces.
-#
-SCM_DIRs = .hg .svn CVS RCS SCCS Codemgr_wsdata deleted_files
-# When changing SCM_DIRs also change SCM_DIRS_rexp and SCM_DIRS_prune:
-SCM_DIRS_rexp = ".hg|.svn|CVS|RCS|SCCS|Codemgr_wsdata|deleted_files"
-SCM_DIRS_prune = \( -name .hg -o -name .svn -o -name CVS -o -name RCS -o -name SCCS -o -name Codemgr_wsdata -o -name deleted_files \) -prune
-
 # Don't define this unless it's not defined
 ifndef VARIANT
   VARIANT=OPT
@@ -372,14 +365,17 @@
   REQUIRED_FREE_SPACE=500000
   OS_VENDOR = Microsoft
   # How much RAM does this machine have:
-  MB_OF_MEMORY := $(shell \
-    if [ -f "C:/cygwin/bin/free.exe" ] ; then \
-      ( C:/cygwin/bin/bash.exe -c "C:/cygwin/bin/free.exe -m" ) | \
-	grep Mem: | \
-	sed -e 's@\ \ *@ @g' | cut -d' ' -f2 ; \
-    else \
-      echo "512"; \
-    fi)
+  ifndef MB_OF_MEMORY
+    MB_OF_MEMORY := $(shell \
+      if [ -f "C:/cygwin/bin/free.exe" ] ; then \
+        ( C:/cygwin/bin/bash.exe -c "C:/cygwin/bin/free.exe -m" ) | \
+	  grep Mem: | \
+	  sed -e 's@\ \ *@ @g' | cut -d' ' -f2 ; \
+      else \
+        echo "512"; \
+      fi)
+    export MB_OF_MEMORY
+  endif
 endif
 
 # Machines with 512Mb or less of real memory are considered low memory
@@ -387,30 +383,36 @@
 #    system swapping during the build.
 #    If we don't know, assume 512. Subtract 128 from MB for VM MAX.
 #    Don't set VM max over 1024-128=896.
-ifneq ($(MB_OF_MEMORY),)
-  LOW_MEMORY_MACHINE := $(shell \
-    if [ $(MB_OF_MEMORY) -le 512 ] ; then \
-      echo "true"; \
-    else \
-      echo "false"; \
-    fi)
-  MAX_VM_MEMORY := $(shell \
-    if [ $(MB_OF_MEMORY) -le 1024 ] ; then \
-      expr $(MB_OF_MEMORY) '-' 128 ; \
-    else \
-      echo "896"; \
-    fi)
-  MIN_VM_MEMORY := $(shell \
-    if [ $(MAX_VM_MEMORY) -le 128 ] ; then \
-      expr $(MAX_VM_MEMORY) '-' 8 ; \
-    else \
-      echo "128"; \
-    fi)
-else
-  MB_OF_MEMORY       := unknown
-  LOW_MEMORY_MACHINE := true
-  MAX_VM_MEMORY      := 384
-  MIN_VM_MEMORY      := 128
+ifndef MAX_VM_MEMORY
+  ifneq ($(MB_OF_MEMORY),)
+    LOW_MEMORY_MACHINE := $(shell \
+      if [ $(MB_OF_MEMORY) -le 512 ] ; then \
+        echo "true"; \
+      else \
+        echo "false"; \
+      fi)
+    MAX_VM_MEMORY := $(shell \
+      if [ $(MB_OF_MEMORY) -le 1024 ] ; then \
+        expr $(MB_OF_MEMORY) '-' 128 ; \
+      else \
+        echo "896"; \
+      fi)
+    MIN_VM_MEMORY := $(shell \
+      if [ $(MAX_VM_MEMORY) -le 128 ] ; then \
+        expr $(MAX_VM_MEMORY) '-' 8 ; \
+      else \
+        echo "128"; \
+      fi)
+  else
+    MB_OF_MEMORY       := unknown
+    LOW_MEMORY_MACHINE := true
+    MAX_VM_MEMORY      := 384
+    MIN_VM_MEMORY      := 128
+  endif
+  export MAX_VM_MEMORY
+  export MIN_VM_MEMORY
+  export LOW_MEMORY_MACHINE
+  export MAX_VM_MEMORY
 endif
 
 REQUIRED_ZIP_VER = 2.2
--- a/corba/make/jprt.properties	Wed Oct 14 19:23:15 2009 +0400
+++ b/corba/make/jprt.properties	Thu Oct 15 16:37:55 2009 -0700
@@ -34,8 +34,8 @@
 solaris_x64_5.10,\
 linux_i586_2.6,\
 linux_x64_2.6,\
-windows_i586,\
-windows_x64
+windows_i586_5.0,\
+windows_x64_5.2
 
 # The different build flavors we want
 jprt.build.flavors=product,fastdebug
--- a/hotspot/.hgtags	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/.hgtags	Thu Oct 15 16:37:55 2009 -0700
@@ -46,3 +46,5 @@
 54fd4d9232969ea6cd3d236e5ad276183bb0d423 jdk7-b69
 0632c3e615a315ff11e2ab1d64f4d82ff9853461 jdk7-b70
 50a95aa4a247f0cbbf66df285a8b1d78ffb153d9 jdk7-b71
+a94714c550658fd6741793ef036cb9625dc2ab1a jdk7-b72
+faf94d94786b621f8e13cbcc941ca69c6d967c3f jdk7-b73
--- a/hotspot/agent/make/saenv.sh	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/agent/make/saenv.sh	Thu Oct 15 16:37:55 2009 -0700
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
--- a/hotspot/agent/make/saenv64.sh	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/agent/make/saenv64.sh	Thu Oct 15 16:37:55 2009 -0700
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
--- a/hotspot/agent/src/os/solaris/proc/Makefile	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/agent/src/os/solaris/proc/Makefile	Thu Oct 15 16:37:55 2009 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright 2002-2006 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2002-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
--- a/hotspot/agent/src/os/solaris/proc/mapfile	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/agent/src/os/solaris/proc/mapfile	Thu Oct 15 16:37:55 2009 -0700
@@ -1,7 +1,7 @@
 #
 
 #
-# Copyright 2003-2004 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java	Thu Oct 15 16:37:55 2009 -0700
@@ -33,6 +33,7 @@
 
 public class CodeCache {
   private static AddressField       heapField;
+  private static AddressField       scavengeRootNMethodsField;
   private static VirtualConstructor virtualConstructor;
 
   private CodeHeap heap;
@@ -49,6 +50,7 @@
     Type type = db.lookupType("CodeCache");
 
     heapField = type.getAddressField("_heap");
+    scavengeRootNMethodsField = type.getAddressField("_scavenge_root_nmethods");
 
     virtualConstructor = new VirtualConstructor(db);
     // Add mappings for all possible CodeBlob subclasses
@@ -67,6 +69,10 @@
     heap = (CodeHeap) VMObjectFactory.newObject(CodeHeap.class, heapField.getValue());
   }
 
+  public NMethod scavengeRootMethods() {
+    return (NMethod) VMObjectFactory.newObject(NMethod.class, scavengeRootNMethodsField.getValue());
+  }
+
   public boolean contains(Address p) {
     return getHeap().contains(p);
   }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java	Thu Oct 15 16:37:55 2009 -0700
@@ -40,7 +40,10 @@
   /** != InvocationEntryBci if this nmethod is an on-stack replacement method */
   private static CIntegerField entryBCIField;
   /** To support simple linked-list chaining of nmethods */
-  private static AddressField  linkField;
+  private static AddressField  osrLinkField;
+  private static AddressField  scavengeRootLinkField;
+  private static CIntegerField scavengeRootStateField;
+
   /** Offsets for different nmethod parts */
   private static CIntegerField exceptionOffsetField;
   private static CIntegerField deoptOffsetField;
@@ -87,7 +90,10 @@
     zombieInstructionSizeField  = type.getCIntegerField("_zombie_instruction_size");
     methodField                 = type.getOopField("_method");
     entryBCIField               = type.getCIntegerField("_entry_bci");
-    linkField                   = type.getAddressField("_link");
+    osrLinkField                = type.getAddressField("_osr_link");
+    scavengeRootLinkField       = type.getAddressField("_scavenge_root_link");
+    scavengeRootStateField      = type.getCIntegerField("_scavenge_root_state");
+
     exceptionOffsetField        = type.getCIntegerField("_exception_offset");
     deoptOffsetField            = type.getCIntegerField("_deoptimize_offset");
     origPCOffsetField           = type.getCIntegerField("_orig_pc_offset");
@@ -219,10 +225,19 @@
     return getEntryBCI();
   }
 
-  public NMethod getLink() {
-    return (NMethod) VMObjectFactory.newObject(NMethod.class, linkField.getValue(addr));
+  public NMethod getOSRLink() {
+    return (NMethod) VMObjectFactory.newObject(NMethod.class, osrLinkField.getValue(addr));
   }
 
+  public NMethod getScavengeRootLink() {
+    return (NMethod) VMObjectFactory.newObject(NMethod.class, scavengeRootLinkField.getValue(addr));
+  }
+
+  public int getScavengeRootState() {
+    return (int) scavengeRootStateField.getValue(addr);
+  }
+
+
   /** Tells whether frames described by this nmethod can be
       deoptimized. Note: native wrappers cannot be deoptimized. */
   public boolean canBeDeoptimized() { return isJavaMethod(); }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/CompactibleFreeListSpace.java	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/CompactibleFreeListSpace.java	Thu Oct 15 16:37:55 2009 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/FreeChunk.java	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/FreeChunk.java	Thu Oct 15 16:37:55 2009 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/make/hotspot_version	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/make/hotspot_version	Thu Oct 15 16:37:55 2009 -0700
@@ -35,7 +35,7 @@
 
 HS_MAJOR_VER=17
 HS_MINOR_VER=0
-HS_BUILD_NUMBER=01
+HS_BUILD_NUMBER=03
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=7
--- a/hotspot/make/linux/makefiles/jvmti.make	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/make/linux/makefiles/jvmti.make	Thu Oct 15 16:37:55 2009 -0700
@@ -70,10 +70,10 @@
 both = $(JvmtiGenClass) $(JvmtiSrcDir)/jvmti.xml $(JvmtiSrcDir)/jvmtiLib.xsl
 
 $(JvmtiGenClass): $(JvmtiGenSource)
-	$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -g -d $(JvmtiOutDir) $(JvmtiGenSource)
+	$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -d $(JvmtiOutDir) $(JvmtiGenSource)
 
 $(JvmtiEnvFillClass): $(JvmtiEnvFillSource)
-	$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -g -d $(JvmtiOutDir) $(JvmtiEnvFillSource)
+	$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -d $(JvmtiOutDir) $(JvmtiEnvFillSource)
 
 $(JvmtiOutDir)/jvmtiEnter.cpp: $(both) $(JvmtiSrcDir)/jvmtiEnter.xsl
 	@echo Generating $@
--- a/hotspot/make/linux/makefiles/mapfile-vers-debug	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/make/linux/makefiles/mapfile-vers-debug	Thu Oct 15 16:37:55 2009 -0700
@@ -74,6 +74,7 @@
                 JVM_CurrentTimeMillis;
                 JVM_DefineClass;
                 JVM_DefineClassWithSource;
+                JVM_DefineClassWithSourceCond;
                 JVM_DesiredAssertionStatus;
                 JVM_DisableCompiler;
                 JVM_DoPrivileged;
--- a/hotspot/make/linux/makefiles/mapfile-vers-product	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/make/linux/makefiles/mapfile-vers-product	Thu Oct 15 16:37:55 2009 -0700
@@ -74,6 +74,7 @@
                 JVM_CurrentTimeMillis;
                 JVM_DefineClass;
                 JVM_DefineClassWithSource;
+                JVM_DefineClassWithSourceCond;
                 JVM_DesiredAssertionStatus;
                 JVM_DisableCompiler;
                 JVM_DoPrivileged;
--- a/hotspot/make/linux/makefiles/rules.make	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/make/linux/makefiles/rules.make	Thu Oct 15 16:37:55 2009 -0700
@@ -122,12 +122,20 @@
 endif
 endif
 
+COMPILE.JAVAC += $(BOOTSTRAP_JAVAC_FLAGS)
+
 SUM = /usr/bin/sum
 
 # 'gmake MAKE_VERBOSE=y' gives all the gory details.
 QUIETLY$(MAKE_VERBOSE)  = @
 RUN.JAR$(MAKE_VERBOSE) += >/dev/null
 
+# Settings for javac
+BOOT_SOURCE_LANGUAGE_VERSION = 6
+BOOT_TARGET_CLASS_VERSION = 6
+JAVAC_FLAGS = -g -encoding ascii
+BOOTSTRAP_JAVAC_FLAGS = $(JAVAC_FLAGS) -source $(BOOT_SOURCE_LANGUAGE_VERSION) -target $(BOOT_TARGET_CLASS_VERSION)
+
 # With parallel makes, print a message at the end of compilation.
 ifeq    ($(findstring j,$(MFLAGS)),j)
 COMPILE_DONE    = && { echo Done with $<; }
--- a/hotspot/make/linux/makefiles/sa.make	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/make/linux/makefiles/sa.make	Thu Oct 15 16:37:55 2009 -0700
@@ -74,8 +74,8 @@
 	  mkdir -p $(SA_CLASSDIR);        \
 	fi
 
-	$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES1)
-	$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES2)
+	$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES1)
+	$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES2)
 
 	$(QUIETLY) $(REMOTE) $(COMPILE.RMIC)  -classpath $(SA_CLASSDIR) -d $(SA_CLASSDIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
 	$(QUIETLY) echo "$(SA_BUILD_VERSION_PROP)" > $(SA_PROPERTIES)
--- a/hotspot/make/linux/makefiles/top.make	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/make/linux/makefiles/top.make	Thu Oct 15 16:37:55 2009 -0700
@@ -24,7 +24,7 @@
 
 # top.make is included in the Makefile in the build directories.
 # It DOES NOT include the vm dependency info in order to be faster.
-# It's main job is to implement the incremental form of make lists.
+# Its main job is to implement the incremental form of make lists.
 # It also:
 #   -builds and runs adlc via adlc.make
 #   -generates JVMTI source and docs via jvmti.make (JSR-163)
@@ -114,7 +114,7 @@
 # make makeDeps: (and zap the cached db files to force a nonincremental run)
 
 $(GENERATED)/$(MakeDepsClass): $(MakeDepsSources)
-	@$(REMOTE) $(COMPILE.JAVAC) -classpath $(GAMMADIR)/src/share/tools/MakeDeps -g -d $(GENERATED) $(MakeDepsSources)
+	@$(REMOTE) $(COMPILE.JAVAC) -classpath $(GAMMADIR)/src/share/tools/MakeDeps -d $(GENERATED) $(MakeDepsSources)
 	@echo Removing $(Incremental_Lists) to force regeneration.
 	@rm -f $(Incremental_Lists)
 	@$(CDG) echo >$(Cached_plat)
--- a/hotspot/make/solaris/makefiles/jvmti.make	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/make/solaris/makefiles/jvmti.make	Thu Oct 15 16:37:55 2009 -0700
@@ -69,10 +69,10 @@
 both = $(JvmtiGenClass) $(JvmtiSrcDir)/jvmti.xml $(JvmtiSrcDir)/jvmtiLib.xsl
 
 $(JvmtiGenClass): $(JvmtiGenSource)
-	$(QUIETLY) $(COMPILE.JAVAC) -g -d $(JvmtiOutDir) $(JvmtiGenSource)
+	$(QUIETLY) $(COMPILE.JAVAC) -d $(JvmtiOutDir) $(JvmtiGenSource)
 
 $(JvmtiEnvFillClass): $(JvmtiEnvFillSource)
-	$(QUIETLY) $(COMPILE.JAVAC) -g -d $(JvmtiOutDir) $(JvmtiEnvFillSource)
+	$(QUIETLY) $(COMPILE.JAVAC) -d $(JvmtiOutDir) $(JvmtiEnvFillSource)
 
 $(JvmtiOutDir)/jvmtiEnter.cpp: $(both) $(JvmtiSrcDir)/jvmtiEnter.xsl
 	@echo Generating $@
--- a/hotspot/make/solaris/makefiles/mapfile-vers	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/make/solaris/makefiles/mapfile-vers	Thu Oct 15 16:37:55 2009 -0700
@@ -74,6 +74,7 @@
 		JVM_CurrentTimeMillis;
 		JVM_DefineClass;
 		JVM_DefineClassWithSource;
+		JVM_DefineClassWithSourceCond;
 		JVM_DesiredAssertionStatus;
 		JVM_DisableCompiler;
 		JVM_DoPrivileged;
--- a/hotspot/make/solaris/makefiles/rules.make	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/make/solaris/makefiles/rules.make	Thu Oct 15 16:37:55 2009 -0700
@@ -122,12 +122,20 @@
 endif
 endif
 
+COMPILE.JAVAC += $(BOOTSTRAP_JAVAC_FLAGS)
+
 SUM = /usr/bin/sum
 
 # 'gmake MAKE_VERBOSE=y' gives all the gory details.
 QUIETLY$(MAKE_VERBOSE)  = @
 RUN.JAR$(MAKE_VERBOSE) += >/dev/null
 
+# Settings for javac
+BOOT_SOURCE_LANGUAGE_VERSION = 6
+BOOT_TARGET_CLASS_VERSION = 6
+JAVAC_FLAGS = -g -encoding ascii
+BOOTSTRAP_JAVAC_FLAGS = $(JAVAC_FLAGS) -source $(BOOT_SOURCE_LANGUAGE_VERSION) -target $(BOOT_TARGET_CLASS_VERSION)
+
 # With parallel makes, print a message at the end of compilation.
 ifeq    ($(findstring j,$(MFLAGS)),j)
 COMPILE_DONE    = && { echo Done with $<; }
--- a/hotspot/make/solaris/makefiles/sa.make	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/make/solaris/makefiles/sa.make	Thu Oct 15 16:37:55 2009 -0700
@@ -67,8 +67,8 @@
 	$(QUIETLY) if [ ! -d $(SA_CLASSDIR) ] ; then \
 	  mkdir -p $(SA_CLASSDIR);        \
 	fi
-	$(QUIETLY) $(COMPILE.JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES1)
-	$(QUIETLY) $(COMPILE.JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES2)
+	$(QUIETLY) $(COMPILE.JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES1)
+	$(QUIETLY) $(COMPILE.JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES2)
 	
 	$(QUIETLY) $(COMPILE.RMIC)  -classpath $(SA_CLASSDIR) -d $(SA_CLASSDIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
 	$(QUIETLY) echo "$(SA_BUILD_VERSION_PROP)" > $(SA_PROPERTIES)
--- a/hotspot/make/solaris/makefiles/top.make	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/make/solaris/makefiles/top.make	Thu Oct 15 16:37:55 2009 -0700
@@ -24,7 +24,7 @@
 
 # top.make is included in the Makefile in the build directories.
 # It DOES NOT include the vm dependency info in order to be faster.
-# It's main job is to implement the incremental form of make lists.
+# Its main job is to implement the incremental form of make lists.
 # It also:
 #   -builds and runs adlc via adlc.make
 #   -generates JVMTI source and docs via jvmti.make (JSR-163)
@@ -112,7 +112,7 @@
 # make makeDeps: (and zap the cached db files to force a nonincremental run)
 
 $(GENERATED)/$(MakeDepsClass): $(MakeDepsSources)
-	@$(COMPILE.JAVAC) -classpath $(GAMMADIR)/src/share/tools/MakeDeps -g -d $(GENERATED) $(MakeDepsSources)
+	@$(COMPILE.JAVAC) -classpath $(GAMMADIR)/src/share/tools/MakeDeps -d $(GENERATED) $(MakeDepsSources)
 	@echo Removing $(Incremental_Lists) to force regeneration.
 	@rm -f $(Incremental_Lists)
 	@$(CDG) echo >$(Cached_plat)
--- a/hotspot/make/windows/makefiles/generated.make	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/make/windows/makefiles/generated.make	Thu Oct 15 16:37:55 2009 -0700
@@ -91,7 +91,7 @@
 classes/MakeDeps.class: $(MakeDepsSources)
 	if exist classes rmdir /s /q classes
 	mkdir classes
-	$(COMPILE_JAVAC) -classpath $(WorkSpace)\src\share\tools\MakeDeps -g -d classes $(MakeDepsSources)
+	$(COMPILE_JAVAC) -classpath $(WorkSpace)\src\share\tools\MakeDeps -d classes $(MakeDepsSources)
 
 !if ("$(Variant)" == "compiler2") || ("$(Variant)" == "tiered")
 
--- a/hotspot/make/windows/makefiles/jvmti.make	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/make/windows/makefiles/jvmti.make	Thu Oct 15 16:37:55 2009 -0700
@@ -68,10 +68,10 @@
         @if not exist $(JvmtiOutDir) mkdir $(JvmtiOutDir)
 
 $(JvmtiGenClass): $(JvmtiGenSource)
-	$(COMPILE_JAVAC) -g -d $(JvmtiOutDir) $(JvmtiGenSource)
+	$(COMPILE_JAVAC) -d $(JvmtiOutDir) $(JvmtiGenSource)
 
 $(JvmtiEnvFillClass): $(JvmtiEnvFillSource)
-	@$(COMPILE_JAVAC) -g -d $(JvmtiOutDir) $(JvmtiEnvFillSource)
+	@$(COMPILE_JAVAC) -d $(JvmtiOutDir) $(JvmtiEnvFillSource)
 
 $(JvmtiOutDir)/jvmtiEnter.cpp: $(both) $(JvmtiSrcDir)/jvmtiEnter.xsl
 	@echo Generating $@
--- a/hotspot/make/windows/makefiles/rules.make	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/make/windows/makefiles/rules.make	Thu Oct 15 16:37:55 2009 -0700
@@ -29,7 +29,7 @@
 RUN_JAVAP=$(BootStrapDir)\bin\javap
 RUN_JAVAH=$(BootStrapDir)\bin\javah
 RUN_JAR=$(BootStrapDir)\bin\jar
-COMPILE_JAVAC=$(BootStrapDir)\bin\javac
+COMPILE_JAVAC=$(BootStrapDir)\bin\javac $(BOOTSTRAP_JAVAC_FLAGS)
 COMPILE_RMIC=$(BootStrapDir)\bin\rmic
 BOOT_JAVA_HOME=$(BootStrapDir)
 !else
@@ -37,11 +37,17 @@
 RUN_JAVAP=javap
 RUN_JAVAH=javah
 RUN_JAR=jar
-COMPILE_JAVAC=javac
+COMPILE_JAVAC=javac $(BOOTSTRAP_JAVAC_FLAGS)
 COMPILE_RMIC=rmic
 BOOT_JAVA_HOME=
 !endif
 
+# Settings for javac
+BOOT_SOURCE_LANGUAGE_VERSION=6
+BOOT_TARGET_CLASS_VERSION=6
+JAVAC_FLAGS=-g -encoding ascii
+BOOTSTRAP_JAVAC_FLAGS=$(JAVAC_FLAGS) -source $(BOOT_SOURCE_LANGUAGE_VERSION) -target $(BOOT_TARGET_CLASS_VERSION)
+
 ProjectFile=vm.vcproj
 
 !if "$(MSC_VER)" == "1200"
--- a/hotspot/make/windows/makefiles/sa.make	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/make/windows/makefiles/sa.make	Thu Oct 15 16:37:55 2009 -0700
@@ -55,9 +55,9 @@
 $(GENERATED)\sa-jdi.jar: $(AGENT_FILES1:/=\) $(AGENT_FILES2:/=\)
 	@if not exist $(SA_CLASSDIR) mkdir $(SA_CLASSDIR)
 	@echo ...Building sa-jdi.jar
-	@echo ...$(COMPILE_JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -g -d $(SA_CLASSDIR) ....
-	@$(COMPILE_JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES1:/=\)
-	@$(COMPILE_JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES2:/=\)
+	@echo ...$(COMPILE_JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -d $(SA_CLASSDIR) ....
+	@$(COMPILE_JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES1:/=\)
+	@$(COMPILE_JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES2:/=\)
 	$(COMPILE_RMIC) -classpath $(SA_CLASSDIR) -d $(SA_CLASSDIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
 	$(QUIETLY) echo $(SA_BUILD_VERSION_PROP)> $(SA_PROPERTIES)
 	$(QUIETLY) rm -f $(SA_CLASSDIR)/sun/jvm/hotspot/utilities/soql/sa.js
--- a/hotspot/make/windows/projectfiles/common/Makefile	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/make/windows/projectfiles/common/Makefile	Thu Oct 15 16:37:55 2009 -0700
@@ -179,6 +179,6 @@
 $(HOTSPOTBUILDSPACE)/classes/MakeDeps.class: $(MakeDepsSources)
 	@if exist $(HOTSPOTBUILDSPACE)\classes rmdir /s /q $(HOTSPOTBUILDSPACE)\classes
 	@mkdir $(HOTSPOTBUILDSPACE)\classes
-	@$(COMPILE_JAVAC) -classpath $(HOTSPOTWORKSPACE)\src\share\tools\MakeDeps -g -d $(HOTSPOTBUILDSPACE)/classes $(MakeDepsSources)
+	@$(COMPILE_JAVAC) -classpath $(HOTSPOTWORKSPACE)\src\share\tools\MakeDeps -d $(HOTSPOTBUILDSPACE)/classes $(MakeDepsSources)
 
 FORCE:
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -4676,3 +4676,50 @@
     load_ptr_contents(base, G6_heapbase);
   }
 }
+
+// Compare char[] arrays aligned to 4 bytes.
+void MacroAssembler::char_arrays_equals(Register ary1, Register ary2,
+                                        Register limit, Register result,
+                                        Register chr1, Register chr2, Label& Ldone) {
+  Label Lvector, Lloop;
+  assert(chr1 == result, "should be the same");
+
+  // Note: limit contains number of bytes (2*char_elements) != 0.
+  andcc(limit, 0x2, chr1); // trailing character ?
+  br(Assembler::zero, false, Assembler::pt, Lvector);
+  delayed()->nop();
+
+  // compare the trailing char
+  sub(limit, sizeof(jchar), limit);
+  lduh(ary1, limit, chr1);
+  lduh(ary2, limit, chr2);
+  cmp(chr1, chr2);
+  br(Assembler::notEqual, true, Assembler::pt, Ldone);
+  delayed()->mov(G0, result);     // not equal
+
+  // only one char ?
+  br_on_reg_cond(rc_z, true, Assembler::pn, limit, Ldone);
+  delayed()->add(G0, 1, result); // zero-length arrays are equal
+
+  // word by word compare, dont't need alignment check
+  bind(Lvector);
+  // Shift ary1 and ary2 to the end of the arrays, negate limit
+  add(ary1, limit, ary1);
+  add(ary2, limit, ary2);
+  neg(limit, limit);
+
+  lduw(ary1, limit, chr1);
+  bind(Lloop);
+  lduw(ary2, limit, chr2);
+  cmp(chr1, chr2);
+  br(Assembler::notEqual, true, Assembler::pt, Ldone);
+  delayed()->mov(G0, result);     // not equal
+  inccc(limit, 2*sizeof(jchar));
+  // annul LDUW if branch is not taken to prevent access past end of array
+  br(Assembler::notZero, true, Assembler::pt, Lloop);
+  delayed()->lduw(ary1, limit, chr1); // hoisted
+
+  // Caller should set it:
+  // add(G0, 1, result); // equals
+}
+
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp	Thu Oct 15 16:37:55 2009 -0700
@@ -2455,6 +2455,11 @@
   void inc_counter(address counter_addr, Register Rtmp1, Register Rtmp2);
   void inc_counter(int*    counter_addr, Register Rtmp1, Register Rtmp2);
 
+  // Compare char[] arrays aligned to 4 bytes.
+  void char_arrays_equals(Register ary1, Register ary2,
+                          Register limit, Register result,
+                          Register chr1, Register chr2, Label& Ldone);
+
 #undef VIRTUAL
 
 };
--- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -2171,7 +2171,7 @@
     // subtype which we can't check or src is the same array as dst
     // but not necessarily exactly of type default_type.
     Label known_ok, halt;
-    jobject2reg(op->expected_type()->encoding(), tmp);
+    jobject2reg(op->expected_type()->constant_encoding(), tmp);
     __ ld_ptr(dst, oopDesc::klass_offset_in_bytes(), tmp2);
     if (basic_type != T_OBJECT) {
       __ cmp(tmp, tmp2);
@@ -2429,7 +2429,7 @@
       assert(data->is_BitData(), "need BitData for checkcast");
       Register mdo      = k_RInfo;
       Register data_val = Rtmp1;
-      jobject2reg(md->encoding(), mdo);
+      jobject2reg(md->constant_encoding(), mdo);
 
       int mdo_offset_bias = 0;
       if (!Assembler::is_simm13(md->byte_offset_of_slot(data, DataLayout::header_offset()) + data->size_in_bytes())) {
@@ -2452,7 +2452,7 @@
     // patching may screw with our temporaries on sparc,
     // so let's do it before loading the class
     if (k->is_loaded()) {
-      jobject2reg(k->encoding(), k_RInfo);
+      jobject2reg(k->constant_encoding(), k_RInfo);
     } else {
       jobject2reg_with_patching(k_RInfo, op->info_for_patch());
     }
@@ -2513,7 +2513,7 @@
     // patching may screw with our temporaries on sparc,
     // so let's do it before loading the class
     if (k->is_loaded()) {
-      jobject2reg(k->encoding(), k_RInfo);
+      jobject2reg(k->constant_encoding(), k_RInfo);
     } else {
       jobject2reg_with_patching(k_RInfo, op->info_for_patch());
     }
@@ -2717,7 +2717,7 @@
   assert(op->tmp1()->is_single_cpu(), "tmp1 must be allocated");
   Register mdo  = op->mdo()->as_register();
   Register tmp1 = op->tmp1()->as_register();
-  jobject2reg(md->encoding(), mdo);
+  jobject2reg(md->constant_encoding(), mdo);
   int mdo_offset_bias = 0;
   if (!Assembler::is_simm13(md->byte_offset_of_slot(data, CounterData::count_offset()) +
                             data->size_in_bytes())) {
@@ -2774,7 +2774,7 @@
         if (receiver == NULL) {
           Address recv_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i)) -
                             mdo_offset_bias);
-          jobject2reg(known_klass->encoding(), tmp1);
+          jobject2reg(known_klass->constant_encoding(), tmp1);
           __ st_ptr(tmp1, recv_addr);
           Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i)) -
                             mdo_offset_bias);
--- a/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -668,7 +668,7 @@
   __ add(obj.result(), offset.result(), addr);
 
   if (type == objectType) {  // Write-barrier needed for Object fields.
-    pre_barrier(obj.result(), false, NULL);
+    pre_barrier(addr, false, NULL);
   }
 
   if (type == objectType)
@@ -896,7 +896,7 @@
   LIR_Opr len = length.result();
   BasicType elem_type = x->elt_type();
 
-  __ oop2reg(ciTypeArrayKlass::make(elem_type)->encoding(), klass_reg);
+  __ oop2reg(ciTypeArrayKlass::make(elem_type)->constant_encoding(), klass_reg);
 
   CodeStub* slow_path = new NewTypeArrayStub(klass_reg, len, reg, info);
   __ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, elem_type, klass_reg, slow_path);
--- a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -1696,6 +1696,9 @@
 void InterpreterMacroAssembler::record_klass_in_profile_helper(
                                         Register receiver, Register scratch,
                                         int start_row, Label& done) {
+  if (TypeProfileWidth == 0)
+    return;
+
   int last_row = VirtualCallData::row_limit() - 1;
   assert(start_row <= last_row, "must be work left to do");
   // Test this row for both the receiver and for null.
--- a/hotspot/src/cpu/sparc/vm/sparc.ad	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad	Thu Oct 15 16:37:55 2009 -0700
@@ -2838,63 +2838,41 @@
   %}
 
 
-  enc_class enc_String_Compare(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result) %{
+  enc_class enc_String_Compare(o0RegP str1, o1RegP str2, g3RegI cnt1, g4RegI cnt2, notemp_iRegI result) %{
     Label Ldone, Lloop;
     MacroAssembler _masm(&cbuf);
 
     Register   str1_reg = reg_to_register_object($str1$$reg);
     Register   str2_reg = reg_to_register_object($str2$$reg);
-    Register   tmp1_reg = reg_to_register_object($tmp1$$reg);
-    Register   tmp2_reg = reg_to_register_object($tmp2$$reg);
+    Register   cnt1_reg = reg_to_register_object($cnt1$$reg);
+    Register   cnt2_reg = reg_to_register_object($cnt2$$reg);
     Register result_reg = reg_to_register_object($result$$reg);
 
-    // Get the first character position in both strings
-    //         [8] char array, [12] offset, [16] count
-    int  value_offset = java_lang_String:: value_offset_in_bytes();
-    int offset_offset = java_lang_String::offset_offset_in_bytes();
-    int  count_offset = java_lang_String:: count_offset_in_bytes();
-
-    // load str1 (jchar*) base address into tmp1_reg
-    __ load_heap_oop(str1_reg, value_offset, tmp1_reg);
-    __ ld(str1_reg, offset_offset, result_reg);
-    __ add(tmp1_reg, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp1_reg);
-    __   ld(str1_reg, count_offset, str1_reg); // hoisted
-    __ sll(result_reg, exact_log2(sizeof(jchar)), result_reg);
-    __   load_heap_oop(str2_reg, value_offset, tmp2_reg); // hoisted
-    __ add(result_reg, tmp1_reg, tmp1_reg);
-
-    // load str2 (jchar*) base address into tmp2_reg
-    // __ ld_ptr(str2_reg, value_offset, tmp2_reg); // hoisted
-    __ ld(str2_reg, offset_offset, result_reg);
-    __ add(tmp2_reg, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp2_reg);
-    __   ld(str2_reg, count_offset, str2_reg); // hoisted
-    __ sll(result_reg, exact_log2(sizeof(jchar)), result_reg);
-    __   subcc(str1_reg, str2_reg, O7); // hoisted
-    __ add(result_reg, tmp2_reg, tmp2_reg);
+    assert(result_reg != str1_reg &&
+           result_reg != str2_reg &&
+           result_reg != cnt1_reg &&
+           result_reg != cnt2_reg ,
+           "need different registers");
 
     // Compute the minimum of the string lengths(str1_reg) and the
     // difference of the string lengths (stack)
 
-    // discard string base pointers, after loading up the lengths
-    // __ ld(str1_reg, count_offset, str1_reg); // hoisted
-    // __ ld(str2_reg, count_offset, str2_reg); // hoisted
-
     // See if the lengths are different, and calculate min in str1_reg.
     // Stash diff in O7 in case we need it for a tie-breaker.
     Label Lskip;
-    // __ subcc(str1_reg, str2_reg, O7); // hoisted
-    __ sll(str1_reg, exact_log2(sizeof(jchar)), str1_reg); // scale the limit
+    __ subcc(cnt1_reg, cnt2_reg, O7);
+    __ sll(cnt1_reg, exact_log2(sizeof(jchar)), cnt1_reg); // scale the limit
     __ br(Assembler::greater, true, Assembler::pt, Lskip);
-    // str2 is shorter, so use its count:
-    __ delayed()->sll(str2_reg, exact_log2(sizeof(jchar)), str1_reg); // scale the limit
+    // cnt2 is shorter, so use its count:
+    __ delayed()->sll(cnt2_reg, exact_log2(sizeof(jchar)), cnt1_reg); // scale the limit
     __ bind(Lskip);
 
-    // reallocate str1_reg, str2_reg, result_reg
+    // reallocate cnt1_reg, cnt2_reg, result_reg
     // Note:  limit_reg holds the string length pre-scaled by 2
-    Register limit_reg =   str1_reg;
-    Register  chr2_reg =   str2_reg;
+    Register limit_reg =   cnt1_reg;
+    Register  chr2_reg =   cnt2_reg;
     Register  chr1_reg = result_reg;
-    // tmp{12} are the base pointers
+    // str{12} are the base pointers
 
     // Is the minimum length zero?
     __ cmp(limit_reg, (int)(0 * sizeof(jchar))); // use cast to resolve overloading ambiguity
@@ -2902,8 +2880,8 @@
     __ delayed()->mov(O7, result_reg);  // result is difference in lengths
 
     // Load first characters
-    __ lduh(tmp1_reg, 0, chr1_reg);
-    __ lduh(tmp2_reg, 0, chr2_reg);
+    __ lduh(str1_reg, 0, chr1_reg);
+    __ lduh(str2_reg, 0, chr2_reg);
 
     // Compare first characters
     __ subcc(chr1_reg, chr2_reg, chr1_reg);
@@ -2915,7 +2893,7 @@
       // Check after comparing first character to see if strings are equivalent
       Label LSkip2;
       // Check if the strings start at same location
-      __ cmp(tmp1_reg, tmp2_reg);
+      __ cmp(str1_reg, str2_reg);
       __ brx(Assembler::notEqual, true, Assembler::pt, LSkip2);
       __ delayed()->nop();
 
@@ -2932,23 +2910,23 @@
     __ br(Assembler::equal, true, Assembler::pn, Ldone);
     __ delayed()->mov(O7, result_reg);  // result is difference in lengths
 
-    // Shift tmp1_reg and tmp2_reg to the end of the arrays, negate limit
-    __ add(tmp1_reg, limit_reg, tmp1_reg);
-    __ add(tmp2_reg, limit_reg, tmp2_reg);
+    // Shift str1_reg and str2_reg to the end of the arrays, negate limit
+    __ add(str1_reg, limit_reg, str1_reg);
+    __ add(str2_reg, limit_reg, str2_reg);
     __ neg(chr1_reg, limit_reg);  // limit = -(limit-2)
 
     // Compare the rest of the characters
-    __ lduh(tmp1_reg, limit_reg, chr1_reg);
+    __ lduh(str1_reg, limit_reg, chr1_reg);
     __ bind(Lloop);
-    // __ lduh(tmp1_reg, limit_reg, chr1_reg); // hoisted
-    __ lduh(tmp2_reg, limit_reg, chr2_reg);
+    // __ lduh(str1_reg, limit_reg, chr1_reg); // hoisted
+    __ lduh(str2_reg, limit_reg, chr2_reg);
     __ subcc(chr1_reg, chr2_reg, chr1_reg);
     __ br(Assembler::notZero, false, Assembler::pt, Ldone);
     assert(chr1_reg == result_reg, "result must be pre-placed");
     __ delayed()->inccc(limit_reg, sizeof(jchar));
     // annul LDUH if branch is not taken to prevent access past end of string
     __ br(Assembler::notZero, true, Assembler::pt, Lloop);
-    __ delayed()->lduh(tmp1_reg, limit_reg, chr1_reg); // hoisted
+    __ delayed()->lduh(str1_reg, limit_reg, chr1_reg); // hoisted
 
     // If strings are equal up to min length, return the length difference.
     __ mov(O7, result_reg);
@@ -2957,125 +2935,80 @@
     __ bind(Ldone);
   %}
 
-enc_class enc_String_Equals(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result) %{
-    Label Lword, Lword_loop, Lpost_word, Lchar, Lchar_loop, Ldone;
+enc_class enc_String_Equals(o0RegP str1, o1RegP str2, g3RegI cnt, notemp_iRegI result) %{
+    Label Lword_loop, Lpost_word, Lchar, Lchar_loop, Ldone;
     MacroAssembler _masm(&cbuf);
 
     Register   str1_reg = reg_to_register_object($str1$$reg);
     Register   str2_reg = reg_to_register_object($str2$$reg);
-    Register   tmp1_reg = reg_to_register_object($tmp1$$reg);
-    Register   tmp2_reg = reg_to_register_object($tmp2$$reg);
+    Register    cnt_reg = reg_to_register_object($cnt$$reg);
+    Register   tmp1_reg = O7;
     Register result_reg = reg_to_register_object($result$$reg);
 
-    // Get the first character position in both strings
-    //         [8] char array, [12] offset, [16] count
-    int  value_offset = java_lang_String:: value_offset_in_bytes();
-    int offset_offset = java_lang_String::offset_offset_in_bytes();
-    int  count_offset = java_lang_String:: count_offset_in_bytes();
-
-    // load str1 (jchar*) base address into tmp1_reg
-    __ load_heap_oop(Address(str1_reg, value_offset), tmp1_reg);
-    __ ld(Address(str1_reg, offset_offset), result_reg);
-    __ add(tmp1_reg, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp1_reg);
-    __    ld(Address(str1_reg, count_offset), str1_reg); // hoisted
-    __ sll(result_reg, exact_log2(sizeof(jchar)), result_reg);
-    __    load_heap_oop(Address(str2_reg, value_offset), tmp2_reg); // hoisted
-    __ add(result_reg, tmp1_reg, tmp1_reg);
-
-    // load str2 (jchar*) base address into tmp2_reg
-    // __ ld_ptr(Address(str2_reg, value_offset), tmp2_reg); // hoisted
-    __ ld(Address(str2_reg, offset_offset), result_reg);
-    __ add(tmp2_reg, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp2_reg);
-    __    ld(Address(str2_reg, count_offset), str2_reg); // hoisted
-    __ sll(result_reg, exact_log2(sizeof(jchar)), result_reg);
-    __   cmp(str1_reg, str2_reg); // hoisted
-    __ add(result_reg, tmp2_reg, tmp2_reg);
-
-    __ sll(str1_reg, exact_log2(sizeof(jchar)), str1_reg);
-    __ br(Assembler::notEqual, true, Assembler::pt, Ldone);
-    __ delayed()->mov(G0, result_reg);    // not equal
-
-    __ br_zero(Assembler::equal, true, Assembler::pn, str1_reg, Ldone);
-    __ delayed()->add(G0, 1, result_reg); //equals
-
-    __ cmp(tmp1_reg, tmp2_reg); //same string ?
+    assert(result_reg != str1_reg &&
+           result_reg != str2_reg &&
+           result_reg !=  cnt_reg &&
+           result_reg != tmp1_reg ,
+           "need different registers");
+
+    __ cmp(str1_reg, str2_reg); //same char[] ?
     __ brx(Assembler::equal, true, Assembler::pn, Ldone);
     __ delayed()->add(G0, 1, result_reg);
 
+    __ br_on_reg_cond(Assembler::rc_z, true, Assembler::pn, cnt_reg, Ldone);
+    __ delayed()->add(G0, 1, result_reg); // count == 0
+
     //rename registers
-    Register limit_reg =   str1_reg;
-    Register  chr2_reg =   str2_reg;
+    Register limit_reg =    cnt_reg;
     Register  chr1_reg = result_reg;
-    // tmp{12} are the base pointers
+    Register  chr2_reg =   tmp1_reg;
 
     //check for alignment and position the pointers to the ends
-    __ or3(tmp1_reg, tmp2_reg, chr1_reg);
-    __ andcc(chr1_reg, 0x3, chr1_reg); // notZero means at least one not 4-byte aligned
-    __ br(Assembler::notZero, false, Assembler::pn, Lchar);
-    __ delayed()->nop();
-
-    __ bind(Lword);
-    __ and3(limit_reg, 0x2, O7); //remember the remainder (either 0 or 2)
-    __ andn(limit_reg, 0x3, limit_reg);
-    __ br_zero(Assembler::zero, false, Assembler::pn, limit_reg, Lpost_word);
-    __ delayed()->nop();
-
-    __ add(tmp1_reg, limit_reg, tmp1_reg);
-    __ add(tmp2_reg, limit_reg, tmp2_reg);
-    __ neg(limit_reg);
-
-    __ lduw(tmp1_reg, limit_reg, chr1_reg);
-    __ bind(Lword_loop);
-    __ lduw(tmp2_reg, limit_reg, chr2_reg);
-    __ cmp(chr1_reg, chr2_reg);
-    __ br(Assembler::notEqual, true, Assembler::pt, Ldone);
-    __ delayed()->mov(G0, result_reg);
-    __ inccc(limit_reg, 2*sizeof(jchar));
-    // annul LDUW if branch i  s not taken to prevent access past end of string
-    __ br(Assembler::notZero, true, Assembler::pt, Lword_loop); //annul on taken
-    __ delayed()->lduw(tmp1_reg, limit_reg, chr1_reg); // hoisted
-
-    __ bind(Lpost_word);
-    __ br_zero(Assembler::zero, true, Assembler::pt, O7, Ldone);
-    __ delayed()->add(G0, 1, result_reg);
-
-    __ lduh(tmp1_reg, 0, chr1_reg);
-    __ lduh(tmp2_reg, 0, chr2_reg);
-    __ cmp (chr1_reg, chr2_reg);
-    __ br(Assembler::notEqual, true, Assembler::pt, Ldone);
-    __ delayed()->mov(G0, result_reg);
+    __ or3(str1_reg, str2_reg, chr1_reg);
+    __ andcc(chr1_reg, 0x3, chr1_reg);
+    // notZero means at least one not 4-byte aligned.
+    // We could optimize the case when both arrays are not aligned
+    // but it is not frequent case and it requires additional checks.
+    __ br(Assembler::notZero, false, Assembler::pn, Lchar); // char by char compare
+    __ delayed()->sll(limit_reg, exact_log2(sizeof(jchar)), limit_reg); // set byte count
+
+    // Compare char[] arrays aligned to 4 bytes.
+    __ char_arrays_equals(str1_reg, str2_reg, limit_reg, result_reg,
+                          chr1_reg, chr2_reg, Ldone);
     __ ba(false,Ldone);
     __ delayed()->add(G0, 1, result_reg);
 
+    // char by char compare
     __ bind(Lchar);
-    __ add(tmp1_reg, limit_reg, tmp1_reg);
-    __ add(tmp2_reg, limit_reg, tmp2_reg);
+    __ add(str1_reg, limit_reg, str1_reg);
+    __ add(str2_reg, limit_reg, str2_reg);
     __ neg(limit_reg); //negate count
 
-    __ lduh(tmp1_reg, limit_reg, chr1_reg);
+    __ lduh(str1_reg, limit_reg, chr1_reg);
+    // Lchar_loop
     __ bind(Lchar_loop);
-    __ lduh(tmp2_reg, limit_reg, chr2_reg);
+    __ lduh(str2_reg, limit_reg, chr2_reg);
     __ cmp(chr1_reg, chr2_reg);
     __ br(Assembler::notEqual, true, Assembler::pt, Ldone);
     __ delayed()->mov(G0, result_reg); //not equal
     __ inccc(limit_reg, sizeof(jchar));
     // annul LDUH if branch is not taken to prevent access past end of string
-    __ br(Assembler::notZero, true, Assembler::pt, Lchar_loop); //annul on taken
-    __ delayed()->lduh(tmp1_reg, limit_reg, chr1_reg); // hoisted
+    __ br(Assembler::notZero, true, Assembler::pt, Lchar_loop);
+    __ delayed()->lduh(str1_reg, limit_reg, chr1_reg); // hoisted
 
     __ add(G0, 1, result_reg);  //equal
 
     __ bind(Ldone);
   %}
 
-enc_class enc_Array_Equals(o0RegP ary1, o1RegP ary2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result) %{
+enc_class enc_Array_Equals(o0RegP ary1, o1RegP ary2, g3RegP tmp1, notemp_iRegI result) %{
     Label Lvector, Ldone, Lloop;
     MacroAssembler _masm(&cbuf);
 
     Register   ary1_reg = reg_to_register_object($ary1$$reg);
     Register   ary2_reg = reg_to_register_object($ary2$$reg);
     Register   tmp1_reg = reg_to_register_object($tmp1$$reg);
-    Register   tmp2_reg = reg_to_register_object($tmp2$$reg);
+    Register   tmp2_reg = O7;
     Register result_reg = reg_to_register_object($result$$reg);
 
     int length_offset  = arrayOopDesc::length_offset_in_bytes();
@@ -3101,7 +3034,7 @@
     __ br(Assembler::notEqual, true, Assembler::pn, Ldone);
     __ delayed()->mov(G0, result_reg);     // not equal
 
-    __ br_zero(Assembler::zero, true, Assembler::pn, tmp1_reg, Ldone);
+    __ br_on_reg_cond(Assembler::rc_z, true, Assembler::pn, tmp1_reg, Ldone);
     __ delayed()->add(G0, 1, result_reg); // zero-length arrays are equal
 
     // load array addresses
@@ -3109,45 +3042,16 @@
     __ add(ary2_reg, base_offset, ary2_reg);
 
     // renaming registers
-    Register chr1_reg  =  tmp2_reg;   // for characters in ary1
-    Register chr2_reg  =  result_reg; // for characters in ary2
+    Register chr1_reg  =  result_reg; // for characters in ary1
+    Register chr2_reg  =  tmp2_reg;   // for characters in ary2
     Register limit_reg =  tmp1_reg;   // length
 
     // set byte count
     __ sll(limit_reg, exact_log2(sizeof(jchar)), limit_reg);
-    __ andcc(limit_reg, 0x2, chr1_reg); //trailing character ?
-    __ br(Assembler::zero, false, Assembler::pt, Lvector);
-    __ delayed()->nop();
-
-    //compare the trailing char
-    __ sub(limit_reg, sizeof(jchar), limit_reg);
-    __ lduh(ary1_reg, limit_reg, chr1_reg);
-    __ lduh(ary2_reg, limit_reg, chr2_reg);
-    __ cmp(chr1_reg, chr2_reg);
-    __ br(Assembler::notEqual, true, Assembler::pt, Ldone);
-    __ delayed()->mov(G0, result_reg);     // not equal
-
-    // only one char ?
-    __ br_zero(Assembler::zero, true, Assembler::pn, limit_reg, Ldone);
-    __ delayed()->add(G0, 1, result_reg); // zero-length arrays are equal
-
-    __ bind(Lvector);
-    // Shift ary1_reg and ary2_reg to the end of the arrays, negate limit
-    __ add(ary1_reg, limit_reg, ary1_reg);
-    __ add(ary2_reg, limit_reg, ary2_reg);
-    __ neg(limit_reg, limit_reg);
-
-    __ lduw(ary1_reg, limit_reg, chr1_reg);
-    __ bind(Lloop);
-    __ lduw(ary2_reg, limit_reg, chr2_reg);
-    __ cmp(chr1_reg, chr2_reg);
-    __ br(Assembler::notEqual, false, Assembler::pt, Ldone);
-    __ delayed()->mov(G0, result_reg);     // not equal
-    __ inccc(limit_reg, 2*sizeof(jchar));
-    // annul LDUW if branch is not taken to prevent access past end of string
-    __ br(Assembler::notZero, true, Assembler::pt, Lloop); //annul on taken
-    __ delayed()->lduw(ary1_reg, limit_reg, chr1_reg); // hoisted
-
+
+    // Compare char[] arrays aligned to 4 bytes.
+    __ char_arrays_equals(ary1_reg, ary2_reg, limit_reg, result_reg,
+                          chr1_reg, chr2_reg, Ldone);
     __ add(G0, 1, result_reg); // equals
 
     __ bind(Ldone);
@@ -5707,7 +5611,7 @@
   effect(TEMP dst, TEMP tmp);
   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
 
-  size(3*4);
+  size((3+1)*4);  // set may use two instructions.
   format %{ "LDUH   $mem,$dst\t! ushort/char & 16-bit mask -> long\n\t"
             "SET    $mask,$tmp\n\t"
             "AND    $dst,$tmp,$dst" %}
@@ -5851,7 +5755,7 @@
   effect(TEMP dst, TEMP tmp);
   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
 
-  size(3*4);
+  size((3+1)*4);  // set may use two instructions.
   format %{ "LDUW   $mem,$dst\t! int & 32-bit mask -> long\n\t"
             "SET    $mask,$tmp\n\t"
             "AND    $dst,$tmp,$dst" %}
@@ -9471,33 +9375,33 @@
   ins_pipe(long_memory_op);
 %}
 
-instruct string_compare(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result,
-                        o7RegI tmp3, flagsReg ccr) %{
-  match(Set result (StrComp str1 str2));
-  effect(USE_KILL str1, USE_KILL str2, KILL tmp1, KILL tmp2, KILL ccr, KILL tmp3);
+instruct string_compare(o0RegP str1, o1RegP str2, g3RegI cnt1, g4RegI cnt2, notemp_iRegI result,
+                        o7RegI tmp, flagsReg ccr) %{
+  match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
+  effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ccr, KILL tmp);
   ins_cost(300);
-  format %{ "String Compare $str1,$str2 -> $result" %}
-  ins_encode( enc_String_Compare(str1, str2, tmp1, tmp2, result) );
+  format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   // KILL $tmp" %}
+  ins_encode( enc_String_Compare(str1, str2, cnt1, cnt2, result) );
   ins_pipe(long_memory_op);
 %}
 
-instruct string_equals(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result,
-                       o7RegI tmp3, flagsReg ccr) %{
-  match(Set result (StrEquals str1 str2));
-  effect(USE_KILL str1, USE_KILL str2, KILL tmp1, KILL tmp2, KILL ccr, KILL tmp3);
+instruct string_equals(o0RegP str1, o1RegP str2, g3RegI cnt, notemp_iRegI result,
+                       o7RegI tmp, flagsReg ccr) %{
+  match(Set result (StrEquals (Binary str1 str2) cnt));
+  effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp, KILL ccr);
   ins_cost(300);
-  format %{ "String Equals $str1,$str2 -> $result" %}
-  ins_encode( enc_String_Equals(str1, str2, tmp1, tmp2, result) );
+  format %{ "String Equals $str1,$str2,$cnt -> $result   // KILL $tmp" %}
+  ins_encode( enc_String_Equals(str1, str2, cnt, result) );
   ins_pipe(long_memory_op);
 %}
 
-instruct array_equals(o0RegP ary1, o1RegP ary2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result,
-                        flagsReg ccr) %{
+instruct array_equals(o0RegP ary1, o1RegP ary2, g3RegI tmp1, notemp_iRegI result,
+                      o7RegI tmp2, flagsReg ccr) %{
   match(Set result (AryEq ary1 ary2));
   effect(USE_KILL ary1, USE_KILL ary2, KILL tmp1, KILL tmp2, KILL ccr);
   ins_cost(300);
-  format %{ "Array Equals $ary1,$ary2 -> $result" %}
-  ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, result));
+  format %{ "Array Equals $ary1,$ary2 -> $result   // KILL $tmp1,$tmp2" %}
+  ins_encode( enc_Array_Equals(ary1, ary2, tmp1, result));
   ins_pipe(long_memory_op);
 %}
 
--- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -8404,6 +8404,319 @@
 }
 #endif // _LP64
 
+// IndexOf substring.
+void MacroAssembler::string_indexof(Register str1, Register str2,
+                                    Register cnt1, Register cnt2, Register result,
+                                    XMMRegister vec, Register tmp) {
+  assert(UseSSE42Intrinsics, "SSE4.2 is required");
+
+  Label RELOAD_SUBSTR, PREP_FOR_SCAN, SCAN_TO_SUBSTR,
+        SCAN_SUBSTR, RET_NOT_FOUND, CLEANUP;
+
+  push(str1); // string addr
+  push(str2); // substr addr
+  push(cnt2); // substr count
+  jmpb(PREP_FOR_SCAN);
+
+  // Substr count saved at sp
+  // Substr saved at sp+1*wordSize
+  // String saved at sp+2*wordSize
+
+  // Reload substr for rescan
+  bind(RELOAD_SUBSTR);
+  movl(cnt2, Address(rsp, 0));
+  movptr(str2, Address(rsp, wordSize));
+  // We came here after the beginninig of the substring was
+  // matched but the rest of it was not so we need to search
+  // again. Start from the next element after the previous match.
+  subptr(str1, result); // Restore counter
+  shrl(str1, 1);
+  addl(cnt1, str1);
+  lea(str1, Address(result, 2)); // Reload string
+
+  // Load substr
+  bind(PREP_FOR_SCAN);
+  movdqu(vec, Address(str2, 0));
+  addl(cnt1, 8);  // prime the loop
+  subptr(str1, 16);
+
+  // Scan string for substr in 16-byte vectors
+  bind(SCAN_TO_SUBSTR);
+  subl(cnt1, 8);
+  addptr(str1, 16);
+
+  // pcmpestri
+  //   inputs:
+  //     xmm - substring
+  //     rax - substring length (elements count)
+  //     mem - scaned string
+  //     rdx - string length (elements count)
+  //     0xd - mode: 1100 (substring search) + 01 (unsigned shorts)
+  //   outputs:
+  //     rcx - matched index in string
+  assert(cnt1 == rdx && cnt2 == rax && tmp == rcx, "pcmpestri");
+
+  pcmpestri(vec, Address(str1, 0), 0x0d);
+  jcc(Assembler::above, SCAN_TO_SUBSTR);      // CF == 0 && ZF == 0
+  jccb(Assembler::aboveEqual, RET_NOT_FOUND); // CF == 0
+
+  // Fallthrough: found a potential substr
+
+  // Make sure string is still long enough
+  subl(cnt1, tmp);
+  cmpl(cnt1, cnt2);
+  jccb(Assembler::negative, RET_NOT_FOUND);
+  // Compute start addr of substr
+  lea(str1, Address(str1, tmp, Address::times_2));
+  movptr(result, str1); // save
+
+  // Compare potential substr
+  addl(cnt1, 8);     // prime the loop
+  addl(cnt2, 8);
+  subptr(str1, 16);
+  subptr(str2, 16);
+
+  // Scan 16-byte vectors of string and substr
+  bind(SCAN_SUBSTR);
+  subl(cnt1, 8);
+  subl(cnt2, 8);
+  addptr(str1, 16);
+  addptr(str2, 16);
+  movdqu(vec, Address(str2, 0));
+  pcmpestri(vec, Address(str1, 0), 0x0d);
+  jcc(Assembler::noOverflow, RELOAD_SUBSTR); // OF == 0
+  jcc(Assembler::positive, SCAN_SUBSTR);     // SF == 0
+
+  // Compute substr offset
+  subptr(result, Address(rsp, 2*wordSize));
+  shrl(result, 1); // index
+  jmpb(CLEANUP);
+
+  bind(RET_NOT_FOUND);
+  movl(result, -1);
+
+  bind(CLEANUP);
+  addptr(rsp, 3*wordSize);
+}
+
+// Compare strings.
+void MacroAssembler::string_compare(Register str1, Register str2,
+                                    Register cnt1, Register cnt2, Register result,
+                                    XMMRegister vec1, XMMRegister vec2) {
+  Label LENGTH_DIFF_LABEL, POP_LABEL, DONE_LABEL, WHILE_HEAD_LABEL;
+
+  // Compute the minimum of the string lengths and the
+  // difference of the string lengths (stack).
+  // Do the conditional move stuff
+  movl(result, cnt1);
+  subl(cnt1, cnt2);
+  push(cnt1);
+  if (VM_Version::supports_cmov()) {
+    cmovl(Assembler::lessEqual, cnt2, result);
+  } else {
+    Label GT_LABEL;
+    jccb(Assembler::greater, GT_LABEL);
+    movl(cnt2, result);
+    bind(GT_LABEL);
+  }
+
+  // Is the minimum length zero?
+  testl(cnt2, cnt2);
+  jcc(Assembler::zero, LENGTH_DIFF_LABEL);
+
+  // Load first characters
+  load_unsigned_short(result, Address(str1, 0));
+  load_unsigned_short(cnt1, Address(str2, 0));
+
+  // Compare first characters
+  subl(result, cnt1);
+  jcc(Assembler::notZero,  POP_LABEL);
+  decrementl(cnt2);
+  jcc(Assembler::zero, LENGTH_DIFF_LABEL);
+
+  {
+    // Check after comparing first character to see if strings are equivalent
+    Label LSkip2;
+    // Check if the strings start at same location
+    cmpptr(str1, str2);
+    jccb(Assembler::notEqual, LSkip2);
+
+    // Check if the length difference is zero (from stack)
+    cmpl(Address(rsp, 0), 0x0);
+    jcc(Assembler::equal,  LENGTH_DIFF_LABEL);
+
+    // Strings might not be equivalent
+    bind(LSkip2);
+  }
+
+  // Advance to next character
+  addptr(str1, 2);
+  addptr(str2, 2);
+
+  if (UseSSE42Intrinsics) {
+    // With SSE4.2, use double quad vector compare
+    Label COMPARE_VECTORS, VECTOR_NOT_EQUAL, COMPARE_TAIL;
+    // Setup to compare 16-byte vectors
+    movl(cnt1, cnt2);
+    andl(cnt2, 0xfffffff8); // cnt2 holds the vector count
+    andl(cnt1, 0x00000007); // cnt1 holds the tail count
+    testl(cnt2, cnt2);
+    jccb(Assembler::zero, COMPARE_TAIL);
+
+    lea(str2, Address(str2, cnt2, Address::times_2));
+    lea(str1, Address(str1, cnt2, Address::times_2));
+    negptr(cnt2);
+
+    bind(COMPARE_VECTORS);
+    movdqu(vec1, Address(str1, cnt2, Address::times_2));
+    movdqu(vec2, Address(str2, cnt2, Address::times_2));
+    pxor(vec1, vec2);
+    ptest(vec1, vec1);
+    jccb(Assembler::notZero, VECTOR_NOT_EQUAL);
+    addptr(cnt2, 8);
+    jcc(Assembler::notZero, COMPARE_VECTORS);
+    jmpb(COMPARE_TAIL);
+
+    // Mismatched characters in the vectors
+    bind(VECTOR_NOT_EQUAL);
+    lea(str1, Address(str1, cnt2, Address::times_2));
+    lea(str2, Address(str2, cnt2, Address::times_2));
+    movl(cnt1, 8);
+
+    // Compare tail (< 8 chars), or rescan last vectors to
+    // find 1st mismatched characters
+    bind(COMPARE_TAIL);
+    testl(cnt1, cnt1);
+    jccb(Assembler::zero, LENGTH_DIFF_LABEL);
+    movl(cnt2, cnt1);
+    // Fallthru to tail compare
+  }
+
+  // Shift str2 and str1 to the end of the arrays, negate min
+  lea(str1, Address(str1, cnt2, Address::times_2, 0));
+  lea(str2, Address(str2, cnt2, Address::times_2, 0));
+  negptr(cnt2);
+
+    // Compare the rest of the characters
+  bind(WHILE_HEAD_LABEL);
+  load_unsigned_short(result, Address(str1, cnt2, Address::times_2, 0));
+  load_unsigned_short(cnt1, Address(str2, cnt2, Address::times_2, 0));
+  subl(result, cnt1);
+  jccb(Assembler::notZero, POP_LABEL);
+  increment(cnt2);
+  jcc(Assembler::notZero, WHILE_HEAD_LABEL);
+
+  // Strings are equal up to min length.  Return the length difference.
+  bind(LENGTH_DIFF_LABEL);
+  pop(result);
+  jmpb(DONE_LABEL);
+
+  // Discard the stored length difference
+  bind(POP_LABEL);
+  addptr(rsp, wordSize);
+
+  // That's it
+  bind(DONE_LABEL);
+}
+
+// Compare char[] arrays aligned to 4 bytes or substrings.
+void MacroAssembler::char_arrays_equals(bool is_array_equ, Register ary1, Register ary2,
+                                        Register limit, Register result, Register chr,
+                                        XMMRegister vec1, XMMRegister vec2) {
+  Label TRUE_LABEL, FALSE_LABEL, DONE, COMPARE_VECTORS, COMPARE_CHAR;
+
+  int length_offset  = arrayOopDesc::length_offset_in_bytes();
+  int base_offset    = arrayOopDesc::base_offset_in_bytes(T_CHAR);
+
+  // Check the input args
+  cmpptr(ary1, ary2);
+  jcc(Assembler::equal, TRUE_LABEL);
+
+  if (is_array_equ) {
+    // Need additional checks for arrays_equals.
+    andptr(ary1, ary2);
+    jcc(Assembler::zero, FALSE_LABEL); // One pointer is NULL
+
+    // Check the lengths
+    movl(limit, Address(ary1, length_offset));
+    cmpl(limit, Address(ary2, length_offset));
+    jcc(Assembler::notEqual, FALSE_LABEL);
+  }
+
+  // count == 0
+  testl(limit, limit);
+  jcc(Assembler::zero, TRUE_LABEL);
+
+  if (is_array_equ) {
+    // Load array address
+    lea(ary1, Address(ary1, base_offset));
+    lea(ary2, Address(ary2, base_offset));
+  }
+
+  shll(limit, 1);      // byte count != 0
+  movl(result, limit); // copy
+
+  if (UseSSE42Intrinsics) {
+    // With SSE4.2, use double quad vector compare
+    Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
+    // Compare 16-byte vectors
+    andl(result, 0x0000000e);  //   tail count (in bytes)
+    andl(limit, 0xfffffff0);   // vector count (in bytes)
+    jccb(Assembler::zero, COMPARE_TAIL);
+
+    lea(ary1, Address(ary1, limit, Address::times_1));
+    lea(ary2, Address(ary2, limit, Address::times_1));
+    negptr(limit);
+
+    bind(COMPARE_WIDE_VECTORS);
+    movdqu(vec1, Address(ary1, limit, Address::times_1));
+    movdqu(vec2, Address(ary2, limit, Address::times_1));
+    pxor(vec1, vec2);
+    ptest(vec1, vec1);
+    jccb(Assembler::notZero, FALSE_LABEL);
+    addptr(limit, 16);
+    jcc(Assembler::notZero, COMPARE_WIDE_VECTORS);
+
+    bind(COMPARE_TAIL); // limit is zero
+    movl(limit, result);
+    // Fallthru to tail compare
+  }
+
+  // Compare 4-byte vectors
+  andl(limit, 0xfffffffc); // vector count (in bytes)
+  jccb(Assembler::zero, COMPARE_CHAR);
+
+  lea(ary1, Address(ary1, limit, Address::times_1));
+  lea(ary2, Address(ary2, limit, Address::times_1));
+  negptr(limit);
+
+  bind(COMPARE_VECTORS);
+  movl(chr, Address(ary1, limit, Address::times_1));
+  cmpl(chr, Address(ary2, limit, Address::times_1));
+  jccb(Assembler::notEqual, FALSE_LABEL);
+  addptr(limit, 4);
+  jcc(Assembler::notZero, COMPARE_VECTORS);
+
+  // Compare trailing char (final 2 bytes), if any
+  bind(COMPARE_CHAR);
+  testl(result, 0x2);   // tail  char
+  jccb(Assembler::zero, TRUE_LABEL);
+  load_unsigned_short(chr, Address(ary1, 0));
+  load_unsigned_short(limit, Address(ary2, 0));
+  cmpl(chr, limit);
+  jccb(Assembler::notEqual, FALSE_LABEL);
+
+  bind(TRUE_LABEL);
+  movl(result, 1);   // return true
+  jmpb(DONE);
+
+  bind(FALSE_LABEL);
+  xorl(result, result); // return false
+
+  // That's it
+  bind(DONE);
+}
+
 Assembler::Condition MacroAssembler::negate_condition(Assembler::Condition cond) {
   switch (cond) {
     // Note some conditions are synonyms for others
--- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp	Thu Oct 15 16:37:55 2009 -0700
@@ -2206,6 +2206,20 @@
   void movl2ptr(Register dst, Address src) { LP64_ONLY(movslq(dst, src)) NOT_LP64(movl(dst, src)); }
   void movl2ptr(Register dst, Register src) { LP64_ONLY(movslq(dst, src)) NOT_LP64(if (dst != src) movl(dst, src)); }
 
+  // IndexOf strings.
+  void string_indexof(Register str1, Register str2,
+                      Register cnt1, Register cnt2, Register result,
+                      XMMRegister vec, Register tmp);
+
+  // Compare strings.
+  void string_compare(Register str1, Register str2,
+                      Register cnt1, Register cnt2, Register result,
+                      XMMRegister vec1, XMMRegister vec2);
+
+  // Compare char[] arrays.
+  void char_arrays_equals(bool is_array_equ, Register ary1, Register ary2,
+                          Register limit, Register result, Register chr,
+                          XMMRegister vec1, XMMRegister vec2);
 
 #undef VIRTUAL
 
--- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -1638,7 +1638,7 @@
       jobject2reg_with_patching(k_RInfo, op->info_for_patch());
     } else {
 #ifdef _LP64
-      __ movoop(k_RInfo, k->encoding());
+      __ movoop(k_RInfo, k->constant_encoding());
 #else
       k_RInfo = noreg;
 #endif // _LP64
@@ -1661,7 +1661,7 @@
       assert(data != NULL,       "need data for checkcast");
       assert(data->is_BitData(), "need BitData for checkcast");
       Register mdo  = klass_RInfo;
-      __ movoop(mdo, md->encoding());
+      __ movoop(mdo, md->constant_encoding());
       Address data_addr(mdo, md->byte_offset_of_slot(data, DataLayout::header_offset()));
       int header_bits = DataLayout::flag_mask_to_header_mask(BitData::null_seen_byte_constant());
       __ orl(data_addr, header_bits);
@@ -1679,7 +1679,7 @@
 #ifdef _LP64
         __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes()));
 #else
-        __ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->encoding());
+        __ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->constant_encoding());
 #endif // _LP64
       } else {
         __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes()));
@@ -1696,7 +1696,7 @@
 #ifdef _LP64
         __ cmpptr(k_RInfo, Address(klass_RInfo, k->super_check_offset()));
 #else
-        __ cmpoop(Address(klass_RInfo, k->super_check_offset()), k->encoding());
+        __ cmpoop(Address(klass_RInfo, k->super_check_offset()), k->constant_encoding());
 #endif // _LP64
         if (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() != k->super_check_offset()) {
           __ jcc(Assembler::notEqual, *stub->entry());
@@ -1707,7 +1707,7 @@
 #ifdef _LP64
           __ cmpptr(klass_RInfo, k_RInfo);
 #else
-          __ cmpoop(klass_RInfo, k->encoding());
+          __ cmpoop(klass_RInfo, k->constant_encoding());
 #endif // _LP64
           __ jcc(Assembler::equal, done);
 
@@ -1715,7 +1715,7 @@
 #ifdef _LP64
           __ push(k_RInfo);
 #else
-          __ pushoop(k->encoding());
+          __ pushoop(k->constant_encoding());
 #endif // _LP64
           __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id)));
           __ pop(klass_RInfo);
@@ -1763,7 +1763,7 @@
     if (!k->is_loaded()) {
       jobject2reg_with_patching(k_RInfo, op->info_for_patch());
     } else {
-      LP64_ONLY(__ movoop(k_RInfo, k->encoding()));
+      LP64_ONLY(__ movoop(k_RInfo, k->constant_encoding()));
     }
     assert(obj != k_RInfo, "must be different");
 
@@ -1774,7 +1774,7 @@
       // get object class
       // not a safepoint as obj null check happens earlier
       if (LP64_ONLY(false &&) k->is_loaded()) {
-        NOT_LP64(__ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->encoding()));
+        NOT_LP64(__ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->constant_encoding()));
         k_RInfo = noreg;
       } else {
         __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes()));
@@ -1791,14 +1791,14 @@
 #ifndef _LP64
       if (k->is_loaded()) {
         // See if we get an immediate positive hit
-        __ cmpoop(Address(klass_RInfo, k->super_check_offset()), k->encoding());
+        __ cmpoop(Address(klass_RInfo, k->super_check_offset()), k->constant_encoding());
         __ jcc(Assembler::equal, one);
         if (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() == k->super_check_offset()) {
           // check for self
-          __ cmpoop(klass_RInfo, k->encoding());
+          __ cmpoop(klass_RInfo, k->constant_encoding());
           __ jcc(Assembler::equal, one);
           __ push(klass_RInfo);
-          __ pushoop(k->encoding());
+          __ pushoop(k->constant_encoding());
           __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id)));
           __ pop(klass_RInfo);
           __ pop(dst);
@@ -3112,7 +3112,7 @@
     // subtype which we can't check or src is the same array as dst
     // but not necessarily exactly of type default_type.
     Label known_ok, halt;
-    __ movoop(tmp, default_type->encoding());
+    __ movoop(tmp, default_type->constant_encoding());
     if (basic_type != T_OBJECT) {
       __ cmpptr(tmp, dst_klass_addr);
       __ jcc(Assembler::notEqual, halt);
@@ -3200,7 +3200,7 @@
   assert(data->is_CounterData(), "need CounterData for calls");
   assert(op->mdo()->is_single_cpu(),  "mdo must be allocated");
   Register mdo  = op->mdo()->as_register();
-  __ movoop(mdo, md->encoding());
+  __ movoop(mdo, md->constant_encoding());
   Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()));
   __ addl(counter_addr, DataLayout::counter_increment);
   Bytecodes::Code bc = method->java_code_at_bci(bci);
@@ -3240,7 +3240,7 @@
         ciKlass* receiver = vc_data->receiver(i);
         if (receiver == NULL) {
           Address recv_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i)));
-          __ movoop(recv_addr, known_klass->encoding());
+          __ movoop(recv_addr, known_klass->constant_encoding());
           Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i)));
           __ addl(data_addr, DataLayout::counter_increment);
           return;
--- a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -827,8 +827,8 @@
     case vmIntrinsics::_dsin:   __ sin  (calc_input, calc_result, tmp1, tmp2);              break;
     case vmIntrinsics::_dcos:   __ cos  (calc_input, calc_result, tmp1, tmp2);              break;
     case vmIntrinsics::_dtan:   __ tan  (calc_input, calc_result, tmp1, tmp2);              break;
-    case vmIntrinsics::_dlog:   __ log  (calc_input, calc_result, LIR_OprFact::illegalOpr); break;
-    case vmIntrinsics::_dlog10: __ log10(calc_input, calc_result, LIR_OprFact::illegalOpr); break;
+    case vmIntrinsics::_dlog:   __ log  (calc_input, calc_result, tmp1);                    break;
+    case vmIntrinsics::_dlog10: __ log10(calc_input, calc_result, tmp1);                    break;
     default:                    ShouldNotReachHere();
   }
 
@@ -994,7 +994,7 @@
   LIR_Opr len = length.result();
   BasicType elem_type = x->elt_type();
 
-  __ oop2reg(ciTypeArrayKlass::make(elem_type)->encoding(), klass_reg);
+  __ oop2reg(ciTypeArrayKlass::make(elem_type)->constant_encoding(), klass_reg);
 
   CodeStub* slow_path = new NewTypeArrayStub(klass_reg, len, reg, info);
   __ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, elem_type, klass_reg, slow_path);
--- a/hotspot/src/cpu/x86/vm/c1_LinearScan_x86.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/cpu/x86/vm/c1_LinearScan_x86.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -764,8 +764,6 @@
       break;
     }
 
-    case lir_log:
-    case lir_log10:
     case lir_abs:
     case lir_sqrt: {
       // Right argument appears to be unused
@@ -785,6 +783,30 @@
       break;
     }
 
+    case lir_log:
+    case lir_log10: {
+      // log and log10 needs one temporary fpu stack slot, so there is ontemporary
+      // registers stored in temp of the operation.
+      // the stack allocator must guarantee that the stack slots are really free,
+      // otherwise there might be a stack overflow.
+      assert(right->is_illegal(), "must be");
+      assert(left->is_fpu_register(), "must be");
+      assert(res->is_fpu_register(), "must be");
+      assert(op2->tmp_opr()->is_fpu_register(), "must be");
+
+      insert_free_if_dead(op2->tmp_opr());
+      insert_free_if_dead(res, left);
+      insert_exchange(left);
+      do_rename(left, res);
+
+      new_left = to_fpu_stack_top(res);
+      new_res = new_left;
+
+      op2->set_fpu_stack_size(sim()->stack_size());
+      assert(sim()->stack_size() <= 7, "at least one stack slot must be free");
+      break;
+    }
+
 
     case lir_tan:
     case lir_sin:
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -1262,6 +1262,9 @@
                                         Register receiver, Register mdp,
                                         Register reg2,
                                         int start_row, Label& done) {
+  if (TypeProfileWidth == 0)
+    return;
+
   int last_row = VirtualCallData::row_limit() - 1;
   assert(start_row <= last_row, "must be work left to do");
   // Test this row for both the receiver and for null.
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -1272,6 +1272,9 @@
                                         Register receiver, Register mdp,
                                         Register reg2,
                                         int start_row, Label& done) {
+  if (TypeProfileWidth == 0)
+    return;
+
   int last_row = VirtualCallData::row_limit() - 1;
   assert(start_row <= last_row, "must be work left to do");
   // Test this row for both the receiver and for null.
--- a/hotspot/src/cpu/x86/vm/x86_32.ad	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/cpu/x86/vm/x86_32.ad	Thu Oct 15 16:37:55 2009 -0700
@@ -379,7 +379,7 @@
         int format) {
 #ifdef ASSERT
   if (rspec.reloc()->type() == relocInfo::oop_type && d32 != 0 && d32 != (int)Universe::non_oop_word()) {
-    assert(oop(d32)->is_oop() && oop(d32)->is_perm(), "cannot embed non-perm oops in code");
+    assert(oop(d32)->is_oop() && (ScavengeRootsInCode || !oop(d32)->is_scavengable()), "cannot embed scavengable oops in code");
   }
 #endif
   cbuf.relocate(cbuf.inst_mark(), rspec, format);
@@ -3701,458 +3701,6 @@
     }
   %}
 
-  enc_class enc_String_Compare(eDIRegP str1, eSIRegP str2, regXD tmp1, regXD tmp2,
-                        eAXRegI tmp3, eBXRegI tmp4, eCXRegI result) %{
-    Label ECX_GOOD_LABEL, LENGTH_DIFF_LABEL,
-          POP_LABEL, DONE_LABEL, CONT_LABEL,
-          WHILE_HEAD_LABEL;
-    MacroAssembler masm(&cbuf);
-
-    XMMRegister tmp1Reg   = as_XMMRegister($tmp1$$reg);
-    XMMRegister tmp2Reg   = as_XMMRegister($tmp2$$reg);
-
-    // Get the first character position in both strings
-    //         [8] char array, [12] offset, [16] count
-    int value_offset  = java_lang_String::value_offset_in_bytes();
-    int offset_offset = java_lang_String::offset_offset_in_bytes();
-    int count_offset  = java_lang_String::count_offset_in_bytes();
-    int base_offset   = arrayOopDesc::base_offset_in_bytes(T_CHAR);
-
-    masm.movptr(rax, Address(rsi, value_offset));
-    masm.movl(rcx, Address(rsi, offset_offset));
-    masm.lea(rax, Address(rax, rcx, Address::times_2, base_offset));
-    masm.movptr(rbx, Address(rdi, value_offset));
-    masm.movl(rcx, Address(rdi, offset_offset));
-    masm.lea(rbx, Address(rbx, rcx, Address::times_2, base_offset));
-
-    // Compute the minimum of the string lengths(rsi) and the
-    // difference of the string lengths (stack)
-
-    if (VM_Version::supports_cmov()) {
-      masm.movl(rdi, Address(rdi, count_offset));
-      masm.movl(rsi, Address(rsi, count_offset));
-      masm.movl(rcx, rdi);
-      masm.subl(rdi, rsi);
-      masm.push(rdi);
-      masm.cmovl(Assembler::lessEqual, rsi, rcx);
-    } else {
-      masm.movl(rdi, Address(rdi, count_offset));
-      masm.movl(rcx, Address(rsi, count_offset));
-      masm.movl(rsi, rdi);
-      masm.subl(rdi, rcx);
-      masm.push(rdi);
-      masm.jccb(Assembler::lessEqual, ECX_GOOD_LABEL);
-      masm.movl(rsi, rcx);
-      // rsi holds min, rcx is unused
-    }
-
-    // Is the minimum length zero?
-    masm.bind(ECX_GOOD_LABEL);
-    masm.testl(rsi, rsi);
-    masm.jcc(Assembler::zero, LENGTH_DIFF_LABEL);
-
-    // Load first characters
-    masm.load_unsigned_short(rcx, Address(rbx, 0));
-    masm.load_unsigned_short(rdi, Address(rax, 0));
-
-    // Compare first characters
-    masm.subl(rcx, rdi);
-    masm.jcc(Assembler::notZero,  POP_LABEL);
-    masm.decrementl(rsi);
-    masm.jcc(Assembler::zero, LENGTH_DIFF_LABEL);
-
-    {
-      // Check after comparing first character to see if strings are equivalent
-      Label LSkip2;
-      // Check if the strings start at same location
-      masm.cmpptr(rbx,rax);
-      masm.jccb(Assembler::notEqual, LSkip2);
-
-      // Check if the length difference is zero (from stack)
-      masm.cmpl(Address(rsp, 0), 0x0);
-      masm.jcc(Assembler::equal,  LENGTH_DIFF_LABEL);
-
-      // Strings might not be equivalent
-      masm.bind(LSkip2);
-    }
-
-   // Advance to next character
-    masm.addptr(rax, 2);
-    masm.addptr(rbx, 2);
-
-    if (UseSSE42Intrinsics) {
-      // With SSE4.2, use double quad vector compare
-      Label COMPARE_VECTORS, VECTOR_NOT_EQUAL, COMPARE_TAIL;
-      // Setup to compare 16-byte vectors
-      masm.movl(rdi, rsi);
-      masm.andl(rsi, 0xfffffff8); // rsi holds the vector count
-      masm.andl(rdi, 0x00000007); // rdi holds the tail count
-      masm.testl(rsi, rsi);
-      masm.jccb(Assembler::zero, COMPARE_TAIL);
-
-      masm.lea(rax, Address(rax, rsi, Address::times_2));
-      masm.lea(rbx, Address(rbx, rsi, Address::times_2));
-      masm.negl(rsi);
-
-      masm.bind(COMPARE_VECTORS);
-      masm.movdqu(tmp1Reg, Address(rax, rsi, Address::times_2));
-      masm.movdqu(tmp2Reg, Address(rbx, rsi, Address::times_2));
-      masm.pxor(tmp1Reg, tmp2Reg);
-      masm.ptest(tmp1Reg, tmp1Reg);
-      masm.jccb(Assembler::notZero, VECTOR_NOT_EQUAL);
-      masm.addl(rsi, 8);
-      masm.jcc(Assembler::notZero, COMPARE_VECTORS);
-      masm.jmpb(COMPARE_TAIL);
-
-      // Mismatched characters in the vectors
-      masm.bind(VECTOR_NOT_EQUAL);
-      masm.lea(rax, Address(rax, rsi, Address::times_2));
-      masm.lea(rbx, Address(rbx, rsi, Address::times_2));
-      masm.movl(rdi, 8);
-
-      // Compare tail (< 8 chars), or rescan last vectors to
-      // find 1st mismatched characters
-      masm.bind(COMPARE_TAIL);
-      masm.testl(rdi, rdi);
-      masm.jccb(Assembler::zero, LENGTH_DIFF_LABEL);
-      masm.movl(rsi, rdi);
-      // Fallthru to tail compare
-    }
-
-    //Shift rax, and rbx, to the end of the arrays, negate min
-    masm.lea(rax, Address(rax, rsi, Address::times_2, 0));
-    masm.lea(rbx, Address(rbx, rsi, Address::times_2, 0));
-    masm.negl(rsi);
-
-    // Compare the rest of the characters
-    masm.bind(WHILE_HEAD_LABEL);
-    masm.load_unsigned_short(rcx, Address(rbx, rsi, Address::times_2, 0));
-    masm.load_unsigned_short(rdi, Address(rax, rsi, Address::times_2, 0));
-    masm.subl(rcx, rdi);
-    masm.jccb(Assembler::notZero, POP_LABEL);
-    masm.incrementl(rsi);
-    masm.jcc(Assembler::notZero, WHILE_HEAD_LABEL);
-
-    // Strings are equal up to min length.  Return the length difference.
-    masm.bind(LENGTH_DIFF_LABEL);
-    masm.pop(rcx);
-    masm.jmpb(DONE_LABEL);
-
-    // Discard the stored length difference
-    masm.bind(POP_LABEL);
-    masm.addptr(rsp, 4);
-
-    // That's it
-    masm.bind(DONE_LABEL);
-  %}
-
- enc_class enc_String_Equals(eDIRegP str1, eSIRegP str2, regXD tmp1, regXD tmp2,
-                       eBXRegI tmp3, eCXRegI tmp4, eAXRegI result) %{
-    Label RET_TRUE, RET_FALSE, DONE, COMPARE_VECTORS, COMPARE_CHAR;
-    MacroAssembler masm(&cbuf);
-
-    XMMRegister tmp1Reg   = as_XMMRegister($tmp1$$reg);
-    XMMRegister tmp2Reg   = as_XMMRegister($tmp2$$reg);
-
-    int value_offset  = java_lang_String::value_offset_in_bytes();
-    int offset_offset = java_lang_String::offset_offset_in_bytes();
-    int count_offset  = java_lang_String::count_offset_in_bytes();
-    int base_offset   = arrayOopDesc::base_offset_in_bytes(T_CHAR);
-
-    // does source == target string?
-    masm.cmpptr(rdi, rsi);
-    masm.jcc(Assembler::equal, RET_TRUE);
-
-    // get and compare counts
-    masm.movl(rcx, Address(rdi, count_offset));
-    masm.movl(rax, Address(rsi, count_offset));
-    masm.cmpl(rcx, rax);
-    masm.jcc(Assembler::notEqual, RET_FALSE);
-    masm.testl(rax, rax);
-    masm.jcc(Assembler::zero, RET_TRUE);
-
-    // get source string offset and value
-    masm.movptr(rbx, Address(rsi, value_offset));
-    masm.movl(rax, Address(rsi, offset_offset));
-    masm.leal(rsi, Address(rbx, rax, Address::times_2, base_offset));
-
-    // get compare string offset and value
-    masm.movptr(rbx, Address(rdi, value_offset));
-    masm.movl(rax, Address(rdi, offset_offset));
-    masm.leal(rdi, Address(rbx, rax, Address::times_2, base_offset));
-
-    // Set byte count
-    masm.shll(rcx, 1);
-    masm.movl(rax, rcx);
-
-    if (UseSSE42Intrinsics) {
-      // With SSE4.2, use double quad vector compare
-      Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
-      // Compare 16-byte vectors
-      masm.andl(rcx, 0xfffffff0);  // vector count (in bytes)
-      masm.andl(rax, 0x0000000e);  // tail count (in bytes)
-      masm.testl(rcx, rcx);
-      masm.jccb(Assembler::zero, COMPARE_TAIL);
-      masm.lea(rdi, Address(rdi, rcx, Address::times_1));
-      masm.lea(rsi, Address(rsi, rcx, Address::times_1));
-      masm.negl(rcx);
-
-      masm.bind(COMPARE_WIDE_VECTORS);
-      masm.movdqu(tmp1Reg, Address(rdi, rcx, Address::times_1));
-      masm.movdqu(tmp2Reg, Address(rsi, rcx, Address::times_1));
-      masm.pxor(tmp1Reg, tmp2Reg);
-      masm.ptest(tmp1Reg, tmp1Reg);
-      masm.jccb(Assembler::notZero, RET_FALSE);
-      masm.addl(rcx, 16);
-      masm.jcc(Assembler::notZero, COMPARE_WIDE_VECTORS);
-      masm.bind(COMPARE_TAIL);
-      masm.movl(rcx, rax);
-      // Fallthru to tail compare
-    }
-
-    // Compare 4-byte vectors
-    masm.andl(rcx, 0xfffffffc);  // vector count (in bytes)
-    masm.andl(rax, 0x00000002);  // tail char (in bytes)
-    masm.testl(rcx, rcx);
-    masm.jccb(Assembler::zero, COMPARE_CHAR);
-    masm.lea(rdi, Address(rdi, rcx, Address::times_1));
-    masm.lea(rsi, Address(rsi, rcx, Address::times_1));
-    masm.negl(rcx);
-
-    masm.bind(COMPARE_VECTORS);
-    masm.movl(rbx, Address(rdi, rcx, Address::times_1));
-    masm.cmpl(rbx, Address(rsi, rcx, Address::times_1));
-    masm.jccb(Assembler::notEqual, RET_FALSE);
-    masm.addl(rcx, 4);
-    masm.jcc(Assembler::notZero, COMPARE_VECTORS);
-
-    // Compare trailing char (final 2 bytes), if any
-    masm.bind(COMPARE_CHAR);
-    masm.testl(rax, rax);
-    masm.jccb(Assembler::zero, RET_TRUE);
-    masm.load_unsigned_short(rbx, Address(rdi, 0));
-    masm.load_unsigned_short(rcx, Address(rsi, 0));
-    masm.cmpl(rbx, rcx);
-    masm.jccb(Assembler::notEqual, RET_FALSE);
-
-    masm.bind(RET_TRUE);
-    masm.movl(rax, 1);   // return true
-    masm.jmpb(DONE);
-
-    masm.bind(RET_FALSE);
-    masm.xorl(rax, rax); // return false
-
-    masm.bind(DONE);
-    %}
-
- enc_class enc_String_IndexOf(eSIRegP str1, eDIRegP str2, regXD tmp1, eAXRegI tmp2,
-                        eCXRegI tmp3, eDXRegI tmp4, eBXRegI result) %{
-    // SSE4.2 version
-    Label LOAD_SUBSTR, PREP_FOR_SCAN, SCAN_TO_SUBSTR,
-          SCAN_SUBSTR, RET_NEG_ONE, RET_NOT_FOUND, CLEANUP, DONE;
-    MacroAssembler masm(&cbuf);
-
-    XMMRegister tmp1Reg   = as_XMMRegister($tmp1$$reg);
-
-    // Get the first character position in both strings
-    //         [8] char array, [12] offset, [16] count
-    int value_offset  = java_lang_String::value_offset_in_bytes();
-    int offset_offset = java_lang_String::offset_offset_in_bytes();
-    int count_offset  = java_lang_String::count_offset_in_bytes();
-    int base_offset   = arrayOopDesc::base_offset_in_bytes(T_CHAR);
-
-    // Get counts for string and substr
-    masm.movl(rdx, Address(rsi, count_offset));
-    masm.movl(rax, Address(rdi, count_offset));
-    // Check for substr count > string count
-    masm.cmpl(rax, rdx);
-    masm.jcc(Assembler::greater, RET_NEG_ONE);
-
-    // Start the indexOf operation
-    // Get start addr of string
-    masm.movptr(rbx, Address(rsi, value_offset));
-    masm.movl(rcx, Address(rsi, offset_offset));
-    masm.lea(rsi, Address(rbx, rcx, Address::times_2, base_offset));
-    masm.push(rsi);
-
-    // Get start addr of substr
-    masm.movptr(rbx, Address(rdi, value_offset));
-    masm.movl(rcx, Address(rdi, offset_offset));
-    masm.lea(rdi, Address(rbx, rcx, Address::times_2, base_offset));
-    masm.push(rdi);
-    masm.push(rax);
-    masm.jmpb(PREP_FOR_SCAN);
-
-    // Substr count saved at sp
-    // Substr saved at sp+4
-    // String saved at sp+8
-
-    // Prep to load substr for scan
-    masm.bind(LOAD_SUBSTR);
-    masm.movptr(rdi, Address(rsp, 4));
-    masm.movl(rax, Address(rsp, 0));
-
-    // Load substr
-    masm.bind(PREP_FOR_SCAN);
-    masm.movdqu(tmp1Reg, Address(rdi, 0));
-    masm.addl(rdx, 8);        // prime the loop
-    masm.subptr(rsi, 16);
-
-    // Scan string for substr in 16-byte vectors
-    masm.bind(SCAN_TO_SUBSTR);
-    masm.subl(rdx, 8);
-    masm.addptr(rsi, 16);
-    masm.pcmpestri(tmp1Reg, Address(rsi, 0), 0x0d);
-    masm.jcc(Assembler::above, SCAN_TO_SUBSTR);     // CF == 0 && ZF == 0
-    masm.jccb(Assembler::aboveEqual, RET_NOT_FOUND); // CF == 0
-
-    // Fallthru: found a potential substr
-
-    // Make sure string is still long enough
-    masm.subl(rdx, rcx);
-    masm.cmpl(rdx, rax);
-    masm.jccb(Assembler::negative, RET_NOT_FOUND);
-    // Compute start addr of substr
-    masm.lea(rsi, Address(rsi, rcx, Address::times_2));
-    masm.movptr(rbx, rsi);
-
-    // Compare potential substr
-    masm.addl(rdx, 8);        // prime the loop
-    masm.addl(rax, 8);
-    masm.subptr(rsi, 16);
-    masm.subptr(rdi, 16);
-
-    // Scan 16-byte vectors of string and substr
-    masm.bind(SCAN_SUBSTR);
-    masm.subl(rax, 8);
-    masm.subl(rdx, 8);
-    masm.addptr(rsi, 16);
-    masm.addptr(rdi, 16);
-    masm.movdqu(tmp1Reg, Address(rdi, 0));
-    masm.pcmpestri(tmp1Reg, Address(rsi, 0), 0x0d);
-    masm.jcc(Assembler::noOverflow, LOAD_SUBSTR);   // OF == 0
-    masm.jcc(Assembler::positive, SCAN_SUBSTR);     // SF == 0
-
-    // Compute substr offset
-    masm.movptr(rsi, Address(rsp, 8));
-    masm.subptr(rbx, rsi);
-    masm.shrl(rbx, 1);
-    masm.jmpb(CLEANUP);
-
-    masm.bind(RET_NEG_ONE);
-    masm.movl(rbx, -1);
-    masm.jmpb(DONE);
-
-    masm.bind(RET_NOT_FOUND);
-    masm.movl(rbx, -1);
-
-    masm.bind(CLEANUP);
-    masm.addptr(rsp, 12);
-
-    masm.bind(DONE);
-  %}
-
-  enc_class enc_Array_Equals(eDIRegP ary1, eSIRegP ary2, regXD tmp1, regXD tmp2,
-                             eBXRegI tmp3, eDXRegI tmp4, eAXRegI result) %{
-    Label TRUE_LABEL, FALSE_LABEL, DONE, COMPARE_VECTORS, COMPARE_CHAR;
-    MacroAssembler masm(&cbuf);
-
-    XMMRegister tmp1Reg   = as_XMMRegister($tmp1$$reg);
-    XMMRegister tmp2Reg   = as_XMMRegister($tmp2$$reg);
-    Register ary1Reg      = as_Register($ary1$$reg);
-    Register ary2Reg      = as_Register($ary2$$reg);
-    Register tmp3Reg      = as_Register($tmp3$$reg);
-    Register tmp4Reg      = as_Register($tmp4$$reg);
-    Register resultReg    = as_Register($result$$reg);
-
-    int length_offset  = arrayOopDesc::length_offset_in_bytes();
-    int base_offset    = arrayOopDesc::base_offset_in_bytes(T_CHAR);
-
-    // Check the input args
-    masm.cmpptr(ary1Reg, ary2Reg);
-    masm.jcc(Assembler::equal, TRUE_LABEL);
-    masm.testptr(ary1Reg, ary1Reg);
-    masm.jcc(Assembler::zero, FALSE_LABEL);
-    masm.testptr(ary2Reg, ary2Reg);
-    masm.jcc(Assembler::zero, FALSE_LABEL);
-
-    // Check the lengths
-    masm.movl(tmp4Reg, Address(ary1Reg, length_offset));
-    masm.movl(resultReg, Address(ary2Reg, length_offset));
-    masm.cmpl(tmp4Reg, resultReg);
-    masm.jcc(Assembler::notEqual, FALSE_LABEL);
-    masm.testl(resultReg, resultReg);
-    masm.jcc(Assembler::zero, TRUE_LABEL);
-
-    // Load array addrs
-    masm.lea(ary1Reg, Address(ary1Reg, base_offset));
-    masm.lea(ary2Reg, Address(ary2Reg, base_offset));
-
-    // Set byte count
-    masm.shll(tmp4Reg, 1);
-    masm.movl(resultReg, tmp4Reg);
-
-    if (UseSSE42Intrinsics) {
-      // With SSE4.2, use double quad vector compare
-      Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
-      // Compare 16-byte vectors
-      masm.andl(tmp4Reg, 0xfffffff0);    // vector count (in bytes)
-      masm.andl(resultReg, 0x0000000e);  // tail count (in bytes)
-      masm.testl(tmp4Reg, tmp4Reg);
-      masm.jccb(Assembler::zero, COMPARE_TAIL);
-      masm.lea(ary1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
-      masm.lea(ary2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
-      masm.negl(tmp4Reg);
-
-      masm.bind(COMPARE_WIDE_VECTORS);
-      masm.movdqu(tmp1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
-      masm.movdqu(tmp2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
-      masm.pxor(tmp1Reg, tmp2Reg);
-      masm.ptest(tmp1Reg, tmp1Reg);
-
-      masm.jccb(Assembler::notZero, FALSE_LABEL);
-      masm.addl(tmp4Reg, 16);
-      masm.jcc(Assembler::notZero, COMPARE_WIDE_VECTORS);
-      masm.bind(COMPARE_TAIL);
-      masm.movl(tmp4Reg, resultReg);
-      // Fallthru to tail compare
-    }
-
-    // Compare 4-byte vectors
-    masm.andl(tmp4Reg, 0xfffffffc);    // vector count (in bytes)
-    masm.andl(resultReg, 0x00000002);  // tail char (in bytes)
-    masm.testl(tmp4Reg, tmp4Reg);
-    masm.jccb(Assembler::zero, COMPARE_CHAR);
-    masm.lea(ary1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
-    masm.lea(ary2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
-    masm.negl(tmp4Reg);
-
-    masm.bind(COMPARE_VECTORS);
-    masm.movl(tmp3Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
-    masm.cmpl(tmp3Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
-    masm.jccb(Assembler::notEqual, FALSE_LABEL);
-    masm.addl(tmp4Reg, 4);
-    masm.jcc(Assembler::notZero, COMPARE_VECTORS);
-
-    // Compare trailing char (final 2 bytes), if any
-    masm.bind(COMPARE_CHAR);
-    masm.testl(resultReg, resultReg);
-    masm.jccb(Assembler::zero, TRUE_LABEL);
-    masm.load_unsigned_short(tmp3Reg, Address(ary1Reg, 0));
-    masm.load_unsigned_short(tmp4Reg, Address(ary2Reg, 0));
-    masm.cmpl(tmp3Reg, tmp4Reg);
-    masm.jccb(Assembler::notEqual, FALSE_LABEL);
-
-    masm.bind(TRUE_LABEL);
-    masm.movl(resultReg, 1);   // return true
-    masm.jmpb(DONE);
-
-    masm.bind(FALSE_LABEL);
-    masm.xorl(resultReg, resultReg); // return false
-
-    // That's it
-    masm.bind(DONE);
-  %}
 
   enc_class enc_pop_rdx() %{
     emit_opcode(cbuf,0x5A);
@@ -12718,48 +12266,64 @@
   ins_pipe( pipe_slow );
 %}
 
-instruct string_compare(eDIRegP str1, eSIRegP str2, regXD tmp1, regXD tmp2,
-                        eAXRegI tmp3, eBXRegI tmp4, eCXRegI result, eFlagsReg cr) %{
-  match(Set result (StrComp str1 str2));
-  effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, KILL tmp3, KILL tmp4, KILL cr);
-  //ins_cost(300);
-
-  format %{ "String Compare $str1,$str2 -> $result    // KILL EAX, EBX" %}
-  ins_encode( enc_String_Compare(str1, str2, tmp1, tmp2, tmp3, tmp4, result) );
+instruct string_compare(eDIRegP str1, eCXRegI cnt1, eSIRegP str2, eBXRegI cnt2,
+                        eAXRegI result, regXD tmp1, regXD tmp2, eFlagsReg cr) %{
+  match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
+  effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
+
+  format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   // KILL $tmp1, $tmp2" %}
+  ins_encode %{
+    __ string_compare($str1$$Register, $str2$$Register,
+                      $cnt1$$Register, $cnt2$$Register, $result$$Register,
+                      $tmp1$$XMMRegister, $tmp2$$XMMRegister);
+  %}
   ins_pipe( pipe_slow );
 %}
 
 // fast string equals
-instruct string_equals(eDIRegP str1, eSIRegP str2, regXD tmp1, regXD tmp2,
-                       eBXRegI tmp3, eCXRegI tmp4, eAXRegI result, eFlagsReg cr) %{
-  match(Set result (StrEquals str1 str2));
-  effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, KILL tmp3, KILL tmp4, KILL cr);
-
-  format %{ "String Equals $str1,$str2 -> $result    // KILL EBX, ECX" %}
-  ins_encode( enc_String_Equals(tmp1, tmp2, str1, str2, tmp3, tmp4, result) );
-  ins_pipe( pipe_slow );
-%}
-
-instruct string_indexof(eSIRegP str1, eDIRegP str2, regXD tmp1, eAXRegI tmp2,
-                        eCXRegI tmp3, eDXRegI tmp4, eBXRegI result, eFlagsReg cr) %{
+instruct string_equals(eDIRegP str1, eSIRegP str2, eCXRegI cnt, eAXRegI result,
+                       regXD tmp1, regXD tmp2, eBXRegI tmp3, eFlagsReg cr) %{
+  match(Set result (StrEquals (Binary str1 str2) cnt));
+  effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr);
+
+  format %{ "String Equals $str1,$str2,$cnt -> $result    // KILL $tmp1, $tmp2, $tmp3" %}
+  ins_encode %{
+    __ char_arrays_equals(false, $str1$$Register, $str2$$Register,
+                          $cnt$$Register, $result$$Register, $tmp3$$Register,
+                          $tmp1$$XMMRegister, $tmp2$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct string_indexof(eDIRegP str1, eDXRegI cnt1, eSIRegP str2, eAXRegI cnt2,
+                        eBXRegI result, regXD tmp1, eCXRegI tmp2, eFlagsReg cr) %{
   predicate(UseSSE42Intrinsics);
-  match(Set result (StrIndexOf str1 str2));
-  effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, KILL tmp2, KILL tmp3, KILL tmp4, KILL cr);
-
-  format %{ "String IndexOf $str1,$str2 -> $result    // KILL EAX, ECX, EDX" %}
-  ins_encode( enc_String_IndexOf(str1, str2, tmp1, tmp2, tmp3, tmp4, result) );
+  match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
+  effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp2, KILL cr);
+
+  format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result   // KILL $tmp2, $tmp1" %}
+  ins_encode %{
+    __ string_indexof($str1$$Register, $str2$$Register,
+                      $cnt1$$Register, $cnt2$$Register, $result$$Register,
+                      $tmp1$$XMMRegister, $tmp2$$Register);
+  %}
   ins_pipe( pipe_slow );
 %}
 
 // fast array equals
-instruct array_equals(eDIRegP ary1, eSIRegP ary2, regXD tmp1, regXD tmp2, eBXRegI tmp3,
-                      eDXRegI tmp4, eAXRegI result, eFlagsReg cr) %{
+instruct array_equals(eDIRegP ary1, eSIRegP ary2, eAXRegI result,
+                      regXD tmp1, regXD tmp2, eCXRegI tmp3, eBXRegI tmp4, eFlagsReg cr)
+%{
   match(Set result (AryEq ary1 ary2));
   effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
   //ins_cost(300);
 
-  format %{ "Array Equals $ary1,$ary2 -> $result    // KILL EBX, EDX" %}
-  ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, tmp3, tmp4, result) );
+  format %{ "Array Equals $ary1,$ary2 -> $result   // KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
+  ins_encode %{
+    __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register,
+                          $tmp3$$Register, $result$$Register, $tmp4$$Register,
+                          $tmp1$$XMMRegister, $tmp2$$XMMRegister);
+  %}
   ins_pipe( pipe_slow );
 %}
 
--- a/hotspot/src/cpu/x86/vm/x86_64.ad	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/cpu/x86/vm/x86_64.ad	Thu Oct 15 16:37:55 2009 -0700
@@ -683,7 +683,7 @@
 #ifdef ASSERT
   if (rspec.reloc()->type() == relocInfo::oop_type &&
       d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) {
-    assert(oop((intptr_t)d32)->is_oop() && oop((intptr_t)d32)->is_perm(), "cannot embed non-perm oops in code");
+    assert(oop((intptr_t)d32)->is_oop() && (ScavengeRootsInCode || !oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code");
   }
 #endif
   cbuf.relocate(cbuf.inst_mark(), rspec, format);
@@ -721,8 +721,8 @@
 #ifdef ASSERT
   if (rspec.reloc()->type() == relocInfo::oop_type &&
       d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) {
-    assert(oop(d64)->is_oop() && oop(d64)->is_perm(),
-           "cannot embed non-perm oops in code");
+    assert(oop(d64)->is_oop() && (ScavengeRootsInCode || !oop(d64)->is_scavengable()),
+           "cannot embed scavengable oops in code");
   }
 #endif
   cbuf.relocate(cbuf.inst_mark(), rspec, format);
@@ -3701,448 +3701,6 @@
     }
   %}
 
-  enc_class enc_String_Compare(rdi_RegP str1, rsi_RegP str2, regD tmp1, regD tmp2,
-                        rax_RegI tmp3, rbx_RegI tmp4, rcx_RegI result) %{
-    Label RCX_GOOD_LABEL, LENGTH_DIFF_LABEL,
-          POP_LABEL, DONE_LABEL, CONT_LABEL,
-          WHILE_HEAD_LABEL;
-    MacroAssembler masm(&cbuf);
-
-    XMMRegister tmp1Reg   = as_XMMRegister($tmp1$$reg);
-    XMMRegister tmp2Reg   = as_XMMRegister($tmp2$$reg);
-
-    // Get the first character position in both strings
-    //         [8] char array, [12] offset, [16] count
-    int value_offset  = java_lang_String::value_offset_in_bytes();
-    int offset_offset = java_lang_String::offset_offset_in_bytes();
-    int count_offset  = java_lang_String::count_offset_in_bytes();
-    int base_offset   = arrayOopDesc::base_offset_in_bytes(T_CHAR);
-
-    masm.load_heap_oop(rax, Address(rsi, value_offset));
-    masm.movl(rcx, Address(rsi, offset_offset));
-    masm.lea(rax, Address(rax, rcx, Address::times_2, base_offset));
-    masm.load_heap_oop(rbx, Address(rdi, value_offset));
-    masm.movl(rcx, Address(rdi, offset_offset));
-    masm.lea(rbx, Address(rbx, rcx, Address::times_2, base_offset));
-
-    // Compute the minimum of the string lengths(rsi) and the
-    // difference of the string lengths (stack)
-
-    // do the conditional move stuff
-    masm.movl(rdi, Address(rdi, count_offset));
-    masm.movl(rsi, Address(rsi, count_offset));
-    masm.movl(rcx, rdi);
-    masm.subl(rdi, rsi);
-    masm.push(rdi);
-    masm.cmov(Assembler::lessEqual, rsi, rcx);
-
-    // Is the minimum length zero?
-    masm.bind(RCX_GOOD_LABEL);
-    masm.testl(rsi, rsi);
-    masm.jcc(Assembler::zero, LENGTH_DIFF_LABEL);
-
-    // Load first characters
-    masm.load_unsigned_short(rcx, Address(rbx, 0));
-    masm.load_unsigned_short(rdi, Address(rax, 0));
-
-    // Compare first characters
-    masm.subl(rcx, rdi);
-    masm.jcc(Assembler::notZero,  POP_LABEL);
-    masm.decrementl(rsi);
-    masm.jcc(Assembler::zero, LENGTH_DIFF_LABEL);
-
-    {
-      // Check after comparing first character to see if strings are equivalent
-      Label LSkip2;
-      // Check if the strings start at same location
-      masm.cmpptr(rbx, rax);
-      masm.jccb(Assembler::notEqual, LSkip2);
-
-      // Check if the length difference is zero (from stack)
-      masm.cmpl(Address(rsp, 0), 0x0);
-      masm.jcc(Assembler::equal,  LENGTH_DIFF_LABEL);
-
-      // Strings might not be equivalent
-      masm.bind(LSkip2);
-    }
-
-    // Advance to next character
-    masm.addptr(rax, 2);
-    masm.addptr(rbx, 2);
-
-    if (UseSSE42Intrinsics) {
-      // With SSE4.2, use double quad vector compare
-      Label COMPARE_VECTORS, VECTOR_NOT_EQUAL, COMPARE_TAIL;
-      // Setup to compare 16-byte vectors
-      masm.movl(rdi, rsi);
-      masm.andl(rsi, 0xfffffff8); // rsi holds the vector count
-      masm.andl(rdi, 0x00000007); // rdi holds the tail count
-      masm.testl(rsi, rsi);
-      masm.jccb(Assembler::zero, COMPARE_TAIL);
-
-      masm.lea(rax, Address(rax, rsi, Address::times_2));
-      masm.lea(rbx, Address(rbx, rsi, Address::times_2));
-      masm.negptr(rsi);
-
-      masm.bind(COMPARE_VECTORS);
-      masm.movdqu(tmp1Reg, Address(rax, rsi, Address::times_2));
-      masm.movdqu(tmp2Reg, Address(rbx, rsi, Address::times_2));
-      masm.pxor(tmp1Reg, tmp2Reg);
-      masm.ptest(tmp1Reg, tmp1Reg);
-      masm.jccb(Assembler::notZero, VECTOR_NOT_EQUAL);
-      masm.addptr(rsi, 8);
-      masm.jcc(Assembler::notZero, COMPARE_VECTORS);
-      masm.jmpb(COMPARE_TAIL);
-
-      // Mismatched characters in the vectors
-      masm.bind(VECTOR_NOT_EQUAL);
-      masm.lea(rax, Address(rax, rsi, Address::times_2));
-      masm.lea(rbx, Address(rbx, rsi, Address::times_2));
-      masm.movl(rdi, 8);
-
-      // Compare tail (< 8 chars), or rescan last vectors to
-      // find 1st mismatched characters
-      masm.bind(COMPARE_TAIL);
-      masm.testl(rdi, rdi);
-      masm.jccb(Assembler::zero, LENGTH_DIFF_LABEL);
-      masm.movl(rsi, rdi);
-      // Fallthru to tail compare
-    }
-
-    // Shift RAX and RBX to the end of the arrays, negate min
-    masm.lea(rax, Address(rax, rsi, Address::times_2, 0));
-    masm.lea(rbx, Address(rbx, rsi, Address::times_2, 0));
-    masm.negptr(rsi);
-
-    // Compare the rest of the characters
-    masm.bind(WHILE_HEAD_LABEL);
-    masm.load_unsigned_short(rcx, Address(rbx, rsi, Address::times_2, 0));
-    masm.load_unsigned_short(rdi, Address(rax, rsi, Address::times_2, 0));
-    masm.subl(rcx, rdi);
-    masm.jccb(Assembler::notZero, POP_LABEL);
-    masm.increment(rsi);
-    masm.jcc(Assembler::notZero, WHILE_HEAD_LABEL);
-
-    // Strings are equal up to min length.  Return the length difference.
-    masm.bind(LENGTH_DIFF_LABEL);
-    masm.pop(rcx);
-    masm.jmpb(DONE_LABEL);
-
-    // Discard the stored length difference
-    masm.bind(POP_LABEL);
-    masm.addptr(rsp, 8);
-
-    // That's it
-    masm.bind(DONE_LABEL);
-  %}
-
- enc_class enc_String_IndexOf(rsi_RegP str1, rdi_RegP str2, regD tmp1, rax_RegI tmp2,
-                        rcx_RegI tmp3, rdx_RegI tmp4, rbx_RegI result) %{
-    // SSE4.2 version
-    Label LOAD_SUBSTR, PREP_FOR_SCAN, SCAN_TO_SUBSTR,
-          SCAN_SUBSTR, RET_NEG_ONE, RET_NOT_FOUND, CLEANUP, DONE;
-    MacroAssembler masm(&cbuf);
-
-    XMMRegister tmp1Reg   = as_XMMRegister($tmp1$$reg);
-
-    // Get the first character position in both strings
-    //         [8] char array, [12] offset, [16] count
-    int value_offset  = java_lang_String::value_offset_in_bytes();
-    int offset_offset = java_lang_String::offset_offset_in_bytes();
-    int count_offset  = java_lang_String::count_offset_in_bytes();
-    int base_offset   = arrayOopDesc::base_offset_in_bytes(T_CHAR);
-
-    // Get counts for string and substr
-    masm.movl(rdx, Address(rsi, count_offset));
-    masm.movl(rax, Address(rdi, count_offset));
-    // Check for substr count > string count
-    masm.cmpl(rax, rdx);
-    masm.jcc(Assembler::greater, RET_NEG_ONE);
-
-    // Start the indexOf operation
-    // Get start addr of string
-    masm.load_heap_oop(rbx, Address(rsi, value_offset));
-    masm.movl(rcx, Address(rsi, offset_offset));
-    masm.lea(rsi, Address(rbx, rcx, Address::times_2, base_offset));
-    masm.push(rsi);
-
-    // Get start addr of substr
-    masm.load_heap_oop(rbx, Address(rdi, value_offset));
-    masm.movl(rcx, Address(rdi, offset_offset));
-    masm.lea(rdi, Address(rbx, rcx, Address::times_2, base_offset));
-    masm.push(rdi);
-    masm.push(rax);
-    masm.jmpb(PREP_FOR_SCAN);
-
-    // Substr count saved at sp
-    // Substr saved at sp+8
-    // String saved at sp+16
-
-    // Prep to load substr for scan
-    masm.bind(LOAD_SUBSTR);
-    masm.movptr(rdi, Address(rsp, 8));
-    masm.movl(rax, Address(rsp, 0));
-
-    // Load substr
-    masm.bind(PREP_FOR_SCAN);
-    masm.movdqu(tmp1Reg, Address(rdi, 0));
-    masm.addq(rdx, 8);    // prime the loop
-    masm.subptr(rsi, 16);
-
-    // Scan string for substr in 16-byte vectors
-    masm.bind(SCAN_TO_SUBSTR);
-    masm.subq(rdx, 8);
-    masm.addptr(rsi, 16);
-    masm.pcmpestri(tmp1Reg, Address(rsi, 0), 0x0d);
-    masm.jcc(Assembler::above, SCAN_TO_SUBSTR);
-    masm.jccb(Assembler::aboveEqual, RET_NOT_FOUND);
-
-    // Fallthru: found a potential substr
-
-    //Make sure string is still long enough
-    masm.subl(rdx, rcx);
-    masm.cmpl(rdx, rax);
-    masm.jccb(Assembler::negative, RET_NOT_FOUND);
-    // Compute start addr of substr
-    masm.lea(rsi, Address(rsi, rcx, Address::times_2));
-    masm.movptr(rbx, rsi);
-
-    // Compare potential substr
-    masm.addq(rdx, 8);        // prime the loop
-    masm.addq(rax, 8);
-    masm.subptr(rsi, 16);
-    masm.subptr(rdi, 16);
-
-    // Scan 16-byte vectors of string and substr
-    masm.bind(SCAN_SUBSTR);
-    masm.subq(rax, 8);
-    masm.subq(rdx, 8);
-    masm.addptr(rsi, 16);
-    masm.addptr(rdi, 16);
-    masm.movdqu(tmp1Reg, Address(rdi, 0));
-    masm.pcmpestri(tmp1Reg, Address(rsi, 0), 0x0d);
-    masm.jcc(Assembler::noOverflow, LOAD_SUBSTR);   // OF == 0
-    masm.jcc(Assembler::positive, SCAN_SUBSTR);     // SF == 0
-
-    // Compute substr offset
-    masm.movptr(rsi, Address(rsp, 16));
-    masm.subptr(rbx, rsi);
-    masm.shrl(rbx, 1);
-    masm.jmpb(CLEANUP);
-
-    masm.bind(RET_NEG_ONE);
-    masm.movl(rbx, -1);
-    masm.jmpb(DONE);
-
-    masm.bind(RET_NOT_FOUND);
-    masm.movl(rbx, -1);
-
-    masm.bind(CLEANUP);
-    masm.addptr(rsp, 24);
-
-    masm.bind(DONE);
-  %}
-
-  enc_class enc_String_Equals(rdi_RegP str1, rsi_RegP str2, regD tmp1, regD tmp2,
-                              rbx_RegI tmp3, rcx_RegI tmp2, rax_RegI result) %{
-    Label RET_TRUE, RET_FALSE, DONE, COMPARE_VECTORS, COMPARE_CHAR;
-    MacroAssembler masm(&cbuf);
-
-    XMMRegister tmp1Reg   = as_XMMRegister($tmp1$$reg);
-    XMMRegister tmp2Reg   = as_XMMRegister($tmp2$$reg);
-
-    int value_offset  = java_lang_String::value_offset_in_bytes();
-    int offset_offset = java_lang_String::offset_offset_in_bytes();
-    int count_offset  = java_lang_String::count_offset_in_bytes();
-    int base_offset   = arrayOopDesc::base_offset_in_bytes(T_CHAR);
-
-    // does source == target string?
-    masm.cmpptr(rdi, rsi);
-    masm.jcc(Assembler::equal, RET_TRUE);
-
-    // get and compare counts
-    masm.movl(rcx, Address(rdi, count_offset));
-    masm.movl(rax, Address(rsi, count_offset));
-    masm.cmpl(rcx, rax);
-    masm.jcc(Assembler::notEqual, RET_FALSE);
-    masm.testl(rax, rax);
-    masm.jcc(Assembler::zero, RET_TRUE);
-
-    // get source string offset and value
-    masm.load_heap_oop(rbx, Address(rsi, value_offset));
-    masm.movl(rax, Address(rsi, offset_offset));
-    masm.lea(rsi, Address(rbx, rax, Address::times_2, base_offset));
-
-    // get compare string offset and value
-    masm.load_heap_oop(rbx, Address(rdi, value_offset));
-    masm.movl(rax, Address(rdi, offset_offset));
-    masm.lea(rdi, Address(rbx, rax, Address::times_2, base_offset));
-
-    // Set byte count
-    masm.shll(rcx, 1);
-    masm.movl(rax, rcx);
-
-    if (UseSSE42Intrinsics) {
-      // With SSE4.2, use double quad vector compare
-      Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
-      // Compare 16-byte vectors
-      masm.andl(rcx, 0xfffffff0);  // vector count (in bytes)
-      masm.andl(rax, 0x0000000e);  // tail count (in bytes)
-      masm.testl(rcx, rcx);
-      masm.jccb(Assembler::zero, COMPARE_TAIL);
-      masm.lea(rdi, Address(rdi, rcx, Address::times_1));
-      masm.lea(rsi, Address(rsi, rcx, Address::times_1));
-      masm.negptr(rcx);
-
-      masm.bind(COMPARE_WIDE_VECTORS);
-      masm.movdqu(tmp1Reg, Address(rdi, rcx, Address::times_1));
-      masm.movdqu(tmp2Reg, Address(rsi, rcx, Address::times_1));
-      masm.pxor(tmp1Reg, tmp2Reg);
-      masm.ptest(tmp1Reg, tmp1Reg);
-      masm.jccb(Assembler::notZero, RET_FALSE);
-      masm.addptr(rcx, 16);
-      masm.jcc(Assembler::notZero, COMPARE_WIDE_VECTORS);
-      masm.bind(COMPARE_TAIL);
-      masm.movl(rcx, rax);
-      // Fallthru to tail compare
-    }
-
-    // Compare 4-byte vectors
-    masm.andl(rcx, 0xfffffffc);  // vector count (in bytes)
-    masm.andl(rax, 0x00000002);  // tail char (in bytes)
-    masm.testl(rcx, rcx);
-    masm.jccb(Assembler::zero, COMPARE_CHAR);
-    masm.lea(rdi, Address(rdi, rcx, Address::times_1));
-    masm.lea(rsi, Address(rsi, rcx, Address::times_1));
-    masm.negptr(rcx);
-
-    masm.bind(COMPARE_VECTORS);
-    masm.movl(rbx, Address(rdi, rcx, Address::times_1));
-    masm.cmpl(rbx, Address(rsi, rcx, Address::times_1));
-    masm.jccb(Assembler::notEqual, RET_FALSE);
-    masm.addptr(rcx, 4);
-    masm.jcc(Assembler::notZero, COMPARE_VECTORS);
-
-    // Compare trailing char (final 2 bytes), if any
-    masm.bind(COMPARE_CHAR);
-    masm.testl(rax, rax);
-    masm.jccb(Assembler::zero, RET_TRUE);
-    masm.load_unsigned_short(rbx, Address(rdi, 0));
-    masm.load_unsigned_short(rcx, Address(rsi, 0));
-    masm.cmpl(rbx, rcx);
-    masm.jccb(Assembler::notEqual, RET_FALSE);
-
-    masm.bind(RET_TRUE);
-    masm.movl(rax, 1);   // return true
-    masm.jmpb(DONE);
-
-    masm.bind(RET_FALSE);
-    masm.xorl(rax, rax); // return false
-
-    masm.bind(DONE);
-  %}
-
-  enc_class enc_Array_Equals(rdi_RegP ary1, rsi_RegP ary2, regD tmp1, regD tmp2,
-                             rax_RegI tmp3, rbx_RegI tmp4, rcx_RegI result) %{
-    Label TRUE_LABEL, FALSE_LABEL, DONE, COMPARE_VECTORS, COMPARE_CHAR;
-    MacroAssembler masm(&cbuf);
-
-    XMMRegister tmp1Reg   = as_XMMRegister($tmp1$$reg);
-    XMMRegister tmp2Reg   = as_XMMRegister($tmp2$$reg);
-    Register ary1Reg      = as_Register($ary1$$reg);
-    Register ary2Reg      = as_Register($ary2$$reg);
-    Register tmp3Reg      = as_Register($tmp3$$reg);
-    Register tmp4Reg      = as_Register($tmp4$$reg);
-    Register resultReg    = as_Register($result$$reg);
-
-    int length_offset  = arrayOopDesc::length_offset_in_bytes();
-    int base_offset    = arrayOopDesc::base_offset_in_bytes(T_CHAR);
-
-    // Check the input args
-    masm.cmpq(ary1Reg, ary2Reg);
-    masm.jcc(Assembler::equal, TRUE_LABEL);
-    masm.testq(ary1Reg, ary1Reg);
-    masm.jcc(Assembler::zero, FALSE_LABEL);
-    masm.testq(ary2Reg, ary2Reg);
-    masm.jcc(Assembler::zero, FALSE_LABEL);
-
-    // Check the lengths
-    masm.movl(tmp4Reg, Address(ary1Reg, length_offset));
-    masm.movl(resultReg, Address(ary2Reg, length_offset));
-    masm.cmpl(tmp4Reg, resultReg);
-    masm.jcc(Assembler::notEqual, FALSE_LABEL);
-    masm.testl(resultReg, resultReg);
-    masm.jcc(Assembler::zero, TRUE_LABEL);
-
-    //load array address
-    masm.lea(ary1Reg, Address(ary1Reg, base_offset));
-    masm.lea(ary2Reg, Address(ary2Reg, base_offset));
-
-    //set byte count
-    masm.shll(tmp4Reg, 1);
-    masm.movl(resultReg,tmp4Reg);
-
-    if (UseSSE42Intrinsics){
-      // With SSE4.2, use double quad vector compare
-      Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
-      // Compare 16-byte vectors
-      masm.andl(tmp4Reg, 0xfffffff0);    // vector count (in bytes)
-      masm.andl(resultReg, 0x0000000e);  // tail count (in bytes)
-      masm.testl(tmp4Reg, tmp4Reg);
-      masm.jccb(Assembler::zero, COMPARE_TAIL);
-      masm.lea(ary1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
-      masm.lea(ary2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
-      masm.negptr(tmp4Reg);
-
-      masm.bind(COMPARE_WIDE_VECTORS);
-      masm.movdqu(tmp1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
-      masm.movdqu(tmp2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
-      masm.pxor(tmp1Reg, tmp2Reg);
-      masm.ptest(tmp1Reg, tmp1Reg);
-
-      masm.jccb(Assembler::notZero, FALSE_LABEL);
-      masm.addptr(tmp4Reg, 16);
-      masm.jcc(Assembler::notZero, COMPARE_WIDE_VECTORS);
-      masm.bind(COMPARE_TAIL);
-      masm.movl(tmp4Reg, resultReg);
-      // Fallthru to tail compare
-    }
-
-   // Compare 4-byte vectors
-    masm.andl(tmp4Reg, 0xfffffffc);    // vector count (in bytes)
-    masm.andl(resultReg, 0x00000002);  // tail char (in bytes)
-    masm.testl(tmp4Reg, tmp4Reg); //if tmp2 == 0, only compare char
-    masm.jccb(Assembler::zero, COMPARE_CHAR);
-    masm.lea(ary1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
-    masm.lea(ary2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
-    masm.negptr(tmp4Reg);
-
-    masm.bind(COMPARE_VECTORS);
-    masm.movl(tmp3Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
-    masm.cmpl(tmp3Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
-    masm.jccb(Assembler::notEqual, FALSE_LABEL);
-    masm.addptr(tmp4Reg, 4);
-    masm.jcc(Assembler::notZero, COMPARE_VECTORS);
-
-    // Compare trailing char (final 2 bytes), if any
-    masm.bind(COMPARE_CHAR);
-    masm.testl(resultReg, resultReg);
-    masm.jccb(Assembler::zero, TRUE_LABEL);
-    masm.load_unsigned_short(tmp3Reg, Address(ary1Reg, 0));
-    masm.load_unsigned_short(tmp4Reg, Address(ary2Reg, 0));
-    masm.cmpl(tmp3Reg, tmp4Reg);
-    masm.jccb(Assembler::notEqual, FALSE_LABEL);
-
-    masm.bind(TRUE_LABEL);
-    masm.movl(resultReg, 1);   // return true
-    masm.jmpb(DONE);
-
-    masm.bind(FALSE_LABEL);
-    masm.xorl(resultReg, resultReg); // return false
-
-    // That's it
-    masm.bind(DONE);
-  %}
 
   enc_class enc_rethrow()
   %{
@@ -12096,52 +11654,67 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct string_compare(rdi_RegP str1, rsi_RegP str2, regD tmp1, regD tmp2,
-                        rax_RegI tmp3, rbx_RegI tmp4, rcx_RegI result, rFlagsReg cr)
-%{
-  match(Set result (StrComp str1 str2));
-  effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, KILL tmp3, KILL tmp4, KILL cr);
-  //ins_cost(300);
-
-  format %{ "String Compare $str1, $str2 -> $result    // XXX KILL RAX, RBX" %}
-  ins_encode( enc_String_Compare(str1, str2, tmp1, tmp2, tmp3, tmp4, result) );
+instruct string_compare(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rbx_RegI cnt2,
+                        rax_RegI result, regD tmp1, regD tmp2, rFlagsReg cr)
+%{
+  match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
+  effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
+
+  format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   // KILL $tmp1, $tmp2" %}
+  ins_encode %{
+    __ string_compare($str1$$Register, $str2$$Register,
+                      $cnt1$$Register, $cnt2$$Register, $result$$Register,
+                      $tmp1$$XMMRegister, $tmp2$$XMMRegister);
+  %}
   ins_pipe( pipe_slow );
 %}
 
-instruct string_indexof(rsi_RegP str1, rdi_RegP str2, regD tmp1, rax_RegI tmp2,
-                        rcx_RegI tmp3, rdx_RegI tmp4, rbx_RegI result, rFlagsReg cr)
+instruct string_indexof(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2,
+                        rbx_RegI result, regD tmp1, rcx_RegI tmp2, rFlagsReg cr)
 %{
   predicate(UseSSE42Intrinsics);
-  match(Set result (StrIndexOf str1 str2));
-  effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, KILL tmp2, KILL tmp3, KILL tmp4, KILL cr);
-
-  format %{ "String IndexOf $str1,$str2 -> $result   // KILL RAX, RCX, RDX" %}
-  ins_encode( enc_String_IndexOf(str1, str2, tmp1, tmp2, tmp3, tmp4, result) );
+  match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
+  effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp2, KILL cr);
+
+  format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result   // KILL $tmp1, $tmp2" %}
+  ins_encode %{
+    __ string_indexof($str1$$Register, $str2$$Register,
+                      $cnt1$$Register, $cnt2$$Register, $result$$Register,
+                      $tmp1$$XMMRegister, $tmp2$$Register);
+  %}
   ins_pipe( pipe_slow );
 %}
 
 // fast string equals
-instruct string_equals(rdi_RegP str1, rsi_RegP str2, regD tmp1, regD tmp2, rbx_RegI tmp3,
-                       rcx_RegI tmp4, rax_RegI result, rFlagsReg cr)
-%{
-  match(Set result (StrEquals str1 str2));
-  effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, KILL tmp3, KILL tmp4, KILL cr);
-
-  format %{ "String Equals $str1,$str2 -> $result    // KILL RBX, RCX" %}
-  ins_encode( enc_String_Equals(str1, str2, tmp1, tmp2, tmp3, tmp4, result) );
+instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result,
+                       regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr)
+%{
+  match(Set result (StrEquals (Binary str1 str2) cnt));
+  effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr);
+
+  format %{ "String Equals $str1,$str2,$cnt -> $result    // KILL $tmp1, $tmp2, $tmp3" %}
+  ins_encode %{
+    __ char_arrays_equals(false, $str1$$Register, $str2$$Register,
+                          $cnt$$Register, $result$$Register, $tmp3$$Register,
+                          $tmp1$$XMMRegister, $tmp2$$XMMRegister);
+  %}
   ins_pipe( pipe_slow );
 %}
 
 // fast array equals
-instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, regD tmp1, regD tmp2, rax_RegI tmp3,
-                      rbx_RegI tmp4, rcx_RegI result, rFlagsReg cr)
+instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result,
+                      regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr)
 %{
   match(Set result (AryEq ary1 ary2));
   effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
   //ins_cost(300);
 
-  format %{ "Array Equals $ary1,$ary2 -> $result   // KILL RAX, RBX" %}
-  ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, tmp3, tmp4, result) );
+  format %{ "Array Equals $ary1,$ary2 -> $result   // KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
+  ins_encode %{
+    __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register,
+                          $tmp3$$Register, $result$$Register, $tmp4$$Register,
+                          $tmp1$$XMMRegister, $tmp2$$XMMRegister);
+  %}
   ins_pipe( pipe_slow );
 %}
 
--- a/hotspot/src/os/windows/vm/os_windows.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/os/windows/vm/os_windows.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -1526,7 +1526,8 @@
     case 5000: st->print(" Windows 2000"); break;
     case 5001: st->print(" Windows XP"); break;
     case 5002:
-    case 6000: {
+    case 6000:
+    case 6001: {
       // Retrieve SYSTEM_INFO from GetNativeSystemInfo call so that we could
       // find out whether we are running on 64 bit processor or not.
       SYSTEM_INFO si;
@@ -1549,13 +1550,27 @@
           st->print(" Windows XP x64 Edition");
         else
             st->print(" Windows Server 2003 family");
-      } else { // os_vers == 6000
+      } else if (os_vers == 6000) {
         if (osvi.wProductType == VER_NT_WORKSTATION)
             st->print(" Windows Vista");
         else
             st->print(" Windows Server 2008");
         if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
             st->print(" , 64 bit");
+      } else if (os_vers == 6001) {
+        if (osvi.wProductType == VER_NT_WORKSTATION) {
+            st->print(" Windows 7");
+        } else {
+            // Unrecognized windows, print out its major and minor versions
+            st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion);
+        }
+        if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
+            st->print(" , 64 bit");
+      } else { // future os
+        // Unrecognized windows, print out its major and minor versions
+        st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion);
+        if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
+            st->print(" , 64 bit");
       }
       break;
     }
--- a/hotspot/src/os_cpu/solaris_sparc/vm/atomic_solaris_sparc.inline.hpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/atomic_solaris_sparc.inline.hpp	Thu Oct 15 16:37:55 2009 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/os_cpu/solaris_x86/vm/atomic_solaris_x86.inline.hpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/os_cpu/solaris_x86/vm/atomic_solaris_x86.inline.hpp	Thu Oct 15 16:37:55 2009 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/adlc/archDesc.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/adlc/archDesc.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -1031,7 +1031,8 @@
 //---------------------------addSUNcopyright-------------------------------
 // output SUN copyright info
 void ArchDesc::addSunCopyright(char* legal, int size, FILE *fp) {
-  fwrite(legal, size, 1, fp);
+  size_t count = fwrite(legal, 1, size, fp);
+  assert(count == (size_t) size, "copyright info truncated");
   fprintf(fp,"\n");
   fprintf(fp,"// Machine Generated File.  Do Not Edit!\n");
   fprintf(fp,"\n");
--- a/hotspot/src/share/vm/adlc/formssel.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/adlc/formssel.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -828,11 +828,13 @@
     return AdlcVMDeps::Parms;   // Skip the machine-state edges
 
   if( _matrule->_rChild &&
-      ( strcmp(_matrule->_rChild->_opType,"StrComp"   )==0 ||
+      ( strcmp(_matrule->_rChild->_opType,"AryEq"     )==0 ||
+        strcmp(_matrule->_rChild->_opType,"StrComp"   )==0 ||
         strcmp(_matrule->_rChild->_opType,"StrEquals" )==0 ||
         strcmp(_matrule->_rChild->_opType,"StrIndexOf")==0 )) {
-        // String.(compareTo/equals/indexOf) take 1 control and 4 memory edges.
-    return 5;
+        // String.(compareTo/equals/indexOf) and Arrays.equals
+        // take 1 control and 1 memory edges.
+    return 2;
   }
 
   // Check for handling of 'Memory' input/edge in the ideal world.
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -1442,7 +1442,7 @@
         switch (field_type) {
         case T_ARRAY:
         case T_OBJECT:
-          if (field_val.as_object()->has_encoding()) {
+          if (field_val.as_object()->should_be_constant()) {
             constant =  new Constant(as_ValueType(field_val));
           }
           break;
--- a/hotspot/src/share/vm/c1/c1_IR.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/c1/c1_IR.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/c1/c1_IR.hpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/c1/c1_IR.hpp	Thu Oct 15 16:37:55 2009 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -133,12 +133,12 @@
       ciMethod* m = (ciMethod*)value;
       output()->print("<method %s.%s>", m->holder()->name()->as_utf8(), m->name()->as_utf8());
     } else {
-      output()->print("<object 0x%x>", value->encoding());
+      output()->print("<object 0x%x>", value->constant_encoding());
     }
   } else if (type->as_InstanceConstant() != NULL) {
-    output()->print("<instance 0x%x>", type->as_InstanceConstant()->value()->encoding());
+    output()->print("<instance 0x%x>", type->as_InstanceConstant()->value()->constant_encoding());
   } else if (type->as_ArrayConstant() != NULL) {
-    output()->print("<array 0x%x>", type->as_ArrayConstant()->value()->encoding());
+    output()->print("<array 0x%x>", type->as_ArrayConstant()->value()->constant_encoding());
   } else if (type->as_ClassConstant() != NULL) {
     ciInstanceKlass* klass = type->as_ClassConstant()->value();
     if (!klass->is_loaded()) {
--- a/hotspot/src/share/vm/c1/c1_LIR.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/c1/c1_LIR.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -567,8 +567,6 @@
     case lir_rem:
     case lir_sqrt:
     case lir_abs:
-    case lir_log:
-    case lir_log10:
     case lir_logic_and:
     case lir_logic_or:
     case lir_logic_xor:
@@ -644,13 +642,16 @@
 
     case lir_tan:
     case lir_sin:
-    case lir_cos: {
+    case lir_cos:
+    case lir_log:
+    case lir_log10: {
       assert(op->as_Op2() != NULL, "must be");
       LIR_Op2* op2 = (LIR_Op2*)op;
 
-      // sin and cos need two temporary fpu stack slots, so register
-      // two temp operands.  Register input operand as temp to
-      // guarantee that they do not overlap
+      // On x86 tan/sin/cos need two temporary fpu stack slots and
+      // log/log10 need one so handle opr2 and tmp as temp inputs.
+      // Register input operand as temp to guarantee that it doesn't
+      // overlap with the input.
       assert(op2->_info == NULL, "not used");
       assert(op2->_opr1->is_valid(), "used");
       do_input(op2->_opr1); do_temp(op2->_opr1);
--- a/hotspot/src/share/vm/c1/c1_LIR.hpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/c1/c1_LIR.hpp	Thu Oct 15 16:37:55 2009 -0700
@@ -1840,8 +1840,8 @@
 
   void abs (LIR_Opr from, LIR_Opr to, LIR_Opr tmp)                { append(new LIR_Op2(lir_abs , from, tmp, to)); }
   void sqrt(LIR_Opr from, LIR_Opr to, LIR_Opr tmp)                { append(new LIR_Op2(lir_sqrt, from, tmp, to)); }
-  void log (LIR_Opr from, LIR_Opr to, LIR_Opr tmp)                { append(new LIR_Op2(lir_log,  from, tmp, to)); }
-  void log10 (LIR_Opr from, LIR_Opr to, LIR_Opr tmp)              { append(new LIR_Op2(lir_log10, from, tmp, to)); }
+  void log (LIR_Opr from, LIR_Opr to, LIR_Opr tmp)                { append(new LIR_Op2(lir_log,  from, LIR_OprFact::illegalOpr, to, tmp)); }
+  void log10 (LIR_Opr from, LIR_Opr to, LIR_Opr tmp)              { append(new LIR_Op2(lir_log10, from, LIR_OprFact::illegalOpr, to, tmp)); }
   void sin (LIR_Opr from, LIR_Opr to, LIR_Opr tmp1, LIR_Opr tmp2) { append(new LIR_Op2(lir_sin , from, tmp1, to, tmp2)); }
   void cos (LIR_Opr from, LIR_Opr to, LIR_Opr tmp1, LIR_Opr tmp2) { append(new LIR_Op2(lir_cos , from, tmp1, to, tmp2)); }
   void tan (LIR_Opr from, LIR_Opr to, LIR_Opr tmp1, LIR_Opr tmp2) { append(new LIR_Op2(lir_tan , from, tmp1, to, tmp2)); }
--- a/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -440,7 +440,7 @@
     __ oop2reg_patch(NULL, r, info);
   } else {
     // no patching needed
-    __ oop2reg(obj->encoding(), r);
+    __ oop2reg(obj->constant_encoding(), r);
   }
 }
 
@@ -831,7 +831,7 @@
     int taken_count_offset     = md->byte_offset_of_slot(data, BranchData::taken_offset());
     int not_taken_count_offset = md->byte_offset_of_slot(data, BranchData::not_taken_offset());
     LIR_Opr md_reg = new_register(T_OBJECT);
-    __ move(LIR_OprFact::oopConst(md->encoding()), md_reg);
+    __ move(LIR_OprFact::oopConst(md->constant_encoding()), md_reg);
     LIR_Opr data_offset_reg = new_register(T_INT);
     __ cmove(lir_cond(cond),
              LIR_OprFact::intConst(taken_count_offset),
@@ -1071,7 +1071,7 @@
     LIR_OprList* args = new LIR_OprList();
     args->append(getThreadPointer());
     LIR_Opr meth = new_register(T_OBJECT);
-    __ oop2reg(method()->encoding(), meth);
+    __ oop2reg(method()->constant_encoding(), meth);
     args->append(meth);
     call_runtime(&signature, args, CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), voidType, NULL);
   }
@@ -1784,7 +1784,7 @@
     LIR_OprList* args = new LIR_OprList();
     args->append(getThreadPointer());
     LIR_Opr meth = new_register(T_OBJECT);
-    __ oop2reg(method()->encoding(), meth);
+    __ oop2reg(method()->constant_encoding(), meth);
     args->append(meth);
     call_runtime(&signature, args, CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), voidType, NULL);
   }
@@ -2207,7 +2207,7 @@
     LIR_OprList* args = new LIR_OprList();
     args->append(getThreadPointer());
     LIR_Opr meth = new_register(T_OBJECT);
-    __ oop2reg(method()->encoding(), meth);
+    __ oop2reg(method()->constant_encoding(), meth);
     args->append(meth);
     call_runtime(&signature, args, CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry), voidType, NULL);
   }
@@ -2216,7 +2216,7 @@
     LIR_Opr obj;
     if (method()->is_static()) {
       obj = new_register(T_OBJECT);
-      __ oop2reg(method()->holder()->java_mirror()->encoding(), obj);
+      __ oop2reg(method()->holder()->java_mirror()->constant_encoding(), obj);
     } else {
       Local* receiver = x->state()->local_at(0)->as_Local();
       assert(receiver != NULL, "must already exist");
@@ -2660,7 +2660,7 @@
     }
 
     LIR_Opr meth = new_register(T_OBJECT);
-    __ oop2reg(method()->encoding(), meth);
+    __ oop2reg(method()->constant_encoding(), meth);
     LIR_Opr result = increment_and_return_counter(meth, offset, InvocationCounter::count_increment);
     __ cmp(lir_cond_aboveEqual, result, LIR_OprFact::intConst(limit));
     CodeStub* overflow = new CounterOverflowStub(info, info->bci());
--- a/hotspot/src/share/vm/c1/c1_ValueType.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/c1/c1_ValueType.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -86,7 +86,7 @@
 
 jobject ObjectType::encoding() const {
   assert(is_constant(), "must be");
-  return constant_value()->encoding();
+  return constant_value()->constant_encoding();
 }
 
 bool ObjectType::is_loaded() const {
--- a/hotspot/src/share/vm/ci/ciEnv.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/ci/ciEnv.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -257,7 +257,7 @@
 
 // ------------------------------------------------------------------
 // ciEnv::make_array
-ciArray* ciEnv::make_array(GrowableArray<ciObject*>* objects) {
+ciArray* ciEnv::make_system_array(GrowableArray<ciObject*>* objects) {
   VM_ENTRY_MARK;
   int length = objects->length();
   objArrayOop a = oopFactory::new_system_objArray(length, THREAD);
--- a/hotspot/src/share/vm/ci/ciEnv.hpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/ci/ciEnv.hpp	Thu Oct 15 16:37:55 2009 -0700
@@ -339,8 +339,8 @@
   // but consider adding to vmSymbols.hpp instead.
 
   // Use this to make a holder for non-perm compile time constants.
-  // The resulting array is guaranteed to satisfy "has_encoding".
-  ciArray*  make_array(GrowableArray<ciObject*>* objects);
+  // The resulting array is guaranteed to satisfy "can_be_constant".
+  ciArray*  make_system_array(GrowableArray<ciObject*>* objects);
 
   // converts the ciKlass* representing the holder of a method into a
   // ciInstanceKlass*.  This is needed since the holder of a method in
--- a/hotspot/src/share/vm/ci/ciMethod.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/ci/ciMethod.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -325,10 +325,10 @@
 }
 
 // ------------------------------------------------------------------
-// ciMethod::liveness_at_bci
+// ciMethod::raw_liveness_at_bci
 //
 // Which local variables are live at a specific bci?
-MethodLivenessResult ciMethod::liveness_at_bci(int bci) {
+MethodLivenessResult ciMethod::raw_liveness_at_bci(int bci) {
   check_is_loaded();
   if (_liveness == NULL) {
     // Create the liveness analyzer.
@@ -336,7 +336,17 @@
     _liveness = new (arena) MethodLiveness(arena, this);
     _liveness->compute_liveness();
   }
-  MethodLivenessResult result = _liveness->get_liveness_at(bci);
+  return _liveness->get_liveness_at(bci);
+}
+
+// ------------------------------------------------------------------
+// ciMethod::liveness_at_bci
+//
+// Which local variables are live at a specific bci?  When debugging
+// will return true for all locals in some cases to improve debug
+// information.
+MethodLivenessResult ciMethod::liveness_at_bci(int bci) {
+  MethodLivenessResult result = raw_liveness_at_bci(bci);
   if (CURRENT_ENV->jvmti_can_access_local_variables() || DeoptimizeALot || CompileTheWorld) {
     // Keep all locals live for the user's edification and amusement.
     result.at_put_range(0, result.size(), true);
--- a/hotspot/src/share/vm/ci/ciMethod.hpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/ci/ciMethod.hpp	Thu Oct 15 16:37:55 2009 -0700
@@ -149,6 +149,12 @@
   bool          has_monitor_bytecodes() const    { return _uses_monitors; }
   bool          has_balanced_monitors();
 
+  // Returns a bitmap indicating which locals are required to be
+  // maintained as live for deopt.  raw_liveness_at_bci is always the
+  // direct output of the liveness computation while liveness_at_bci
+  // may mark all locals as live to improve support for debugging Java
+  // code by maintaining the state of as many locals as possible.
+  MethodLivenessResult raw_liveness_at_bci(int bci);
   MethodLivenessResult liveness_at_bci(int bci);
 
   // Get the interpreters viewpoint on oop liveness.  MethodLiveness is
--- a/hotspot/src/share/vm/ci/ciObject.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/ci/ciObject.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -55,6 +55,7 @@
   }
   _klass = NULL;
   _ident = 0;
+  init_flags_from(o);
 }
 
 // ------------------------------------------------------------------
@@ -69,6 +70,7 @@
   }
   _klass = NULL;
   _ident = 0;
+  init_flags_from(h());
 }
 
 // ------------------------------------------------------------------
@@ -158,7 +160,7 @@
 }
 
 // ------------------------------------------------------------------
-// ciObject::encoding
+// ciObject::constant_encoding
 //
 // The address which the compiler should embed into the
 // generated code to represent this oop.  This address
@@ -172,16 +174,24 @@
 //
 // This method should be changed to return an generified address
 // to discourage use of the JNI handle.
-jobject ciObject::encoding() {
+jobject ciObject::constant_encoding() {
   assert(is_null_object() || handle() != NULL, "cannot embed null pointer");
-  assert(has_encoding(), "oop must be NULL or perm");
+  assert(can_be_constant(), "oop must be NULL or perm");
   return handle();
 }
 
 // ------------------------------------------------------------------
-// ciObject::has_encoding
-bool ciObject::has_encoding() {
-  return handle() == NULL || is_perm();
+// ciObject::can_be_constant
+bool ciObject::can_be_constant() {
+  if (ScavengeRootsInCode >= 1)  return true;  // now everybody can encode as a constant
+  return handle() == NULL || !is_scavengable();
+}
+
+// ------------------------------------------------------------------
+// ciObject::should_be_constant()
+bool ciObject::should_be_constant() {
+  if (ScavengeRootsInCode >= 2)  return true;  // force everybody to be a constant
+  return handle() == NULL || !is_scavengable();
 }
 
 
@@ -195,8 +205,9 @@
 void ciObject::print(outputStream* st) {
   st->print("<%s", type_string());
   GUARDED_VM_ENTRY(print_impl(st);)
-  st->print(" ident=%d %s address=0x%x>", ident(),
+  st->print(" ident=%d %s%s address=0x%x>", ident(),
         is_perm() ? "PERM" : "",
+        is_scavengable() ? "SCAVENGABLE" : "",
         (address)this);
 }
 
--- a/hotspot/src/share/vm/ci/ciObject.hpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/ci/ciObject.hpp	Thu Oct 15 16:37:55 2009 -0700
@@ -51,9 +51,10 @@
   ciKlass* _klass;
   uint     _ident;
 
-  enum { FLAG_BITS   = 1};
+  enum { FLAG_BITS   = 2 };
   enum {
-         PERM_FLAG    = 1
+         PERM_FLAG        = 1,
+         SCAVENGABLE_FLAG = 2
        };
 protected:
   ciObject();
@@ -68,8 +69,15 @@
     return JNIHandles::resolve_non_null(_handle);
   }
 
-  void set_perm() {
-    _ident |=  PERM_FLAG;
+  void init_flags_from(oop x) {
+    int flags = 0;
+    if (x != NULL) {
+      if (x->is_perm())
+        flags |= PERM_FLAG;
+      if (x->is_scavengable())
+        flags |= SCAVENGABLE_FLAG;
+    }
+    _ident |= flags;
   }
 
   // Virtual behavior of the print() method.
@@ -91,17 +99,27 @@
   // A hash value for the convenience of compilers.
   int hash();
 
-  // Tells if this oop has an encoding.  (I.e., is it null or perm?)
+  // Tells if this oop has an encoding as a constant.
+  // True if is_scavengable is false.
+  // Also true if ScavengeRootsInCode is non-zero.
   // If it does not have an encoding, the compiler is responsible for
   // making other arrangements for dealing with the oop.
-  // See ciEnv::make_perm_array
-  bool has_encoding();
+  // See ciEnv::make_array
+  bool can_be_constant();
+
+  // Tells if this oop should be made a constant.
+  // True if is_scavengable is false or ScavengeRootsInCode > 1.
+  bool should_be_constant();
 
   // Is this object guaranteed to be in the permanent part of the heap?
   // If so, CollectedHeap::can_elide_permanent_oop_store_barriers is relevant.
   // If the answer is false, no guarantees are made.
   bool is_perm() { return (_ident & PERM_FLAG) != 0; }
 
+  // Might this object possibly move during a scavenge operation?
+  // If the answer is true and ScavengeRootsInCode==0, the oop cannot be embedded in code.
+  bool is_scavengable() { return (_ident & SCAVENGABLE_FLAG) != 0; }
+
   // The address which the compiler should embed into the
   // generated code to represent this oop.  This address
   // is not the true address of the oop -- it will get patched
@@ -109,7 +127,7 @@
   //
   // Usage note: no address arithmetic allowed.  Oop must
   // be registered with the oopRecorder.
-  jobject encoding();
+  jobject constant_encoding();
 
   // What kind of ciObject is this?
   virtual bool is_null_object() const       { return false; }
--- a/hotspot/src/share/vm/ci/ciObjectFactory.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/ci/ciObjectFactory.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -261,12 +261,11 @@
     ciObject* new_object = create_new_object(keyHandle());
     assert(keyHandle() == new_object->get_oop(), "must be properly recorded");
     init_ident_of(new_object);
-    if (!keyHandle->is_perm()) {
+    if (!new_object->is_perm()) {
       // Not a perm-space object.
       insert_non_perm(bucket, keyHandle(), new_object);
       return new_object;
     }
-    new_object->set_perm();
     if (len != _ci_objects->length()) {
       // creating the new object has recursively entered new objects
       // into the table.  We need to recompute our index.
--- a/hotspot/src/share/vm/ci/ciTypeFlow.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/ci/ciTypeFlow.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -2486,8 +2486,13 @@
         // Assume irreducible entries need more data flow
         add_to_work_list(succ);
       }
-      lp = lp->parent();
-      assert(lp != NULL, "nested loop must have parent by now");
+      Loop* plp = lp->parent();
+      if (plp == NULL) {
+        // This only happens for some irreducible cases.  The parent
+        // will be updated during a later pass.
+        break;
+      }
+      lp = plp;
     }
 
     // Merge loop tree branch for all successors.
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -2547,6 +2547,7 @@
                                                     KlassHandle host_klass,
                                                     GrowableArray<Handle>* cp_patches,
                                                     symbolHandle& parsed_name,
+                                                    bool verify,
                                                     TRAPS) {
   // So that JVMTI can cache class file in the state before retransformable agents
   // have modified it
@@ -2591,7 +2592,7 @@
   instanceKlassHandle nullHandle;
 
   // Figure out whether we can skip format checking (matching classic VM behavior)
-  _need_verify = Verifier::should_verify_for(class_loader());
+  _need_verify = Verifier::should_verify_for(class_loader(), verify);
 
   // Set the verify flag in stream
   cfs->set_verify(_need_verify);
@@ -3210,6 +3211,7 @@
 
     // Fill in information already parsed
     this_klass->set_access_flags(access_flags);
+    this_klass->set_should_verify_class(verify);
     jint lh = Klass::instance_layout_helper(instance_size, false);
     this_klass->set_layout_helper(lh);
     assert(this_klass->oop_is_instance(), "layout is correct");
@@ -3229,6 +3231,12 @@
       this_klass->set_has_final_method();
     }
     this_klass->set_method_ordering(method_ordering());
+    // The instanceKlass::_methods_jmethod_ids cache and the
+    // instanceKlass::_methods_cached_itable_indices cache are
+    // both managed on the assumption that the initial cache
+    // size is equal to the number of methods in the class. If
+    // that changes, then instanceKlass::idnum_can_increment()
+    // has to be changed accordingly.
     this_klass->set_initial_method_idnum(methods->length());
     this_klass->set_name(cp->klass_name_at(this_class_index));
     if (LinkWellKnownClasses || is_anonymous())  // I am well known to myself
--- a/hotspot/src/share/vm/classfile/classFileParser.hpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/classfile/classFileParser.hpp	Thu Oct 15 16:37:55 2009 -0700
@@ -260,9 +260,10 @@
                                      Handle class_loader,
                                      Handle protection_domain,
                                      symbolHandle& parsed_name,
+                                     bool verify,
                                      TRAPS) {
     KlassHandle no_host_klass;
-    return parseClassFile(name, class_loader, protection_domain, no_host_klass, NULL, parsed_name, THREAD);
+    return parseClassFile(name, class_loader, protection_domain, no_host_klass, NULL, parsed_name, verify, THREAD);
   }
   instanceKlassHandle parseClassFile(symbolHandle name,
                                      Handle class_loader,
@@ -270,6 +271,7 @@
                                      KlassHandle host_klass,
                                      GrowableArray<Handle>* cp_patches,
                                      symbolHandle& parsed_name,
+                                     bool verify,
                                      TRAPS);
 
   // Verifier checks
--- a/hotspot/src/share/vm/classfile/classLoader.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/classfile/classLoader.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -874,6 +874,7 @@
                                                        class_loader,
                                                        protection_domain,
                                                        parsed_name,
+                                                       false,
                                                        CHECK_(h));
 
     // add to package table
--- a/hotspot/src/share/vm/classfile/classLoader.hpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/classfile/classLoader.hpp	Thu Oct 15 16:37:55 2009 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -252,7 +252,7 @@
   typeArrayOop value  = java_lang_String::value(obj);
   int          offset = java_lang_String::offset(obj);
   int          length = java_lang_String::length(obj);
-  jchar* base = value->char_at_addr(offset);
+  jchar* base = (length == 0) ? NULL : value->char_at_addr(offset);
   symbolOop sym = SymbolTable::lookup_unicode(base, length, THREAD);
   return symbolHandle(THREAD, sym);
 }
@@ -261,7 +261,7 @@
   typeArrayOop value  = java_lang_String::value(java_string);
   int          offset = java_lang_String::offset(java_string);
   int          length = java_lang_String::length(java_string);
-  jchar* base = value->char_at_addr(offset);
+  jchar* base = (length == 0) ? NULL : value->char_at_addr(offset);
   return SymbolTable::probe_unicode(base, length);
 }
 
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -970,6 +970,7 @@
                                                              host_klass,
                                                              cp_patches,
                                                              parsed_name,
+                                                             true,
                                                              THREAD);
 
 
@@ -1025,6 +1026,7 @@
                                                Handle class_loader,
                                                Handle protection_domain,
                                                ClassFileStream* st,
+                                               bool verify,
                                                TRAPS) {
 
   // Classloaders that support parallelism, e.g. bootstrap classloader,
@@ -1055,6 +1057,7 @@
                                                              class_loader,
                                                              protection_domain,
                                                              parsed_name,
+                                                             verify,
                                                              THREAD);
 
   const char* pkg = "java/";
@@ -2414,6 +2417,8 @@
                          vmSymbols::makeSite_name(), vmSymbols::makeSite_signature(),
                          &args, CHECK_(empty));
   oop call_site_oop = (oop) result.get_jobject();
+  assert(call_site_oop->is_oop()
+         /*&& sun_dyn_CallSiteImpl::is_instance(call_site_oop)*/, "must be sane");
   sun_dyn_CallSiteImpl::set_vmmethod(call_site_oop, mh_invdyn());
   if (TraceMethodHandles) {
     tty->print_cr("Linked invokedynamic bci=%d site="INTPTR_FORMAT":", caller_bci, call_site_oop);
@@ -2450,6 +2455,8 @@
   oop boot_method_oop = (oop) result.get_jobject();
 
   if (boot_method_oop != NULL) {
+    assert(boot_method_oop->is_oop()
+           && java_dyn_MethodHandle::is_instance(boot_method_oop), "must be sane");
     // probably no race conditions, but let's be careful:
     if (Atomic::cmpxchg_ptr(boot_method_oop, ik->adr_bootstrap_method(), NULL) == NULL)
       ik->set_bootstrap_method(boot_method_oop);
--- a/hotspot/src/share/vm/classfile/systemDictionary.hpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp	Thu Oct 15 16:37:55 2009 -0700
@@ -259,7 +259,9 @@
                                TRAPS);
 
   // Resolve from stream (called by jni_DefineClass and JVM_DefineClass)
-  static klassOop resolve_from_stream(symbolHandle class_name, Handle class_loader, Handle protection_domain, ClassFileStream* st, TRAPS);
+  static klassOop resolve_from_stream(symbolHandle class_name, Handle class_loader,
+                                      Handle protection_domain,
+                                      ClassFileStream* st, bool verify, TRAPS);
 
   // Lookup an already loaded class. If not found NULL is returned.
   static klassOop find(symbolHandle class_name, Handle class_loader, Handle protection_domain, TRAPS);
--- a/hotspot/src/share/vm/classfile/verifier.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/classfile/verifier.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -53,8 +53,8 @@
 
 // Methods in Verifier
 
-bool Verifier::should_verify_for(oop class_loader) {
-  return class_loader == NULL ?
+bool Verifier::should_verify_for(oop class_loader, bool should_verify_class) {
+  return (class_loader == NULL || !should_verify_class) ?
     BytecodeVerificationLocal : BytecodeVerificationRemote;
 }
 
@@ -68,7 +68,7 @@
   return !need_verify;
 }
 
-bool Verifier::verify(instanceKlassHandle klass, Verifier::Mode mode, TRAPS) {
+bool Verifier::verify(instanceKlassHandle klass, Verifier::Mode mode, bool should_verify_class, TRAPS) {
   ResourceMark rm(THREAD);
   HandleMark hm;
 
@@ -81,7 +81,7 @@
   // If the class should be verified, first see if we can use the split
   // verifier.  If not, or if verification fails and FailOverToOldVerifier
   // is set, then call the inference verifier.
-  if (is_eligible_for_verification(klass)) {
+  if (is_eligible_for_verification(klass, should_verify_class)) {
     if (TraceClassInitialization) {
       tty->print_cr("Start class verification for: %s", klassName);
     }
@@ -141,12 +141,13 @@
   }
 }
 
-bool Verifier::is_eligible_for_verification(instanceKlassHandle klass) {
+bool Verifier::is_eligible_for_verification(instanceKlassHandle klass, bool should_verify_class) {
   symbolOop name = klass->name();
   klassOop refl_magic_klass = SystemDictionary::reflect_magic_klass();
 
-  return (should_verify_for(klass->class_loader()) &&
+  return (should_verify_for(klass->class_loader(), should_verify_class) &&
     // return if the class is a bootstrapping class
+    // or defineClass specified not to verify by default (flags override passed arg)
     // We need to skip the following four for bootstraping
     name != vmSymbols::java_lang_Object() &&
     name != vmSymbols::java_lang_Class() &&
--- a/hotspot/src/share/vm/classfile/verifier.hpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/classfile/verifier.hpp	Thu Oct 15 16:37:55 2009 -0700
@@ -34,16 +34,18 @@
    * Otherwise, no exception is thrown and the return indicates the
    * error.
    */
-  static bool verify(instanceKlassHandle klass, Mode mode, TRAPS);
+  static bool verify(instanceKlassHandle klass, Mode mode, bool should_verify_class, TRAPS);
 
-  // Return false if the class is loaded by the bootstrap loader.
-  static bool should_verify_for(oop class_loader);
+  // Return false if the class is loaded by the bootstrap loader,
+  // or if defineClass was called requesting skipping verification
+  // -Xverify:all/none override this value
+  static bool should_verify_for(oop class_loader, bool should_verify_class);
 
   // Relax certain verifier checks to enable some broken 1.1 apps to run on 1.2.
   static bool relax_verify_for(oop class_loader);
 
  private:
-  static bool is_eligible_for_verification(instanceKlassHandle klass);
+  static bool is_eligible_for_verification(instanceKlassHandle klass, bool should_verify_class);
   static symbolHandle inference_verify(
     instanceKlassHandle klass, char* msg, size_t msg_len, TRAPS);
 };
--- a/hotspot/src/share/vm/code/codeBlob.hpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/code/codeBlob.hpp	Thu Oct 15 16:37:55 2009 -0700
@@ -175,6 +175,8 @@
                             OopClosure* keep_alive,
                             bool unloading_occurred);
   virtual void oops_do(OopClosure* f) = 0;
+  // (All CodeBlob subtypes other than NMethod currently have
+  // an empty oops_do() method.
 
   // OopMap for frame
   OopMapSet* oop_maps() const                    { return _oop_maps; }
--- a/hotspot/src/share/vm/code/codeCache.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/code/codeCache.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -95,6 +95,7 @@
 int CodeCache::_number_of_blobs = 0;
 int CodeCache::_number_of_nmethods_with_dependencies = 0;
 bool CodeCache::_needs_cache_clean = false;
+nmethod* CodeCache::_scavenge_root_nmethods = NULL;
 
 
 CodeBlob* CodeCache::first() {
@@ -148,10 +149,7 @@
     }
   }
   verify_if_often();
-  if (PrintCodeCache2) {        // Need to add a new flag
-      ResourceMark rm;
-      tty->print_cr("CodeCache allocation:  addr: " INTPTR_FORMAT ", size: 0x%x\n", cb, size);
-  }
+  print_trace("allocation", cb, size);
   return cb;
 }
 
@@ -159,10 +157,7 @@
   assert_locked_or_safepoint(CodeCache_lock);
   verify_if_often();
 
-  if (PrintCodeCache2) {        // Need to add a new flag
-      ResourceMark rm;
-      tty->print_cr("CodeCache free:  addr: " INTPTR_FORMAT ", size: 0x%x\n", cb, cb->size());
-  }
+  print_trace("free", cb);
   if (cb->is_nmethod() && ((nmethod *)cb)->has_dependencies()) {
     _number_of_nmethods_with_dependencies--;
   }
@@ -260,14 +255,148 @@
   }
 }
 
-void CodeCache::oops_do(OopClosure* f) {
+void CodeCache::blobs_do(CodeBlobClosure* f) {
   assert_locked_or_safepoint(CodeCache_lock);
   FOR_ALL_ALIVE_BLOBS(cb) {
-    cb->oops_do(f);
+    f->do_code_blob(cb);
+
+#ifdef ASSERT
+    if (cb->is_nmethod())
+      ((nmethod*)cb)->verify_scavenge_root_oops();
+#endif //ASSERT
   }
 }
 
+// Walk the list of methods which might contain non-perm oops.
+void CodeCache::scavenge_root_nmethods_do(CodeBlobClosure* f) {
+  assert_locked_or_safepoint(CodeCache_lock);
+  debug_only(mark_scavenge_root_nmethods());
+
+  for (nmethod* cur = scavenge_root_nmethods(); cur != NULL; cur = cur->scavenge_root_link()) {
+    debug_only(cur->clear_scavenge_root_marked());
+    assert(cur->scavenge_root_not_marked(), "");
+    assert(cur->on_scavenge_root_list(), "else shouldn't be on this list");
+
+    bool is_live = (!cur->is_zombie() && !cur->is_unloaded());
+#ifndef PRODUCT
+    if (TraceScavenge) {
+      cur->print_on(tty, is_live ? "scavenge root" : "dead scavenge root"); tty->cr();
+    }
+#endif //PRODUCT
+    if (is_live)
+      // Perform cur->oops_do(f), maybe just once per nmethod.
+      f->do_code_blob(cur);
+  }
+
+  // Check for stray marks.
+  debug_only(verify_perm_nmethods(NULL));
+}
+
+void CodeCache::add_scavenge_root_nmethod(nmethod* nm) {
+  assert_locked_or_safepoint(CodeCache_lock);
+  nm->set_on_scavenge_root_list();
+  nm->set_scavenge_root_link(_scavenge_root_nmethods);
+  set_scavenge_root_nmethods(nm);
+  print_trace("add_scavenge_root", nm);
+}
+
+void CodeCache::drop_scavenge_root_nmethod(nmethod* nm) {
+  assert_locked_or_safepoint(CodeCache_lock);
+  print_trace("drop_scavenge_root", nm);
+  nmethod* last = NULL;
+  nmethod* cur = scavenge_root_nmethods();
+  while (cur != NULL) {
+    nmethod* next = cur->scavenge_root_link();
+    if (cur == nm) {
+      if (last != NULL)
+            last->set_scavenge_root_link(next);
+      else  set_scavenge_root_nmethods(next);
+      nm->set_scavenge_root_link(NULL);
+      nm->clear_on_scavenge_root_list();
+      return;
+    }
+    last = cur;
+    cur = next;
+  }
+  assert(false, "should have been on list");
+}
+
+void CodeCache::prune_scavenge_root_nmethods() {
+  assert_locked_or_safepoint(CodeCache_lock);
+  debug_only(mark_scavenge_root_nmethods());
+
+  nmethod* last = NULL;
+  nmethod* cur = scavenge_root_nmethods();
+  while (cur != NULL) {
+    nmethod* next = cur->scavenge_root_link();
+    debug_only(cur->clear_scavenge_root_marked());
+    assert(cur->scavenge_root_not_marked(), "");
+    assert(cur->on_scavenge_root_list(), "else shouldn't be on this list");
+
+    if (!cur->is_zombie() && !cur->is_unloaded()
+        && cur->detect_scavenge_root_oops()) {
+      // Keep it.  Advance 'last' to prevent deletion.
+      last = cur;
+    } else {
+      // Prune it from the list, so we don't have to look at it any more.
+      print_trace("prune_scavenge_root", cur);
+      cur->set_scavenge_root_link(NULL);
+      cur->clear_on_scavenge_root_list();
+      if (last != NULL)
+            last->set_scavenge_root_link(next);
+      else  set_scavenge_root_nmethods(next);
+    }
+    cur = next;
+  }
+
+  // Check for stray marks.
+  debug_only(verify_perm_nmethods(NULL));
+}
+
+#ifndef PRODUCT
+void CodeCache::asserted_non_scavengable_nmethods_do(CodeBlobClosure* f) {
+  // While we are here, verify the integrity of the list.
+  mark_scavenge_root_nmethods();
+  for (nmethod* cur = scavenge_root_nmethods(); cur != NULL; cur = cur->scavenge_root_link()) {
+    assert(cur->on_scavenge_root_list(), "else shouldn't be on this list");
+    cur->clear_scavenge_root_marked();
+  }
+  verify_perm_nmethods(f);
+}
+
+// Temporarily mark nmethods that are claimed to be on the non-perm list.
+void CodeCache::mark_scavenge_root_nmethods() {
+  FOR_ALL_ALIVE_BLOBS(cb) {
+    if (cb->is_nmethod()) {
+      nmethod *nm = (nmethod*)cb;
+      assert(nm->scavenge_root_not_marked(), "clean state");
+      if (nm->on_scavenge_root_list())
+        nm->set_scavenge_root_marked();
+    }
+  }
+}
+
+// If the closure is given, run it on the unlisted nmethods.
+// Also make sure that the effects of mark_scavenge_root_nmethods is gone.
+void CodeCache::verify_perm_nmethods(CodeBlobClosure* f_or_null) {
+  FOR_ALL_ALIVE_BLOBS(cb) {
+    bool call_f = (f_or_null != NULL);
+    if (cb->is_nmethod()) {
+      nmethod *nm = (nmethod*)cb;
+      assert(nm->scavenge_root_not_marked(), "must be already processed");
+      if (nm->on_scavenge_root_list())
+        call_f = false;  // don't show this one to the client
+      nm->verify_scavenge_root_oops();
+    } else {
+      call_f = false;   // not an nmethod
+    }
+    if (call_f)  f_or_null->do_code_blob(cb);
+  }
+}
+#endif //PRODUCT
+
 void CodeCache::gc_prologue() {
+  assert(!nmethod::oops_do_marking_is_active(), "oops_do_marking_epilogue must be called");
 }
 
 
@@ -285,6 +414,8 @@
     cb->fix_oop_relocations();
   }
   set_needs_cache_clean(false);
+  prune_scavenge_root_nmethods();
+  assert(!nmethod::oops_do_marking_is_active(), "oops_do_marking_prologue must be called");
 }
 
 
@@ -508,6 +639,14 @@
   }
 }
 
+void CodeCache::print_trace(const char* event, CodeBlob* cb, int size) {
+  if (PrintCodeCache2) {  // Need to add a new flag
+    ResourceMark rm;
+    if (size == 0)  size = cb->size();
+    tty->print_cr("CodeCache %s:  addr: " INTPTR_FORMAT ", size: 0x%x", event, cb, size);
+  }
+}
+
 void CodeCache::print_internals() {
   int nmethodCount = 0;
   int runtimeStubCount = 0;
--- a/hotspot/src/share/vm/code/codeCache.hpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/code/codeCache.hpp	Thu Oct 15 16:37:55 2009 -0700
@@ -45,8 +45,13 @@
   static int _number_of_blobs;
   static int _number_of_nmethods_with_dependencies;
   static bool _needs_cache_clean;
+  static nmethod* _scavenge_root_nmethods;  // linked via nm->scavenge_root_link()
 
   static void verify_if_often() PRODUCT_RETURN;
+
+  static void mark_scavenge_root_nmethods() PRODUCT_RETURN;
+  static void verify_perm_nmethods(CodeBlobClosure* f_or_null) PRODUCT_RETURN;
+
  public:
 
   // Initialization
@@ -61,6 +66,7 @@
   static void flush();                              // flushes all CodeBlobs
   static bool contains(void *p);                    // returns whether p is included
   static void blobs_do(void f(CodeBlob* cb));       // iterates over all CodeBlobs
+  static void blobs_do(CodeBlobClosure* f);         // iterates over all CodeBlobs
   static void nmethods_do(void f(nmethod* nm));     // iterates over all nmethods
 
   // Lookup
@@ -106,12 +112,24 @@
   static void do_unloading(BoolObjectClosure* is_alive,
                            OopClosure* keep_alive,
                            bool unloading_occurred);
-  static void oops_do(OopClosure* f);
+  static void oops_do(OopClosure* f) {
+    CodeBlobToOopClosure oopc(f, /*do_marking=*/ false);
+    blobs_do(&oopc);
+  }
+  static void asserted_non_scavengable_nmethods_do(CodeBlobClosure* f = NULL) PRODUCT_RETURN;
+  static void scavenge_root_nmethods_do(CodeBlobClosure* f);
+
+  static nmethod* scavenge_root_nmethods()          { return _scavenge_root_nmethods; }
+  static void set_scavenge_root_nmethods(nmethod* nm) { _scavenge_root_nmethods = nm; }
+  static void add_scavenge_root_nmethod(nmethod* nm);
+  static void drop_scavenge_root_nmethod(nmethod* nm);
+  static void prune_scavenge_root_nmethods();
 
   // Printing/debugging
   static void print()   PRODUCT_RETURN;          // prints summary
   static void print_internals();
   static void verify();                          // verifies the code cache
+  static void print_trace(const char* event, CodeBlob* cb, int size = 0) PRODUCT_RETURN;
 
   // The full limits of the codeCache
   static address  low_bound()                    { return (address) _heap->low_boundary(); }
--- a/hotspot/src/share/vm/code/debugInfoRec.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/code/debugInfoRec.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -299,7 +299,7 @@
   stream()->write_int(sender_stream_offset);
 
   // serialize scope
-  jobject method_enc = (method == NULL)? NULL: method->encoding();
+  jobject method_enc = (method == NULL)? NULL: method->constant_encoding();
   stream()->write_int(oop_recorder()->find_index(method_enc));
   stream()->write_bci(bci);
   assert(method == NULL ||
--- a/hotspot/src/share/vm/code/debugInfoRec.hpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/code/debugInfoRec.hpp	Thu Oct 15 16:37:55 2009 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1998-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/code/dependencies.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/code/dependencies.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -302,7 +302,7 @@
       bytes.write_byte(code_byte);
       for (int j = 0; j < stride; j++) {
         if (j == skipj)  continue;
-        bytes.write_int(_oop_recorder->find_index(deps->at(i+j)->encoding()));
+        bytes.write_int(_oop_recorder->find_index(deps->at(i+j)->constant_encoding()));
       }
     }
   }
--- a/hotspot/src/share/vm/code/nmethod.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/code/nmethod.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -581,10 +581,13 @@
     debug_only(No_Safepoint_Verifier nsv;)
     assert_locked_or_safepoint(CodeCache_lock);
 
-    NOT_PRODUCT(_has_debug_info = false; )
+    NOT_PRODUCT(_has_debug_info = false);
+    _oops_do_mark_link       = NULL;
     _method                  = method;
     _entry_bci               = InvocationEntryBci;
-    _link                    = NULL;
+    _osr_link                = NULL;
+    _scavenge_root_link      = NULL;
+    _scavenge_root_state     = 0;
     _compiler                = NULL;
     // We have no exception handler or deopt handler make the
     // values something that will never match a pc like the nmethod vtable entry
@@ -618,7 +621,7 @@
     _stack_traversal_mark    = 0;
 
     code_buffer->copy_oops_to(this);
-    debug_only(check_store();)
+    debug_only(verify_scavenge_root_oops());
     CodeCache::commit(this);
     VTune::create_nmethod(this);
   }
@@ -668,10 +671,13 @@
     debug_only(No_Safepoint_Verifier nsv;)
     assert_locked_or_safepoint(CodeCache_lock);
 
-    NOT_PRODUCT(_has_debug_info = false; )
+    NOT_PRODUCT(_has_debug_info = false);
+    _oops_do_mark_link       = NULL;
     _method                  = method;
     _entry_bci               = InvocationEntryBci;
-    _link                    = NULL;
+    _osr_link                = NULL;
+    _scavenge_root_link      = NULL;
+    _scavenge_root_state     = 0;
     _compiler                = NULL;
     // We have no exception handler or deopt handler make the
     // values something that will never match a pc like the nmethod vtable entry
@@ -703,7 +709,7 @@
     _stack_traversal_mark    = 0;
 
     code_buffer->copy_oops_to(this);
-    debug_only(check_store();)
+    debug_only(verify_scavenge_root_oops());
     CodeCache::commit(this);
     VTune::create_nmethod(this);
   }
@@ -770,12 +776,15 @@
     debug_only(No_Safepoint_Verifier nsv;)
     assert_locked_or_safepoint(CodeCache_lock);
 
-    NOT_PRODUCT(_has_debug_info = false; )
+    NOT_PRODUCT(_has_debug_info = false);
+    _oops_do_mark_link       = NULL;
     _method                  = method;
     _compile_id              = compile_id;
     _comp_level              = comp_level;
     _entry_bci               = entry_bci;
-    _link                    = NULL;
+    _osr_link                = NULL;
+    _scavenge_root_link      = NULL;
+    _scavenge_root_state     = 0;
     _compiler                = compiler;
     _orig_pc_offset          = orig_pc_offset;
 #ifdef HAVE_DTRACE_H
@@ -813,7 +822,10 @@
     code_buffer->copy_oops_to(this);
     debug_info->copy_to(this);
     dependencies->copy_to(this);
-    debug_only(check_store();)
+    if (ScavengeRootsInCode && detect_scavenge_root_oops()) {
+      CodeCache::add_scavenge_root_nmethod(this);
+    }
+    debug_only(verify_scavenge_root_oops());
 
     CodeCache::commit(this);
 
@@ -902,23 +914,30 @@
   if (st != NULL) {
     ttyLocker ttyl;
     // Print a little tag line that looks like +PrintCompilation output:
-    st->print("%3d%c  %s",
+    int tlen = (int) strlen(title);
+    bool do_nl = false;
+    if (tlen > 0 && title[tlen-1] == '\n') { tlen--; do_nl = true; }
+    st->print("%3d%c  %.*s",
               compile_id(),
               is_osr_method() ? '%' :
               method() != NULL &&
               is_native_method() ? 'n' : ' ',
-              title);
+              tlen, title);
 #ifdef TIERED
     st->print(" (%d) ", comp_level());
 #endif // TIERED
     if (WizardMode) st->print(" (" INTPTR_FORMAT ")", this);
-    if (method() != NULL) {
-      method()->print_short_name(st);
+    if (Universe::heap()->is_gc_active() && method() != NULL) {
+      st->print("(method)");
+    } else if (method() != NULL) {
+        method()->print_short_name(st);
       if (is_osr_method())
         st->print(" @ %d", osr_entry_bci());
       if (method()->code_size() > 0)
         st->print(" (%d bytes)", method()->code_size());
     }
+
+    if (do_nl)  st->cr();
   }
 }
 
@@ -1033,6 +1052,7 @@
   }
 }
 
+// This is a private interface with the sweeper.
 void nmethod::mark_as_seen_on_stack() {
   assert(is_not_entrant(), "must be a non-entrant method");
   set_stack_traversal_mark(NMethodSweeper::traversal_count());
@@ -1077,7 +1097,8 @@
                   " unloadable], methodOop(" INTPTR_FORMAT
                   "), cause(" INTPTR_FORMAT ")",
                   this, (address)_method, (address)cause);
-    cause->klass()->print();
+    if (!Universe::heap()->is_gc_active())
+      cause->klass()->print();
   }
   // Unlink the osr method, so we do not look this up again
   if (is_osr_method()) {
@@ -1109,7 +1130,8 @@
   // The methodOop is gone at this point
   assert(_method == NULL, "Tautology");
 
-  set_link(NULL);
+  set_osr_link(NULL);
+  //set_scavenge_root_link(NULL); // done by prune_scavenge_root_nmethods
   NMethodSweeper::notify(this);
 }
 
@@ -1295,6 +1317,10 @@
     ec = next;
   }
 
+  if (on_scavenge_root_list()) {
+    CodeCache::drop_scavenge_root_nmethod(this);
+  }
+
   ((CodeBlob*)(this))->flush();
 
   CodeCache::free(this);
@@ -1354,7 +1380,10 @@
       return false;
     }
   }
-  assert(unloading_occurred, "Inconsistency in unloading");
+  // If ScavengeRootsInCode is true, an nmethod might be unloaded
+  // simply because one of its constant oops has gone dead.
+  // No actual classes need to be unloaded in order for this to occur.
+  assert(unloading_occurred || ScavengeRootsInCode, "Inconsistency in unloading");
   make_unloaded(is_alive, obj);
   return true;
 }
@@ -1529,13 +1558,12 @@
 // the (strong) marking phase, and then again when walking
 // the code cache contents during the weak roots processing
 // phase. The two uses are distinguished by means of the
-// do_nmethods() method in the closure "f" below -- which
-// answers "yes" in the first case, and "no" in the second
+// 'do_strong_roots_only' flag, which is true in the first
 // case. We want to walk the weak roots in the nmethod
 // only in the second case. The weak roots in the nmethod
 // are the oops in the ExceptionCache and the InlineCache
 // oops.
-void nmethod::oops_do(OopClosure* f) {
+void nmethod::oops_do(OopClosure* f, bool do_strong_roots_only) {
   // make sure the oops ready to receive visitors
   assert(!is_zombie() && !is_unloaded(),
          "should not call follow on zombie or unloaded nmethod");
@@ -1553,7 +1581,7 @@
 
   // Compiled code
   f->do_oop((oop*) &_method);
-  if (!f->do_nmethods()) {
+  if (!do_strong_roots_only) {
     // weak roots processing phase -- update ExceptionCache oops
     ExceptionCache* ec = exception_cache();
     while(ec != NULL) {
@@ -1579,12 +1607,108 @@
   }
 
   // Scopes
+  // This includes oop constants not inlined in the code stream.
   for (oop* p = oops_begin(); p < oops_end(); p++) {
     if (*p == Universe::non_oop_word())  continue;  // skip non-oops
     f->do_oop(p);
   }
 }
 
+#define NMETHOD_SENTINEL ((nmethod*)badAddress)
+
+nmethod* volatile nmethod::_oops_do_mark_nmethods;
+
+// An nmethod is "marked" if its _mark_link is set non-null.
+// Even if it is the end of the linked list, it will have a non-null link value,
+// as long as it is on the list.
+// This code must be MP safe, because it is used from parallel GC passes.
+bool nmethod::test_set_oops_do_mark() {
+  assert(nmethod::oops_do_marking_is_active(), "oops_do_marking_prologue must be called");
+  nmethod* observed_mark_link = _oops_do_mark_link;
+  if (observed_mark_link == NULL) {
+    // Claim this nmethod for this thread to mark.
+    observed_mark_link = (nmethod*)
+      Atomic::cmpxchg_ptr(NMETHOD_SENTINEL, &_oops_do_mark_link, NULL);
+    if (observed_mark_link == NULL) {
+
+      // Atomically append this nmethod (now claimed) to the head of the list:
+      nmethod* observed_mark_nmethods = _oops_do_mark_nmethods;
+      for (;;) {
+        nmethod* required_mark_nmethods = observed_mark_nmethods;
+        _oops_do_mark_link = required_mark_nmethods;
+        observed_mark_nmethods = (nmethod*)
+          Atomic::cmpxchg_ptr(this, &_oops_do_mark_nmethods, required_mark_nmethods);
+        if (observed_mark_nmethods == required_mark_nmethods)
+          break;
+      }
+      // Mark was clear when we first saw this guy.
+      NOT_PRODUCT(if (TraceScavenge)  print_on(tty, "oops_do, mark\n"));
+      return false;
+    }
+  }
+  // On fall through, another racing thread marked this nmethod before we did.
+  return true;
+}
+
+void nmethod::oops_do_marking_prologue() {
+  NOT_PRODUCT(if (TraceScavenge)  tty->print_cr("[oops_do_marking_prologue"));
+  assert(_oops_do_mark_nmethods == NULL, "must not call oops_do_marking_prologue twice in a row");
+  // We use cmpxchg_ptr instead of regular assignment here because the user
+  // may fork a bunch of threads, and we need them all to see the same state.
+  void* observed = Atomic::cmpxchg_ptr(NMETHOD_SENTINEL, &_oops_do_mark_nmethods, NULL);
+  guarantee(observed == NULL, "no races in this sequential code");
+}
+
+void nmethod::oops_do_marking_epilogue() {
+  assert(_oops_do_mark_nmethods != NULL, "must not call oops_do_marking_epilogue twice in a row");
+  nmethod* cur = _oops_do_mark_nmethods;
+  while (cur != NMETHOD_SENTINEL) {
+    assert(cur != NULL, "not NULL-terminated");
+    nmethod* next = cur->_oops_do_mark_link;
+    cur->_oops_do_mark_link = NULL;
+    NOT_PRODUCT(if (TraceScavenge)  cur->print_on(tty, "oops_do, unmark\n"));
+    cur = next;
+  }
+  void* required = _oops_do_mark_nmethods;
+  void* observed = Atomic::cmpxchg_ptr(NULL, &_oops_do_mark_nmethods, required);
+  guarantee(observed == required, "no races in this sequential code");
+  NOT_PRODUCT(if (TraceScavenge)  tty->print_cr("oops_do_marking_epilogue]"));
+}
+
+class DetectScavengeRoot: public OopClosure {
+  bool     _detected_scavenge_root;
+public:
+  DetectScavengeRoot() : _detected_scavenge_root(false)
+  { NOT_PRODUCT(_print_nm = NULL); }
+  bool detected_scavenge_root() { return _detected_scavenge_root; }
+  virtual void do_oop(oop* p) {
+    if ((*p) != NULL && (*p)->is_scavengable()) {
+      NOT_PRODUCT(maybe_print(p));
+      _detected_scavenge_root = true;
+    }
+  }
+  virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); }
+
+#ifndef PRODUCT
+  nmethod* _print_nm;
+  void maybe_print(oop* p) {
+    if (_print_nm == NULL)  return;
+    if (!_detected_scavenge_root)  _print_nm->print_on(tty, "new scavenge root");
+    tty->print_cr(""PTR_FORMAT"[offset=%d] detected non-perm oop "PTR_FORMAT" (found at "PTR_FORMAT")",
+                  _print_nm, (int)((intptr_t)p - (intptr_t)_print_nm),
+                  (intptr_t)(*p), (intptr_t)p);
+    (*p)->print();
+  }
+#endif //PRODUCT
+};
+
+bool nmethod::detect_scavenge_root_oops() {
+  DetectScavengeRoot detect_scavenge_root;
+  NOT_PRODUCT(if (TraceScavenge)  detect_scavenge_root._print_nm = this);
+  oops_do(&detect_scavenge_root);
+  return detect_scavenge_root.detected_scavenge_root();
+}
+
 // Method that knows how to preserve outgoing arguments at call. This method must be
 // called with a frame corresponding to a Java invoke
 void nmethod::preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) {
@@ -1899,6 +2023,24 @@
 // -----------------------------------------------------------------------------
 // Verification
 
+class VerifyOopsClosure: public OopClosure {
+  nmethod* _nm;
+  bool     _ok;
+public:
+  VerifyOopsClosure(nmethod* nm) : _nm(nm), _ok(true) { }
+  bool ok() { return _ok; }
+  virtual void do_oop(oop* p) {
+    if ((*p) == NULL || (*p)->is_oop())  return;
+    if (_ok) {
+      _nm->print_nmethod(true);
+      _ok = false;
+    }
+    tty->print_cr("*** non-oop "PTR_FORMAT" found at "PTR_FORMAT" (offset %d)",
+                  (intptr_t)(*p), (intptr_t)p, (int)((intptr_t)p - (intptr_t)_nm));
+  }
+  virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); }
+};
+
 void nmethod::verify() {
 
   // Hmm. OSR methods can be deopted but not marked as zombie or not_entrant
@@ -1932,6 +2074,11 @@
     }
   }
 
+  VerifyOopsClosure voc(this);
+  oops_do(&voc);
+  assert(voc.ok(), "embedded oops must be OK");
+  verify_scavenge_root_oops();
+
   verify_scopes();
 }
 
@@ -1995,19 +2142,34 @@
 // Non-product code
 #ifndef PRODUCT
 
-void nmethod::check_store() {
-  // Make sure all oops in the compiled code are tenured
+class DebugScavengeRoot: public OopClosure {
+  nmethod* _nm;
+  bool     _ok;
+public:
+  DebugScavengeRoot(nmethod* nm) : _nm(nm), _ok(true) { }
+  bool ok() { return _ok; }
+  virtual void do_oop(oop* p) {
+    if ((*p) == NULL || !(*p)->is_scavengable())  return;
+    if (_ok) {
+      _nm->print_nmethod(true);
+      _ok = false;
+    }
+    tty->print_cr("*** non-perm oop "PTR_FORMAT" found at "PTR_FORMAT" (offset %d)",
+                  (intptr_t)(*p), (intptr_t)p, (int)((intptr_t)p - (intptr_t)_nm));
+    (*p)->print();
+  }
+  virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); }
+};
 
-  RelocIterator iter(this);
-  while (iter.next()) {
-    if (iter.type() == relocInfo::oop_type) {
-      oop_Relocation* reloc = iter.oop_reloc();
-      oop obj = reloc->oop_value();
-      if (obj != NULL && !obj->is_perm()) {
-        fatal("must be permanent oop in compiled code");
-      }
-    }
+void nmethod::verify_scavenge_root_oops() {
+  if (!on_scavenge_root_list()) {
+    // Actually look inside, to verify the claim that it's clean.
+    DebugScavengeRoot debug_scavenge_root(this);
+    oops_do(&debug_scavenge_root);
+    if (!debug_scavenge_root.ok())
+      fatal("found an unadvertised bad non-perm oop in the code cache");
   }
+  assert(scavenge_root_not_marked(), "");
 }
 
 #endif // PRODUCT
@@ -2040,6 +2202,7 @@
     if (is_not_entrant()) tty->print("not_entrant ");
     if (is_zombie())      tty->print("zombie ");
     if (is_unloaded())    tty->print("unloaded ");
+    if (on_scavenge_root_list())  tty->print("scavenge_root ");
     tty->print_cr("}:");
   }
   if (size              () > 0) tty->print_cr(" total in heap  [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
--- a/hotspot/src/share/vm/code/nmethod.hpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/code/nmethod.hpp	Thu Oct 15 16:37:55 2009 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -125,6 +125,7 @@
 class nmethod : public CodeBlob {
   friend class VMStructs;
   friend class NMethodSweeper;
+  friend class CodeCache;  // non-perm oops
  private:
   // Shared fields for all nmethod's
   static int _zombie_instruction_size;
@@ -132,7 +133,12 @@
   methodOop _method;
   int       _entry_bci;        // != InvocationEntryBci if this nmethod is an on-stack replacement method
 
-  nmethod*  _link;             // To support simple linked-list chaining of nmethods
+  // To support simple linked-list chaining of nmethods:
+  nmethod*  _osr_link;         // from instanceKlass::osr_nmethods_head
+  nmethod*  _scavenge_root_link; // from CodeCache::scavenge_root_nmethods
+
+  static nmethod* volatile _oops_do_mark_nmethods;
+  nmethod*        volatile _oops_do_mark_link;
 
   AbstractCompiler* _compiler; // The compiler which compiled this nmethod
 
@@ -174,6 +180,8 @@
   // used by jvmti to track if an unload event has been posted for this nmethod.
   bool _unload_reported;
 
+  jbyte _scavenge_root_state;
+
   NOT_PRODUCT(bool _has_debug_info; )
 
   // Nmethod Flushing lock (if non-zero, then the nmethod is not removed)
@@ -242,7 +250,6 @@
 
   // helper methods
   void* operator new(size_t size, int nmethod_size);
-  void check_store();
 
   const char* reloc_string_for(u_char* begin, u_char* end);
   void make_not_entrant_or_zombie(int state);
@@ -406,6 +413,24 @@
   int   version() const                           { return flags.version; }
   void  set_version(int v);
 
+  // Non-perm oop support
+  bool  on_scavenge_root_list() const                  { return (_scavenge_root_state & 1) != 0; }
+ protected:
+  enum { npl_on_list = 0x01, npl_marked = 0x10 };
+  void  set_on_scavenge_root_list()                    { _scavenge_root_state = npl_on_list; }
+  void  clear_on_scavenge_root_list()                  { _scavenge_root_state = 0; }
+  // assertion-checking and pruning logic uses the bits of _scavenge_root_state
+#ifndef PRODUCT
+  void  set_scavenge_root_marked()                     { _scavenge_root_state |= npl_marked; }
+  void  clear_scavenge_root_marked()                   { _scavenge_root_state &= ~npl_marked; }
+  bool  scavenge_root_not_marked()                     { return (_scavenge_root_state &~ npl_on_list) == 0; }
+  // N.B. there is no positive marked query, and we only use the not_marked query for asserts.
+#endif //PRODUCT
+  nmethod* scavenge_root_link() const                  { return _scavenge_root_link; }
+  void     set_scavenge_root_link(nmethod *n)          { _scavenge_root_link = n; }
+
+ public:
+
   // Sweeper support
   long  stack_traversal_mark()                    { return _stack_traversal_mark; }
   void  set_stack_traversal_mark(long l)          { _stack_traversal_mark = l; }
@@ -424,8 +449,8 @@
   int   osr_entry_bci() const                     { assert(_entry_bci != InvocationEntryBci, "wrong kind of nmethod"); return _entry_bci; }
   address  osr_entry() const                      { assert(_entry_bci != InvocationEntryBci, "wrong kind of nmethod"); return _osr_entry_point; }
   void  invalidate_osr_method();
-  nmethod* link() const                           { return _link; }
-  void     set_link(nmethod *n)                   { _link = n; }
+  nmethod* osr_link() const                       { return _osr_link; }
+  void     set_osr_link(nmethod *n)               { _osr_link = n; }
 
   // tells whether frames described by this nmethod can be deoptimized
   // note: native wrappers cannot be deoptimized.
@@ -465,7 +490,16 @@
 
   void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map,
                                      OopClosure* f);
-  void oops_do(OopClosure* f);
+  virtual void oops_do(OopClosure* f) { oops_do(f, false); }
+  void         oops_do(OopClosure* f, bool do_strong_roots_only);
+  bool detect_scavenge_root_oops();
+  void verify_scavenge_root_oops() PRODUCT_RETURN;
+
+  bool test_set_oops_do_mark();
+  static void oops_do_marking_prologue();
+  static void oops_do_marking_epilogue();
+  static bool oops_do_marking_is_active() { return _oops_do_mark_nmethods != NULL; }
+  DEBUG_ONLY(bool test_oops_do_mark() { return _oops_do_mark_link != NULL; })
 
   // ScopeDesc for an instruction
   ScopeDesc* scope_desc_at(address pc);
--- a/hotspot/src/share/vm/compiler/oopMap.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/compiler/oopMap.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1998-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/compiler/oopMap.hpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/compiler/oopMap.hpp	Thu Oct 15 16:37:55 2009 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1998-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp	Thu Oct 15 16:37:55 2009 -0700
@@ -47,20 +47,15 @@
  private:
   const MemRegion _span;
   CMSBitMap*      _bitMap;
-  const bool      _should_do_nmethods;
  protected:
   DO_OOP_WORK_DEFN
  public:
-  MarkRefsIntoClosure(MemRegion span, CMSBitMap* bitMap,
-                      bool should_do_nmethods);
+  MarkRefsIntoClosure(MemRegion span, CMSBitMap* bitMap);
   virtual void do_oop(oop* p);
   virtual void do_oop(narrowOop* p);
   inline void do_oop_nv(oop* p)       { MarkRefsIntoClosure::do_oop_work(p); }
   inline void do_oop_nv(narrowOop* p) { MarkRefsIntoClosure::do_oop_work(p); }
   bool do_header() { return true; }
-  virtual const bool do_nmethods() const {
-    return _should_do_nmethods;
-  }
   Prefetch::style prefetch_style() {
     return Prefetch::do_read;
   }
@@ -73,20 +68,16 @@
   const MemRegion _span;
   CMSBitMap*      _verification_bm;
   CMSBitMap*      _cms_bm;
-  const bool      _should_do_nmethods;
  protected:
   DO_OOP_WORK_DEFN
  public:
   MarkRefsIntoVerifyClosure(MemRegion span, CMSBitMap* verification_bm,
-                            CMSBitMap* cms_bm, bool should_do_nmethods);
+                            CMSBitMap* cms_bm);
   virtual void do_oop(oop* p);
   virtual void do_oop(narrowOop* p);
   inline void do_oop_nv(oop* p)       { MarkRefsIntoVerifyClosure::do_oop_work(p); }
   inline void do_oop_nv(narrowOop* p) { MarkRefsIntoVerifyClosure::do_oop_work(p); }
   bool do_header() { return true; }
-  virtual const bool do_nmethods() const {
-    return _should_do_nmethods;
-  }
   Prefetch::style prefetch_style() {
     return Prefetch::do_read;
   }
@@ -228,7 +219,6 @@
   inline void do_oop_nv(oop* p)       { MarkRefsIntoAndScanClosure::do_oop_work(p); }
   inline void do_oop_nv(narrowOop* p) { MarkRefsIntoAndScanClosure::do_oop_work(p); }
   bool do_header() { return true; }
-  virtual const bool do_nmethods() const { return true; }
   Prefetch::style prefetch_style() {
     return Prefetch::do_read;
   }
@@ -273,7 +263,6 @@
   inline void do_oop_nv(oop* p)       { Par_MarkRefsIntoAndScanClosure::do_oop_work(p); }
   inline void do_oop_nv(narrowOop* p) { Par_MarkRefsIntoAndScanClosure::do_oop_work(p); }
   bool do_header() { return true; }
-  virtual const bool do_nmethods() const { return true; }
   // When ScanMarkedObjectsAgainClosure is used,
   // it passes [Par_]MarkRefsIntoAndScanClosure to oop_oop_iterate(),
   // and this delegation is used.
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -2852,14 +2852,17 @@
   GenCollectedHeap* gch = GenCollectedHeap::heap();
 
   // Mark from roots one level into CMS
-  MarkRefsIntoClosure notOlder(_span, verification_mark_bm(), true /* nmethods */);
+  MarkRefsIntoClosure notOlder(_span, verification_mark_bm());
   gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
 
   gch->gen_process_strong_roots(_cmsGen->level(),
                                 true,   // younger gens are roots
+                                true,   // activate StrongRootsScope
                                 true,   // collecting perm gen
                                 SharedHeap::ScanningOption(roots_scanning_options()),
-                                NULL, &notOlder);
+                                &notOlder,
+                                true,   // walk code active on stacks
+                                NULL);
 
   // Now mark from the roots
   assert(_revisitStack.isEmpty(), "Should be empty");
@@ -2901,13 +2904,16 @@
 
   // Mark from roots one level into CMS
   MarkRefsIntoVerifyClosure notOlder(_span, verification_mark_bm(),
-                                     markBitMap(), true /* nmethods */);
+                                     markBitMap());
   gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
   gch->gen_process_strong_roots(_cmsGen->level(),
                                 true,   // younger gens are roots
+                                true,   // activate StrongRootsScope
                                 true,   // collecting perm gen
                                 SharedHeap::ScanningOption(roots_scanning_options()),
-                                NULL, &notOlder);
+                                &notOlder,
+                                true,   // walk code active on stacks
+                                NULL);
 
   // Now mark from the roots
   assert(_revisitStack.isEmpty(), "Should be empty");
@@ -3484,8 +3490,10 @@
   FalseClosure falseClosure;
   // In the case of a synchronous collection, we will elide the
   // remark step, so it's important to catch all the nmethod oops
-  // in this step; hence the last argument to the constrcutor below.
-  MarkRefsIntoClosure notOlder(_span, &_markBitMap, !asynch /* nmethods */);
+  // in this step.
+  // The final 'true' flag to gen_process_strong_roots will ensure this.
+  // If 'async' is true, we can relax the nmethod tracing.
+  MarkRefsIntoClosure notOlder(_span, &_markBitMap);
   GenCollectedHeap* gch = GenCollectedHeap::heap();
 
   verify_work_stacks_empty();
@@ -3504,9 +3512,12 @@
     gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
     gch->gen_process_strong_roots(_cmsGen->level(),
                                   true,   // younger gens are roots
+                                  true,   // activate StrongRootsScope
                                   true,   // collecting perm gen
                                   SharedHeap::ScanningOption(roots_scanning_options()),
-                                  NULL, &notOlder);
+                                  &notOlder,
+                                  true,   // walk all of code cache if (so & SO_CodeCache)
+                                  NULL);
   }
 
   // Clear mod-union table; it will be dirtied in the prologue of
@@ -5040,9 +5051,15 @@
   _timer.start();
   gch->gen_process_strong_roots(_collector->_cmsGen->level(),
                                 false,     // yg was scanned above
+                                false,     // this is parallel code
                                 true,      // collecting perm gen
                                 SharedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()),
-                                NULL, &par_mrias_cl);
+                                &par_mrias_cl,
+                                true,   // walk all of code cache if (so & SO_CodeCache)
+                                NULL);
+  assert(_collector->should_unload_classes()
+         || (_collector->CMSCollector::roots_scanning_options() & SharedHeap::SO_CodeCache),
+         "if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops");
   _timer.stop();
   if (PrintCMSStatistics != 0) {
     gclog_or_tty->print_cr(
@@ -5423,7 +5440,6 @@
 
   // Set up for parallel process_strong_roots work.
   gch->set_par_threads(n_workers);
-  gch->change_strong_roots_parity();
   // We won't be iterating over the cards in the card table updating
   // the younger_gen cards, so we shouldn't call the following else
   // the verification code as well as subsequent younger_refs_iterate
@@ -5454,8 +5470,10 @@
   if (n_workers > 1) {
     // Make refs discovery MT-safe
     ReferenceProcessorMTMutator mt(ref_processor(), true);
+    GenCollectedHeap::StrongRootsScope srs(gch);
     workers->run_task(&tsk);
   } else {
+    GenCollectedHeap::StrongRootsScope srs(gch);
     tsk.work(0);
   }
   gch->set_par_threads(0);  // 0 ==> non-parallel.
@@ -5539,11 +5557,18 @@
     verify_work_stacks_empty();
 
     gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
+    GenCollectedHeap::StrongRootsScope srs(gch);
     gch->gen_process_strong_roots(_cmsGen->level(),
                                   true,  // younger gens as roots
+                                  false, // use the local StrongRootsScope
                                   true,  // collecting perm gen
                                   SharedHeap::ScanningOption(roots_scanning_options()),
-                                  NULL, &mrias_cl);
+                                  &mrias_cl,
+                                  true,   // walk code active on stacks
+                                  NULL);
+    assert(should_unload_classes()
+           || (roots_scanning_options() & SharedHeap::SO_CodeCache),
+           "if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops");
   }
   verify_work_stacks_empty();
   // Restore evacuated mark words, if any, used for overflow list links
@@ -6418,10 +6443,9 @@
 // generation then this will lose younger_gen cards!
 
 MarkRefsIntoClosure::MarkRefsIntoClosure(
-  MemRegion span, CMSBitMap* bitMap, bool should_do_nmethods):
+  MemRegion span, CMSBitMap* bitMap):
     _span(span),
-    _bitMap(bitMap),
-    _should_do_nmethods(should_do_nmethods)
+    _bitMap(bitMap)
 {
     assert(_ref_processor == NULL, "deliberately left NULL");
     assert(_bitMap->covers(_span), "_bitMap/_span mismatch");
@@ -6442,12 +6466,11 @@
 
 // A variant of the above, used for CMS marking verification.
 MarkRefsIntoVerifyClosure::MarkRefsIntoVerifyClosure(
-  MemRegion span, CMSBitMap* verification_bm, CMSBitMap* cms_bm,
-  bool should_do_nmethods):
+  MemRegion span, CMSBitMap* verification_bm, CMSBitMap* cms_bm):
     _span(span),
     _verification_bm(verification_bm),
-    _cms_bm(cms_bm),
-    _should_do_nmethods(should_do_nmethods) {
+    _cms_bm(cms_bm)
+{
     assert(_ref_processor == NULL, "deliberately left NULL");
     assert(_verification_bm->covers(_span), "_verification_bm/_span mismatch");
 }
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -746,10 +746,11 @@
   // clear the mark bitmap (no grey objects to start with)
   _nextMarkBitMap->clearAll();
   PrintReachableClosure prcl(_nextMarkBitMap);
-  g1h->process_strong_roots(
+  g1h->process_strong_roots(true,    // activate StrongRootsScope
                             false,   // fake perm gen collection
                             SharedHeap::SO_AllClasses,
                             &prcl, // Regular roots
+                            NULL,  // do not visit active blobs
                             &prcl    // Perm Gen Roots
                             );
   // The root iteration above "consumed" dirty cards in the perm gen.
@@ -852,9 +853,11 @@
   g1h->set_marking_started();
   g1h->rem_set()->prepare_for_younger_refs_iterate(false);
 
-  g1h->process_strong_roots(false,   // fake perm gen collection
+  g1h->process_strong_roots(true,    // activate StrongRootsScope
+                            false,   // fake perm gen collection
                             SharedHeap::SO_AllClasses,
                             &notOlder, // Regular roots
+                            NULL,     // do not visit active blobs
                             &older    // Perm Gen Roots
                             );
   checkpointRootsInitialPost();
@@ -1915,7 +1918,7 @@
   g1h->ensure_parsability(false);
 
   if (ParallelGCThreads > 0) {
-    g1h->change_strong_roots_parity();
+    G1CollectedHeap::StrongRootsScope srs(g1h);
     // this is remark, so we'll use up all available threads
     int active_workers = ParallelGCThreads;
     set_phase(active_workers, false);
@@ -1932,7 +1935,7 @@
     SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
     guarantee( satb_mq_set.completed_buffers_num() == 0, "invariant" );
   } else {
-    g1h->change_strong_roots_parity();
+    G1CollectedHeap::StrongRootsScope srs(g1h);
     // this is remark, so we'll use up all available threads
     int active_workers = 1;
     set_phase(active_workers, false);
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentZFThread.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentZFThread.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -2300,9 +2300,12 @@
   if (SafepointSynchronize::is_at_safepoint() || ! UseTLAB) {
     if (!silent) { gclog_or_tty->print("roots "); }
     VerifyRootsClosure rootsCl(use_prev_marking);
-    process_strong_roots(false,
+    CodeBlobToOopClosure blobsCl(&rootsCl, /*do_marking=*/ false);
+    process_strong_roots(true,  // activate StrongRootsScope
+                         false,
                          SharedHeap::SO_AllClasses,
                          &rootsCl,
+                         &blobsCl,
                          &rootsCl);
     rem_set()->invalidate(perm_gen()->used_region(), false);
     if (!silent) { gclog_or_tty->print("heapRegions "); }
@@ -3987,8 +3990,14 @@
   BufferingOopsInGenClosure buf_scan_perm(scan_perm);
   buf_scan_perm.set_generation(perm_gen());
 
-  process_strong_roots(collecting_perm_gen, so,
+  // Walk the code cache w/o buffering, because StarTask cannot handle
+  // unaligned oop locations.
+  CodeBlobToOopClosure eager_scan_code_roots(scan_non_heap_roots, /*do_marking=*/ true);
+
+  process_strong_roots(false, // no scoping; this is parallel code
+                       collecting_perm_gen, so,
                        &buf_scan_non_heap_roots,
+                       &eager_scan_code_roots,
                        &buf_scan_perm);
   // Finish up any enqueued closure apps.
   buf_scan_non_heap_roots.done();
@@ -4078,7 +4087,8 @@
 void
 G1CollectedHeap::g1_process_weak_roots(OopClosure* root_closure,
                                        OopClosure* non_root_closure) {
-  SharedHeap::process_weak_roots(root_closure, non_root_closure);
+  CodeBlobToOopClosure roots_in_blobs(root_closure, /*do_marking=*/ false);
+  SharedHeap::process_weak_roots(root_closure, &roots_in_blobs, non_root_closure);
 }
 
 
@@ -4112,15 +4122,16 @@
 
   init_for_evac_failure(NULL);
 
-  change_strong_roots_parity();  // In preparation for parallel strong roots.
   rem_set()->prepare_for_younger_refs_iterate(true);
 
   assert(dirty_card_queue_set().completed_buffers_num() == 0, "Should be empty");
   double start_par = os::elapsedTime();
   if (ParallelGCThreads > 0) {
     // The individual threads will set their evac-failure closures.
+    StrongRootsScope srs(this);
     workers()->run_task(&g1_par_task);
   } else {
+    StrongRootsScope srs(this);
     g1_par_task.work(0);
   }
 
--- a/hotspot/src/share/vm/gc_implementation/g1/g1MMUTracker.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1MMUTracker.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -121,9 +121,11 @@
 
   SharedHeap* sh = SharedHeap::heap();
 
-  sh->process_strong_roots(true,  // Collecting permanent generation.
+  sh->process_strong_roots(true,  // activeate StrongRootsScope
+                           true,  // Collecting permanent generation.
                            SharedHeap::SO_SystemClasses,
                            &GenMarkSweep::follow_root_closure,
+                           &GenMarkSweep::follow_code_root_closure,
                            &GenMarkSweep::follow_root_closure);
 
   // Process reference objects found during marking
@@ -286,9 +288,11 @@
 
   SharedHeap* sh = SharedHeap::heap();
 
-  sh->process_strong_roots(true,  // Collecting permanent generation.
+  sh->process_strong_roots(true,  // activate StrongRootsScope
+                           true,  // Collecting permanent generation.
                            SharedHeap::SO_AllClasses,
                            &GenMarkSweep::adjust_root_pointer_closure,
+                           NULL,  // do not touch code cache here
                            &GenMarkSweep::adjust_pointer_closure);
 
   g1h->ref_processor()->weak_oops_do(&GenMarkSweep::adjust_root_pointer_closure);
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -302,9 +302,9 @@
     if (cur->isHumongous()) {
       return MemRegion(last_start, end);
     }
-    cur->reset_zero_fill();
     assert(cur == _regions.top(), "Should be top");
     if (!cur->is_empty()) break;
+    cur->reset_zero_fill();
     shrink_bytes -= cur->capacity();
     num_regions_deleted++;
     _regions.pop();
--- a/hotspot/src/share/vm/gc_implementation/includeDB_gc_parallelScavenge	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/gc_implementation/includeDB_gc_parallelScavenge	Thu Oct 15 16:37:55 2009 -0700
@@ -373,6 +373,7 @@
 psScavenge.inline.hpp                   psPromotionManager.hpp
 psScavenge.inline.hpp                   psScavenge.hpp
 
+pcTasks.cpp                             codeCache.hpp
 pcTasks.cpp                             collectedHeap.hpp
 pcTasks.cpp                             fprofiler.hpp
 pcTasks.cpp                             jniHandles.hpp
@@ -392,6 +393,7 @@
 pcTasks.hpp				psTasks.hpp
 
 psTasks.cpp                             cardTableExtension.hpp
+psTasks.cpp                             codeCache.hpp
 psTasks.cpp                             fprofiler.hpp
 psTasks.cpp                             gcTaskManager.hpp
 psTasks.cpp                             iterator.hpp
--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -480,12 +480,14 @@
 
   par_scan_state.start_strong_roots();
   gch->gen_process_strong_roots(_gen->level(),
-                                true, // Process younger gens, if any,
-                                      // as strong roots.
-                                false,// not collecting perm generation.
+                                true,  // Process younger gens, if any,
+                                       // as strong roots.
+                                false, // no scope; this is parallel code
+                                false, // not collecting perm generation.
                                 SharedHeap::SO_AllClasses,
-                                &par_scan_state.older_gen_closure(),
-                                &par_scan_state.to_space_root_closure());
+                                &par_scan_state.to_space_root_closure(),
+                                true,   // walk *all* scavengable nmethods
+                                &par_scan_state.older_gen_closure());
   par_scan_state.end_strong_roots();
 
   // "evacuate followers".
@@ -799,15 +801,16 @@
   ParNewGenTask tsk(this, _next_gen, reserved().end(), &thread_state_set);
   int n_workers = workers->total_workers();
   gch->set_par_threads(n_workers);
-  gch->change_strong_roots_parity();
   gch->rem_set()->prepare_for_younger_refs_iterate(true);
   // It turns out that even when we're using 1 thread, doing the work in a
   // separate thread causes wide variance in run times.  We can't help this
   // in the multi-threaded case, but we special-case n=1 here to get
   // repeatable measurements of the 1-thread overhead of the parallel code.
   if (n_workers > 1) {
+    GenCollectedHeap::StrongRootsScope srs(gch);
     workers->run_task(&tsk);
   } else {
+    GenCollectedHeap::StrongRootsScope srs(gch);
     tsk.work(0);
   }
   thread_state_set.reset();
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -962,6 +962,14 @@
   _old_gen->resize(desired_free_space);
 }
 
+ParallelScavengeHeap::ParStrongRootsScope::ParStrongRootsScope() {
+  // nothing particular
+}
+
+ParallelScavengeHeap::ParStrongRootsScope::~ParStrongRootsScope() {
+  // nothing particular
+}
+
 #ifndef PRODUCT
 void ParallelScavengeHeap::record_gen_tops_before_GC() {
   if (ZapUnusedHeapArea) {
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp	Thu Oct 15 16:37:55 2009 -0700
@@ -234,6 +234,13 @@
 
   // Mangle the unused parts of all spaces in the heap
   void gen_mangle_unused_area() PRODUCT_RETURN;
+
+  // Call these in sequential code around the processing of strong roots.
+  class ParStrongRootsScope : public MarkingCodeBlobClosure::MarkScope {
+  public:
+    ParStrongRootsScope();
+    ~ParStrongRootsScope();
+  };
 };
 
 inline size_t ParallelScavengeHeap::set_alignment(size_t& var, size_t val)
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,12 +39,13 @@
   ParCompactionManager* cm =
     ParCompactionManager::gc_thread_compaction_manager(which);
   PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm);
+  CodeBlobToOopClosure mark_and_push_in_blobs(&mark_and_push_closure, /*do_marking=*/ true);
 
   if (_java_thread != NULL)
-    _java_thread->oops_do(&mark_and_push_closure);
+    _java_thread->oops_do(&mark_and_push_closure, &mark_and_push_in_blobs);
 
   if (_vm_thread != NULL)
-    _vm_thread->oops_do(&mark_and_push_closure);
+    _vm_thread->oops_do(&mark_and_push_closure, &mark_and_push_in_blobs);
 
   // Do the real work
   cm->drain_marking_stacks(&mark_and_push_closure);
@@ -78,7 +79,8 @@
     case threads:
     {
       ResourceMark rm;
-      Threads::oops_do(&mark_and_push_closure);
+      CodeBlobToOopClosure each_active_code_blob(&mark_and_push_closure, /*do_marking=*/ true);
+      Threads::oops_do(&mark_and_push_closure, &each_active_code_blob);
     }
     break;
 
@@ -106,6 +108,11 @@
       vmSymbols::oops_do(&mark_and_push_closure);
       break;
 
+    case code_cache:
+      // Do not treat nmethods as strong roots for mark/sweep, since we can unload them.
+      //CodeCache::scavenge_root_nmethods_do(CodeBlobToOopClosure(&mark_and_push_closure));
+      break;
+
     default:
       fatal("Unknown root type");
   }
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.hpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.hpp	Thu Oct 15 16:37:55 2009 -0700
@@ -92,7 +92,8 @@
     jvmti                 = 7,
     system_dictionary     = 8,
     vm_symbols            = 9,
-    reference_processing  = 10
+    reference_processing  = 10,
+    code_cache            = 11
   };
  private:
   RootType _root_type;
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.hpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.hpp	Thu Oct 15 16:37:55 2009 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -511,16 +511,22 @@
   assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
 
   // General strong roots.
-  Universe::oops_do(mark_and_push_closure());
-  ReferenceProcessor::oops_do(mark_and_push_closure());
-  JNIHandles::oops_do(mark_and_push_closure());   // Global (strong) JNI handles
-  Threads::oops_do(mark_and_push_closure());
-  ObjectSynchronizer::oops_do(mark_and_push_closure());
-  FlatProfiler::oops_do(mark_and_push_closure());
-  Management::oops_do(mark_and_push_closure());
-  JvmtiExport::oops_do(mark_and_push_closure());
-  SystemDictionary::always_strong_oops_do(mark_and_push_closure());
-  vmSymbols::oops_do(mark_and_push_closure());
+  {
+    ParallelScavengeHeap::ParStrongRootsScope psrs;
+    Universe::oops_do(mark_and_push_closure());
+    ReferenceProcessor::oops_do(mark_and_push_closure());
+    JNIHandles::oops_do(mark_and_push_closure());   // Global (strong) JNI handles
+    CodeBlobToOopClosure each_active_code_blob(mark_and_push_closure(), /*do_marking=*/ true);
+    Threads::oops_do(mark_and_push_closure(), &each_active_code_blob);
+    ObjectSynchronizer::oops_do(mark_and_push_closure());
+    FlatProfiler::oops_do(mark_and_push_closure());
+    Management::oops_do(mark_and_push_closure());
+    JvmtiExport::oops_do(mark_and_push_closure());
+    SystemDictionary::always_strong_oops_do(mark_and_push_closure());
+    vmSymbols::oops_do(mark_and_push_closure());
+    // Do not treat nmethods as strong roots for mark/sweep, since we can unload them.
+    //CodeCache::scavenge_root_nmethods_do(CodeBlobToOopClosure(mark_and_push_closure()));
+  }
 
   // Flush marking stack.
   follow_stack();
@@ -617,7 +623,7 @@
   Universe::oops_do(adjust_root_pointer_closure());
   ReferenceProcessor::oops_do(adjust_root_pointer_closure());
   JNIHandles::oops_do(adjust_root_pointer_closure());   // Global (strong) JNI handles
-  Threads::oops_do(adjust_root_pointer_closure());
+  Threads::oops_do(adjust_root_pointer_closure(), NULL);
   ObjectSynchronizer::oops_do(adjust_root_pointer_closure());
   FlatProfiler::oops_do(adjust_root_pointer_closure());
   Management::oops_do(adjust_root_pointer_closure());
@@ -625,6 +631,7 @@
   // SO_AllClasses
   SystemDictionary::oops_do(adjust_root_pointer_closure());
   vmSymbols::oops_do(adjust_root_pointer_closure());
+  //CodeCache::scavenge_root_nmethods_oops_do(adjust_root_pointer_closure());
 
   // Now adjust pointers in remaining weak roots.  (All of which should
   // have been cleared if they pointed to non-surviving objects.)
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -2322,6 +2322,7 @@
 
   {
     TraceTime tm_m("par mark", print_phases(), true, gclog_or_tty);
+    ParallelScavengeHeap::ParStrongRootsScope psrs;
 
     GCTaskQueue* q = GCTaskQueue::create();
 
@@ -2335,6 +2336,7 @@
     q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::system_dictionary));
     q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::jvmti));
     q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::vm_symbols));
+    q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::code_cache));
 
     if (parallel_gc_threads > 1) {
       for (uint j = 0; j < parallel_gc_threads; j++) {
@@ -2408,7 +2410,7 @@
   Universe::oops_do(adjust_root_pointer_closure());
   ReferenceProcessor::oops_do(adjust_root_pointer_closure());
   JNIHandles::oops_do(adjust_root_pointer_closure());   // Global (strong) JNI handles
-  Threads::oops_do(adjust_root_pointer_closure());
+  Threads::oops_do(adjust_root_pointer_closure(), NULL);
   ObjectSynchronizer::oops_do(adjust_root_pointer_closure());
   FlatProfiler::oops_do(adjust_root_pointer_closure());
   Management::oops_do(adjust_root_pointer_closure());
@@ -2752,7 +2754,6 @@
   cm->revisit_klass_stack()->push(k);
 }
 
-#if ( defined(COMPILER1) || defined(COMPILER2) )
 void PSParallelCompact::revisit_mdo(ParCompactionManager* cm, DataLayout* p) {
   cm->revisit_mdo_stack()->push(p);
 }
@@ -2778,7 +2779,6 @@
     follow_stack(cm);
   }
 }
-#endif //  ( COMPILER1 || COMPILER2 )
 
 
 #ifdef VALIDATE_MARK_SWEEP
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp	Thu Oct 15 16:37:55 2009 -0700
@@ -799,8 +799,7 @@
     FollowRootClosure(ParCompactionManager* cm) : _compaction_manager(cm) { }
     virtual void do_oop(oop* p);
     virtual void do_oop(narrowOop* p);
-    virtual const bool do_nmethods() const { return true; }
-  };
+ };
 
   class FollowStackClosure: public VoidClosure {
    private:
@@ -817,6 +816,8 @@
     AdjustPointerClosure(bool is_root) : _is_root(is_root) { }
     virtual void do_oop(oop* p);
     virtual void do_oop(narrowOop* p);
+    // do not walk from thread stacks to the code cache on this phase
+    virtual void do_code_blob(CodeBlob* cb) const { }
   };
 
   // Closure for verifying update of pointers.  Does not
@@ -1063,7 +1064,6 @@
     MarkAndPushClosure(ParCompactionManager* cm) : _compaction_manager(cm) { }
     virtual void do_oop(oop* p);
     virtual void do_oop(narrowOop* p);
-    virtual const bool do_nmethods() const { return true; }
   };
 
   PSParallelCompact();
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -358,6 +358,7 @@
     PSPromotionManager* promotion_manager = PSPromotionManager::vm_thread_promotion_manager();
     {
       // TraceTime("Roots");
+      ParallelScavengeHeap::ParStrongRootsScope psrs;
 
       GCTaskQueue* q = GCTaskQueue::create();
 
@@ -376,6 +377,7 @@
       q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::management));
       q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::system_dictionary));
       q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jvmti));
+      q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::code_cache));
 
       ParallelTaskTerminator terminator(
         gc_task_manager()->workers(),
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -66,7 +66,7 @@
     case threads:
     {
       ResourceMark rm;
-      Threads::oops_do(&roots_closure);
+      Threads::oops_do(&roots_closure, NULL);
     }
     break;
 
@@ -90,6 +90,14 @@
       JvmtiExport::oops_do(&roots_closure);
       break;
 
+
+    case code_cache:
+      {
+        CodeBlobToOopClosure each_scavengable_code_blob(&roots_closure, /*do_marking=*/ true);
+        CodeCache::scavenge_root_nmethods_do(&each_scavengable_code_blob);
+      }
+      break;
+
     default:
       fatal("Unknown root type");
   }
@@ -107,12 +115,13 @@
 
   PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(which);
   PSScavengeRootsClosure roots_closure(pm);
+  CodeBlobToOopClosure roots_in_blobs(&roots_closure, /*do_marking=*/ true);
 
   if (_java_thread != NULL)
-    _java_thread->oops_do(&roots_closure);
+    _java_thread->oops_do(&roots_closure, &roots_in_blobs);
 
   if (_vm_thread != NULL)
-    _vm_thread->oops_do(&roots_closure);
+    _vm_thread->oops_do(&roots_closure, &roots_in_blobs);
 
   // Do the real work
   pm->drain_stacks(false);
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.hpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.hpp	Thu Oct 15 16:37:55 2009 -0700
@@ -54,7 +54,8 @@
     flat_profiler         = 5,
     system_dictionary     = 6,
     management            = 7,
-    jvmti                 = 8
+    jvmti                 = 8,
+    code_cache            = 9
   };
  private:
   RootType _root_type;
--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -73,7 +73,6 @@
   follow_stack();
 }
 
-#if ( defined(COMPILER1) || defined(COMPILER2) )
 void MarkSweep::revisit_mdo(DataLayout* p) {
   _revisit_mdo_stack->push(p);
 }
@@ -92,9 +91,9 @@
   }
   follow_stack();
 }
-#endif //  ( COMPILER1 || COMPILER2 )
 
 MarkSweep::FollowRootClosure  MarkSweep::follow_root_closure;
+CodeBlobToOopClosure MarkSweep::follow_code_root_closure(&MarkSweep::follow_root_closure, /*do_marking=*/ true);
 
 void MarkSweep::FollowRootClosure::do_oop(oop* p)       { follow_root(p); }
 void MarkSweep::FollowRootClosure::do_oop(narrowOop* p) { follow_root(p); }
--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp	Thu Oct 15 16:37:55 2009 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -58,14 +58,12 @@
    public:
     virtual void do_oop(oop* p);
     virtual void do_oop(narrowOop* p);
-    virtual const bool do_nmethods() const { return true; }
   };
 
   class MarkAndPushClosure: public OopClosure {
    public:
     virtual void do_oop(oop* p);
     virtual void do_oop(narrowOop* p);
-    virtual const bool do_nmethods() const { return true; }
     virtual const bool should_remember_mdo() const { return true; }
     virtual void remember_mdo(DataLayout* p) { MarkSweep::revisit_mdo(p); }
   };
@@ -173,6 +171,7 @@
  public:
   // Public closures
   static FollowRootClosure    follow_root_closure;
+  static CodeBlobToOopClosure follow_code_root_closure; // => follow_root_closure
   static MarkAndPushClosure   mark_and_push_closure;
   static FollowStackClosure   follow_stack_closure;
   static AdjustPointerClosure adjust_root_pointer_closure;
--- a/hotspot/src/share/vm/gc_interface/collectedHeap.hpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/gc_interface/collectedHeap.hpp	Thu Oct 15 16:37:55 2009 -0700
@@ -263,6 +263,14 @@
     return p == NULL || is_permanent(p);
   }
 
+  // An object is scavengable if its location may move during a scavenge.
+  // (A scavenge is a GC which is not a full GC.)
+  // Currently, this just means it is not perm (and not null).
+  // This could change if we rethink what's in perm-gen.
+  bool is_scavengable(const void *p) const {
+    return !is_in_permanent_or_null(p);
+  }
+
   // Returns "TRUE" if "p" is a method oop in the
   // current heap, with high probability. This predicate
   // is not stable, in general.
--- a/hotspot/src/share/vm/memory/defNewGeneration.cpp	Wed Oct 14 19:23:15 2009 +0400
+++ b/hotspot/src/share/vm/memory/defNewGeneration.cpp	Thu Oct 15 16:37:55 2009 -0700
@@ -555,12 +555,14 @@
          "save marks have not been newly set.");