changeset 460:e12adc424b43

Merge
author mlapshin
date Wed, 30 Apr 2008 07:03:08 -0700
parents 8682623ee3c3 04b351ea4b87
children 67f5e7e1b94a
files hotspot/src/share/vm/memory/allocationStats.cpp hotspot/src/share/vm/memory/allocationStats.hpp jdk/make/tools/winver/bin/winver.exe langtools/src/share/opensource/javac/Makefile langtools/src/share/opensource/javac/README-template.html langtools/src/share/opensource/javac/build.properties langtools/src/share/opensource/javac/build.xml langtools/src/share/opensource/javac/doc/document.css langtools/src/share/opensource/javac/doc/javac_lifecycle/Context.html langtools/src/share/opensource/javac/doc/javac_lifecycle/Enter.html langtools/src/share/opensource/javac/doc/javac_lifecycle/JavaCompiler.html langtools/src/share/opensource/javac/doc/javac_lifecycle/Main.html langtools/src/share/opensource/javac/doc/javac_lifecycle/ToDo.html langtools/src/share/opensource/javac/doc/javac_lifecycle/contents.html langtools/src/share/opensource/javac/doc/javac_lifecycle/index.html langtools/src/share/opensource/javac/doc/javac_lifecycle/packages.html langtools/src/share/opensource/javac/doc/javac_lifecycle/style.css langtools/src/share/opensource/javac/nbproject/project.xml langtools/src/share/opensource/javac/src/bin/javac.sh langtools/test/tools/javac/expression/ObjectAppend.java
diffstat 1103 files changed, 59291 insertions(+), 22897 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgtags	Wed Apr 30 07:03:08 2008 -0700
@@ -0,0 +1,2 @@
+1cc8dd79fd1cd13d36b385196271a29632c67c3b jdk7-b24
+bf2517e15f0c0f950e5b3143c4ca11e2df73dcc1 jdk7-b25
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgtags-top-repo	Wed Apr 30 07:03:08 2008 -0700
@@ -0,0 +1,2 @@
+cfeea66a3fa8ca3686a7cfa2d0ce8ab0169f168d jdk7-b24
+cbc8ad9dd0e085a607427ea35411990982f19a36 jdk7-b25
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.jcheck/conf	Wed Apr 30 07:03:08 2008 -0700
@@ -0,0 +1,1 @@
+project=jdk7
--- a/Makefile	Wed Apr 30 12:32:05 2008 +0400
+++ b/Makefile	Wed Apr 30 07:03:08 2008 -0700
@@ -23,25 +23,25 @@
 # have any questions.
 #
 
+BUILD_PARENT_DIRECTORY=.
+
 ifndef TOPDIR
-  TOPDIR:=$(shell \
-    if [ -r ./j2se/make/Makefile -o -r ./jdk/make/Makefile ]; then \
-      echo "."; \
-    else \
-      echo "../.."; \
-    fi)
+  TOPDIR:=.
 endif
 
 ifndef CONTROL_TOPDIR
-  CONTROL_TOPDIR=$(TOPDIR)/control
-  CONTROL_TOPDIR:=$(shell \
-    if [ -r $(TOPDIR)/control/make/Makefile ]; then \
-      echo "$(TOPDIR)/control"; \
-    else \
-      echo "$(TOPDIR)"; \
-    fi)
+  CONTROL_TOPDIR=$(TOPDIR)
 endif
 
+# Openjdk sources (only used if SKIP_OPENJDK_BUILD!=true)
+OPENJDK_SOURCETREE=$(TOPDIR)/openjdk
+OPENJDK_BUILDDIR:=$(shell \
+  if [ -r $(OPENJDK_SOURCETREE)/Makefile ]; then \
+    echo "$(OPENJDK_SOURCETREE)"; \
+  else \
+    echo "."; \
+  fi)
+
 ifndef JDK_TOPDIR
   JDK_TOPDIR=$(TOPDIR)/jdk
 endif
@@ -55,6 +55,7 @@
 
 all::
 	@$(ECHO) $(PLATFORM) $(ARCH) $(RELEASE) build started: `$(DATE) '+%y-%m-%d %H:%M'`
+	$(MKDIR) -p $(OUTPUTDIR)
 
 # Rules for sanity checks
 include ./make/sanity-rules.gmk
@@ -81,11 +82,24 @@
 
 all:: setup build
 
-setup:
+setup: openjdk_check
 	$(MKDIR) -p $(OUTPUTDIR)/j2sdk-image
-	$(MKDIR) -p $(ABS_OUTPUTDIR)/j2sdk-image
-	$(MKDIR) -p $(OUTPUTDIR)-fastdebug/j2sdk-image
-	$(MKDIR) -p $(ABS_OUTPUTDIR)-fastdebug/j2sdk-image
+
+# Check on whether we really can build the openjdk, need source etc.
+openjdk_check: FRC
+ifneq ($(SKIP_OPENJDK_BUILD), true)
+	@$(ECHO) " "
+	@$(ECHO) "================================================="
+	@if [ ! -r $(OPENJDK_BUILDDIR)/Makefile ] ; then \
+	    $(ECHO) "ERROR: No openjdk source tree available at: $(OPENJDK_BUILDDIR)"; \
+	    exit 1; \
+	else \
+	    $(ECHO) "OpenJDK will be built after JDK is built"; \
+	    $(ECHO) "  OPENJDK_BUILDDIR=$(OPENJDK_BUILDDIR)"; \
+	fi
+	@$(ECHO) "================================================="
+	@$(ECHO) " "
+endif
 
 build:: sanity 
 
@@ -143,7 +157,7 @@
 
 COMMON_DEBUG_FLAGS= \
 	DEBUG_NAME=$(DEBUG_NAME) \
-	ALT_OUTPUTDIR=$(_OUTPUTDIR)-$(DEBUG_NAME) \
+	ALT_OUTPUTDIR=$(ABS_OUTPUTDIR)-$(DEBUG_NAME) \
 	NO_DOCS=true
 
 product_build: setup
@@ -190,46 +204,64 @@
   all :: compare-image
 endif
 
-ifeq ($(SKIP_OPENJDK_BUILD), false)
+ifneq ($(SKIP_OPENJDK_BUILD), true)
+  all :: openjdk_build
+endif
+
+# If we have bundle rules, we have a chance here to do a complete cycle
+#   build, of production and open build.
+# FIXUP: We should create the openjdk source bundle and build that?
+#   But how do we reliable create or get at a formal openjdk source tree?
+#   The one we have needs to be trimmed of built bits and closed dirs.
+#   The repositories might not be available.
+#   The openjdk source bundle is probably not available.
+
+ifneq ($(SKIP_OPENJDK_BUILD), true)
   ifeq ($(BUILD_JDK), true)
     ifeq ($(BUNDLE_RULES_AVAILABLE), true)
-      # If we have bundle rules, we have a chance here to do a complete cycle
-      #   build, of closed and open build.
-      # FIXUP: We should create the openjdk source bundle and build that?
-      ABS_OPENJDK_PLUGS=$(ABS_OUTPUTDIR)/$(OPENJDK_BINARY_PLUGS_INAME)
-      ABS_OPENJDK_OUTPUTDIR=$(ABS_OUTPUTDIR)/openjdk
-      OPENJDK_BUILD_NAME_PREFIX \
-	= $(J2SDK_NAME)-$(JDK_MKTG_UNDERSCORE_VERSION)-$(MILESTONE)
-      OPENJDK_BUILD_NAME_SUFFIX \
-	= $(BUILD_NUMBER)-$(PLATFORM)-$(ARCH)-$(BUNDLE_DATE)
-      OPENJDK_BUILD_NAME \
-	= $(OPENJDK_BUILD_NAME_PREFIX)-openjdk-$(OPENJDK_BUILD_NAME_SUFFIX)
-      OPENJDK_BUILD_BINARY_ZIP \
-	= $(ABS_BIN_BUNDLEDIR)/$(OPENJDK_BUILD_NAME).zip
-  all :: openjdk-build
-  openjdk-build:
+
+OPENJDK_PLUGS=$(ABS_OUTPUTDIR)/$(OPENJDK_BINARY_PLUGS_INAME)
+OPENJDK_OUTPUTDIR=$(ABS_OUTPUTDIR)/open-output
+OPENJDK_BUILD_NAME \
+  = openjdk-$(JDK_MINOR_VERSION)-$(BUILD_NUMBER)-$(PLATFORM)-$(ARCH)-$(BUNDLE_DATE)
+OPENJDK_BUILD_BINARY_ZIP=$(ABS_BIN_BUNDLEDIR)/$(OPENJDK_BUILD_NAME).zip
+BUILT_IMAGE=$(ABS_OUTPUTDIR)/j2sdk-image
+ifeq ($(PLATFORM)$(ARCH_DATA_MODEL),solaris64)
+  OPENJDK_BOOTDIR=$(BOOTDIR)
+  OPENJDK_IMPORTJDK=$(JDK_IMPORT_PATH)
+else
+  OPENJDK_BOOTDIR=$(BUILT_IMAGE)
+  OPENJDK_IMPORTJDK=$(BUILT_IMAGE)
+endif
+
+openjdk_build:
 	@$(ECHO) " "
 	@$(ECHO) "================================================="
 	@$(ECHO) "Starting openjdk build"
+	@$(ECHO) " Using: ALT_JDK_DEVTOOLS_DIR=$(JDK_DEVTOOLS_DIR)"
 	@$(ECHO) "================================================="
 	@$(ECHO) " "
-	$(RM) -r $(ABS_OPENJDK_OUTPUTDIR)
-	$(MKDIR) -p $(ABS_OPENJDK_OUTPUTDIR)
-	$(MAKE) OPENJDK=true \
-	  BUILD_LANGTOOLS=$(BUILD_LANGTOOLS) \
-	  BUILD_CORBA=$(BUILD_CORBA) \
-	  BUILD_JAXP=$(BUILD_JAXP) \
-	  BUILD_JAXWS=$(BUILD_JAXWS) \
-	  BUILD_HOTSPOT=$(BUILD_HOTSPOT) \
-	  ALT_OUTPUTDIR=$(ABS_OPENJDK_OUTPUTDIR) \
-	  ALT_BINARY_PLUGS_PATH=$(ABS_OUTPUTDIR)/$(OPENJDK_BINARY_PLUGS_INAME) \
-	  ALT_BOOTDIR=$(ABS_OUTPUTDIR)/j2sdk-image \
-	  ALT_JDK_IMPORT_PATH=$(ABS_OUTPUTDIR)/j2sdk-image \
-		product_build
+	$(RM) -r $(OPENJDK_OUTPUTDIR)
+	$(MKDIR) -p $(OPENJDK_OUTPUTDIR)
+	($(CD) $(OPENJDK_BUILDDIR) && $(MAKE) \
+	  OPENJDK=true \
+	  ALT_JDK_DEVTOOLS_DIR=$(JDK_DEVTOOLS_DIR) \
+	  ALT_OUTPUTDIR=$(OPENJDK_OUTPUTDIR) \
+	  ALT_BINARY_PLUGS_PATH=$(OPENJDK_PLUGS) \
+	  ALT_BOOTDIR=$(OPENJDK_BOOTDIR) \
+	  ALT_JDK_IMPORT_PATH=$(OPENJDK_IMPORTJDK) \
+		product_build )
 	$(RM) $(OPENJDK_BUILD_BINARY_ZIP)
-	( $(CD) $(ABS_OPENJDK_OUTPUTDIR)/j2sdk-image && \
+	( $(CD) $(OPENJDK_OUTPUTDIR)/j2sdk-image && \
 	  $(ZIPEXE) -q -r $(OPENJDK_BUILD_BINARY_ZIP) .)
-	$(RM) -r $(ABS_OPENJDK_OUTPUTDIR)
+	$(RM) -r $(OPENJDK_OUTPUTDIR)
+	@$(ECHO) " "
+	@$(ECHO) "================================================="
+	@$(ECHO) "Finished openjdk build"
+	@$(ECHO) " Binary Bundle: $(OPENJDK_BUILD_BINARY_ZIP)"
+	@$(ECHO) "================================================="
+	@$(ECHO) " "
+    
     endif
   endif
 endif
@@ -432,11 +464,11 @@
 # Cycle build. Build the jdk, use it to build the jdk again.
 ################################################################
   
-ABS_BOOTJDK_OUTPUTDIR=$(ABS_OUTPUTDIR)/bootjdk
+ABS_BOOTDIR_OUTPUTDIR=$(ABS_OUTPUTDIR)/bootjdk
   
 boot_cycle:
-	$(MAKE) ALT_OUTPUTDIR=$(ABS_BOOTJDK_OUTPUTDIR) product_build
-	$(MAKE) ALT_BOOTDIR=$(ABS_BOOTJDK_OUTPUTDIR)/j2sdk-image product_build
+	$(MAKE) ALT_OUTPUTDIR=$(ABS_BOOTDIR_OUTPUTDIR) product_build
+	$(MAKE) ALT_BOOTDIR=$(ABS_BOOTDIR_OUTPUTDIR)/j2sdk-image product_build
 
 ################################################################
 # JPRT rule to build
@@ -452,7 +484,6 @@
 	fastdebug_build debug_build product_build setup \
         dev dev-build dev-sanity dev-clobber
 
-# FIXUP: Old j2se targets
-j2se_fastdebug_only: jdk_fastdebug_only
-j2se_only: jdk_only
+# Force target
+FRC:
 
--- a/README-builds.html	Wed Apr 30 12:32:05 2008 +0400
+++ b/README-builds.html	Wed Apr 30 07:03:08 2008 -0700
@@ -342,32 +342,29 @@
 
 <blockquote>
     <p>
-    The source code for the 
-    OpenJDK is
-    delivered in <i>3</i> sibling directories:
+    The source code for the OpenJDK is delivered in a set of
+    directories:
     <tt>hotspot</tt>, 
     <tt>langtools</tt>, 
     <tt>corba</tt>, 
     <tt>jaxws</tt>, 
     <tt>jaxp</tt>, 
-    <tt>jdk</tt>
     and
+    <tt>jdk</tt>.
     The <tt>hotspot</tt> directory contains the source code and make
-    files for
-    building the 
-    OpenJDK
-    Hotspot Virtual Machine. 
-    The <tt>jdk</tt>
-    directory contains the source code and make files for
-    building the 
-    OpenJDK
-    runtime libraries, tools and demos. 
-    The top level Makefile is used to build the complete OpenJDK 
-    release including building the hotspot
-    VM, staging the VM binaries, and building the 
-    OpenJDK 
-    runtime libraries,
-    tools and demos.
+    files for building the OpenJDK Hotspot Virtual Machine. 
+    The <tt>langtools</tt> directory contains the source code and make
+    files for building the OpenJDK javac and language tools.
+    The <tt>corba</tt> directory contains the source code and make
+    files for building the OpenJDK Corba files.
+    The <tt>jaxws</tt> directory contains the source code and make
+    files for building the OpenJDK JAXWS files.
+    The <tt>jaxp</tt> directory contains the source code and make
+    files for building the OpenJDK JAXP files.
+    The <tt>jdk</tt> directory contains the source code and make files for
+    building the OpenJDK runtime libraries and misc files.
+    The top level <tt>Makefile</tt>
+    is used to build the entire OpenJDK.
 </blockquote>
 
 <!-- ------------------------------------------------------ -->
@@ -730,17 +727,15 @@
         under an open-source license.
         In order to build an OpenJDK binary from source code,
         you must first download and install the appropriate
-        binary plug bundles from the OpenJDK Download area.
+	binary plug bundles from the OpenJDK, go to the
+	<a href="http://openjdk.java.net">OpenJDK</a> site and select
+	the "<b>Bundles(7)</b>" link.
         During the OpenJDK build process these "binary plugs"
         for the encumbered components will be copied into your
         resulting OpenJDK binary build image.
         These binary plug files are only for the purpose of
         building an OpenJDK binary.
-        Download the Binary Plugs by selecting the <b>Downloads</b>
-        link at
-        <a href="http://openjdk.java.net/">the OpenJDK site</a>,
-        install the bundle,
-        and make sure you set
+        Make sure you set
         <tt><a href="#ALT_BINARY_PLUGS_PATH">ALT_BINARY_PLUGS_PATH</a></tt>
         to the root of this installation.
     </blockquote>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/corba/.hgtags	Wed Apr 30 07:03:08 2008 -0700
@@ -0,0 +1,2 @@
+55540e827aef970ecc010b7e06b912d991c8e3ce jdk7-b24
+5e61d5df62586474414d1058e9186441aa908f51 jdk7-b25
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/corba/.jcheck/conf	Wed Apr 30 07:03:08 2008 -0700
@@ -0,0 +1,1 @@
+project=jdk7
--- a/corba/make/common/shared/Defs.gmk	Wed Apr 30 12:32:05 2008 +0400
+++ b/corba/make/common/shared/Defs.gmk	Wed Apr 30 07:03:08 2008 -0700
@@ -281,6 +281,13 @@
 # Get platform specific settings
 include $(BUILDDIR)/common/shared/Defs-$(PLATFORM).gmk
 
+# Components
+ifdef ALT_LANGTOOLS_DIST
+  LANGTOOLS_DIST :=$(call FullPath,$(ALT_LANGTOOLS_DIST))
+else
+  LANGTOOLS_DIST =
+endif
+
 # These are the same on all platforms but require the above platform include 1st
 
 # BOOTDIR: Bootstrap JDK, previous released JDK.
--- a/corba/src/share/classes/com/sun/corba/se/impl/corba/orb_config_design.txt	Wed Apr 30 12:32:05 2008 +0400
+++ b/corba/src/share/classes/com/sun/corba/se/impl/corba/orb_config_design.txt	Wed Apr 30 07:03:08 2008 -0700
@@ -318,7 +318,7 @@
 
 11. RequestHandler and ORB
 
-    The RH interface is currently implemented in the ORB class, but migūt better be a separate
+    The RH interface is currently implemented in the ORB class, but might better be a separate
     class.  The API is currently almost the same as a ServerSubcontract.  Should we regularize
     this?  Also, the API would need to be extended to handle shutdown properly.
 
--- a/corba/src/share/classes/org/omg/CORBA/ir.idl	Wed Apr 30 12:32:05 2008 +0400
+++ b/corba/src/share/classes/org/omg/CORBA/ir.idl	Wed Apr 30 07:03:08 2008 -0700
@@ -774,18 +774,18 @@
     
     // orbos 98-01-18: Objects By Value -- end
 
-    enum TCKind {
-        tk_null, tk_void,
+    enum TCKind {
+        tk_null, tk_void,
         tk_short, tk_long, tk_ushort, tk_ulong,
-        tk_float, tk_double, tk_boolean, tk_char,
-        tk_octet, tk_any, tk_TypeCode, tk_Principal, tk_objref,
-        tk_struct, tk_union, tk_enum, tk_string,
-        tk_sequence, tk_array, tk_alias, tk_except,
-        tk_longlong, tk_ulonglong, tk_longdouble,
-        tk_wchar, tk_wstring, tk_fixed,
-        tk_value, tk_value_box,
-        tk_native,
-        tk_abstract_interface
+        tk_float, tk_double, tk_boolean, tk_char,
+        tk_octet, tk_any, tk_TypeCode, tk_Principal, tk_objref,
+        tk_struct, tk_union, tk_enum, tk_string,
+        tk_sequence, tk_array, tk_alias, tk_except,
+        tk_longlong, tk_ulonglong, tk_longdouble,
+        tk_wchar, tk_wstring, tk_fixed,
+        tk_value, tk_value_box,
+        tk_native,
+        tk_abstract_interface
     };
 
     interface NativeDef : TypedefDef {
--- a/corba/src/share/classes/org/omg/DynamicAny/DynamicAny.idl	Wed Apr 30 12:32:05 2008 +0400
+++ b/corba/src/share/classes/org/omg/DynamicAny/DynamicAny.idl	Wed Apr 30 07:03:08 2008 -0700
@@ -1042,24 +1042,24 @@
     /**
     * DynValueCommon provides operations supported by both the DynValue and DynValueBox interfaces.
     */
-    interface DynValueCommon : DynAny {
+    interface DynValueCommon : DynAny {
         /**
         * Returns true if the DynValueCommon represents a null value type.
         */
-        boolean is_null();
+        boolean is_null();
 
         /**
         * Changes the representation of a DynValueCommon to a null value type.
         */
-        void set_to_null();
+        void set_to_null();
 
         /**
         * Replaces a null value type with a newly constructed value. Its components are initialized
         * to default values as in DynAnyFactory.create_dyn_any_from_type_code.
         * If the DynValueCommon represents a non-null value type, then this operation has no effect. 
         */
-        void set_to_value();
-    }; 
+        void set_to_value();
+    }; 
 
     /**
     * DynValue objects support the manipulation of IDL non-boxed value types.
@@ -1164,14 +1164,14 @@
     * of the boxed type. A DynValueBox representing a null value type has no components
     * and a current position of -1.
     */
-    interface DynValueBox : DynValueCommon {
+    interface DynValueBox : DynValueCommon {
 
         /**
         * Returns the boxed value as an Any.
         *
         * @exception InvalidValue if this object represents a null value box type
         */
-        any get_boxed_value()
+        any get_boxed_value()
             raises(InvalidValue);
 
         /**
@@ -1189,7 +1189,7 @@
         *
         * @exception InvalidValue if this object represents a null value box type
         */
-        DynAny get_boxed_value_as_dyn_any()
+        DynAny get_boxed_value_as_dyn_any()
             raises(InvalidValue);
 
         /**
@@ -1199,7 +1199,7 @@
         * @exception TypeMismatch if this object represents a non-null value box type and the type
         *            of the parameter is not matching the current boxed value type.
         */
-        void set_boxed_value_as_dyn_any(in DynAny boxed)
+        void set_boxed_value_as_dyn_any(in DynAny boxed)
             raises(TypeMismatch);
     };
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/.hgtags	Wed Apr 30 07:03:08 2008 -0700
@@ -0,0 +1,2 @@
+a61af66fc99eb5ec9d50c05b0c599757b1289ceb jdk7-b24
+7836be3e92d0a4f9ee7566f602c91f5609534e66 jdk7-b25
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/.jcheck/conf	Wed Apr 30 07:03:08 2008 -0700
@@ -0,0 +1,1 @@
+project=jdk7
--- a/hotspot/agent/src/os/linux/ps_core.c	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/agent/src/os/linux/ps_core.c	Wed Apr 30 07:03:08 2008 -0700
@@ -518,10 +518,10 @@
 }
 
 static ps_prochandle_ops core_ops = {
-   release:  core_release,
-   p_pread:  core_read_data,
-   p_pwrite: core_write_data,
-   get_lwp_regs: core_get_lwp_regs
+   .release=  core_release,
+   .p_pread=  core_read_data,
+   .p_pwrite= core_write_data,
+   .get_lwp_regs= core_get_lwp_regs
 };
 
 // read regs and create thread from NT_PRSTATUS entries from core file
--- a/hotspot/agent/src/os/linux/ps_proc.c	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/agent/src/os/linux/ps_proc.c	Wed Apr 30 07:03:08 2008 -0700
@@ -291,10 +291,10 @@
 }
 
 static ps_prochandle_ops process_ops = {
-  release:  process_cleanup,
-  p_pread:  process_read_data,
-  p_pwrite: process_write_data,
-  get_lwp_regs: process_get_lwp_regs
+  .release=  process_cleanup,
+  .p_pread=  process_read_data,
+  .p_pwrite= process_write_data,
+  .get_lwp_regs= process_get_lwp_regs
 };
 
 // attach to the process. One and only one exposed stuff
--- a/hotspot/build/linux/Makefile	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/build/linux/Makefile	Wed Apr 30 07:03:08 2008 -0700
@@ -80,6 +80,11 @@
   MFLAGS += " LP64=1 "
 endif
 
+# pass USE_SUNCC further, through MFLAGS
+ifdef USE_SUNCC
+  MFLAGS += " USE_SUNCC=1 "
+endif
+
 # The following renders pathnames in generated Makefiles valid on
 # machines other than the machine containing the build tree.
 #
--- a/hotspot/build/linux/makefiles/amd64.make	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/build/linux/makefiles/amd64.make	Wed Apr 30 07:03:08 2008 -0700
@@ -35,6 +35,8 @@
 CFLAGS += -D_LP64=1
 
 # The serviceability agent relies on frame pointer (%rbp) to walk thread stack
-CFLAGS += -fno-omit-frame-pointer
+ifndef USE_SUNCC
+  CFLAGS += -fno-omit-frame-pointer
+endif
 
 OPT_CFLAGS/compactingPermGenGen.o = -O1
--- a/hotspot/build/linux/makefiles/buildtree.make	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/build/linux/makefiles/buildtree.make	Wed Apr 30 07:03:08 2008 -0700
@@ -63,7 +63,11 @@
 # For now, until the compiler is less wobbly:
 TESTFLAGS	= -Xbatch -showversion
 
-PLATFORM_FILE	= $(GAMMADIR)/build/$(OS_FAMILY)/platform_$(BUILDARCH)
+ifdef USE_SUNCC
+PLATFORM_FILE	= $(GAMMADIR)/build/$(OS_FAMILY)/platform_$(BUILDARCH).suncc
+else
+PLATFORM_FILE   = $(GAMMADIR)/build/$(OS_FAMILY)/platform_$(BUILDARCH)
+endif
 
 ifdef FORCE_TIERED
 ifeq		($(VARIANT),tiered)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/build/linux/makefiles/sparcWorks.make	Wed Apr 30 07:03:08 2008 -0700
@@ -0,0 +1,93 @@
+#
+# Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#  
+#
+
+#------------------------------------------------------------------------
+# CC, CPP & AS
+
+CPP = CC
+CC  = cc
+AS  = $(CC) -c
+
+ARCHFLAG = $(ARCHFLAG/$(BUILDARCH))
+ARCHFLAG/i486    = -m32
+ARCHFLAG/amd64   = -m64
+
+CFLAGS     += $(ARCHFLAG)
+AOUT_FLAGS += $(ARCHFLAG)
+LFLAGS     += $(ARCHFLAG)
+ASFLAGS    += $(ARCHFLAG)
+
+#------------------------------------------------------------------------
+# Compiler flags
+
+# position-independent code
+PICFLAG = -KPIC
+
+CFLAGS += $(PICFLAG)
+# no more exceptions
+CFLAGS += -features=no%except
+# Reduce code bloat by reverting back to 5.0 behavior for static initializers
+CFLAGS += -features=no%split_init
+# allow zero sized arrays
+CFLAGS += -features=zla
+
+# Use C++ Interpreter
+ifdef CC_INTERP
+  CFLAGS += -DCC_INTERP
+endif
+
+# We don't need libCstd.so and librwtools7.so, only libCrun.so
+CFLAGS += -library=Crun
+LIBS += -lCrun
+
+CFLAGS += -mt
+LFLAGS += -mt
+
+# Compiler warnings are treated as errors
+#WARNINGS_ARE_ERRORS = -errwarn=%all
+CFLAGS_WARN/DEFAULT = $(WARNINGS_ARE_ERRORS) 
+# Special cases
+CFLAGS_WARN/BYFILE = $(CFLAGS_WARN/$@)$(CFLAGS_WARN/DEFAULT$(CFLAGS_WARN/$@)) 
+
+# The flags to use for an Optimized build
+OPT_CFLAGS+=-xO4
+OPT_CFLAGS/NOOPT=-xO0
+
+#------------------------------------------------------------------------
+# Linker flags
+
+# Use $(MAPFLAG:FILENAME=real_file_name) to specify a map file.
+MAPFLAG = -Wl,--version-script=FILENAME
+
+# Use $(SONAMEFLAG:SONAME=soname) to specify the intrinsic name of a shared obj
+SONAMEFLAG = -h SONAME
+
+# Build shared library
+SHARED_FLAG = -G
+
+#------------------------------------------------------------------------
+# Debug flags
+DEBUG_CFLAGS += -g
+FASTDEBUG_CFLAGS = -g0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/build/linux/platform_amd64.suncc	Wed Apr 30 07:03:08 2008 -0700
@@ -0,0 +1,17 @@
+os_family = linux
+
+arch = x86
+
+arch_model = x86_64
+
+os_arch = linux_x86
+
+os_arch_model = linux_x86_64
+
+lib_arch = amd64
+
+compiler = sparcWorks
+
+gnu_dis_arch = amd64
+
+sysdefs = -DLINUX -DSPARC_WORKS -D_GNU_SOURCE -DAMD64
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/build/linux/platform_i486.suncc	Wed Apr 30 07:03:08 2008 -0700
@@ -0,0 +1,17 @@
+os_family = linux
+
+arch = x86
+
+arch_model = x86_32
+
+os_arch = linux_x86
+
+os_arch_model = linux_x86_32
+
+lib_arch = i386
+
+compiler = sparcWorks
+
+gnu_dis_arch = i386
+
+sysdefs = -DLINUX -DSPARC_WORKS -D_GNU_SOURCE -DIA32
--- a/hotspot/build/solaris/makefiles/amd64.make	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/build/solaris/makefiles/amd64.make	Wed Apr 30 07:03:08 2008 -0700
@@ -19,7 +19,7 @@
 # Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 # CA 95054 USA or visit www.sun.com if you need additional information or
 # have any questions.
-#  
+#
 #
 
 # Must also specify if CPU is little endian
@@ -45,6 +45,10 @@
 OPT_CFLAGS/generateOptoStub.o = -xO2
 OPT_CFLAGS/thread.o = -xO2
 
+# Work around for 6624782
+OPT_CFLAGS/instanceKlass.o = -Qoption ube -no_a2lf
+OPT_CFLAGS/objArrayKlass.o = -Qoption ube -no_a2lf
+
 else
 
 ifeq ("${Platform_compiler}", "gcc")
@@ -58,6 +62,6 @@
 # error
 _JUNK2_ := $(shell echo >&2 \
        "*** ERROR: this compiler is not yet supported by this code base!")
-	@exit 1
+       @exit 1
 endif
 endif
--- a/hotspot/build/windows/makefiles/compile.make	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/build/windows/makefiles/compile.make	Wed Apr 30 07:03:08 2008 -0700
@@ -44,6 +44,10 @@
 #   /Od       Disable all optimizations
 #
 # NOTE: Normally following any of the above with a '-' will turn off that flag
+#
+# 6655385: For VS2003/2005 we now specify /Oy- (disable frame pointer
+# omission.)  This has little to no effect on performance while vastly
+# improving the quality of crash log stack traces involving jvm.dll.
 
 # These are always used in all compiles
 CPP_FLAGS=/nologo /W3 /WX
@@ -141,14 +145,14 @@
 !endif
 
 !if "$(COMPILER_NAME)" == "VS2003"
-PRODUCT_OPT_OPTION   = /O2
-FASTDEBUG_OPT_OPTION = /O2
+PRODUCT_OPT_OPTION   = /O2 /Oy-
+FASTDEBUG_OPT_OPTION = /O2 /Oy-
 DEBUG_OPT_OPTION     = /Od
 !endif
 
 !if "$(COMPILER_NAME)" == "VS2005"
-PRODUCT_OPT_OPTION   = /O2
-FASTDEBUG_OPT_OPTION = /O2
+PRODUCT_OPT_OPTION   = /O2 /Oy-
+FASTDEBUG_OPT_OPTION = /O2 /Oy-
 DEBUG_OPT_OPTION     = /Od
 GX_OPTION = /EHsc
 # This VS2005 compiler has /GS as a default and requires bufferoverflowU.lib 
@@ -165,8 +169,8 @@
 
 # Compile for space above time.
 !if "$(Variant)" == "kernel"
-PRODUCT_OPT_OPTION   = /O1
-FASTDEBUG_OPT_OPTION = /O1
+PRODUCT_OPT_OPTION   = /O1 /Oy-
+FASTDEBUG_OPT_OPTION = /O1 /Oy-
 DEBUG_OPT_OPTION     = /Od
 !endif
 
--- a/hotspot/make/hotspot_version	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/make/hotspot_version	Wed Apr 30 07:03:08 2008 -0700
@@ -35,7 +35,7 @@
 
 HS_MAJOR_VER=12
 HS_MINOR_VER=0
-HS_BUILD_NUMBER=01
+HS_BUILD_NUMBER=03
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=7
--- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -2037,7 +2037,7 @@
 
 
 int LIR_Assembler::shift_amount(BasicType t) {
-  int elem_size = type2aelembytes[t];
+  int elem_size = type2aelembytes(t);
   switch (elem_size) {
     case 1 : return 0;
     case 2 : return 1;
@@ -2360,7 +2360,7 @@
                       op->tmp2()->as_register(),
                       op->tmp3()->as_register(),
                       arrayOopDesc::header_size(op->type()),
-                      type2aelembytes[op->type()],
+                      type2aelembytes(op->type()),
                       op->klass()->as_register(),
                       *op->stub()->entry());
   }
--- a/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -179,7 +179,7 @@
 
 LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_opr,
                                               BasicType type, bool needs_card_mark) {
-  int elem_size = type2aelembytes[type];
+  int elem_size = type2aelembytes(type);
   int shift = exact_log2(elem_size);
 
   LIR_Opr base_opr;
--- a/hotspot/src/cpu/sparc/vm/sparc.ad	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad	Wed Apr 30 07:03:08 2008 -0700
@@ -6023,7 +6023,7 @@
   ins_pipe(ialu_imm);
 %}
 
-instruct cmovII_U_reg(cmpOp cmp, flagsRegU icc, iRegI dst, iRegI src) %{
+instruct cmovII_U_reg(cmpOpU cmp, flagsRegU icc, iRegI dst, iRegI src) %{
   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
   ins_cost(150);
   size(4);
@@ -6032,7 +6032,7 @@
   ins_pipe(ialu_reg);
 %}
 
-instruct cmovII_U_imm(cmpOp cmp, flagsRegU icc, iRegI dst, immI11 src) %{
+instruct cmovII_U_imm(cmpOpU cmp, flagsRegU icc, iRegI dst, immI11 src) %{
   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
   ins_cost(140);
   size(4);
--- a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -2911,6 +2911,7 @@
 
     // These entry points require SharedInfo::stack0 to be set up in non-core builds
     StubRoutines::_throw_AbstractMethodError_entry         = generate_throw_exception("AbstractMethodError throw_exception",          CAST_FROM_FN_PTR(address, SharedRuntime::throw_AbstractMethodError),  false);
+    StubRoutines::_throw_IncompatibleClassChangeError_entry= generate_throw_exception("IncompatibleClassChangeError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_IncompatibleClassChangeError),  false);
     StubRoutines::_throw_ArithmeticException_entry         = generate_throw_exception("ArithmeticException throw_exception",          CAST_FROM_FN_PTR(address, SharedRuntime::throw_ArithmeticException),  true);
     StubRoutines::_throw_NullPointerException_entry        = generate_throw_exception("NullPointerException throw_exception",         CAST_FROM_FN_PTR(address, SharedRuntime::throw_NullPointerException), true);
     StubRoutines::_throw_NullPointerException_at_call_entry= generate_throw_exception("NullPointerException at call throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_NullPointerException_at_call), false);
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -28,6 +28,12 @@
 int VM_Version::_features = VM_Version::unknown_m;
 const char* VM_Version::_features_str = "";
 
+bool VM_Version::is_niagara1_plus() {
+  // This is a placeholder until the real test is determined.
+  return is_niagara1() &&
+    (os::processor_count() > maximum_niagara1_processor_count());
+}
+
 void VM_Version::initialize() {
   _features = determine_features();
   PrefetchCopyIntervalInBytes = prefetch_copy_interval_in_bytes();
@@ -160,3 +166,13 @@
 void VM_Version::revert() {
   _features = saved_features;
 }
+
+unsigned int VM_Version::calc_parallel_worker_threads() {
+  unsigned int result;
+  if (is_niagara1_plus()) {
+    result = nof_parallel_worker_threads(5, 16, 8);
+  } else {
+    result = nof_parallel_worker_threads(5, 8, 8);
+  }
+  return result;
+}
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp	Wed Apr 30 07:03:08 2008 -0700
@@ -64,6 +64,11 @@
 
   static bool is_niagara1(int features) { return (features & niagara1_m) == niagara1_m; }
 
+  static int maximum_niagara1_processor_count() { return 32; }
+  // Returns true if the platform is in the niagara line and
+  // newer than the niagara1.
+  static bool is_niagara1_plus();
+
 public:
   // Initialization
   static void initialize();
@@ -129,4 +134,7 @@
 
   // Override the Abstract_VM_Version implementation.
   static uint page_size_count() { return is_sun4v() ? 4 : 2; }
+
+  // Calculates the number of parallel threads
+  static unsigned int calc_parallel_worker_threads();
 };
--- a/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -175,17 +175,12 @@
   // %%%% Could load both offset and interface in one ldx, if they were
   // in the opposite order.  This would save a load.
   __ ld_ptr(L0, base + itableOffsetEntry::interface_offset_in_bytes(), L1);
-#ifdef ASSERT
-  Label ok;
-  // Check that entry is non-null and an Oop
-  __ bpr(Assembler::rc_nz, false, Assembler::pt, L1, ok);
-  __ delayed()->nop();
-  __ stop("null entry point found in itable's offset table");
-  __ bind(ok);
-  __ verify_oop(L1);
-#endif // ASSERT
 
-  __ cmp(G5_interface, L1);
+  // If the entry is NULL then we've reached the end of the table
+  // without finding the expected interface, so throw an exception
+  Label throw_icce;
+  __ bpr(Assembler::rc_z, false, Assembler::pn, L1, throw_icce);
+  __ delayed()->cmp(G5_interface, L1);
   __ brx(Assembler::notEqual, true, Assembler::pn, search);
   __ delayed()->add(L0, itableOffsetEntry::size() * wordSize, L0);
 
@@ -223,24 +218,30 @@
   __ JMP(G3_scratch, 0);
   __ delayed()->nop();
 
+  __ bind(throw_icce);
+  Address icce(G3_scratch, StubRoutines::throw_IncompatibleClassChangeError_entry());
+  __ jump_to(icce, 0);
+  __ delayed()->restore();
+
   masm->flush();
+
+  guarantee(__ pc() <= s->code_end(), "overflowed buffer");
+
   s->set_exception_points(npe_addr, ame_addr);
   return s;
 }
 
 
 int VtableStub::pd_code_size_limit(bool is_vtable_stub) {
-  if (TraceJumps || DebugVtables || CountCompiledCalls || VerifyOops) return 999;
+  if (TraceJumps || DebugVtables || CountCompiledCalls || VerifyOops) return 1000;
   else {
     const int slop = 2*BytesPerInstWord; // sethi;add  (needed for long offsets)
     if (is_vtable_stub) {
       const int basic = 5*BytesPerInstWord; // ld;ld;ld,jmp,nop
       return basic + slop;
     } else {
-#ifdef ASSERT
-      return 999;
-#endif // ASSERT
-      const int basic = 17*BytesPerInstWord; // save, ld, ld, sll, and, add, add, ld, cmp, br, add, ld, add, ld, ld, jmp, restore
+      // save, ld, ld, sll, and, add, add, ld, cmp, br, add, ld, add, ld, ld, jmp, restore, sethi, jmpl, restore
+      const int basic = (20 LP64_ONLY(+ 6)) * BytesPerInstWord;
       return (basic + slop);
     }
   }
@@ -252,29 +253,3 @@
   const unsigned int icache_line_size = 32;
   return icache_line_size;
 }
-
-
-//Reconciliation History
-// 1.2 97/12/09 17:13:31 vtableStubs_i486.cpp
-// 1.4 98/01/21 19:18:37 vtableStubs_i486.cpp
-// 1.5 98/02/13 16:33:55 vtableStubs_i486.cpp
-// 1.7 98/03/05 17:17:28 vtableStubs_i486.cpp
-// 1.9 98/05/18 09:26:17 vtableStubs_i486.cpp
-// 1.10 98/05/26 16:28:13 vtableStubs_i486.cpp
-// 1.11 98/05/27 08:51:35 vtableStubs_i486.cpp
-// 1.12 98/06/15 15:04:12 vtableStubs_i486.cpp
-// 1.13 98/07/28 18:44:22 vtableStubs_i486.cpp
-// 1.15 98/08/28 11:31:19 vtableStubs_i486.cpp
-// 1.16 98/09/02 12:58:31 vtableStubs_i486.cpp
-// 1.17 98/09/04 12:15:52 vtableStubs_i486.cpp
-// 1.18 98/11/19 11:55:24 vtableStubs_i486.cpp
-// 1.19 99/01/12 14:57:56 vtableStubs_i486.cpp
-// 1.20 99/01/19 17:42:52 vtableStubs_i486.cpp
-// 1.22 99/01/21 10:29:25 vtableStubs_i486.cpp
-// 1.30 99/06/02 15:27:39 vtableStubs_i486.cpp
-// 1.26 99/06/24 14:25:07 vtableStubs_i486.cpp
-// 1.23 99/02/22 14:37:52 vtableStubs_i486.cpp
-// 1.28 99/06/29 18:06:17 vtableStubs_i486.cpp
-// 1.29 99/07/22 17:03:44 vtableStubs_i486.cpp
-// 1.30 99/08/11 09:33:27 vtableStubs_i486.cpp
-//End
--- a/hotspot/src/cpu/x86/vm/assembler_x86_32.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/cpu/x86/vm/assembler_x86_32.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -2672,6 +2672,22 @@
   emit_sse_operand(dst, src);
 }
 
+void Assembler::cvtdq2pd(XMMRegister dst, XMMRegister src) {
+  assert(VM_Version::supports_sse2(), "");
+
+  emit_byte(0xF3);
+  emit_byte(0x0F);
+  emit_byte(0xE6);
+  emit_sse_operand(dst, src);
+}
+
+void Assembler::cvtdq2ps(XMMRegister dst, XMMRegister src) {
+  assert(VM_Version::supports_sse2(), "");
+
+  emit_byte(0x0F);
+  emit_byte(0x5B);
+  emit_sse_operand(dst, src);
+}
 
 emit_sse_instruction(andps,  sse,  0,    0x54, XMMRegister, XMMRegister);
 emit_sse_instruction(andpd,  sse2, 0x66, 0x54, XMMRegister, XMMRegister);
--- a/hotspot/src/cpu/x86/vm/assembler_x86_32.hpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/cpu/x86/vm/assembler_x86_32.hpp	Wed Apr 30 07:03:08 2008 -0700
@@ -901,6 +901,8 @@
   void cvtss2sd(XMMRegister dst, XMMRegister src);
   void cvtsd2ss(XMMRegister dst, Address src);   // Convert Scalar Double-Precision Floating-Point Value to Scalar Single-Precision Floating-Point Value
   void cvtsd2ss(XMMRegister dst, XMMRegister src);
+  void cvtdq2pd(XMMRegister dst, XMMRegister src);
+  void cvtdq2ps(XMMRegister dst, XMMRegister src);
 
   void cvtsi2ss(XMMRegister dst, Address src);   // Convert Doubleword Integer to Scalar Single-Precision Floating-Point Value
   void cvtsi2ss(XMMRegister dst, Register src);
--- a/hotspot/src/cpu/x86/vm/assembler_x86_64.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/cpu/x86/vm/assembler_x86_64.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -1304,7 +1304,7 @@
   emit_operand(src, dst);
 }
 
-void Assembler::mov64(Register dst, int64_t imm64) {
+void Assembler::mov64(Register dst, intptr_t imm64) {
   InstructionMark im(this);
   int encode = prefixq_and_encode(dst->encoding());
   emit_byte(0xB8 | encode);
@@ -1331,7 +1331,7 @@
   emit_operand(dst, src);
 }
 
-void Assembler::mov64(Address dst, int64_t imm32) {
+void Assembler::mov64(Address dst, intptr_t imm32) {
   assert(is_simm32(imm32), "lost bits");
   InstructionMark im(this);
   prefixq(dst);
@@ -3372,6 +3372,21 @@
   emit_byte(0xC0 | encode);
 }
 
+void Assembler::cvtdq2pd(XMMRegister dst, XMMRegister src) {
+  emit_byte(0xF3);
+  int encode = prefix_and_encode(dst->encoding(), src->encoding());
+  emit_byte(0x0F);
+  emit_byte(0xE6);
+  emit_byte(0xC0 | encode);
+}
+
+void Assembler::cvtdq2ps(XMMRegister dst, XMMRegister src) {
+  int encode = prefix_and_encode(dst->encoding(), src->encoding());
+  emit_byte(0x0F);
+  emit_byte(0x5B);
+  emit_byte(0xC0 | encode);
+}
+
 void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) {
   emit_byte(0xF2);
   int encode = prefix_and_encode(dst->encoding(), src->encoding());
--- a/hotspot/src/cpu/x86/vm/assembler_x86_64.hpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/cpu/x86/vm/assembler_x86_64.hpp	Wed Apr 30 07:03:08 2008 -0700
@@ -922,6 +922,8 @@
   void cvttsd2siq(Register dst, XMMRegister src); // truncates
   void cvtss2sd(XMMRegister dst, XMMRegister src);
   void cvtsd2ss(XMMRegister dst, XMMRegister src);
+  void cvtdq2pd(XMMRegister dst, XMMRegister src);
+  void cvtdq2ps(XMMRegister dst, XMMRegister src);
 
   void pxor(XMMRegister dst, Address src);       // Xor Packed Byte Integer Values
   void pxor(XMMRegister dst, XMMRegister src);   // Xor Packed Byte Integer Values
--- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -546,8 +546,8 @@
   // set rsi.edi to the end of the arrays (arrays have same length)
   // negate the index
 
-  __ leal(rsi, Address(rsi, rax, Address::times_2, type2aelembytes[T_CHAR]));
-  __ leal(rdi, Address(rdi, rax, Address::times_2, type2aelembytes[T_CHAR]));
+  __ leal(rsi, Address(rsi, rax, Address::times_2, type2aelembytes(T_CHAR)));
+  __ leal(rdi, Address(rdi, rax, Address::times_2, type2aelembytes(T_CHAR)));
   __ negl(rax);
 
   // compare the strings in a loop
@@ -1232,7 +1232,7 @@
 
 NEEDS_CLEANUP; // This could be static?
 Address::ScaleFactor LIR_Assembler::array_element_size(BasicType type) const {
-  int elem_size = type2aelembytes[type];
+  int elem_size = type2aelembytes(type);
   switch (elem_size) {
     case 1: return Address::times_1;
     case 2: return Address::times_2;
@@ -2739,7 +2739,7 @@
 
   assert(default_type != NULL && default_type->is_array_klass() && default_type->is_loaded(), "must be true at this point");
 
-  int elem_size = type2aelembytes[basic_type];
+  int elem_size = type2aelembytes(basic_type);
   int shift_amount;
   Address::ScaleFactor scale;
 
--- a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -151,7 +151,7 @@
 
   LIR_Address* addr;
   if (index_opr->is_constant()) {
-    int elem_size = type2aelembytes[type];
+    int elem_size = type2aelembytes(type);
     addr = new LIR_Address(array_opr,
                            offset_in_bytes + index_opr->as_jint() * elem_size, type);
   } else {
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -1416,8 +1416,8 @@
     // ======== end loop ========
 
     // It was a real error; we must depend on the caller to finish the job.
-    // Register rdx = -1 * number of *remaining* oops, r14 = *total* oops.
-    // Emit GC store barriers for the oops we have copied (r14 + rdx),
+    // Register "count" = -1 * number of *remaining* oops, length_arg = *total* oops.
+    // Emit GC store barriers for the oops we have copied (length_arg + count),
     // and report their number to the caller.
     __ addl(count, length_arg);         // transfers = (length - remaining)
     __ movl(rax, count);                // save the value
@@ -1430,6 +1430,7 @@
     // Come here on success only.
     __ BIND(L_do_card_marks);
     __ movl(count, length_arg);
+    __ movl(to, to_arg);                // reload
     gen_write_ref_array_post_barrier(to, count);
     __ xorl(rax, rax);                  // return 0 on success
 
@@ -2151,6 +2152,7 @@
     // These entry points require SharedInfo::stack0 to be set up in non-core builds
     // and need to be relocatable, so they each fabricate a RuntimeStub internally.
     StubRoutines::_throw_AbstractMethodError_entry         = generate_throw_exception("AbstractMethodError throw_exception",          CAST_FROM_FN_PTR(address, SharedRuntime::throw_AbstractMethodError),  false);
+    StubRoutines::_throw_IncompatibleClassChangeError_entry= generate_throw_exception("IncompatibleClassChangeError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_IncompatibleClassChangeError),  false);
     StubRoutines::_throw_ArithmeticException_entry         = generate_throw_exception("ArithmeticException throw_exception",          CAST_FROM_FN_PTR(address, SharedRuntime::throw_ArithmeticException),  true);
     StubRoutines::_throw_NullPointerException_entry        = generate_throw_exception("NullPointerException throw_exception",         CAST_FROM_FN_PTR(address, SharedRuntime::throw_NullPointerException), true);
     StubRoutines::_throw_NullPointerException_at_call_entry= generate_throw_exception("NullPointerException at call throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_NullPointerException_at_call), false);
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -2832,6 +2832,13 @@
                                                 throw_AbstractMethodError),
                                false);
 
+    StubRoutines::_throw_IncompatibleClassChangeError_entry =
+      generate_throw_exception("IncompatibleClassChangeError throw_exception",
+                               CAST_FROM_FN_PTR(address,
+                                                SharedRuntime::
+                                                throw_IncompatibleClassChangeError),
+                               false);
+
     StubRoutines::_throw_ArithmeticException_entry =
       generate_throw_exception("ArithmeticException throw_exception",
                                CAST_FROM_FN_PTR(address,
--- a/hotspot/src/cpu/x86/vm/vm_version_x86_32.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86_32.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -321,6 +321,20 @@
         UseXmmRegToRegMoveAll = false;
       }
     }
+    if( FLAG_IS_DEFAULT(UseXmmI2F) ) {
+      if( supports_sse4a() ) {
+        UseXmmI2F = true;
+      } else {
+        UseXmmI2F = false;
+      }
+    }
+    if( FLAG_IS_DEFAULT(UseXmmI2D) ) {
+      if( supports_sse4a() ) {
+        UseXmmI2D = true;
+      } else {
+        UseXmmI2D = false;
+      }
+    }
   }
 
   if( is_intel() ) { // Intel cpus specific settings
--- a/hotspot/src/cpu/x86/vm/vm_version_x86_64.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86_64.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -265,6 +265,20 @@
         UseXmmRegToRegMoveAll = false;
       }
     }
+    if( FLAG_IS_DEFAULT(UseXmmI2F) ) {
+      if( supports_sse4a() ) {
+        UseXmmI2F = true;
+      } else {
+        UseXmmI2F = false;
+      }
+    }
+    if( FLAG_IS_DEFAULT(UseXmmI2D) ) {
+      if( supports_sse4a() ) {
+        UseXmmI2D = true;
+      } else {
+        UseXmmI2D = false;
+      }
+    }
   }
 
   if( is_intel() ) { // Intel cpus specific settings
--- a/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -138,29 +138,21 @@
     __ round_to(rbx, BytesPerLong);
   }
 
-  Label hit, next, entry;
+  Label hit, next, entry, throw_icce;
 
-  __ jmp(entry);
+  __ jmpb(entry);
 
   __ bind(next);
   __ addl(rbx, itableOffsetEntry::size() * wordSize);
 
   __ bind(entry);
 
-#ifdef ASSERT
-    // Check that the entry is non-null
-  if (DebugVtables) {
-    Label L;
-    __ pushl(rbx);
-    __ movl(rbx, Address(rbx, itableOffsetEntry::interface_offset_in_bytes()));
-    __ testl(rbx, rbx);
-    __ jcc(Assembler::notZero, L);
-    __ stop("null entry point found in itable's offset table");
-    __ bind(L);
-    __ popl(rbx);
-  }
-#endif
-  __ cmpl(rax, Address(rbx, itableOffsetEntry::interface_offset_in_bytes()));
+  // If the entry is NULL then we've reached the end of the table
+  // without finding the expected interface, so throw an exception
+  __ movl(rdx, Address(rbx, itableOffsetEntry::interface_offset_in_bytes()));
+  __ testl(rdx, rdx);
+  __ jcc(Assembler::zero, throw_icce);
+  __ cmpl(rax, rdx);
   __ jcc(Assembler::notEqual, next);
 
   // We found a hit, move offset into rbx,
@@ -194,7 +186,15 @@
   address ame_addr = __ pc();
   __ jmp(Address(method, methodOopDesc::from_compiled_offset()));
 
+  __ bind(throw_icce);
+  // Restore saved register
+  __ popl(rdx);
+  __ jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry()));
+
   masm->flush();
+
+  guarantee(__ pc() <= s->code_end(), "overflowed buffer");
+
   s->set_exception_points(npe_addr, ame_addr);
   return s;
 }
@@ -207,7 +207,7 @@
     return (DebugVtables ? 210 : 16) + (CountCompiledCalls ? 6 : 0);
   } else {
     // Itable stub size
-    return (DebugVtables ? 140 : 55) + (CountCompiledCalls ? 6 : 0);
+    return (DebugVtables ? 144 : 64) + (CountCompiledCalls ? 6 : 0);
   }
 }
 
--- a/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -153,7 +153,7 @@
     // Round up to align_object_offset boundary
     __ round_to_q(rbx, BytesPerLong);
   }
-  Label hit, next, entry;
+  Label hit, next, entry, throw_icce;
 
   __ jmpb(entry);
 
@@ -162,22 +162,13 @@
 
   __ bind(entry);
 
-#ifdef ASSERT
-    // Check that the entry is non-null
-  if (DebugVtables) {
-    Label L;
-    __ pushq(rbx);
-    __ movq(rbx, Address(rbx, itableOffsetEntry::interface_offset_in_bytes()));
-    __ testq(rbx, rbx);
-    __ jcc(Assembler::notZero, L);
-    __ stop("null entry point found in itable's offset table");
-    __ bind(L);
-    __ popq(rbx);
-  }
-#endif
-
-  __ cmpq(rax, Address(rbx, itableOffsetEntry::interface_offset_in_bytes()));
-  __ jcc(Assembler::notEqual, next);
+  // If the entry is NULL then we've reached the end of the table
+  // without finding the expected interface, so throw an exception
+  __ movq(j_rarg1, Address(rbx, itableOffsetEntry::interface_offset_in_bytes()));
+  __ testq(j_rarg1, j_rarg1);
+  __ jcc(Assembler::zero, throw_icce);
+  __ cmpq(rax, j_rarg1);
+  __ jccb(Assembler::notEqual, next);
 
   // We found a hit, move offset into j_rarg1
   __ movl(j_rarg1, Address(rbx, itableOffsetEntry::offset_offset_in_bytes()));
@@ -203,23 +194,31 @@
 
 
 #ifdef ASSERT
-    if (DebugVtables) {
-      Label L2;
-      __ cmpq(method, (int)NULL);
-      __ jcc(Assembler::equal, L2);
-      __ cmpq(Address(method, methodOopDesc::from_compiled_offset()), (int)NULL_WORD);
-      __ jcc(Assembler::notZero, L2);
-      __ stop("compiler entrypoint is null");
-      __ bind(L2);
-    }
+  if (DebugVtables) {
+    Label L2;
+    __ cmpq(method, (int)NULL);
+    __ jcc(Assembler::equal, L2);
+    __ cmpq(Address(method, methodOopDesc::from_compiled_offset()), (int)NULL_WORD);
+    __ jcc(Assembler::notZero, L2);
+    __ stop("compiler entrypoint is null");
+    __ bind(L2);
+  }
 #endif // ASSERT
 
-    // rbx: methodOop
-    // j_rarg0: receiver
-    address ame_addr = __ pc();
-    __ jmp(Address(method, methodOopDesc::from_compiled_offset()));
+  // rbx: methodOop
+  // j_rarg0: receiver
+  address ame_addr = __ pc();
+  __ jmp(Address(method, methodOopDesc::from_compiled_offset()));
+
+  __ bind(throw_icce);
+  // Restore saved register
+  __ popq(j_rarg1);
+  __ jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry()));
 
   __ flush();
+
+  guarantee(__ pc() <= s->code_end(), "overflowed buffer");
+
   s->set_exception_points(npe_addr, ame_addr);
   return s;
 }
@@ -230,7 +229,7 @@
     return (DebugVtables ? 512 : 24) + (CountCompiledCalls ? 13 : 0);
   } else {
     // Itable stub size
-    return (DebugVtables ? 636 : 64) + (CountCompiledCalls ? 13 : 0);
+    return (DebugVtables ? 636 : 72) + (CountCompiledCalls ? 13 : 0);
   }
 }
 
--- a/hotspot/src/cpu/x86/vm/x86_32.ad	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/cpu/x86/vm/x86_32.ad	Wed Apr 30 07:03:08 2008 -0700
@@ -10970,7 +10970,7 @@
 %}
 
 instruct convI2XD_reg(regXD dst, eRegI src) %{
-  predicate( UseSSE>=2 );
+  predicate( UseSSE>=2 && !UseXmmI2D );
   match(Set dst (ConvI2D src));
   format %{ "CVTSI2SD $dst,$src" %}
   opcode(0xF2, 0x0F, 0x2A);
@@ -10987,6 +10987,20 @@
   ins_pipe( pipe_slow );
 %}
 
+instruct convXI2XD_reg(regXD dst, eRegI src)
+%{
+  predicate( UseSSE>=2 && UseXmmI2D );
+  match(Set dst (ConvI2D src));
+
+  format %{ "MOVD  $dst,$src\n\t"
+            "CVTDQ2PD $dst,$dst\t# i2d" %}
+  ins_encode %{
+    __ movd($dst$$XMMRegister, $src$$Register);
+    __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe(pipe_slow); // XXX
+%}
+
 instruct convI2D_mem(regD dst, memory mem) %{
   predicate( UseSSE<=1 && !Compile::current()->select_24_bit_instr());
   match(Set dst (ConvI2D (LoadI mem)));
@@ -11062,7 +11076,7 @@
 
 // Convert an int to a float in xmm; no rounding step needed.
 instruct convI2X_reg(regX dst, eRegI src) %{
-  predicate(UseSSE>=1);
+  predicate( UseSSE==1 || UseSSE>=2 && !UseXmmI2F );
   match(Set dst (ConvI2F src));
   format %{ "CVTSI2SS $dst, $src" %}
 
@@ -11071,6 +11085,20 @@
   ins_pipe( pipe_slow );
 %}
 
+ instruct convXI2X_reg(regX dst, eRegI src)
+%{
+  predicate( UseSSE>=2 && UseXmmI2F );
+  match(Set dst (ConvI2F src));
+
+  format %{ "MOVD  $dst,$src\n\t"
+            "CVTDQ2PS $dst,$dst\t# i2f" %}
+  ins_encode %{
+    __ movd($dst$$XMMRegister, $src$$Register);
+    __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe(pipe_slow); // XXX
+%}
+
 instruct convI2L_reg( eRegL dst, eRegI src, eFlagsReg cr) %{
   match(Set dst (ConvI2L src));
   effect(KILL cr);
--- a/hotspot/src/cpu/x86/vm/x86_64.ad	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/cpu/x86/vm/x86_64.ad	Wed Apr 30 07:03:08 2008 -0700
@@ -10098,6 +10098,7 @@
 
 instruct convI2F_reg_reg(regF dst, rRegI src)
 %{
+  predicate(!UseXmmI2F);
   match(Set dst (ConvI2F src));
 
   format %{ "cvtsi2ssl $dst, $src\t# i2f" %}
@@ -10118,6 +10119,7 @@
 
 instruct convI2D_reg_reg(regD dst, rRegI src)
 %{
+  predicate(!UseXmmI2D);
   match(Set dst (ConvI2D src));
 
   format %{ "cvtsi2sdl $dst, $src\t# i2d" %}
@@ -10136,6 +10138,34 @@
   ins_pipe(pipe_slow); // XXX
 %}
 
+instruct convXI2F_reg(regF dst, rRegI src)
+%{
+  predicate(UseXmmI2F);
+  match(Set dst (ConvI2F src));
+
+  format %{ "movdl $dst, $src\n\t"
+            "cvtdq2psl $dst, $dst\t# i2f" %}
+  ins_encode %{
+    __ movdl($dst$$XMMRegister, $src$$Register);
+    __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe(pipe_slow); // XXX
+%}
+
+instruct convXI2D_reg(regD dst, rRegI src)
+%{
+  predicate(UseXmmI2D);
+  match(Set dst (ConvI2D src));
+
+  format %{ "movdl $dst, $src\n\t"
+            "cvtdq2pdl $dst, $dst\t# i2d" %}
+  ins_encode %{
+    __ movdl($dst$$XMMRegister, $src$$Register);
+    __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe(pipe_slow); // XXX
+%}
+
 instruct convL2F_reg_reg(regF dst, rRegL src)
 %{
   match(Set dst (ConvL2F src));
--- a/hotspot/src/os/linux/vm/attachListener_linux.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/os/linux/vm/attachListener_linux.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -232,7 +232,7 @@
   // where <ver> is the protocol version (1), <cmd> is the command
   // name ("load", "datadump", ...), and <arg> is an argument
   int expected_str_count = 2 + AttachOperation::arg_count_max;
-  int max_len = (strlen(ver_str) + 1) + (AttachOperation::name_length_max + 1) +
+  const int max_len = (sizeof(ver_str) + 1) + (AttachOperation::name_length_max + 1) +
     AttachOperation::arg_count_max*(AttachOperation::arg_length_max + 1);
 
   char buf[max_len];
--- a/hotspot/src/os/linux/vm/os_linux.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/os/linux/vm/os_linux.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -116,6 +116,20 @@
   return Linux::physical_memory();
 }
 
+julong os::allocatable_physical_memory(julong size) {
+#ifdef _LP64
+  return size;
+#else
+  julong result = MIN2(size, (julong)3800*M);
+   if (!is_allocatable(result)) {
+     // See comments under solaris for alignment considerations
+     julong reasonable_size = (julong)2*G - 2 * os::vm_page_size();
+     result =  MIN2(size, reasonable_size);
+   }
+   return result;
+#endif // _LP64
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // environment support
 
@@ -1247,19 +1261,13 @@
   return (1000 * 1000);
 }
 
-jlong os::timeofday() {
+jlong os::javaTimeMillis() {
   timeval time;
   int status = gettimeofday(&time, NULL);
   assert(status != -1, "linux error");
   return jlong(time.tv_sec) * 1000  +  jlong(time.tv_usec / 1000);
 }
 
-// Must return millis since Jan 1 1970 for JVM_CurrentTimeMillis
-// _use_global_time is only set if CacheTimeMillis is true
-jlong os::javaTimeMillis() {
-  return (_use_global_time ? read_global_time() : timeofday());
-}
-
 #ifndef CLOCK_MONOTONIC
 #define CLOCK_MONOTONIC (1)
 #endif
@@ -2472,6 +2480,10 @@
   return false;
 }
 
+bool os::can_execute_large_page_memory() {
+  return false;
+}
+
 // Reserve memory at an arbitrary address, only if that area is
 // available (and not reserved for something else).
 
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -1691,19 +1691,14 @@
   return (jlong)(nanotime / NANOSECS_PER_MILLISECS);
 }
 
-jlong os::timeofday() {
+// Must return millis since Jan 1 1970 for JVM_CurrentTimeMillis
+jlong os::javaTimeMillis() {
   timeval t;
   if (gettimeofday( &t, NULL) == -1)
-    fatal1("timeofday: gettimeofday (%s)", strerror(errno));
+    fatal1("os::javaTimeMillis: gettimeofday (%s)", strerror(errno));
   return jlong(t.tv_sec) * 1000  +  jlong(t.tv_usec) / 1000;
 }
 
-// Must return millis since Jan 1 1970 for JVM_CurrentTimeMillis
-// _use_global_time is only set if CacheTimeMillis is true
-jlong os::javaTimeMillis() {
-  return (_use_global_time ? read_global_time() : timeofday());
-}
-
 jlong os::javaTimeNanos() {
   return (jlong)getTimeNanos();
 }
@@ -2785,16 +2780,15 @@
   return b;
 }
 
-char*
-os::reserve_memory(size_t bytes, char* requested_addr, size_t alignment_hint) {
-  char* addr = NULL;
-  int   flags;
-
-  flags = MAP_PRIVATE | MAP_NORESERVE;
-  if (requested_addr != NULL) {
-      flags |= MAP_FIXED;
-      addr = requested_addr;
-  } else if (has_map_align && alignment_hint > (size_t) vm_page_size()) {
+char* os::Solaris::anon_mmap(char* requested_addr, size_t bytes, size_t alignment_hint, bool fixed) {
+  char* addr = requested_addr;
+  int flags = MAP_PRIVATE | MAP_NORESERVE;
+
+  assert(!(fixed && (alignment_hint > 0)), "alignment hint meaningless with fixed mmap");
+
+  if (fixed) {
+    flags |= MAP_FIXED;
+  } else if (has_map_align && (alignment_hint > (size_t) vm_page_size())) {
     flags |= MAP_ALIGN;
     addr = (char*) alignment_hint;
   }
@@ -2802,11 +2796,14 @@
   // Map uncommitted pages PROT_NONE so we fail early if we touch an
   // uncommitted page. Otherwise, the read/write might succeed if we
   // have enough swap space to back the physical page.
-  addr = Solaris::mmap_chunk(addr, bytes, flags, PROT_NONE);
+  return mmap_chunk(addr, bytes, flags, PROT_NONE);
+}
+
+char* os::reserve_memory(size_t bytes, char* requested_addr, size_t alignment_hint) {
+  char* addr = Solaris::anon_mmap(requested_addr, bytes, alignment_hint, (requested_addr != NULL));
 
   guarantee(requested_addr == NULL || requested_addr == addr,
             "OS failed to return requested mmap address.");
-
   return addr;
 }
 
@@ -2832,6 +2829,31 @@
   // in one of the methods further up the call chain.  See bug 5044738.
   assert(bytes % os::vm_page_size() == 0, "reserving unexpected size block");
 
+  // Since snv_84, Solaris attempts to honor the address hint - see 5003415.
+  // Give it a try, if the kernel honors the hint we can return immediately.
+  char* addr = Solaris::anon_mmap(requested_addr, bytes, 0, false);
+  volatile int err = errno;
+  if (addr == requested_addr) {
+    return addr;
+  } else if (addr != NULL) {
+    unmap_memory(addr, bytes);
+  }
+
+  if (PrintMiscellaneous && Verbose) {
+    char buf[256];
+    buf[0] = '\0';
+    if (addr == NULL) {
+      jio_snprintf(buf, sizeof(buf), ": %s", strerror(err));
+    }
+    warning("attempt_reserve_memory_at: couldn't reserve %d bytes at "
+            PTR_FORMAT ": reserve_memory_helper returned " PTR_FORMAT
+            "%s", bytes, requested_addr, addr, buf);
+  }
+
+  // Address hint method didn't work.  Fall back to the old method.
+  // In theory, once SNV becomes our oldest supported platform, this
+  // code will no longer be needed.
+  //
   // Repeatedly allocate blocks until the block is allocated at the
   // right spot. Give up after max_tries.
   int i;
@@ -3067,6 +3089,8 @@
   if (UseISM) {
     // ISM disables MPSS to be compatible with old JDK behavior
     UseMPSS = false;
+    _page_sizes[0] = _large_page_size;
+    _page_sizes[1] = vm_page_size();
   }
 
   UseMPSS = UseMPSS &&
@@ -3156,6 +3180,10 @@
   return UseISM ? false : true;
 }
 
+bool os::can_execute_large_page_memory() {
+  return UseISM ? false : true;
+}
+
 static int os_sleep(jlong millis, bool interruptible) {
   const jlong limit = INT_MAX;
   jlong prevtime;
--- a/hotspot/src/os/solaris/vm/os_solaris.hpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/os/solaris/vm/os_solaris.hpp	Wed Apr 30 07:03:08 2008 -0700
@@ -156,6 +156,7 @@
   static int get_dev_zero_fd() { return _dev_zero_fd; }
   static void set_dev_zero_fd(int fd) { _dev_zero_fd = fd; }
   static char* mmap_chunk(char *addr, size_t size, int flags, int prot);
+  static char* anon_mmap(char* requested_addr, size_t bytes, size_t alignment_hint, bool fixed);
   static bool mpss_sanity_check(bool warn, size_t * page_size);
   static bool ism_sanity_check (bool warn, size_t * page_size);
 
--- a/hotspot/src/os/windows/vm/os_windows.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/os/windows/vm/os_windows.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -621,7 +621,12 @@
 }
 
 julong os::allocatable_physical_memory(julong size) {
+#ifdef _LP64
+  return size;
+#else
+  // Limit to 1400m because of the 2gb address space wall
   return MIN2(size, (julong)1400*M);
+#endif
 }
 
 // VC6 lacks DWORD_PTR
@@ -732,20 +737,13 @@
   return result;
 }
 
-jlong os::timeofday() {
-  FILETIME wt;
-  GetSystemTimeAsFileTime(&wt);
-  return windows_to_java_time(wt);
-}
-
-
-// Must return millis since Jan 1 1970 for JVM_CurrentTimeMillis
-// _use_global_time is only set if CacheTimeMillis is true
 jlong os::javaTimeMillis() {
   if (UseFakeTimers) {
     return fake_time++;
   } else {
-    return (_use_global_time ? read_global_time() : timeofday());
+    FILETIME wt;
+    GetSystemTimeAsFileTime(&wt);
+    return windows_to_java_time(wt);
   }
 }
 
@@ -2518,9 +2516,13 @@
   return false;
 }
 
+bool os::can_execute_large_page_memory() {
+  return true;
+}
+
 char* os::reserve_memory_special(size_t bytes) {
   DWORD flag = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES;
-  char * res = (char *)VirtualAlloc(NULL, bytes, flag, PAGE_READWRITE);
+  char * res = (char *)VirtualAlloc(NULL, bytes, flag, PAGE_EXECUTE_READWRITE);
   return res;
 }
 
--- a/hotspot/src/os_cpu/linux_x86/vm/bytes_linux_x86.inline.hpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/os_cpu/linux_x86/vm/bytes_linux_x86.inline.hpp	Wed Apr 30 07:03:08 2008 -0700
@@ -60,7 +60,18 @@
 
 #ifdef AMD64
 inline u8 Bytes::swap_u8(u8 x) {
+#ifdef SPARC_WORKS
+  // workaround for SunStudio12 CR6615391
+  __asm__ __volatile__ (
+    "bswapq %0"
+    :"=r" (x)        // output : register 0 => x
+    :"0"  (x)        // input  : x => register 0
+    :"0"             // clobbered register
+  );
+  return x;
+#else
   return bswap_64(x);
+#endif
 }
 #else
 // Helper function for swap_u8
--- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -62,8 +62,14 @@
 #endif // AMD64
 
 address os::current_stack_pointer() {
+#ifdef SPARC_WORKS
+  register void *esp;
+  __asm__("mov %%"SPELL_REG_SP", %0":"=r"(esp));
+  return (address) ((char*)esp + sizeof(long)*2);
+#else
   register void *esp __asm__ (SPELL_REG_SP);
   return (address) esp;
+#endif
 }
 
 char* os::non_memory_address_word() {
@@ -139,7 +145,12 @@
 }
 
 intptr_t* _get_previous_fp() {
+#ifdef SPARC_WORKS
+  register intptr_t **ebp;
+  __asm__("mov %%"SPELL_REG_FP", %0":"=r"(ebp));
+#else
   register intptr_t **ebp __asm__ (SPELL_REG_FP);
+#endif
   return (intptr_t*) *ebp;   // we want what it points to.
 }
 
@@ -157,23 +168,8 @@
   }
 }
 
-
 // Utility functions
 
-julong os::allocatable_physical_memory(julong size) {
-#ifdef AMD64
-  return size;
-#else
-  julong result = MIN2(size, (julong)3800*M);
-   if (!is_allocatable(result)) {
-     // See comments under solaris for alignment considerations
-     julong reasonable_size = (julong)2*G - 2 * os::vm_page_size();
-     result =  MIN2(size, reasonable_size);
-   }
-   return result;
-#endif // AMD64
-}
-
 // From IA32 System Programming Guide
 enum {
   trap_page_fault = 0xE
@@ -575,7 +571,9 @@
 #else
 size_t os::Linux::min_stack_allowed  =  (48 DEBUG_ONLY(+4))*K;
 
+#ifdef __GNUC__
 #define GET_GS() ({int gs; __asm__ volatile("movw %%gs, %w0":"=q"(gs)); gs&0xffff;})
+#endif
 
 // Test if pthread library can support variable thread stack size. LinuxThreads
 // in fixed stack mode allocates 2M fixed slot for each thread. LinuxThreads
@@ -606,7 +604,11 @@
     // return true and skip _thread_safety_check(), so we may not be able to
     // detect stack-heap collisions. But otherwise it's harmless.
     //
+#ifdef __GNUC__
     return (GET_GS() != 0);
+#else
+    return false;
+#endif
   }
 }
 #endif // AMD64
--- a/hotspot/src/share/vm/c1/c1_LIR.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/c1/c1_LIR.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -105,7 +105,7 @@
 
 
 LIR_Address::Scale LIR_Address::scale(BasicType type) {
-  int elem_size = type2aelembytes[type];
+  int elem_size = type2aelembytes(type);
   switch (elem_size) {
   case 1: return LIR_Address::times_1;
   case 2: return LIR_Address::times_2;
--- a/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -104,7 +104,7 @@
 };
 
 void BCEscapeAnalyzer::set_returned(ArgumentMap vars) {
-  for (int i = 0; i <= _arg_size; i++) {
+  for (int i = 0; i < _arg_size; i++) {
     if (vars.contains(i))
       _arg_returned.set_bit(i);
   }
@@ -112,10 +112,9 @@
   _return_allocated = _return_allocated && vars.contains_allocated() && !(vars.contains_unknown() || vars.contains_vars());
 }
 
-
 // return true if any element of vars is an argument
 bool BCEscapeAnalyzer::is_argument(ArgumentMap vars) {
-  for (int i = 0; i <= _arg_size; i++) {
+  for (int i = 0; i < _arg_size; i++) {
     if (vars.contains(i))
       return true;
   }
@@ -126,7 +125,7 @@
 bool BCEscapeAnalyzer::is_arg_stack(ArgumentMap vars){
   if (_conservative)
     return true;
-  for (int i = 0; i <= _arg_size; i++) {
+  for (int i = 0; i < _arg_size; i++) {
     if (vars.contains(i) && _arg_stack.at(i))
       return true;
   }
@@ -134,12 +133,13 @@
 }
 
 void BCEscapeAnalyzer::clear_bits(ArgumentMap vars, BitMap &bm) {
-  for (int i = 0; i <= _arg_size; i++) {
+  for (int i = 0; i < _arg_size; i++) {
     if (vars.contains(i)) {
       bm.clear_bit(i);
     }
   }
 }
+
 void BCEscapeAnalyzer::set_method_escape(ArgumentMap vars) {
   clear_bits(vars, _arg_local);
 }
@@ -155,6 +155,17 @@
   clear_bits(vars, _dirty);
 }
 
+void BCEscapeAnalyzer::set_modified(ArgumentMap vars, int offs, int size) {
+
+  for (int i = 0; i < _arg_size; i++) {
+    if (vars.contains(i)) {
+      set_arg_modified(i, offs, size);
+    }
+  }
+  if (vars.contains_unknown())
+    _unknown_modified = true;
+}
+
 bool BCEscapeAnalyzer::is_recursive_call(ciMethod* callee) {
   for (BCEscapeAnalyzer* scope = this; scope != NULL; scope = scope->_parent) {
     if (scope->method() == callee) {
@@ -164,6 +175,40 @@
   return false;
 }
 
+bool BCEscapeAnalyzer::is_arg_modified(int arg, int offset, int size_in_bytes) {
+  if (offset == OFFSET_ANY)
+    return _arg_modified[arg] != 0;
+  assert(arg >= 0 && arg < _arg_size, "must be an argument.");
+  bool modified = false;
+  int l = offset / HeapWordSize;
+  int h = round_to(offset + size_in_bytes, HeapWordSize) / HeapWordSize;
+  if (l > ARG_OFFSET_MAX)
+    l = ARG_OFFSET_MAX;
+  if (h > ARG_OFFSET_MAX+1)
+    h = ARG_OFFSET_MAX + 1;
+  for (int i = l; i < h; i++) {
+    modified = modified || (_arg_modified[arg] & (1 << i)) != 0;
+  }
+  return modified;
+}
+
+void BCEscapeAnalyzer::set_arg_modified(int arg, int offset, int size_in_bytes) {
+  if (offset == OFFSET_ANY) {
+    _arg_modified[arg] =  (uint) -1;
+    return;
+  }
+  assert(arg >= 0 && arg < _arg_size, "must be an argument.");
+  int l = offset / HeapWordSize;
+  int h = round_to(offset + size_in_bytes, HeapWordSize) / HeapWordSize;
+  if (l > ARG_OFFSET_MAX)
+    l = ARG_OFFSET_MAX;
+  if (h > ARG_OFFSET_MAX+1)
+    h = ARG_OFFSET_MAX + 1;
+  for (int i = l; i < h; i++) {
+    _arg_modified[arg] |= (1 << i);
+  }
+}
+
 void BCEscapeAnalyzer::invoke(StateInfo &state, Bytecodes::Code code, ciMethod* target, ciKlass* holder) {
   int i;
 
@@ -197,6 +242,7 @@
     for (i = 0; i < arg_size; i++) {
       set_method_escape(state.raw_pop());
     }
+    _unknown_modified = true;  // assume the worst since we don't analyze the called method
     return;
   }
 
@@ -224,6 +270,11 @@
       ArgumentMap arg = state.raw_pop();
       if (!is_argument(arg))
         continue;
+      for (int j = 0; j < _arg_size; j++) {
+        if (arg.contains(j)) {
+          _arg_modified[j] |= analyzer._arg_modified[i];
+        }
+      }
       if (!is_arg_stack(arg)) {
         // arguments have already been recognized as escaping
       } else if (analyzer.is_arg_stack(i) && !analyzer.is_arg_returned(i)) {
@@ -233,6 +284,7 @@
         set_global_escape(arg);
       }
     }
+    _unknown_modified = _unknown_modified || analyzer.has_non_arg_side_affects();
 
     // record dependencies if at least one parameter retained stack-allocatable
     if (must_record_dependencies) {
@@ -250,8 +302,10 @@
       ArgumentMap arg = state.raw_pop();
       if (!is_argument(arg))
         continue;
+      set_modified(arg, OFFSET_ANY, type2size[T_INT]*HeapWordSize);
       set_global_escape(arg);
     }
+    _unknown_modified = true;  // assume the worst since we don't know the called method
   }
 }
 
@@ -421,6 +475,7 @@
         state.spop();
         ArgumentMap arr = state.apop();
         set_method_escape(arr);
+        set_modified(arr, OFFSET_ANY, type2size[T_INT]*HeapWordSize);
         break;
       }
       case Bytecodes::_lastore:
@@ -430,6 +485,7 @@
         state.spop();
         ArgumentMap arr = state.apop();
         set_method_escape(arr);
+        set_modified(arr, OFFSET_ANY, type2size[T_LONG]*HeapWordSize);
         break;
       }
       case Bytecodes::_aastore:
@@ -437,6 +493,7 @@
         set_global_escape(state.apop());
         state.spop();
         ArgumentMap arr = state.apop();
+        set_modified(arr, OFFSET_ANY, type2size[T_OBJECT]*HeapWordSize);
         break;
       }
       case Bytecodes::_pop:
@@ -762,6 +819,7 @@
           if (s.cur_bc() != Bytecodes::_putstatic) {
             ArgumentMap p = state.apop();
             set_method_escape(p);
+            set_modified(p, will_link ? field->offset() : OFFSET_ANY, type2size[field_type]*HeapWordSize);
           }
         }
         break;
@@ -872,7 +930,7 @@
 }
 
 void BCEscapeAnalyzer::merge_block_states(StateInfo *blockstates, ciBlock *dest, StateInfo *s_state) {
-  StateInfo *d_state = blockstates+dest->index();
+  StateInfo *d_state = blockstates + dest->index();
   int nlocals = _method->max_locals();
 
   // exceptions may cause transfer of control to handlers in the middle of a
@@ -916,6 +974,7 @@
     }
     for (int i = 0; i < s_state->_stack_height; i++) {
       ArgumentMap t;
+      //extra_vars |= !d_state->_vars[i] & s_state->_vars[i];
       t.clear();
       t = s_state->_stack[i];
       t.set_difference(d_state->_stack[i]);
@@ -933,7 +992,7 @@
 
   int datacount = (numblocks + 1) * (stkSize + numLocals);
   int datasize = datacount * sizeof(ArgumentMap);
-  StateInfo *blockstates = (StateInfo *) arena->Amalloc(_methodBlocks->num_blocks() * sizeof(StateInfo));
+  StateInfo *blockstates = (StateInfo *) arena->Amalloc(numblocks * sizeof(StateInfo));
   ArgumentMap *statedata  = (ArgumentMap *) arena->Amalloc(datasize);
   for (int i = 0; i < datacount; i++) ::new ((void*)&statedata[i]) ArgumentMap();
   ArgumentMap *dp = statedata;
@@ -961,33 +1020,35 @@
   ArgumentMap allVars;   // all oop arguments to method
   ciSignature* sig = method()->signature();
   int j = 0;
+  ciBlock* first_blk = _methodBlocks->block_containing(0);
+  int fb_i = first_blk->index();
   if (!method()->is_static()) {
     // record information for "this"
-    blockstates[0]._vars[j].set(j);
+    blockstates[fb_i]._vars[j].set(j);
     allVars.add(j);
     j++;
   }
   for (int i = 0; i < sig->count(); i++) {
     ciType* t = sig->type_at(i);
     if (!t->is_primitive_type()) {
-      blockstates[0]._vars[j].set(j);
+      blockstates[fb_i]._vars[j].set(j);
       allVars.add(j);
     }
     j += t->size();
   }
-  blockstates[0]._initialized = true;
+  blockstates[fb_i]._initialized = true;
   assert(j == _arg_size, "just checking");
 
   ArgumentMap unknown_map;
   unknown_map.add_unknown();
 
-  worklist.push(_methodBlocks->block_containing(0));
+  worklist.push(first_blk);
   while(worklist.length() > 0) {
     ciBlock *blk = worklist.pop();
-    StateInfo *blkState = blockstates+blk->index();
+    StateInfo *blkState = blockstates + blk->index();
     if (blk->is_handler() || blk->is_ret_target()) {
       // for an exception handler or a target of a ret instruction, we assume the worst case,
-      // that any variable or stack slot could contain any argument
+      // that any variable could contain any argument
       for (int i = 0; i < numLocals; i++) {
         state._vars[i] = allVars;
       }
@@ -997,6 +1058,7 @@
         state._stack_height = blkState->_stack_height;
       }
       for (int i = 0; i < state._stack_height; i++) {
+// ??? should this be unknown_map ???
         state._stack[i] = allVars;
       }
     } else {
@@ -1053,6 +1115,7 @@
   vmIntrinsics::ID iid = method()->intrinsic_id();
 
   if (iid == vmIntrinsics::_getClass ||
+      iid ==  vmIntrinsics::_fillInStackTrace ||
       iid == vmIntrinsics::_hashCode)
     return iid;
   else
@@ -1060,12 +1123,16 @@
 }
 
 bool BCEscapeAnalyzer::compute_escape_for_intrinsic(vmIntrinsics::ID iid) {
-  ArgumentMap empty;
-  empty.clear();
+  ArgumentMap arg;
+  arg.clear();
   switch (iid) {
   case vmIntrinsics::_getClass:
     _return_local = false;
     break;
+  case vmIntrinsics::_fillInStackTrace:
+    arg.set(0); // 'this'
+    set_returned(arg);
+    break;
   case vmIntrinsics::_hashCode:
     // initialized state is correct
     break;
@@ -1109,15 +1176,21 @@
     _return_allocated = true;
   }
   _allocated_escapes = false;
+  _unknown_modified = false;
 }
 
 void BCEscapeAnalyzer::clear_escape_info() {
   ciSignature* sig = method()->signature();
   int arg_count = sig->count();
   ArgumentMap var;
+  if (!method()->is_static()) {
+    arg_count++;  // allow for "this"
+  }
   for (int i = 0; i < arg_count; i++) {
+    set_arg_modified(i, OFFSET_ANY, 4);
     var.clear();
     var.set(i);
+    set_modified(var, OFFSET_ANY, 4);
     set_global_escape(var);
   }
   _arg_local.clear();
@@ -1126,6 +1199,7 @@
   _return_local = false;
   _return_allocated = false;
   _allocated_escapes = true;
+  _unknown_modified = true;
 }
 
 
@@ -1173,8 +1247,14 @@
 
   initialize();
 
-  // do not scan method if it has no object parameters
-  if (_arg_local.is_empty()) {
+  // Do not scan method if it has no object parameters and
+  // does not returns an object (_return_allocated is set in initialize()).
+  if (_arg_local.is_empty() && !_return_allocated) {
+    // Clear all info since method's bytecode was not analysed and
+    // set pessimistic escape information.
+    clear_escape_info();
+    methodData()->set_eflag(methodDataOopDesc::allocated_escapes);
+    methodData()->set_eflag(methodDataOopDesc::unknown_modified);
     methodData()->set_eflag(methodDataOopDesc::estimated);
     return;
   }
@@ -1185,36 +1265,8 @@
     success = do_analysis();
   }
 
-  // dump result of bytecode analysis
-#ifndef PRODUCT
-  if (BCEATraceLevel >= 3) {
-    tty->print("[EA] estimated escape information for");
-    if (iid != vmIntrinsics::_none)
-      tty->print(" intrinsic");
-    method()->print_short_name();
-    tty->print_cr(has_dependencies() ? " (not stored)" : "");
-    tty->print("     non-escaping args:      ");
-    _arg_local.print_on(tty);
-    tty->print("     stack-allocatable args: ");
-    _arg_stack.print_on(tty);
-    if (_return_local) {
-      tty->print("     returned args:          ");
-      _arg_returned.print_on(tty);
-    } else if (is_return_allocated()) {
-      tty->print_cr("     allocated return values");
-    } else {
-      tty->print_cr("     non-local return values");
-    }
-    tty->cr();
-    tty->print("     flags: ");
-    if (_return_allocated)
-      tty->print(" return_allocated");
-    tty->cr();
-  }
-
-#endif
-  // don't store interprocedural escape information if it introduces dependencies
-  // or if method data is empty
+  // don't store interprocedural escape information if it introduces
+  // dependencies or if method data is empty
   //
   if (!has_dependencies() && !methodData()->is_empty()) {
     for (i = 0; i < _arg_size; i++) {
@@ -1228,10 +1280,20 @@
       if (_arg_returned.at(i)) {
         methodData()->set_arg_returned(i);
       }
+      methodData()->set_arg_modified(i, _arg_modified[i]);
     }
     if (_return_local) {
       methodData()->set_eflag(methodDataOopDesc::return_local);
     }
+    if (_return_allocated) {
+      methodData()->set_eflag(methodDataOopDesc::return_allocated);
+    }
+    if (_allocated_escapes) {
+      methodData()->set_eflag(methodDataOopDesc::allocated_escapes);
+    }
+    if (_unknown_modified) {
+      methodData()->set_eflag(methodDataOopDesc::unknown_modified);
+    }
     methodData()->set_eflag(methodDataOopDesc::estimated);
   }
 }
@@ -1244,29 +1306,50 @@
     _arg_local.at_put(i, methodData()->is_arg_local(i));
     _arg_stack.at_put(i, methodData()->is_arg_stack(i));
     _arg_returned.at_put(i, methodData()->is_arg_returned(i));
+    _arg_modified[i] = methodData()->arg_modified(i);
   }
   _return_local = methodData()->eflag_set(methodDataOopDesc::return_local);
-
-  // dump result of loaded escape information
-#ifndef PRODUCT
-  if (BCEATraceLevel >= 4) {
-    tty->print("     non-escaping args:      ");
-    _arg_local.print_on(tty);
-    tty->print("     stack-allocatable args: ");
-    _arg_stack.print_on(tty);
-    if (_return_local) {
-      tty->print("     returned args:          ");
-      _arg_returned.print_on(tty);
-    } else {
-      tty->print_cr("     non-local return values");
-    }
-    tty->print("     modified args: ");
-    tty->cr();
-  }
-#endif
+  _return_allocated = methodData()->eflag_set(methodDataOopDesc::return_allocated);
+  _allocated_escapes = methodData()->eflag_set(methodDataOopDesc::allocated_escapes);
+  _unknown_modified = methodData()->eflag_set(methodDataOopDesc::unknown_modified);
 
 }
 
+#ifndef PRODUCT
+void BCEscapeAnalyzer::dump() {
+  tty->print("[EA] estimated escape information for");
+  method()->print_short_name();
+  tty->print_cr(has_dependencies() ? " (not stored)" : "");
+  tty->print("     non-escaping args:      ");
+  _arg_local.print_on(tty);
+  tty->print("     stack-allocatable args: ");
+  _arg_stack.print_on(tty);
+  if (_return_local) {
+    tty->print("     returned args:          ");
+    _arg_returned.print_on(tty);
+  } else if (is_return_allocated()) {
+    tty->print_cr("     return allocated value");
+  } else {
+    tty->print_cr("     return non-local value");
+  }
+  tty->print("     modified args: ");
+  for (int i = 0; i < _arg_size; i++) {
+    if (_arg_modified[i] == 0)
+      tty->print("    0");
+    else
+      tty->print("    0x%x", _arg_modified[i]);
+  }
+  tty->cr();
+  tty->print("     flags: ");
+  if (_return_allocated)
+    tty->print(" return_allocated");
+  if (_allocated_escapes)
+    tty->print(" allocated_escapes");
+  if (_unknown_modified)
+    tty->print(" unknown_modified");
+  tty->cr();
+}
+#endif
 
 BCEscapeAnalyzer::BCEscapeAnalyzer(ciMethod* method, BCEscapeAnalyzer* parent)
     : _conservative(method == NULL || !EstimateArgEscape)
@@ -1281,6 +1364,7 @@
     , _return_local(false)
     , _return_allocated(false)
     , _allocated_escapes(false)
+    , _unknown_modified(false)
     , _dependencies()
     , _parent(parent)
     , _level(parent == NULL ? 0 : parent->level() + 1) {
@@ -1290,6 +1374,8 @@
     _arg_returned.clear();
     _dirty.clear();
     Arena* arena = CURRENT_ENV->arena();
+    _arg_modified = (uint *) arena->Amalloc(_arg_size * sizeof(uint));
+    Copy::zero_to_bytes(_arg_modified, _arg_size * sizeof(uint));
 
     if (methodData() == NULL)
       return;
@@ -1307,6 +1393,12 @@
       compute_escape_info();
       methodData()->update_escape_info();
     }
+#ifndef PRODUCT
+    if (BCEATraceLevel >= 3) {
+      // dump escape information
+      dump();
+    }
+#endif
   }
 }
 
--- a/hotspot/src/share/vm/ci/bcEscapeAnalyzer.hpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/ci/bcEscapeAnalyzer.hpp	Wed Apr 30 07:03:08 2008 -0700
@@ -46,10 +46,13 @@
   BitMap            _arg_stack;
   BitMap            _arg_returned;
   BitMap            _dirty;
+  enum{ ARG_OFFSET_MAX = 31};
+  uint              *_arg_modified;
 
   bool              _return_local;
+  bool              _return_allocated;
   bool              _allocated_escapes;
-  bool              _return_allocated;
+  bool              _unknown_modified;
 
   ciObjectList     _dependencies;
 
@@ -80,6 +83,7 @@
   void set_method_escape(ArgumentMap vars);
   void set_global_escape(ArgumentMap vars);
   void set_dirty(ArgumentMap vars);
+  void set_modified(ArgumentMap vars, int offs, int size);
 
   bool is_recursive_call(ciMethod* callee);
   void add_dependence(ciKlass *klass, ciMethod *meth);
@@ -140,6 +144,18 @@
     return !_conservative && _return_allocated && !_allocated_escapes;
   }
 
+  // Tracking of argument modification
+
+  enum {OFFSET_ANY = -1};
+  bool is_arg_modified(int arg, int offset, int size_in_bytes);
+  void set_arg_modified(int arg, int offset, int size_in_bytes);
+  bool has_non_arg_side_affects()    { return _unknown_modified; }
+
   // Copy dependencies from this analysis into "deps"
   void copy_dependencies(Dependencies *deps);
+
+#ifndef PRODUCT
+  // dump escape information
+  void dump();
+#endif
 };
--- a/hotspot/src/share/vm/ci/ciField.hpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/ci/ciField.hpp	Wed Apr 30 07:03:08 2008 -0700
@@ -102,7 +102,7 @@
   BasicType layout_type() { return type2field[(_type == NULL) ? T_OBJECT : _type->basic_type()]; }
 
   // How big is this field in memory?
-  int size_in_bytes() { return type2aelembytes[layout_type()]; }
+  int size_in_bytes() { return type2aelembytes(layout_type()); }
 
   // What is the offset of this field?
   int offset() {
--- a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -34,7 +34,9 @@
 // ciInstanceKlass::ciInstanceKlass
 //
 // Loaded instance klass.
-ciInstanceKlass::ciInstanceKlass(KlassHandle h_k) : ciKlass(h_k) {
+ciInstanceKlass::ciInstanceKlass(KlassHandle h_k) :
+  ciKlass(h_k), _non_static_fields(NULL)
+{
   assert(get_Klass()->oop_is_instance(), "wrong type");
   instanceKlass* ik = get_instanceKlass();
 
@@ -335,6 +337,37 @@
   return field;
 }
 
+// ------------------------------------------------------------------
+// ciInstanceKlass::non_static_fields.
+
+class NonStaticFieldFiller: public FieldClosure {
+  GrowableArray<ciField*>* _arr;
+  ciEnv* _curEnv;
+public:
+  NonStaticFieldFiller(ciEnv* curEnv, GrowableArray<ciField*>* arr) :
+    _curEnv(curEnv), _arr(arr)
+  {}
+  void do_field(fieldDescriptor* fd) {
+    ciField* field = new (_curEnv->arena()) ciField(fd);
+    _arr->append(field);
+  }
+};
+
+GrowableArray<ciField*>* ciInstanceKlass::non_static_fields() {
+  if (_non_static_fields == NULL) {
+    VM_ENTRY_MARK;
+    ciEnv* curEnv = ciEnv::current();
+    instanceKlass* ik = get_instanceKlass();
+    int max_n_fields = ik->fields()->length()/instanceKlass::next_offset;
+
+    _non_static_fields =
+      new (curEnv->arena()) GrowableArray<ciField*>(max_n_fields);
+    NonStaticFieldFiller filler(curEnv, _non_static_fields);
+    ik->do_nonstatic_fields(&filler);
+  }
+  return _non_static_fields;
+}
+
 static int sort_field_by_offset(ciField** a, ciField** b) {
   return (*a)->offset_in_bytes() - (*b)->offset_in_bytes();
   // (no worries about 32-bit overflow...)
--- a/hotspot/src/share/vm/ci/ciInstanceKlass.hpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/ci/ciInstanceKlass.hpp	Wed Apr 30 07:03:08 2008 -0700
@@ -46,6 +46,7 @@
   bool                   _has_subklass;
   ciFlags                _flags;
   jint                   _nonstatic_field_size;
+  jint                   _nonstatic_oop_map_size;
 
   // Lazy fields get filled in only upon request.
   ciInstanceKlass*       _super;
@@ -58,6 +59,8 @@
   ciInstanceKlass*       _implementors[implementors_limit];
   jint                   _nof_implementors;
 
+  GrowableArray<ciField*>* _non_static_fields;
+
 protected:
   ciInstanceKlass(KlassHandle h_k);
   ciInstanceKlass(ciSymbol* name, jobject loader, jobject protection_domain);
@@ -129,6 +132,9 @@
   jint                   nonstatic_field_size()  {
     assert(is_loaded(), "must be loaded");
     return _nonstatic_field_size; }
+  jint                   nonstatic_oop_map_size()  {
+    assert(is_loaded(), "must be loaded");
+    return _nonstatic_oop_map_size; }
   ciInstanceKlass*       super();
   jint                   nof_implementors()  {
     assert(is_loaded(), "must be loaded");
@@ -138,6 +144,9 @@
 
   ciInstanceKlass* get_canonical_holder(int offset);
   ciField* get_field_by_offset(int field_offset, bool is_static);
+
+  GrowableArray<ciField*>* non_static_fields();
+
   // total number of nonstatic fields (including inherited):
   int nof_nonstatic_fields() {
     if (_nonstatic_fields == NULL)
--- a/hotspot/src/share/vm/ci/ciMethod.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/ci/ciMethod.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -146,7 +146,7 @@
   memcpy(_code, me->code_base(), code_size());
 
   // Revert any breakpoint bytecodes in ci's copy
-  if (_is_compilable && me->number_of_breakpoints() > 0) {
+  if (me->number_of_breakpoints() > 0) {
     BreakpointInfo* bp = instanceKlass::cast(me->method_holder())->breakpoints();
     for (; bp != NULL; bp = bp->next()) {
       if (bp->match(me)) {
--- a/hotspot/src/share/vm/ci/ciMethodBlocks.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/ci/ciMethodBlocks.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -67,6 +67,14 @@
       break;
     }
   }
+  // Move an exception handler information if needed.
+  if (former_block->is_handler()) {
+    int ex_start = former_block->ex_start_bci();
+    int ex_end = former_block->ex_limit_bci();
+    new_block->set_exception_range(ex_start, ex_end);
+    // Clear information in former_block.
+    former_block->clear_exception_handler();
+  }
   return former_block;
 }
 
@@ -102,7 +110,7 @@
     // one and end the old one.
     assert(cur_block != NULL, "must always have a current block");
     ciBlock *new_block = block_containing(bci);
-    if (new_block == NULL) {
+    if (new_block == NULL || new_block == cur_block) {
       // We have not marked this bci as the start of a new block.
       // Keep interpreting the current_range.
       _bci_to_block[bci] = cur_block;
@@ -254,9 +262,33 @@
     for(ciExceptionHandlerStream str(meth); !str.is_done(); str.next()) {
       ciExceptionHandler* handler = str.handler();
       ciBlock *eb = make_block_at(handler->handler_bci());
-      eb->set_handler();
+      //
+      // Several exception handlers can have the same handler_bci:
+      //
+      //  try {
+      //    if (a.foo(b) < 0) {
+      //      return a.error();
+      //    }
+      //    return CoderResult.UNDERFLOW;
+      //  } finally {
+      //      a.position(b);
+      //  }
+      //
+      //  The try block above is divided into 2 exception blocks
+      //  separated by 'areturn' bci.
+      //
       int ex_start = handler->start();
       int ex_end = handler->limit();
+      if (eb->is_handler()) {
+        // Extend old handler exception range to cover additional range.
+        int old_ex_start = eb->ex_start_bci();
+        int old_ex_end   = eb->ex_limit_bci();
+        if (ex_start > old_ex_start)
+          ex_start = old_ex_start;
+        if (ex_end < old_ex_end)
+          ex_end = old_ex_end;
+        eb->clear_exception_handler(); // Reset exception information
+      }
       eb->set_exception_range(ex_start, ex_end);
       // ensure a block at the start of exception range and start of following code
       (void) make_block_at(ex_start);
@@ -312,9 +344,10 @@
 
 void ciBlock::set_exception_range(int start_bci, int limit_bci)  {
    assert(limit_bci >= start_bci, "valid range");
-   assert(is_handler(), "must be handler");
+   assert(!is_handler() && _ex_start_bci == -1 && _ex_limit_bci == -1, "must not be handler");
    _ex_start_bci = start_bci;
    _ex_limit_bci = limit_bci;
+   set_handler();
 }
 
 #ifndef PRODUCT
--- a/hotspot/src/share/vm/ci/ciMethodBlocks.hpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/ci/ciMethodBlocks.hpp	Wed Apr 30 07:03:08 2008 -0700
@@ -110,9 +110,10 @@
   void  set_does_jsr()              { _flags |= DoesJsr; }
   void  clear_does_jsr()            { _flags &= ~DoesJsr; }
   void  set_does_ret()              { _flags |= DoesRet; }
-  void  clear_does_ret()            { _flags |= DoesRet; }
+  void  clear_does_ret()            { _flags &= ~DoesRet; }
   void  set_is_ret_target()         { _flags |= RetTarget; }
   void  set_has_handler()           { _flags |= HasHandler; }
+  void  clear_exception_handler()   { _flags &= ~Handler; _ex_start_bci = -1; _ex_limit_bci = -1; }
 #ifndef PRODUCT
   ciMethod *method() const          { return _method; }
   void dump();
--- a/hotspot/src/share/vm/ci/ciMethodData.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/ci/ciMethodData.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -42,6 +42,8 @@
   // Set an initial hint. Don't use set_hint_di() because
   // first_di() may be out of bounds if data_size is 0.
   _hint_di = first_di();
+  // Initialize the escape information (to "don't know.");
+  _eflags = _arg_local = _arg_stack = _arg_returned = 0;
 }
 
 // ------------------------------------------------------------------
@@ -59,6 +61,8 @@
   // Set an initial hint. Don't use set_hint_di() because
   // first_di() may be out of bounds if data_size is 0.
   _hint_di = first_di();
+  // Initialize the escape information (to "don't know.");
+  _eflags = _arg_local = _arg_stack = _arg_returned = 0;
 }
 
 void ciMethodData::load_data() {
@@ -142,6 +146,8 @@
     return new ciBranchData(data_layout);
   case DataLayout::multi_branch_data_tag:
     return new ciMultiBranchData(data_layout);
+  case DataLayout::arg_info_data_tag:
+    return new ciArgInfoData(data_layout);
   };
 }
 
@@ -172,6 +178,9 @@
       _saw_free_extra_data = true;  // observed an empty slot (common case)
       return NULL;
     }
+    if (dp->tag() == DataLayout::arg_info_data_tag) {
+      break; // ArgInfoData is at the end of extra data section.
+    }
     if (dp->bci() == bci) {
       assert(dp->tag() == DataLayout::bit_data_tag, "sane");
       return new ciBitData(dp);
@@ -217,8 +226,14 @@
 void ciMethodData::clear_escape_info() {
   VM_ENTRY_MARK;
   methodDataOop mdo = get_methodDataOop();
-  if (mdo != NULL)
+  if (mdo != NULL) {
     mdo->clear_escape_info();
+    ArgInfoData *aid = arg_info();
+    int arg_count = (aid == NULL) ? 0 : aid->number_of_args();
+    for (int i = 0; i < arg_count; i++) {
+      set_arg_modified(i, 0);
+    }
+  }
   _eflags = _arg_local = _arg_stack = _arg_returned = 0;
 }
 
@@ -231,6 +246,10 @@
     mdo->set_arg_local(_arg_local);
     mdo->set_arg_stack(_arg_stack);
     mdo->set_arg_returned(_arg_returned);
+    int arg_count = mdo->method()->size_of_parameters();
+    for (int i = 0; i < arg_count; i++) {
+      mdo->set_arg_modified(i, arg_modified(i));
+    }
   }
 }
 
@@ -262,6 +281,14 @@
   set_nth_bit(_arg_returned, i);
 }
 
+void ciMethodData::set_arg_modified(int arg, uint val) {
+  ArgInfoData *aid = arg_info();
+  if (aid == NULL)
+    return;
+  assert(arg >= 0 && arg < aid->number_of_args(), "valid argument number");
+  aid->set_arg_modified(arg, val);
+}
+
 bool ciMethodData::is_arg_local(int i) const {
   return is_set_nth_bit(_arg_local, i);
 }
@@ -274,6 +301,14 @@
   return is_set_nth_bit(_arg_returned, i);
 }
 
+uint ciMethodData::arg_modified(int arg) const {
+  ArgInfoData *aid = arg_info();
+  if (aid == NULL)
+    return 0;
+  assert(arg >= 0 && arg < aid->number_of_args(), "valid argument number");
+  return aid->arg_modified(arg);
+}
+
 ByteSize ciMethodData::offset_of_slot(ciProfileData* data, ByteSize slot_offset_in_data) {
   // Get offset within methodDataOop of the data array
   ByteSize data_offset = methodDataOopDesc::data_offset();
@@ -287,6 +322,18 @@
   return in_ByteSize(offset);
 }
 
+ciArgInfoData *ciMethodData::arg_info() const {
+  // Should be last, have to skip all traps.
+  DataLayout* dp  = data_layout_at(data_size());
+  DataLayout* end = data_layout_at(data_size() + extra_data_size());
+  for (; dp < end; dp = methodDataOopDesc::next_extra(dp)) {
+    if (dp->tag() == DataLayout::arg_info_data_tag)
+      return new ciArgInfoData(dp);
+  }
+  return NULL;
+}
+
+
 // Implementation of the print method.
 void ciMethodData::print_impl(outputStream* st) {
   ciObject::print_impl(st);
@@ -305,6 +352,22 @@
     st->fill_to(6);
     data->print_data_on(st);
   }
+  st->print_cr("--- Extra data:");
+  DataLayout* dp  = data_layout_at(data_size());
+  DataLayout* end = data_layout_at(data_size() + extra_data_size());
+  for (; dp < end; dp = methodDataOopDesc::next_extra(dp)) {
+    if (dp->tag() == DataLayout::no_tag)  continue;
+    if (dp->tag() == DataLayout::bit_data_tag) {
+      data = new BitData(dp);
+    } else {
+      assert(dp->tag() == DataLayout::arg_info_data_tag, "must be BitData or ArgInfo");
+      data = new ciArgInfoData(dp);
+      dp = end; // ArgInfoData is at the end of extra data section.
+    }
+    st->print("%d", dp_to_di(data->dp()));
+    st->fill_to(6);
+    data->print_data_on(st);
+  }
 }
 
 void ciReceiverTypeData::print_receiver_data_on(outputStream* st) {
--- a/hotspot/src/share/vm/ci/ciMethodData.hpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/ci/ciMethodData.hpp	Wed Apr 30 07:03:08 2008 -0700
@@ -30,6 +30,7 @@
 class ciBranchData;
 class ciArrayData;
 class ciMultiBranchData;
+class ciArgInfoData;
 
 typedef ProfileData ciProfileData;
 
@@ -121,6 +122,11 @@
   ciMultiBranchData(DataLayout* layout) : MultiBranchData(layout) {};
 };
 
+class ciArgInfoData : public ArgInfoData {
+public:
+  ciArgInfoData(DataLayout* layout) : ArgInfoData(layout) {};
+};
+
 // ciMethodData
 //
 // This class represents a methodDataOop in the HotSpot virtual
@@ -163,9 +169,9 @@
   ciMethodData();
 
   // Accessors
-  int data_size() { return _data_size; }
-  int extra_data_size() { return _extra_data_size; }
-  intptr_t * data() { return _data; }
+  int data_size() const { return _data_size; }
+  int extra_data_size() const { return _extra_data_size; }
+  intptr_t * data() const { return _data; }
 
   methodDataOop get_methodDataOop() const {
     if (handle() == NULL) return NULL;
@@ -178,7 +184,7 @@
 
   void print_impl(outputStream* st);
 
-  DataLayout* data_layout_at(int data_index) {
+  DataLayout* data_layout_at(int data_index) const {
     assert(data_index % sizeof(intptr_t) == 0, "unaligned");
     return (DataLayout*) (((address)_data) + data_index);
   }
@@ -207,6 +213,8 @@
   // What is the index of the first data entry?
   int first_di() { return 0; }
 
+  ciArgInfoData *arg_info() const;
+
 public:
   bool is_method_data()  { return true; }
   bool is_empty() { return _state == empty_state; }
@@ -270,10 +278,12 @@
   void set_arg_local(int i);
   void set_arg_stack(int i);
   void set_arg_returned(int i);
+  void set_arg_modified(int arg, uint val);
 
   bool is_arg_local(int i) const;
   bool is_arg_stack(int i) const;
   bool is_arg_returned(int i) const;
+  uint arg_modified(int arg) const;
 
   // Code generation helper
   ByteSize offset_of_slot(ciProfileData* data, ByteSize slot_offset_in_data);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/ci/ciObjArray.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -0,0 +1,43 @@
+/*
+ * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_ciObjArray.cpp.incl"
+
+// ciObjArray
+//
+// This class represents an objArrayOop in the HotSpot virtual
+// machine.
+
+ciObject* ciObjArray::obj_at(int index) {
+  VM_ENTRY_MARK;
+  objArrayOop array = get_objArrayOop();
+  if (index < 0 || index >= array->length()) return NULL;
+  oop o = array->obj_at(index);
+  if (o == NULL) {
+    return ciNullObject::make();
+  } else {
+    return CURRENT_ENV->get_object(o);
+  }
+}
--- a/hotspot/src/share/vm/ci/ciObjArray.hpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/ci/ciObjArray.hpp	Wed Apr 30 07:03:08 2008 -0700
@@ -43,4 +43,6 @@
 public:
   // What kind of ciObject is this?
   bool is_obj_array() { return true; }
+
+  ciObject* obj_at(int index);
 };
--- a/hotspot/src/share/vm/classfile/dictionary.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/classfile/dictionary.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -155,8 +155,8 @@
         for (int i = ik->previous_versions()->length() - 1; i >= 0; i--) {
           // check the previous versions array for GC'ed weak refs
           PreviousVersionNode * pv_node = ik->previous_versions()->at(i);
-          jweak cp_ref = pv_node->prev_constant_pool();
-          assert(cp_ref != NULL, "weak cp ref was unexpectedly cleared");
+          jobject cp_ref = pv_node->prev_constant_pool();
+          assert(cp_ref != NULL, "cp ref was unexpectedly cleared");
           if (cp_ref == NULL) {
             delete pv_node;
             ik->previous_versions()->remove_at(i);
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -143,13 +143,43 @@
   jstring js = NULL;
   { JavaThread* thread = (JavaThread*)THREAD;
     assert(thread->is_Java_thread(), "must be java thread");
+    HandleMark hm(thread);
     ThreadToNativeFromVM ttn(thread);
-    HandleMark hm(thread);
     js = (_to_java_string_fn)(thread->jni_environment(), str);
   }
   return Handle(THREAD, JNIHandles::resolve(js));
 }
 
+// Converts a Java String to a native C string that can be used for
+// native OS calls.
+char* java_lang_String::as_platform_dependent_str(Handle java_string, TRAPS) {
+
+  typedef char* (*to_platform_string_fn_t)(JNIEnv*, jstring, bool*);
+  static to_platform_string_fn_t _to_platform_string_fn = NULL;
+
+  if (_to_platform_string_fn == NULL) {
+    void *lib_handle = os::native_java_library();
+    _to_platform_string_fn = CAST_TO_FN_PTR(to_platform_string_fn_t, hpi::dll_lookup(lib_handle, "GetStringPlatformChars"));
+    if (_to_platform_string_fn == NULL) {
+      fatal("GetStringPlatformChars missing");
+    }
+  }
+
+  char *native_platform_string;
+  { JavaThread* thread = (JavaThread*)THREAD;
+    assert(thread->is_Java_thread(), "must be java thread");
+    JNIEnv *env = thread->jni_environment();
+    jstring js = (jstring) JNIHandles::make_local(env, java_string());
+    bool is_copy;
+    HandleMark hm(thread);
+    ThreadToNativeFromVM ttn(thread);
+    native_platform_string = (_to_platform_string_fn)(env, js, &is_copy);
+    assert(is_copy == JNI_TRUE, "is_copy value changed");
+    JNIHandles::destroy_local(js);
+  }
+  return native_platform_string;
+}
+
 Handle java_lang_String::char_converter(Handle java_string, jchar from_char, jchar to_char, TRAPS) {
   oop          obj    = java_string();
   // Typical usage is to convert all '/' to '.' in string.
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp	Wed Apr 30 07:03:08 2008 -0700
@@ -96,6 +96,7 @@
   // String converters
   static char*  as_utf8_string(oop java_string);
   static char*  as_utf8_string(oop java_string, int start, int len);
+  static char*  as_platform_dependent_str(Handle java_string, TRAPS);
   static jchar* as_unicode_string(oop java_string, int& length);
 
   static bool equals(oop java_string, jchar* chars, int len);
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -1242,7 +1242,9 @@
     oop obj = (oop) result.get_jobject();
     if (obj == NULL) { return nk; }
 
-    char* new_class_name = java_lang_String::as_utf8_string(obj);
+    Handle h_obj(THREAD, obj);
+    char* new_class_name = java_lang_String::as_platform_dependent_str(h_obj,
+                                                                  CHECK_(nk));
 
     // lock the loader
     // we use this lock because JVMTI does.
--- a/hotspot/src/share/vm/classfile/vmSymbols.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/classfile/vmSymbols.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -318,6 +318,11 @@
   const int neg = JVM_ACC_SYNCHRONIZED;
   return (flags & (req | neg)) == req;
 }
+inline bool match_F_RNY(jshort flags) {
+  const int req = JVM_ACC_NATIVE | JVM_ACC_SYNCHRONIZED;
+  const int neg = JVM_ACC_STATIC;
+  return (flags & (req | neg)) == req;
+}
 
 // These are for forming case labels:
 #define ID3(x, y, z) (( jint)(z) +                                  \
@@ -359,6 +364,7 @@
   case F_RN: fname = "native ";        break;
   case F_SN: fname = "native static "; break;
   case F_S:  fname = "static ";        break;
+  case F_RNY:fname = "native synchronized "; break;
   }
   const char* kptr = strrchr(kname, '/');
   if (kptr != NULL)  kname = kptr + 1;
@@ -485,7 +491,7 @@
   if (PrintMiscellaneous && (WizardMode || Verbose)) {
     tty->print_cr("*** misidentified method; %s(%d) should be %s(%d):",
                   declared_name, declared_id, actual_name, actual_id);
-    m->print_short_name(tty);
+    mh()->print_short_name(tty);
     tty->cr();
   }
 }
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp	Wed Apr 30 07:03:08 2008 -0700
@@ -58,12 +58,17 @@
   template(java_lang_ThreadDeath,                     "java/lang/ThreadDeath")                    \
   template(java_lang_Boolean,                         "java/lang/Boolean")                        \
   template(java_lang_Character,                       "java/lang/Character")                      \
+  template(java_lang_Character_CharacterCache,        "java/lang/Character$CharacterCache")       \
   template(java_lang_Float,                           "java/lang/Float")                          \
   template(java_lang_Double,                          "java/lang/Double")                         \
   template(java_lang_Byte,                            "java/lang/Byte")                           \
+  template(java_lang_Byte_Cache,                      "java/lang/Byte$ByteCache")                 \
   template(java_lang_Short,                           "java/lang/Short")                          \
+  template(java_lang_Short_ShortCache,                "java/lang/Short$ShortCache")               \
   template(java_lang_Integer,                         "java/lang/Integer")                        \
+  template(java_lang_Integer_IntegerCache,            "java/lang/Integer$IntegerCache")           \
   template(java_lang_Long,                            "java/lang/Long")                           \
+  template(java_lang_Long_LongCache,                  "java/lang/Long$LongCache")                 \
   template(java_lang_Shutdown,                        "java/lang/Shutdown")                       \
   template(java_lang_ref_Reference,                   "java/lang/ref/Reference")                  \
   template(java_lang_ref_SoftReference,               "java/lang/ref/SoftReference")              \
@@ -91,10 +96,11 @@
   template(java_util_Vector,                          "java/util/Vector")                         \
   template(java_util_AbstractList,                    "java/util/AbstractList")                   \
   template(java_util_Hashtable,                       "java/util/Hashtable")                      \
+  template(java_util_HashMap,                         "java/util/HashMap")                        \
   template(java_lang_Compiler,                        "java/lang/Compiler")                       \
   template(sun_misc_Signal,                           "sun/misc/Signal")                          \
   template(java_lang_AssertionStatusDirectives,       "java/lang/AssertionStatusDirectives")      \
-  template(sun_jkernel_DownloadManager,               "sun/jkernel/DownloadManager")                 \
+  template(sun_jkernel_DownloadManager,               "sun/jkernel/DownloadManager")              \
   template(getBootClassPathEntryForClass_name,        "getBootClassPathEntryForClass")            \
                                                                                                   \
   /* class file format tags */                                                                    \
@@ -274,7 +280,9 @@
   template(exclusive_owner_thread_name,               "exclusiveOwnerThread")                     \
   template(park_blocker_name,                         "parkBlocker")                              \
   template(park_event_name,                           "nativeParkEventPointer")                   \
+  template(cache_field_name,                          "cache")                                    \
   template(value_name,                                "value")                                    \
+  template(frontCacheEnabled_name,                    "frontCacheEnabled")                        \
                                                                                                   \
   /* non-intrinsic name/signature pairs: */                                                       \
   template(register_method_name,                      "register")                                 \
@@ -576,6 +584,8 @@
    do_name(     attemptUpdate_name,                                 "attemptUpdate")                                    \
    do_signature(attemptUpdate_signature,                            "(JJ)Z")                                            \
                                                                                                                         \
+  do_intrinsic(_fillInStackTrace,         java_lang_Throwable, fillInStackTrace_name, void_throwable_signature,  F_RNY) \
+                                                                                                                        \
   /* support for sun.misc.Unsafe */                                                                                     \
   do_class(sun_misc_Unsafe,               "sun/misc/Unsafe")                                                            \
                                                                                                                         \
@@ -863,7 +873,8 @@
     F_R,                        // !static        !synchronized (R="regular")
     F_S,                        //  static        !synchronized
     F_RN,                       // !static native !synchronized
-    F_SN                        //  static native !synchronized
+    F_SN,                       //  static native !synchronized
+    F_RNY                       // !static native  synchronized
   };
 
 public:
--- a/hotspot/src/share/vm/code/debugInfo.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/code/debugInfo.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -47,7 +47,8 @@
   }
 #endif
   ObjectValue* result = new ObjectValue(id);
-  _obj_pool->append(result);
+  // Cache the object since an object field could reference it.
+  _obj_pool->push(result);
   result->read_object(this);
   return result;
 }
@@ -56,9 +57,9 @@
   int id = read_int();
   assert(_obj_pool != NULL, "object pool does not exist");
   for (int i = _obj_pool->length() - 1; i >= 0; i--) {
-    ObjectValue* sv = (ObjectValue*) _obj_pool->at(i);
-    if (sv->id() == id) {
-      return sv;
+    ObjectValue* ov = (ObjectValue*) _obj_pool->at(i);
+    if (ov->id() == id) {
+      return ov;
     }
   }
   ShouldNotReachHere();
--- a/hotspot/src/share/vm/code/dependencies.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/code/dependencies.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -882,6 +882,14 @@
   // Must not move the class hierarchy during this check:
   assert_locked_or_safepoint(Compile_lock);
 
+  int nof_impls = instanceKlass::cast(context_type)->nof_implementors();
+  if (nof_impls > 1) {
+    // Avoid this case: *I.m > { A.m, C }; B.m > C
+    // %%% Until this is fixed more systematically, bail out.
+    // See corresponding comment in find_witness_anywhere.
+    return context_type;
+  }
+
   assert(!is_participant(new_type), "only old classes are participants");
   if (participants_hide_witnesses) {
     // If the new type is a subtype of a participant, we are done.
@@ -1491,9 +1499,12 @@
     // fall through:
     _change_type = Change_new_sub;
   case Change_new_sub:
-    _klass = instanceKlass::cast(_klass)->super();
-    if (_klass != NULL) {
-      return true;
+    // 6598190: brackets workaround Sun Studio C++ compiler bug 6629277
+    {
+      _klass = instanceKlass::cast(_klass)->super();
+      if (_klass != NULL) {
+        return true;
+      }
     }
     // else set up _ti_limit and fall through:
     _ti_limit = (_ti_base == NULL) ? 0 : _ti_base->length();
--- a/hotspot/src/share/vm/code/nmethod.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/code/nmethod.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -1971,7 +1971,7 @@
     if (ctxk != NULL) {
       Klass* k = Klass::cast(ctxk);
       if (k->oop_is_instance() && ((instanceKlass*)k)->is_dependent_nmethod(this)) {
-        tty->print("   [nmethod<=klass]%s", k->external_name());
+        tty->print_cr("   [nmethod<=klass]%s", k->external_name());
       }
     }
     deps.log_dependency();  // put it into the xml log also
--- a/hotspot/src/share/vm/code/scopeDesc.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/code/scopeDesc.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -91,7 +91,9 @@
   DebugInfoReadStream* stream = new DebugInfoReadStream(_code, decode_offset, result);
   int length = stream->read_int();
   for (int index = 0; index < length; index++) {
-    result->push(ScopeValue::read_from(stream));
+    // Objects values are pushed to 'result' array during read so that
+    // object's fields could reference it (OBJECT_ID_CODE).
+    (void)ScopeValue::read_from(stream);
   }
   assert(result->length() == length, "inconsistent debug information");
   return result;
--- a/hotspot/src/share/vm/code/vmreg.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/code/vmreg.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -36,16 +36,16 @@
 // Register names
 const char *VMRegImpl::regName[ConcreteRegisterImpl::number_of_registers];
 
-void VMRegImpl::print() {
 #ifndef PRODUCT
+void VMRegImpl::print_on(outputStream* st) const {
   if( is_reg() ) {
     assert( VMRegImpl::regName[value()], "" );
-    tty->print("%s",VMRegImpl::regName[value()]);
+    st->print("%s",VMRegImpl::regName[value()]);
   } else if (is_stack()) {
     int stk = value() - stack0->value();
-    tty->print("[%d]", stk*4);
+    st->print("[%d]", stk*4);
   } else {
-    tty->print("BAD!");
+    st->print("BAD!");
   }
+}
 #endif // PRODUCT
-}
--- a/hotspot/src/share/vm/code/vmreg.hpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/code/vmreg.hpp	Wed Apr 30 07:03:08 2008 -0700
@@ -66,9 +66,9 @@
     }
   }
   static VMReg Bad() { return (VMReg) (intptr_t) BAD; }
-  bool is_valid() { return ((intptr_t) this) != BAD; }
-  bool is_stack() { return (intptr_t) this >= (intptr_t) stack0; }
-  bool is_reg() { return is_valid() && !is_stack(); }
+  bool is_valid() const { return ((intptr_t) this) != BAD; }
+  bool is_stack() const { return (intptr_t) this >= (intptr_t) stack0; }
+  bool is_reg()   const { return is_valid() && !is_stack(); }
 
   // A concrete register is a value that returns true for is_reg() and is
   // also a register you could use in the assembler. On machines with
@@ -96,7 +96,8 @@
 
   intptr_t value() const         {return (intptr_t) this; }
 
-  void print();
+  void print_on(outputStream* st) const PRODUCT_RETURN;
+  void print() const { print_on(tty); }
 
   // bias a stack slot.
   // Typically used to adjust a virtual frame slots by amounts that are offset by
--- a/hotspot/src/share/vm/compiler/oopMap.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/compiler/oopMap.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -506,27 +506,27 @@
 }
 
 
-void print_register_type(OopMapValue::oop_types x, VMReg optional) {
+static void print_register_type(OopMapValue::oop_types x, VMReg optional, outputStream* st) {
   switch( x ) {
   case OopMapValue::oop_value:
-    tty->print("Oop");
+    st->print("Oop");
     break;
   case OopMapValue::value_value:
-    tty->print("Value" );
+    st->print("Value" );
     break;
   case OopMapValue::dead_value:
-    tty->print("Dead" );
+    st->print("Dead" );
     break;
   case OopMapValue::callee_saved_value:
-    tty->print("Callers_" );
-    optional->print();
+    st->print("Callers_" );
+    optional->print_on(st);
     break;
   case OopMapValue::derived_oop_value:
-    tty->print("Derived_oop_" );
-    optional->print();
+    st->print("Derived_oop_" );
+    optional->print_on(st);
     break;
   case OopMapValue::stack_obj:
-    tty->print("Stack");
+    st->print("Stack");
     break;
   default:
     ShouldNotReachHere();
@@ -534,11 +534,11 @@
 }
 
 
-void OopMapValue::print() const {
-  reg()->print();
-  tty->print("=");
-  print_register_type(type(),content_reg());
-  tty->print(" ");
+void OopMapValue::print_on(outputStream* st) const {
+  reg()->print_on(st);
+  st->print("=");
+  print_register_type(type(),content_reg(),st);
+  st->print(" ");
 }
 
 
--- a/hotspot/src/share/vm/compiler/oopMap.hpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/compiler/oopMap.hpp	Wed Apr 30 07:03:08 2008 -0700
@@ -129,7 +129,8 @@
     return reg()->reg2stack();
   }
 
-  void print( ) const PRODUCT_RETURN;
+  void print_on(outputStream* st) const PRODUCT_RETURN;
+  void print() const { print_on(tty); }
 };
 
 
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -1071,85 +1071,56 @@
 // for each list in the tree.  Also print some summary
 // information.
 class printTreeCensusClosure : public AscendTreeCensusClosure {
+  int _print_line;
   size_t _totalFree;
-  AllocationStats _totals;
-  size_t _count;
+  FreeList _total;
 
  public:
   printTreeCensusClosure() {
+    _print_line = 0;
     _totalFree = 0;
-    _count = 0;
-    _totals.initialize();
   }
-  AllocationStats* totals() { return &_totals; }
-  size_t count() { return _count; }
-  void increment_count_by(size_t v) { _count += v; }
+  FreeList* total() { return &_total; }
   size_t totalFree() { return _totalFree; }
-  void increment_totalFree_by(size_t v) { _totalFree += v; }
   void do_list(FreeList* fl) {
-    bool nl = false; // "maybe this is not needed" isNearLargestChunk(fl->head());
-
-    gclog_or_tty->print("%c %4d\t\t" "%7d\t" "%7d\t"
-               "%7d\t"      "%7d\t" "%7d\t" "%7d\t"
-               "%7d\t"      "%7d\t" "%7d\t"
-               "%7d\t" "\n",
-               " n"[nl], fl->size(), fl->bfrSurp(), fl->surplus(),
-               fl->desired(), fl->prevSweep(), fl->beforeSweep(), fl->count(),
-               fl->coalBirths(), fl->coalDeaths(), fl->splitBirths(),
-               fl->splitDeaths());
-
-    increment_totalFree_by(fl->count() * fl->size());
-    increment_count_by(fl->count());
-    totals()->set_bfrSurp(totals()->bfrSurp() + fl->bfrSurp());
-    totals()->set_surplus(totals()->splitDeaths()     + fl->surplus());
-    totals()->set_prevSweep(totals()->prevSweep()   + fl->prevSweep());
-    totals()->set_beforeSweep(totals()->beforeSweep() + fl->beforeSweep());
-    totals()->set_coalBirths(totals()->coalBirths()  + fl->coalBirths());
-    totals()->set_coalDeaths(totals()->coalDeaths()  + fl->coalDeaths());
-    totals()->set_splitBirths(totals()->splitBirths() + fl->splitBirths());
-    totals()->set_splitDeaths(totals()->splitDeaths() + fl->splitDeaths());
+    if (++_print_line >= 40) {
+      FreeList::print_labels_on(gclog_or_tty, "size");
+      _print_line = 0;
+    }
+    fl->print_on(gclog_or_tty);
+    _totalFree +=            fl->count()            * fl->size()        ;
+    total()->set_count(      total()->count()       + fl->count()      );
+    total()->set_bfrSurp(    total()->bfrSurp()     + fl->bfrSurp()    );
+    total()->set_surplus(    total()->splitDeaths() + fl->surplus()    );
+    total()->set_desired(    total()->desired()     + fl->desired()    );
+    total()->set_prevSweep(  total()->prevSweep()   + fl->prevSweep()  );
+    total()->set_beforeSweep(total()->beforeSweep() + fl->beforeSweep());
+    total()->set_coalBirths( total()->coalBirths()  + fl->coalBirths() );
+    total()->set_coalDeaths( total()->coalDeaths()  + fl->coalDeaths() );
+    total()->set_splitBirths(total()->splitBirths() + fl->splitBirths());
+    total()->set_splitDeaths(total()->splitDeaths() + fl->splitDeaths());
   }
 };
 
 void BinaryTreeDictionary::printDictCensus(void) const {
 
   gclog_or_tty->print("\nBinaryTree\n");
-  gclog_or_tty->print(
-             "%4s\t\t" "%7s\t"   "%7s\t"    "%7s\t"    "%7s\t"    "%7s\t"
-             "%7s\t"   "%7s\t"   "%7s\t"    "%7s\t"    "%7s\t"     "\n",
-             "size",  "bfrsurp", "surplus", "desired", "prvSwep", "bfrSwep",
-             "count", "cBirths", "cDeaths", "sBirths", "sDeaths");
-
+  FreeList::print_labels_on(gclog_or_tty, "size");
   printTreeCensusClosure ptc;
   ptc.do_tree(root());
 
+  FreeList* total = ptc.total();
+  FreeList::print_labels_on(gclog_or_tty, " ");
+  total->print_on(gclog_or_tty, "TOTAL\t");
   gclog_or_tty->print(
-             "\t\t"    "%7s\t"    "%7s\t"    "%7s\t"    "%7s\t"
-             "%7s\t"   "%7s\t"    "%7s\t"    "%7s\t"    "%7s\t"     "\n",
-                       "bfrsurp", "surplus", "prvSwep", "bfrSwep",
-             "count",  "cBirths", "cDeaths", "sBirths", "sDeaths");
-  gclog_or_tty->print(
-             "%s\t\t"  "%7d\t"    "%7d\t"     "%7d\t"    "%7d\t"
-             "%7d\t"   "%7d\t"    "%7d\t"     "%7d\t"    "%7d\t"    "\n",
-             "totl",
-             ptc.totals()->bfrSurp(),
-             ptc.totals()->surplus(),
-             ptc.totals()->prevSweep(),
-             ptc.totals()->beforeSweep(),
-             ptc.count(),
-             ptc.totals()->coalBirths(),
-             ptc.totals()->coalDeaths(),
-             ptc.totals()->splitBirths(),
-             ptc.totals()->splitDeaths());
-  gclog_or_tty->print("totalFree(words): %7d growth: %8.5f  deficit: %8.5f\n",
+              "totalFree(words): " SIZE_FORMAT_W(16)
+              " growth: %8.5f  deficit: %8.5f\n",
               ptc.totalFree(),
-              (double)(ptc.totals()->splitBirths()+ptc.totals()->coalBirths()
-                       -ptc.totals()->splitDeaths()-ptc.totals()->coalDeaths())
-              /(ptc.totals()->prevSweep() != 0 ?
-                (double)ptc.totals()->prevSweep() : 1.0),
-             (double)(ptc.totals()->desired() - ptc.count())
-             /(ptc.totals()->desired() != 0 ?
-               (double)ptc.totals()->desired() : 1.0));
+              (double)(total->splitBirths() + total->coalBirths()
+                     - total->splitDeaths() - total->coalDeaths())
+              /(total->prevSweep() != 0 ? (double)total->prevSweep() : 1.0),
+             (double)(total->desired() - total->count())
+             /(total->desired() != 0 ? (double)total->desired() : 1.0));
 }
 
 // Verify the following tree invariants:
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -1835,7 +1835,7 @@
   guarantee(false, "NYI");
 }
 
-bool CompactibleFreeListSpace::linearAllocationWouldFail() {
+bool CompactibleFreeListSpace::linearAllocationWouldFail() const {
   return _smallLinearAllocBlock._word_size == 0;
 }
 
@@ -1906,6 +1906,13 @@
   }
 }
 
+// Support for concurrent collection policy decisions.
+bool CompactibleFreeListSpace::should_concurrent_collect() const {
+  // In the future we might want to add in frgamentation stats --
+  // including erosion of the "mountain" into this decision as well.
+  return !adaptive_freelists() && linearAllocationWouldFail();
+}
+
 // Support for compaction
 
 void CompactibleFreeListSpace::prepare_for_compaction(CompactPoint* cp) {
@@ -2013,11 +2020,11 @@
   }
 }
 
-void CompactibleFreeListSpace::endSweepFLCensus(int sweepCt) {
+void CompactibleFreeListSpace::endSweepFLCensus(size_t sweep_count) {
   setFLSurplus();
   setFLHints();
   if (PrintGC && PrintFLSCensus > 0) {
-    printFLCensus(sweepCt);
+    printFLCensus(sweep_count);
   }
   clearFLCensus();
   assert_locked();
@@ -2293,59 +2300,37 @@
 }
 #endif
 
-void CompactibleFreeListSpace::printFLCensus(int sweepCt) const {
+void CompactibleFreeListSpace::printFLCensus(size_t sweep_count) const {
   assert_lock_strong(&_freelistLock);
-  ssize_t bfrSurp     = 0;
-  ssize_t surplus     = 0;
-  ssize_t desired     = 0;
-  ssize_t prevSweep   = 0;
-  ssize_t beforeSweep = 0;
-  ssize_t count       = 0;
-  ssize_t coalBirths  = 0;
-  ssize_t coalDeaths  = 0;
-  ssize_t splitBirths = 0;
-  ssize_t splitDeaths = 0;
-  gclog_or_tty->print("end sweep# %d\n", sweepCt);
-  gclog_or_tty->print("%4s\t"    "%7s\t"      "%7s\t"      "%7s\t"      "%7s\t"
-             "%7s\t"    "%7s\t"      "%7s\t"      "%7s\t"      "%7s\t"
-             "%7s\t"    "\n",
-             "size",    "bfrsurp",   "surplus",   "desired",   "prvSwep",
-             "bfrSwep", "count",     "cBirths",   "cDeaths",   "sBirths",
-             "sDeaths");
-
+  FreeList total;
+  gclog_or_tty->print("end sweep# " SIZE_FORMAT "\n", sweep_count);
+  FreeList::print_labels_on(gclog_or_tty, "size");
   size_t totalFree = 0;
   for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
     const FreeList *fl = &_indexedFreeList[i];
-        totalFree += fl->count() * fl->size();
-
-    gclog_or_tty->print("%4d\t"          "%7d\t"             "%7d\t"        "%7d\t"
-               "%7d\t"          "%7d\t"             "%7d\t"        "%7d\t"
-               "%7d\t"          "%7d\t"             "%7d\t"        "\n",
-               fl->size(),       fl->bfrSurp(),     fl->surplus(), fl->desired(),
-               fl->prevSweep(),  fl->beforeSweep(), fl->count(),   fl->coalBirths(),
-               fl->coalDeaths(), fl->splitBirths(), fl->splitDeaths());
-    bfrSurp     += fl->bfrSurp();
-    surplus     += fl->surplus();
-    desired     += fl->desired();
-    prevSweep   += fl->prevSweep();
-    beforeSweep += fl->beforeSweep();
-    count       += fl->count();
-    coalBirths  += fl->coalBirths();
-    coalDeaths  += fl->coalDeaths();
-    splitBirths += fl->splitBirths();
-    splitDeaths += fl->splitDeaths();
+    totalFree += fl->count() * fl->size();
+    if (i % (40*IndexSetStride) == 0) {
+      FreeList::print_labels_on(gclog_or_tty, "size");
+    }
+    fl->print_on(gclog_or_tty);
+    total.set_bfrSurp(    total.bfrSurp()     + fl->bfrSurp()    );
+    total.set_surplus(    total.surplus()     + fl->surplus()    );
+    total.set_desired(    total.desired()     + fl->desired()    );
+    total.set_prevSweep(  total.prevSweep()   + fl->prevSweep()  );
+    total.set_beforeSweep(total.beforeSweep() + fl->beforeSweep());
+    total.set_count(      total.count()       + fl->count()      );
+    total.set_coalBirths( total.coalBirths()  + fl->coalBirths() );
+    total.set_coalDeaths( total.coalDeaths()  + fl->coalDeaths() );
+    total.set_splitBirths(total.splitBirths() + fl->splitBirths());
+    total.set_splitDeaths(total.splitDeaths() + fl->splitDeaths());
   }
-  gclog_or_tty->print("%4s\t"
-            "%7d\t"      "%7d\t"     "%7d\t"        "%7d\t"       "%7d\t"
-            "%7d\t"      "%7d\t"     "%7d\t"        "%7d\t"       "%7d\t" "\n",
-            "totl",
-            bfrSurp,     surplus,     desired,     prevSweep,     beforeSweep,
-            count,       coalBirths,  coalDeaths,  splitBirths,   splitDeaths);
-  gclog_or_tty->print_cr("Total free in indexed lists %d words", totalFree);
+  total.print_on(gclog_or_tty, "TOTAL");
+  gclog_or_tty->print_cr("Total free in indexed lists "
+                         SIZE_FORMAT " words", totalFree);
   gclog_or_tty->print("growth: %8.5f  deficit: %8.5f\n",
-    (double)(splitBirths+coalBirths-splitDeaths-coalDeaths)/
-            (prevSweep != 0 ? (double)prevSweep : 1.0),
-    (double)(desired - count)/(desired != 0 ? (double)desired : 1.0));
+    (double)(total.splitBirths()+total.coalBirths()-total.splitDeaths()-total.coalDeaths())/
+            (total.prevSweep() != 0 ? (double)total.prevSweep() : 1.0),
+    (double)(total.desired() - total.count())/(total.desired() != 0 ? (double)total.desired() : 1.0));
   _dictionary->printDictCensus();
 }
 
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp	Wed Apr 30 07:03:08 2008 -0700
@@ -418,7 +418,7 @@
   // chunk exists, return NULL.
   FreeChunk* find_chunk_at_end();
 
-  bool adaptive_freelists() { return _adaptive_freelists; }
+  bool adaptive_freelists() const { return _adaptive_freelists; }
 
   void set_collector(CMSCollector* collector) { _collector = collector; }
 
@@ -566,7 +566,7 @@
   FreeChunk* allocateScratch(size_t size);
 
   // returns true if either the small or large linear allocation buffer is empty.
-  bool       linearAllocationWouldFail();
+  bool       linearAllocationWouldFail() const;
 
   // Adjust the chunk for the minimum size.  This version is called in
   // most cases in CompactibleFreeListSpace methods.
@@ -585,6 +585,9 @@
   void      addChunkAndRepairOffsetTable(HeapWord* chunk, size_t size,
               bool coalesced);
 
+  // Support for decisions regarding concurrent collection policy
+  bool should_concurrent_collect() const;
+
   // Support for compaction
   void prepare_for_compaction(CompactPoint* cp);
   void adjust_pointers();
@@ -622,7 +625,7 @@
   // coalescing of chunks during the sweep of garbage.
 
   // Print the statistics for the free lists.
-  void printFLCensus(int sweepCt)         const;
+  void printFLCensus(size_t sweep_count) const;
 
   // Statistics functions
   // Initialize census for lists before the sweep.
@@ -635,12 +638,11 @@
   // Clear the census for each of the free lists.
   void clearFLCensus();
   // Perform functions for the census after the end of the sweep.
-  void endSweepFLCensus(int sweepCt);
+  void endSweepFLCensus(size_t sweep_count);
   // Return true if the count of free chunks is greater
   // than the desired number of free chunks.
   bool coalOverPopulated(size_t size);
 
-
 // Record (for each size):
 //
 //   split-births = #chunks added due to splits in (prev-sweep-end,
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -3121,12 +3121,7 @@
   if (GCExpandToAllocateDelayMillis > 0) {
     os::sleep(Thread::current(), GCExpandToAllocateDelayMillis, false);
   }
-  size_t adj_word_sz = CompactibleFreeListSpace::adjustObjectSize(word_size);
-  if (parallel) {
-    return cmsSpace()->par_allocate(adj_word_sz);
-  } else {
-    return cmsSpace()->allocate(adj_word_sz);
-  }
+  return have_lock_and_allocate(word_size, tlab);
 }
 
 // YSR: All of this generation expansion/shrinking stuff is an exact copy of
@@ -5732,13 +5727,19 @@
   // in the perm_gen_verify_bit_map. In order to do that we traverse
   // all blocks in perm gen and mark all dead objects.
   if (verifying() && !cms_should_unload_classes()) {
-    CMSTokenSyncWithLocks ts(true, _permGen->freelistLock(),
-                             bitMapLock());
     assert(perm_gen_verify_bit_map()->sizeInBits() != 0,
            "Should have already been allocated");
     MarkDeadObjectsClosure mdo(this, _permGen->cmsSpace(),
                                markBitMap(), perm_gen_verify_bit_map());
-    _permGen->cmsSpace()->blk_iterate(&mdo);
+    if (asynch) {
+      CMSTokenSyncWithLocks ts(true, _permGen->freelistLock(),
+                               bitMapLock());
+      _permGen->cmsSpace()->blk_iterate(&mdo);
+    } else {
+      // In the case of synchronous sweep, we already have
+      // the requisite locks/tokens.
+      _permGen->cmsSpace()->blk_iterate(&mdo);
+    }
   }
 
   if (asynch) {
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -302,3 +302,29 @@
 #endif
 }
 #endif
+
+// Print the "label line" for free list stats.
+void FreeList::print_labels_on(outputStream* st, const char* c) {
+  st->print("%16s\t", c);
+  st->print("%14s\t"    "%14s\t"    "%14s\t"    "%14s\t"    "%14s\t"
+            "%14s\t"    "%14s\t"    "%14s\t"    "%14s\t"    "%14s\t"    "\n",
+            "bfrsurp", "surplus", "desired", "prvSwep", "bfrSwep",
+            "count",   "cBirths", "cDeaths", "sBirths", "sDeaths");
+}
+
+// Print the AllocationStats for the given free list. If the second argument
+// to the call is a non-null string, it is printed in the first column;
+// otherwise, if the argument is null (the default), then the size of the
+// (free list) block is printed in the first column.
+void FreeList::print_on(outputStream* st, const char* c) const {
+  if (c != NULL) {
+    st->print("%16s", c);
+  } else {
+    st->print(SIZE_FORMAT_W(16), size());
+  }
+  st->print("\t"
+           SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\t"
+           SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\n",
+           bfrSurp(),             surplus(),             desired(),             prevSweep(),           beforeSweep(),
+           count(),               coalBirths(),          coalDeaths(),          splitBirths(),         splitDeaths());
+}
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.hpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.hpp	Wed Apr 30 07:03:08 2008 -0700
@@ -38,6 +38,7 @@
 
 class FreeList VALUE_OBJ_CLASS_SPEC {
   friend class CompactibleFreeListSpace;
+  friend class printTreeCensusClosure;
   FreeChunk*    _head;          // List of free chunks
   FreeChunk*    _tail;          // Tail of list of free chunks
   size_t        _size;          // Size in Heap words of each chunks
@@ -63,10 +64,11 @@
  protected:
   void init_statistics();
   void set_count(ssize_t v) { _count = v;}
-  void increment_count() { _count++; }
+  void increment_count()    { _count++; }
   void decrement_count() {
     _count--;
-    assert(_count >= 0, "Count should not be negative"); }
+    assert(_count >= 0, "Count should not be negative");
+  }
 
  public:
   // Constructor
@@ -159,6 +161,10 @@
   ssize_t desired() const {
     return _allocation_stats.desired();
   }
+  void set_desired(ssize_t v) {
+    assert_proper_lock_protection();
+    _allocation_stats.set_desired(v);
+  }
   void compute_desired(float inter_sweep_current,
                        float inter_sweep_estimate) {
     assert_proper_lock_protection();
@@ -298,4 +304,8 @@
   // Verify that the chunk is in the list.
   // found.  Return NULL if "fc" is not found.
   bool verifyChunkInFreeLists(FreeChunk* fc) const;
+
+  // Printing support
+  static void print_labels_on(outputStream* st, const char* c);
+  void print_on(outputStream* st, const char* c = NULL) const;
 };
--- a/hotspot/src/share/vm/gc_implementation/includeDB_gc_shared	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/gc_implementation/includeDB_gc_shared	Wed Apr 30 07:03:08 2008 -0700
@@ -19,15 +19,22 @@
 // Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 // CA 95054 USA or visit www.sun.com if you need additional information or
 // have any questions.
-//  
+//
 //
 
 // NOTE: DO NOT CHANGE THIS COPYRIGHT TO NEW STYLE - IT WILL BREAK makeDeps!
 
-gcAdaptivePolicyCounters.hpp		adaptiveSizePolicy.hpp
-gcAdaptivePolicyCounters.hpp		gcPolicyCounters.hpp
+allocationStats.cpp                     allocationStats.hpp
+allocationStats.cpp                     ostream.hpp
 
-gcAdaptivePolicyCounters.cpp		resourceArea.hpp
+allocationStats.hpp                     allocation.hpp
+allocationStats.hpp                     gcUtil.hpp
+allocationStats.hpp                     globalDefinitions.hpp
+
+gcAdaptivePolicyCounters.hpp            adaptiveSizePolicy.hpp
+gcAdaptivePolicyCounters.hpp            gcPolicyCounters.hpp
+
+gcAdaptivePolicyCounters.cpp            resourceArea.hpp
 gcAdaptivePolicyCounters.cpp            gcAdaptivePolicyCounters.hpp
 
 gSpaceCounters.cpp                      generation.hpp
@@ -44,7 +51,7 @@
 
 isGCActiveMark.hpp                      parallelScavengeHeap.hpp
 
-markSweep.inline.hpp			psParallelCompact.hpp
+markSweep.inline.hpp                    psParallelCompact.hpp
 
 mutableNUMASpace.cpp                    mutableNUMASpace.hpp
 mutableNUMASpace.cpp                    sharedHeap.hpp
--- a/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -74,8 +74,8 @@
 #ifdef SHRINKS_AT_END_OF_EDEN
   size_t delta_in_survivor = 0;
   ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-  const size_t space_alignment = heap->intra_generation_alignment();
-  const size_t gen_alignment = heap->generation_alignment();
+  const size_t space_alignment = heap->intra_heap_alignment();
+  const size_t gen_alignment = heap->object_heap_alignment();
 
   MutableSpace* space_shrinking = NULL;
   if (from_space()->end() > to_space()->end()) {
--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -785,6 +785,9 @@
     swap_spaces();  // Make life simpler for CMS || rescan; see 6483690.
     from()->set_next_compaction_space(to());
     gch->set_incremental_collection_will_fail();
+
+    // Reset the PromotionFailureALot counters.
+    NOT_PRODUCT(Universe::heap()->reset_promotion_should_fail();)
   }
   // set new iteration safe limit for the survivor spaces
   from()->set_concurrent_iteration_safe_limit(from()->top());
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -86,7 +86,7 @@
   if (eden_space()->is_empty()) {
     // Respect the minimum size for eden and for the young gen as a whole.
     ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-    const size_t eden_alignment = heap->intra_generation_alignment();
+    const size_t eden_alignment = heap->intra_heap_alignment();
     const size_t gen_alignment = heap->young_gen_alignment();
 
     assert(eden_space()->capacity_in_bytes() >= eden_alignment,
@@ -124,7 +124,7 @@
 // to_space can be.
 size_t ASPSYoungGen::available_to_live() {
   ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-  const size_t alignment = heap->intra_generation_alignment();
+  const size_t alignment = heap->intra_heap_alignment();
 
   // Include any space that is committed but is not in eden.
   size_t available = pointer_delta(eden_space()->bottom(),
@@ -275,7 +275,7 @@
   assert(eden_start < from_start, "Cannot push into from_space");
 
   ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-  const size_t alignment = heap->intra_generation_alignment();
+  const size_t alignment = heap->intra_heap_alignment();
 
   // Check whether from space is below to space
   if (from_start < to_start) {
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp	Wed Apr 30 07:03:08 2008 -0700
@@ -39,10 +39,10 @@
 
     // If the user hasn't explicitly set the number of worker
     // threads, set the count.
-    if (ParallelGCThreads == 0) {
-      assert(UseParallelGC, "Setting ParallelGCThreads without UseParallelGC");
-      ParallelGCThreads = os::active_processor_count();
-    }
+    assert(UseSerialGC ||
+           !FLAG_IS_DEFAULT(ParallelGCThreads) ||
+           (ParallelGCThreads > 0),
+           "ParallelGCThreads should be set before flag initialization");
 
     // The survivor ratio's are calculated "raw", unlike the
     // default gc, which adds 2 to the ratio value. We need to
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -41,7 +41,7 @@
 
   const size_t rs_align = page_sz == (size_t) os::vm_page_size() ? 0 :
     MAX2(page_sz, granularity);
-  ReservedSpace rs(bytes, rs_align, false);
+  ReservedSpace rs(bytes, rs_align, rs_align > 0);
   os::trace_page_sizes("par bitmap", raw_bytes, raw_bytes, page_sz,
                        rs.base(), rs.size());
   _virtual_space = new PSVirtualSpace(rs, page_sz);
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -173,7 +173,7 @@
     new PSAdaptiveSizePolicy(eden_capacity,
                              initial_promo_size,
                              young_gen()->to_space()->capacity_in_bytes(),
-                             intra_generation_alignment(),
+                             intra_heap_alignment(),
                              max_gc_pause_sec,
                              max_gc_minor_pause_sec,
                              GCTimeRatio
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp	Wed Apr 30 07:03:08 2008 -0700
@@ -58,9 +58,9 @@
 
  public:
   ParallelScavengeHeap() : CollectedHeap() {
-    set_alignment(_perm_gen_alignment, intra_generation_alignment());
-    set_alignment(_young_gen_alignment, intra_generation_alignment());
-    set_alignment(_old_gen_alignment, intra_generation_alignment());
+    set_alignment(_perm_gen_alignment, intra_heap_alignment());
+    set_alignment(_young_gen_alignment, intra_heap_alignment());
+    set_alignment(_old_gen_alignment, intra_heap_alignment());
   }
 
   // For use by VM operations
@@ -92,14 +92,14 @@
 
   void post_initialize();
   void update_counters();
-
   // The alignment used for the various generations.
   size_t perm_gen_alignment()  const { return _perm_gen_alignment; }
   size_t young_gen_alignment() const { return _young_gen_alignment; }
   size_t old_gen_alignment()  const { return _old_gen_alignment; }
 
-  // The alignment used for eden and survivors within the young gen.
-  size_t intra_generation_alignment() const { return 64 * K; }
+  // The alignment used for eden and survivors within the young gen
+  // and for boundary between young gen and old gen.
+  size_t intra_heap_alignment() const { return 64 * K; }
 
   size_t capacity() const;
   size_t used() const;
@@ -217,6 +217,6 @@
 inline size_t ParallelScavengeHeap::set_alignment(size_t& var, size_t val)
 {
   assert(is_power_of_2((intptr_t)val), "must be a power of 2");
-  var = round_to(val, intra_generation_alignment());
+  var = round_to(val, intra_heap_alignment());
   return var;
 }
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -413,7 +413,7 @@
 
   const size_t rs_align = page_sz == (size_t) os::vm_page_size() ? 0 :
     MAX2(page_sz, granularity);
-  ReservedSpace rs(bytes, rs_align, false);
+  ReservedSpace rs(bytes, rs_align, rs_align > 0);
   os::trace_page_sizes("par compact", raw_bytes, raw_bytes, page_sz, rs.base(),
                        rs.size());
   PSVirtualSpace* vspace = new PSVirtualSpace(rs, page_sz);
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -88,7 +88,7 @@
 
   // Compute maximum space sizes for performance counters
   ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-  size_t alignment = heap->intra_generation_alignment();
+  size_t alignment = heap->intra_heap_alignment();
   size_t size = _virtual_space->reserved_size();
 
   size_t max_survivor_size;
@@ -141,7 +141,7 @@
   assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
 
   // Compute sizes
-  size_t alignment = heap->intra_generation_alignment();
+  size_t alignment = heap->intra_heap_alignment();
   size_t size = _virtual_space->committed_size();
 
   size_t survivor_size = size / InitialSurvivorRatio;
@@ -192,7 +192,7 @@
 #ifndef PRODUCT
 void PSYoungGen::space_invariants() {
   ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-  const size_t alignment = heap->intra_generation_alignment();
+  const size_t alignment = heap->intra_heap_alignment();
 
   // Currently, our eden size cannot shrink to zero
   guarantee(eden_space()->capacity_in_bytes() >= alignment, "eden too small");
@@ -392,7 +392,7 @@
   char* to_end     = (char*)to_space()->end();
 
   ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-  const size_t alignment = heap->intra_generation_alignment();
+  const size_t alignment = heap->intra_heap_alignment();
   const bool maintain_minimum =
     (requested_eden_size + 2 * requested_survivor_size) <= min_gen_size();
 
@@ -708,7 +708,7 @@
 size_t PSYoungGen::available_to_live() {
   size_t delta_in_survivor = 0;
   ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-  const size_t space_alignment = heap->intra_generation_alignment();
+  const size_t space_alignment = heap->intra_heap_alignment();
   const size_t gen_alignment = heap->young_gen_alignment();
 
   MutableSpace* space_shrinking = NULL;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc_implementation/shared/allocationStats.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+# include "incls/_precompiled.incl"
+# include "incls/_allocationStats.cpp.incl"
+
+// Technically this should be derived from machine speed, and
+// ideally it would be dynamically adjusted.
+float AllocationStats::_threshold = ((float)CMS_SweepTimerThresholdMillis)/1000;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc_implementation/shared/allocationStats.hpp	Wed Apr 30 07:03:08 2008 -0700
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2001-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+class AllocationStats VALUE_OBJ_CLASS_SPEC {
+  // A duration threshold (in ms) used to filter
+  // possibly unreliable samples.
+  static float _threshold;
+
+  // We measure the demand between the end of the previous sweep and
+  // beginning of this sweep:
+  //   Count(end_last_sweep) - Count(start_this_sweep)
+  //     + splitBirths(between) - splitDeaths(between)
+  // The above number divided by the time since the start [END???] of the
+  // previous sweep gives us a time rate of demand for blocks
+  // of this size. We compute a padded average of this rate as
+  // our current estimate for the time rate of demand for blocks
+  // of this size. Similarly, we keep a padded average for the time
+  // between sweeps. Our current estimate for demand for blocks of
+  // this size is then simply computed as the product of these two
+  // estimates.
+  AdaptivePaddedAverage _demand_rate_estimate;
+
+  ssize_t     _desired;          // Estimate computed as described above
+  ssize_t     _coalDesired;     // desired +/- small-percent for tuning coalescing
+
+  ssize_t     _surplus;         // count - (desired +/- small-percent),
+                                // used to tune splitting in best fit
+  ssize_t     _bfrSurp;         // surplus at start of current sweep
+  ssize_t     _prevSweep;       // count from end of previous sweep
+  ssize_t     _beforeSweep;     // count from before current sweep
+  ssize_t     _coalBirths;      // additional chunks from coalescing
+  ssize_t     _coalDeaths;      // loss from coalescing
+  ssize_t     _splitBirths;     // additional chunks from splitting
+  ssize_t     _splitDeaths;     // loss from splitting
+  size_t     _returnedBytes;    // number of bytes returned to list.
+ public:
+  void initialize() {
+    AdaptivePaddedAverage* dummy =
+      new (&_demand_rate_estimate) AdaptivePaddedAverage(CMS_FLSWeight,
+                                                         CMS_FLSPadding);
+    _desired = 0;
+    _coalDesired = 0;
+    _surplus = 0;
+    _bfrSurp = 0;
+    _prevSweep = 0;
+    _beforeSweep = 0;
+    _coalBirths = 0;
+    _coalDeaths = 0;
+    _splitBirths = 0;
+    _splitDeaths = 0;
+    _returnedBytes = 0;
+  }
+
+  AllocationStats() {
+    initialize();
+  }
+  // The rate estimate is in blocks per second.
+  void compute_desired(size_t count,
+                       float inter_sweep_current,
+                       float inter_sweep_estimate) {
+    // If the latest inter-sweep time is below our granularity
+    // of measurement, we may call in here with
+    // inter_sweep_current == 0. However, even for suitably small
+    // but non-zero inter-sweep durations, we may not trust the accuracy
+    // of accumulated data, since it has not been "integrated"
+    // (read "low-pass-filtered") long enough, and would be
+    // vulnerable to noisy glitches. In such cases, we
+    // ignore the current sample and use currently available
+    // historical estimates.
+    if (inter_sweep_current > _threshold) {
+      ssize_t demand = prevSweep() - count + splitBirths() - splitDeaths();
+      float rate = ((float)demand)/inter_sweep_current;
+      _demand_rate_estimate.sample(rate);
+      _desired = (ssize_t)(_demand_rate_estimate.padded_average()
+                           *inter_sweep_estimate);
+    }
+  }
+
+  ssize_t desired() const { return _desired; }
+  void set_desired(ssize_t v) { _desired = v; }
+
+  ssize_t coalDesired() const { return _coalDesired; }
+  void set_coalDesired(ssize_t v) { _coalDesired = v; }
+
+  ssize_t surplus() const { return _surplus; }
+  void set_surplus(ssize_t v) { _surplus = v; }
+  void increment_surplus() { _surplus++; }
+  void decrement_surplus() { _surplus--; }
+
+  ssize_t bfrSurp() const { return _bfrSurp; }
+  void set_bfrSurp(ssize_t v) { _bfrSurp = v; }
+  ssize_t prevSweep() const { return _prevSweep; }
+  void set_prevSweep(ssize_t v) { _prevSweep = v; }
+  ssize_t beforeSweep() const { return _beforeSweep; }
+  void set_beforeSweep(ssize_t v) { _beforeSweep = v; }
+
+  ssize_t coalBirths() const { return _coalBirths; }
+  void set_coalBirths(ssize_t v) { _coalBirths = v; }
+  void increment_coalBirths() { _coalBirths++; }
+
+  ssize_t coalDeaths() const { return _coalDeaths; }
+  void set_coalDeaths(ssize_t v) { _coalDeaths = v; }
+  void increment_coalDeaths() { _coalDeaths++; }
+
+  ssize_t splitBirths() const { return _splitBirths; }
+  void set_splitBirths(ssize_t v) { _splitBirths = v; }
+  void increment_splitBirths() { _splitBirths++; }
+
+  ssize_t splitDeaths() const { return _splitDeaths; }
+  void set_splitDeaths(ssize_t v) { _splitDeaths = v; }
+  void increment_splitDeaths() { _splitDeaths++; }
+
+  NOT_PRODUCT(
+    size_t returnedBytes() const { return _returnedBytes; }
+    void set_returnedBytes(size_t v) { _returnedBytes = v; }
+  )
+};
--- a/hotspot/src/share/vm/includeDB_compiler2	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/includeDB_compiler2	Wed Apr 30 07:03:08 2008 -0700
@@ -19,7 +19,7 @@
 // Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 // CA 95054 USA or visit www.sun.com if you need additional information or
 // have any questions.
-//  
+//
 //
 
 ad_<arch_model>.cpp                     adGlobals_<arch_model>.hpp
@@ -164,6 +164,7 @@
 callGenerator.hpp                       type.hpp
 
 callnode.cpp                            callnode.hpp
+callnode.cpp                            bcEscapeAnalyzer.hpp
 callnode.cpp                            escape.hpp
 callnode.cpp                            locknode.hpp
 callnode.cpp                            machnode.hpp
@@ -176,7 +177,6 @@
 callnode.cpp                            runtime.hpp
 
 callnode.hpp                            connode.hpp
-callnode.hpp                            escape.hpp
 callnode.hpp                            mulnode.hpp
 callnode.hpp                            multnode.hpp
 callnode.hpp                            opcodes.hpp
@@ -347,7 +347,6 @@
 connode.cpp                             allocation.inline.hpp
 connode.cpp                             compile.hpp
 connode.cpp                             connode.hpp
-connode.cpp                             escape.hpp
 connode.cpp                             machnode.hpp
 connode.cpp                             matcher.hpp
 connode.cpp                             memnode.hpp
@@ -410,6 +409,7 @@
 
 escape.cpp                              allocation.hpp
 escape.cpp                              bcEscapeAnalyzer.hpp
+escape.cpp                              c2compiler.hpp
 escape.cpp                              callnode.hpp
 escape.cpp                              cfgnode.hpp
 escape.cpp                              compile.hpp
@@ -843,7 +843,6 @@
 phaseX.cpp                              callnode.hpp
 phaseX.cpp                              cfgnode.hpp
 phaseX.cpp                              connode.hpp
-phaseX.cpp                              escape.hpp
 phaseX.cpp                              loopnode.hpp
 phaseX.cpp                              machnode.hpp
 phaseX.cpp                              opcodes.hpp
@@ -990,6 +989,7 @@
 
 subnode.cpp                             addnode.hpp
 subnode.cpp                             allocation.inline.hpp
+subnode.cpp                             callnode.hpp
 subnode.cpp                             cfgnode.hpp
 subnode.cpp                             compileLog.hpp
 subnode.cpp                             connode.hpp
@@ -1086,7 +1086,7 @@
 idealGraphPrinter.hpp                   ostream.hpp
 
 idealGraphPrinter.cpp                   idealGraphPrinter.hpp
-idealGraphPrinter.cpp			chaitin.hpp
+idealGraphPrinter.cpp                   chaitin.hpp
 idealGraphPrinter.cpp                   machnode.hpp
 idealGraphPrinter.cpp                   parse.hpp
 idealGraphPrinter.cpp                   threadCritical.hpp
@@ -1098,4 +1098,4 @@
 parse1.cpp                              idealGraphPrinter.hpp
 matcher.cpp                             idealGraphPrinter.hpp
 loopnode.cpp                            idealGraphPrinter.hpp
-chaitin.cpp				idealGraphPrinter.hpp
+chaitin.cpp                             idealGraphPrinter.hpp
--- a/hotspot/src/share/vm/includeDB_core	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/includeDB_core	Wed Apr 30 07:03:08 2008 -0700
@@ -19,7 +19,7 @@
 // Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 // CA 95054 USA or visit www.sun.com if you need additional information or
 // have any questions.
-//  
+//
 //
 
 // NOTE: DO NOT CHANGE THIS COPYRIGHT TO NEW STYLE - IT WILL BREAK makeDeps!
@@ -46,13 +46,13 @@
 // as dependencies.  Header files named H.inline.hpp generally contain
 // bodies for inline functions declared in H.hpp.
 //
-// NOTE: Files that use the token "generate_platform_dependent_include" 
+// NOTE: Files that use the token "generate_platform_dependent_include"
 // are expected to contain macro references like <os>, <arch_model>, ... and
 // makedeps has a dependency on these platform files looking like:
-// foo_<macro>.trailing_string 
+// foo_<macro>.trailing_string
 // (where "trailing_string" can be any legal filename strings but typically
 // is "hpp" or "inline.hpp").
-// 
+//
 // The dependency in makedeps (and enforced) is that an underscore
 // will precedure the macro invocation. Note that this restriction
 // is only enforced on filenames that have the dependency token
@@ -148,12 +148,6 @@
 
 allocation.inline.hpp                   os.hpp
 
-allocationStats.cpp                     allocationStats.hpp
-
-allocationStats.hpp                     allocation.hpp
-allocationStats.hpp                     gcUtil.hpp
-allocationStats.hpp                     globalDefinitions.hpp
-
 aprofiler.cpp                           aprofiler.hpp
 aprofiler.cpp                           collectedHeap.inline.hpp
 aprofiler.cpp                           oop.inline.hpp
@@ -720,6 +714,11 @@
 ciObjArray.hpp                          ciClassList.hpp
 ciObjArray.hpp                          objArrayOop.hpp
 
+ciObjArray.cpp                          ciObjArray.hpp
+ciObjArray.cpp                          ciNullObject.hpp
+ciObjArray.cpp                          ciUtilities.hpp
+ciObjArray.cpp                          objArrayOop.hpp
+
 ciObjArrayKlass.cpp                     ciInstanceKlass.hpp
 ciObjArrayKlass.cpp                     ciObjArrayKlass.hpp
 ciObjArrayKlass.cpp                     ciObjArrayKlassKlass.hpp
@@ -1935,7 +1934,7 @@
 
 init.cpp                                bytecodes.hpp
 init.cpp                                collectedHeap.hpp
-init.cpp				handles.inline.hpp
+init.cpp                                handles.inline.hpp
 init.cpp                                icBuffer.hpp
 init.cpp                                icache.hpp
 init.cpp                                init.hpp
@@ -3068,6 +3067,7 @@
 
 oopMapCache.cpp                         allocation.inline.hpp
 oopMapCache.cpp                         handles.inline.hpp
+oopMapCache.cpp                         jvmtiRedefineClassesTrace.hpp
 oopMapCache.cpp                         oop.inline.hpp
 oopMapCache.cpp                         oopMapCache.hpp
 oopMapCache.cpp                         resourceArea.hpp
--- a/hotspot/src/share/vm/interpreter/oopMapCache.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/interpreter/oopMapCache.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -532,6 +532,10 @@
     if (!_array[i].is_empty() && _array[i].method()->is_old()) {
       // Cache entry is occupied by an old redefined method and we don't want
       // to pin it down so flush the entry.
+      RC_TRACE(0x08000000, ("flush: %s(%s): cached entry @%d",
+        _array[i].method()->name()->as_C_string(),
+        _array[i].method()->signature()->as_C_string(), i));
+
       _array[i].flush();
     }
 }
@@ -577,6 +581,15 @@
   // Entry is not in hashtable.
   // Compute entry and return it
 
+  if (method->should_not_be_cached()) {
+    // It is either not safe or not a good idea to cache this methodOop
+    // at this time. We give the caller of lookup() a copy of the
+    // interesting info via parameter entry_for, but we don't add it to
+    // the cache. See the gory details in methodOop.cpp.
+    compute_one_oop_map(method, bci, entry_for);
+    return;
+  }
+
   // First search for an empty slot
   for(i = 0; i < _probe_depth; i++) {
     entry  = entry_at(probe + i);
@@ -584,12 +597,6 @@
       entry->fill(method, bci);
       entry_for->resource_copy(entry);
       assert(!entry_for->is_empty(), "A non-empty oop map should be returned");
-      if (method->is_old()) {
-        // The caller of lookup() will receive a copy of the interesting
-        // info via entry_for, but we don't keep an old redefined method in
-        // the cache to avoid pinning down the method.
-        entry->flush();
-      }
       return;
     }
   }
@@ -623,13 +630,6 @@
   }
   assert(!entry_for->is_empty(), "A non-empty oop map should be returned");
 
-  if (method->is_old()) {
-    // The caller of lookup() will receive a copy of the interesting
-    // info via entry_for, but we don't keep an old redefined method in
-    // the cache to avoid pinning down the method.
-    entry->flush();
-  }
-
   return;
 }
 
--- a/hotspot/src/share/vm/memory/allocationStats.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- */
-
-# include "incls/_precompiled.incl"
-# include "incls/_allocationStats.cpp.incl"
-
-// Technically this should be derived from machine speed, and
-// ideally it would be dynamically adjusted.
-float AllocationStats::_threshold = ((float)CMS_SweepTimerThresholdMillis)/1000;
--- a/hotspot/src/share/vm/memory/allocationStats.hpp	Wed Apr 30 12:32:05 2008 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,136 +0,0 @@
-/*
- * Copyright 2001-2005 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- */
-
-class AllocationStats VALUE_OBJ_CLASS_SPEC {
-  // A duration threshold (in ms) used to filter
-  // possibly unreliable samples.
-  static float _threshold;
-
-  // We measure the demand between the end of the previous sweep and
-  // beginning of this sweep:
-  //   Count(end_last_sweep) - Count(start_this_sweep)
-  //     + splitBirths(between) - splitDeaths(between)
-  // The above number divided by the time since the start [END???] of the
-  // previous sweep gives us a time rate of demand for blocks
-  // of this size. We compute a padded average of this rate as
-  // our current estimate for the time rate of demand for blocks
-  // of this size. Similarly, we keep a padded average for the time
-  // between sweeps. Our current estimate for demand for blocks of
-  // this size is then simply computed as the product of these two
-  // estimates.
-  AdaptivePaddedAverage _demand_rate_estimate;
-
-  ssize_t     _desired;          // Estimate computed as described above
-  ssize_t     _coalDesired;     // desired +/- small-percent for tuning coalescing
-
-  ssize_t     _surplus;         // count - (desired +/- small-percent),
-                                // used to tune splitting in best fit
-  ssize_t     _bfrSurp;         // surplus at start of current sweep
-  ssize_t     _prevSweep;       // count from end of previous sweep
-  ssize_t     _beforeSweep;     // count from before current sweep
-  ssize_t     _coalBirths;      // additional chunks from coalescing
-  ssize_t     _coalDeaths;      // loss from coalescing
-  ssize_t     _splitBirths;     // additional chunks from splitting
-  ssize_t     _splitDeaths;     // loss from splitting
-  size_t     _returnedBytes;    // number of bytes returned to list.
- public:
-  void initialize() {
-    AdaptivePaddedAverage* dummy =
-      new (&_demand_rate_estimate) AdaptivePaddedAverage(CMS_FLSWeight,
-                                                         CMS_FLSPadding);
-    _desired = 0;
-    _coalDesired = 0;
-    _surplus = 0;
-    _bfrSurp = 0;
-    _prevSweep = 0;
-    _beforeSweep = 0;
-    _coalBirths = 0;
-    _coalDeaths = 0;
-    _splitBirths = 0;
-    _splitDeaths = 0;
-    _returnedBytes = 0;
-  }
-
-  AllocationStats() {
-    initialize();
-  }
-  // The rate estimate is in blocks per second.
-  void compute_desired(size_t count,
-                       float inter_sweep_current,
-                       float inter_sweep_estimate) {
-    // If the latest inter-sweep time is below our granularity
-    // of measurement, we may call in here with
-    // inter_sweep_current == 0. However, even for suitably small
-    // but non-zero inter-sweep durations, we may not trust the accuracy
-    // of accumulated data, since it has not been "integrated"
-    // (read "low-pass-filtered") long enough, and would be
-    // vulnerable to noisy glitches. In such cases, we
-    // ignore the current sample and use currently available
-    // historical estimates.
-    if (inter_sweep_current > _threshold) {
-      ssize_t demand = prevSweep() - count + splitBirths() - splitDeaths();
-      float rate = ((float)demand)/inter_sweep_current;
-      _demand_rate_estimate.sample(rate);
-      _desired = (ssize_t)(_demand_rate_estimate.padded_average()
-                           *inter_sweep_estimate);
-    }
-  }
-
-  ssize_t desired() const { return _desired; }
-  ssize_t coalDesired() const { return _coalDesired; }
-  void set_coalDesired(ssize_t v) { _coalDesired = v; }
-
-  ssize_t surplus() const { return _surplus; }
-  void set_surplus(ssize_t v) { _surplus = v; }
-  void increment_surplus() { _surplus++; }
-  void decrement_surplus() { _surplus--; }
-
-  ssize_t bfrSurp() const { return _bfrSurp; }
-  void set_bfrSurp(ssize_t v) { _bfrSurp = v; }
-  ssize_t prevSweep() const { return _prevSweep; }
-  void set_prevSweep(ssize_t v) { _prevSweep = v; }
-  ssize_t beforeSweep() const { return _beforeSweep; }
-  void set_beforeSweep(ssize_t v) { _beforeSweep = v; }
-
-  ssize_t coalBirths() const { return _coalBirths; }
-  void set_coalBirths(ssize_t v) { _coalBirths = v; }
-  void increment_coalBirths() { _coalBirths++; }
-
-  ssize_t coalDeaths() const { return _coalDeaths; }
-  void set_coalDeaths(ssize_t v) { _coalDeaths = v; }
-  void increment_coalDeaths() { _coalDeaths++; }
-
-  ssize_t splitBirths() const { return _splitBirths; }
-  void set_splitBirths(ssize_t v) { _splitBirths = v; }
-  void increment_splitBirths() { _splitBirths++; }
-
-  ssize_t splitDeaths() const { return _splitDeaths; }
-  void set_splitDeaths(ssize_t v) { _splitDeaths = v; }
-  void increment_splitDeaths() { _splitDeaths++; }
-
-  NOT_PRODUCT(
-    size_t returnedBytes() const { return _returnedBytes; }
-    void set_returnedBytes(size_t v) { _returnedBytes = v; }
-  )
-};
--- a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -51,7 +51,7 @@
   _whole_heap(whole_heap),
   _guard_index(cards_required(whole_heap.word_size()) - 1),
   _last_valid_index(_guard_index - 1),
-  _page_size(os::page_size_for_region(_guard_index + 1, _guard_index + 1, 1)),
+  _page_size(os::vm_page_size()),
   _byte_map_size(compute_byte_map_size())
 {
   _kind = BarrierSet::CardTableModRef;
@@ -196,8 +196,8 @@
   assert(_whole_heap.contains(new_region),
            "attempt to cover area not in reserved area");
   debug_only(verify_guard();)
-  int ind = find_covering_region_by_base(new_region.start());
-  MemRegion old_region = _covered[ind];
+  int const ind = find_covering_region_by_base(new_region.start());
+  MemRegion const old_region = _covered[ind];
   assert(old_region.start() == new_region.start(), "just checking");
   if (new_region.word_size() != old_region.word_size()) {
     // Commit new or uncommit old pages, if necessary.
@@ -205,21 +205,21 @@
     // Extend the end of this _commited region
     // to cover the end of any lower _committed regions.
     // This forms overlapping regions, but never interior regions.
-    HeapWord* max_prev_end = largest_prev_committed_end(ind);
+    HeapWord* const max_prev_end = largest_prev_committed_end(ind);
     if (max_prev_end > cur_committed.end()) {
       cur_committed.set_end(max_prev_end);
     }
     // Align the end up to a page size (starts are already aligned).
-    jbyte* new_end = byte_after(new_region.last());
-    HeapWord* new_end_aligned =
-      (HeapWord*)align_size_up((uintptr_t)new_end, _page_size);
+    jbyte* const new_end = byte_after(new_region.last());
+    HeapWord* const new_end_aligned =
+      (HeapWord*) align_size_up((uintptr_t)new_end, _page_size);
     assert(new_end_aligned >= (HeapWord*) new_end,
            "align up, but less");
     // The guard page is always committed and should not be committed over.
-    HeapWord* new_end_for_commit = MIN2(new_end_aligned, _guard_region.start());
+    HeapWord* const new_end_for_commit = MIN2(new_end_aligned, _guard_region.start());
     if (new_end_for_commit > cur_committed.end()) {
       // Must commit new pages.
-      MemRegion new_committed =
+      MemRegion const new_committed =
         MemRegion(cur_committed.end(), new_end_for_commit);
 
       assert(!new_committed.is_empty(), "Region should not be empty here");
@@ -233,7 +233,7 @@
     // the cur_committed region may include the guard region.
     } else if (new_end_aligned < cur_committed.end()) {
       // Must uncommit pages.
-      MemRegion uncommit_region =
+      MemRegion const uncommit_region =
         committed_unique_to_self(ind, MemRegion(new_end_aligned,
                                                 cur_committed.end()));
       if (!uncommit_region.is_empty()) {
@@ -257,7 +257,7 @@
     }
     assert(index_for(new_region.last()) < (int) _guard_index,
       "The guard card will be overwritten");
-    jbyte* end = byte_after(new_region.last());
+    jbyte* const end = byte_after(new_region.last());
     // do nothing if we resized downward.
     if (entry < end) {
       memset(entry, clean_card, pointer_delta(end, entry, sizeof(jbyte)));
--- a/hotspot/src/share/vm/memory/cardTableRS.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/memory/cardTableRS.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -556,10 +556,16 @@
 }
 
 
-void CardTableRS::verify_empty(MemRegion mr) {
+void CardTableRS::verify_aligned_region_empty(MemRegion mr) {
   if (!mr.is_empty()) {
     jbyte* cur_entry = byte_for(mr.start());
     jbyte* limit = byte_after(mr.last());
+    // The region mr may not start on a card boundary so
+    // the first card may reflect a write to the space
+    // just prior to mr.
+    if (!is_aligned(mr.start())) {
+      cur_entry++;
+    }
     for (;cur_entry < limit; cur_entry++) {
       guarantee(*cur_entry == CardTableModRefBS::clean_card,
                 "Unexpected dirty card found");
--- a/hotspot/src/share/vm/memory/cardTableRS.hpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/memory/cardTableRS.hpp	Wed Apr 30 07:03:08 2008 -0700
@@ -126,7 +126,7 @@
   }
 
   void verify();
-  void verify_empty(MemRegion mr);
+  void verify_aligned_region_empty(MemRegion mr);
 
   void clear(MemRegion mr) { _ct_bs.clear(mr); }
   void clear_into_younger(Generation* gen, bool clear_perm);
--- a/hotspot/src/share/vm/memory/collectorPolicy.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/memory/collectorPolicy.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -57,45 +57,51 @@
   // User inputs from -mx and ms are aligned
   _initial_heap_byte_size = align_size_up(Arguments::initial_heap_size(),
                                           min_alignment());
-  _min_heap_byte_size = align_size_up(Arguments::min_heap_size(),
-                                          min_alignment());
-  _max_heap_byte_size = align_size_up(MaxHeapSize, max_alignment());
+  set_min_heap_byte_size(align_size_up(Arguments::min_heap_size(),
+                                          min_alignment()));
+  set_max_heap_byte_size(align_size_up(MaxHeapSize, max_alignment()));
 
   // Check validity of heap parameters from launcher
-  if (_initial_heap_byte_size == 0) {
-    _initial_heap_byte_size = NewSize + OldSize;
+  if (initial_heap_byte_size() == 0) {
+    set_initial_heap_byte_size(NewSize + OldSize);
   } else {
-    Universe::check_alignment(_initial_heap_byte_size, min_alignment(),
+    Universe::check_alignment(initial_heap_byte_size(), min_alignment(),
                             "initial heap");
   }
-  if (_min_heap_byte_size == 0) {
-    _min_heap_byte_size = NewSize + OldSize;
+  if (min_heap_byte_size() == 0) {
+    set_min_heap_byte_size(NewSize + OldSize);
   } else {
-    Universe::check_alignment(_min_heap_byte_size, min_alignment(),
+    Universe::check_alignment(min_heap_byte_size(), min_alignment(),
                             "initial heap");
   }
 
   // Check heap parameter properties
-  if (_initial_heap_byte_size < M) {
+  if (initial_heap_byte_size() < M) {
     vm_exit_during_initialization("Too small initial heap");
   }
   // Check heap parameter properties
-  if (_min_heap_byte_size < M) {
+  if (min_heap_byte_size() < M) {
     vm_exit_during_initialization("Too small minimum heap");
   }
-  if (_initial_heap_byte_size <= NewSize) {
+  if (initial_heap_byte_size() <= NewSize) {
      // make sure there is at least some room in old space
     vm_exit_during_initialization("Too small initial heap for new size specified");
   }
-  if (_max_heap_byte_size < _min_heap_byte_size) {
+  if (max_heap_byte_size() < min_heap_byte_size()) {
     vm_exit_during_initialization("Incompatible minimum and maximum heap sizes specified");
   }
-  if (_initial_heap_byte_size < _min_heap_byte_size) {
+  if (initial_heap_byte_size() < min_heap_byte_size()) {
     vm_exit_during_initialization("Incompatible minimum and initial heap sizes specified");
   }
-  if (_max_heap_byte_size < _initial_heap_byte_size) {
+  if (max_heap_byte_size() < initial_heap_byte_size()) {
     vm_exit_during_initialization("Incompatible initial and maximum heap sizes specified");
   }
+
+  if (PrintGCDetails && Verbose) {
+    gclog_or_tty->print_cr("Minimum heap " SIZE_FORMAT "  Initial heap "
+      SIZE_FORMAT "  Maximum heap " SIZE_FORMAT,
+      min_heap_byte_size(), initial_heap_byte_size(), max_heap_byte_size());
+  }
 }
 
 void CollectorPolicy::initialize_perm_generation(PermGen::Name pgnm) {
@@ -128,10 +134,26 @@
 
 // GenCollectorPolicy methods.
 
+size_t GenCollectorPolicy::scale_by_NewRatio_aligned(size_t base_size) {
+  size_t x = base_size / (NewRatio+1);
+  size_t new_gen_size = x > min_alignment() ?
+                     align_size_down(x, min_alignment()) :
+                     min_alignment();
+  return new_gen_size;
+}
+
+size_t GenCollectorPolicy::bound_minus_alignment(size_t desired_size,
+                                                 size_t maximum_size) {
+  size_t alignment = min_alignment();
+  size_t max_minus = maximum_size - alignment;
+  return desired_size < max_minus ? desired_size : max_minus;
+}
+
+
 void GenCollectorPolicy::initialize_size_policy(size_t init_eden_size,
                                                 size_t init_promo_size,
                                                 size_t init_survivor_size) {
-  double max_gc_minor_pause_sec = ((double) MaxGCMinorPauseMillis)/1000.0;
+  const double max_gc_minor_pause_sec = ((double) MaxGCMinorPauseMillis)/1000.0;
   _size_policy = new AdaptiveSizePolicy(init_eden_size,
                                         init_promo_size,
                                         init_survivor_size,
@@ -210,74 +232,260 @@
   assert(MaxHeapSize % max_alignment() == 0, "maximum heap alignment");
 }
 
+// Values set on the command line win over any ergonomically
+// set command line parameters.
+// Ergonomic choice of parameters are done before this
+// method is called.  Values for command line parameters such as NewSize
+// and MaxNewSize feed those ergonomic choices into this method.
+// This method makes the final generation sizings consistent with
+// themselves and with overall heap sizings.
+// In the absence of explicitly set command line flags, policies
+// such as the use of NewRatio are used to size the generation.
 void GenCollectorPolicy::initialize_size_info() {
   CollectorPolicy::initialize_size_info();
 
-  // Minimum sizes of the generations may be different than
-  // the initial sizes.
-  if (!FLAG_IS_DEFAULT(NewSize)) {
-    _min_gen0_size = NewSize;
+  // min_alignment() is used for alignment within a generation.
+  // There is additional alignment done down stream for some
+  // collectors that sometimes causes unwanted rounding up of
+  // generations sizes.
+
+  // Determine maximum size of gen0
+
+  size_t max_new_size = 0;
+  if (FLAG_IS_CMDLINE(MaxNewSize)) {
+    if (MaxNewSize < min_alignment()) {
+      max_new_size = min_alignment();
+    } else if (MaxNewSize >= max_heap_byte_size()) {
+      max_new_size = align_size_down(max_heap_byte_size() - min_alignment(),
+                                     min_alignment());
+      warning("MaxNewSize (" SIZE_FORMAT "k) is equal to or "
+        "greater than the entire heap (" SIZE_FORMAT "k).  A "
+        "new generation size of " SIZE_FORMAT "k will be used.",
+        MaxNewSize/K, max_heap_byte_size()/K, max_new_size/K);
+    } else {
+      max_new_size = align_size_down(MaxNewSize, min_alignment());
+    }
+
+  // The case for FLAG_IS_ERGO(MaxNewSize) could be treated
+  // specially at this point to just use an ergonomically set
+  // MaxNewSize to set max_new_size.  For cases with small
+  // heaps such a policy often did not work because the MaxNewSize
+  // was larger than the entire heap.  The interpretation given
+  // to ergonomically set flags is that the flags are set
+  // by different collectors for their own special needs but
+  // are not allowed to badly shape the heap.  This allows the
+  // different collectors to decide what's best for themselves
+  // without having to factor in the overall heap shape.  It
+  // can be the case in the future that the collectors would
+  // only make "wise" ergonomics choices and this policy could
+  // just accept those choices.  The choices currently made are
+  // not always "wise".
   } else {
-    _min_gen0_size = align_size_down(_min_heap_byte_size / (NewRatio+1),
-                                     min_alignment());
-    // We bound the minimum size by NewSize below (since it historically
+    max_new_size = scale_by_NewRatio_aligned(max_heap_byte_size());
+    // Bound the maximum size by NewSize below (since it historically
     // would have been NewSize and because the NewRatio calculation could
     // yield a size that is too small) and bound it by MaxNewSize above.
-    // This is not always best.  The NewSize calculated by CMS (which has
-    // a fixed minimum of 16m) can sometimes be "too" large.  Consider
-    // the case where -Xmx32m.  The CMS calculated NewSize would be about
-    // half the entire heap which seems too large.  But the counter
-    // example is seen when the client defaults for NewRatio are used.
-    // An initial young generation size of 640k was observed
-    // with -Xmx128m -XX:MaxNewSize=32m when NewSize was not used
-    // as a lower bound as with
-    // _min_gen0_size = MIN2(_min_gen0_size, MaxNewSize);
-    // and 640k seemed too small a young generation.
-    _min_gen0_size = MIN2(MAX2(_min_gen0_size, NewSize), MaxNewSize);
+    // Ergonomics plays here by previously calculating the desired
+    // NewSize and MaxNewSize.
+    max_new_size = MIN2(MAX2(max_new_size, NewSize), MaxNewSize);
+  }
+  assert(max_new_size > 0, "All paths should set max_new_size");
+
+  // Given the maximum gen0 size, determine the initial and
+  // minimum sizes.
+
+  if (max_heap_byte_size() == min_heap_byte_size()) {
+    // The maximum and minimum heap sizes are the same so
+    // the generations minimum and initial must be the
+    // same as its maximum.
+    set_min_gen0_size(max_new_size);
+    set_initial_gen0_size(max_new_size);
+    set_max_gen0_size(max_new_size);
+  } else {
+    size_t desired_new_size = 0;
+    if (!FLAG_IS_DEFAULT(NewSize)) {
+      // If NewSize is set ergonomically (for example by cms), it
+      // would make sense to use it.  If it is used, also use it
+      // to set the initial size.  Although there is no reason
+      // the minimum size and the initial size have to be the same,
+      // the current implementation gets into trouble during the calculation
+      // of the tenured generation sizes if they are different.
+      // Note that this makes the initial size and the minimum size
+      // generally small compared to the NewRatio calculation.
+      _min_gen0_size = NewSize;
+      desired_new_size = NewSize;
+      max_new_size = MAX2(max_new_size, NewSize);
+    } else {
+      // For the case where NewSize is the default, use NewRatio
+      // to size the minimum and initial generation sizes.
+      // Use the default NewSize as the floor for these values.  If
+      // NewRatio is overly large, the resulting sizes can be too
+      // small.
+      _min_gen0_size = MAX2(scale_by_NewRatio_aligned(min_heap_byte_size()),
+                          NewSize);
+      desired_new_size =
+        MAX2(scale_by_NewRatio_aligned(initial_heap_byte_size()),
+             NewSize);
+    }
+
+    assert(_min_gen0_size > 0, "Sanity check");
+    set_initial_gen0_size(desired_new_size);
+    set_max_gen0_size(max_new_size);
+
+    // At this point the desirable initial and minimum sizes have been
+    // determined without regard to the maximum sizes.
+
+    // Bound the sizes by the corresponding overall heap sizes.
+    set_min_gen0_size(
+      bound_minus_alignment(_min_gen0_size, min_heap_byte_size()));
+    set_initial_gen0_size(
+      bound_minus_alignment(_initial_gen0_size, initial_heap_byte_size()));
+    set_max_gen0_size(
+      bound_minus_alignment(_max_gen0_size, max_heap_byte_size()));
+
+    // At this point all three sizes have been checked against the
+    // maximum sizes but have not been checked for consistency
+    // amoung the three.
+
+    // Final check min <= initial <= max
+    set_min_gen0_size(MIN2(_min_gen0_size, _max_gen0_size));
+    set_initial_gen0_size(
+      MAX2(MIN2(_initial_gen0_size, _max_gen0_size), _min_gen0_size));
+    set_min_gen0_size(MIN2(_min_gen0_size, _initial_gen0_size));
   }
 
-  // Parameters are valid, compute area sizes.
-  size_t max_new_size = align_size_down(_max_heap_byte_size / (NewRatio+1),
-                                        min_alignment());
-  max_new_size = MIN2(MAX2(max_new_size, _min_gen0_size), MaxNewSize);
+  if (PrintGCDetails && Verbose) {
+    gclog_or_tty->print_cr("Minimum gen0 " SIZE_FORMAT "  Initial gen0 "
+      SIZE_FORMAT "  Maximum gen0 " SIZE_FORMAT,
+      min_gen0_size(), initial_gen0_size(), max_gen0_size());
+  }
+}
 
-  // desired_new_size is used to set the initial size.  The
-  // initial size must be greater than the minimum size.
-  size_t desired_new_size =
-    align_size_down(_initial_heap_byte_size / (NewRatio+1),
-                  min_alignment());
+// Call this method during the sizing of the gen1 to make
+// adjustments to gen0 because of gen1 sizing policy.  gen0 initially has
+// the most freedom in sizing because it is done before the
+// policy for gen1 is applied.  Once gen1 policies have been applied,
+// there may be conflicts in the shape of the heap and this method
+// is used to make the needed adjustments.  The application of the
+// policies could be more sophisticated (iterative for example) but
+// keeping it simple also seems a worthwhile goal.
+bool TwoGenerationCollectorPolicy::adjust_gen0_sizes(size_t* gen0_size_ptr,
+                                                     size_t* gen1_size_ptr,
+                                                     size_t heap_size,
+                                                     size_t min_gen0_size) {
+  bool result = false;
+  if ((*gen1_size_ptr + *gen0_size_ptr) > heap_size) {
+    if (((*gen0_size_ptr + OldSize) > heap_size) &&
+       (heap_size - min_gen0_size) >= min_alignment()) {
+      // Adjust gen0 down to accomodate OldSize
+      *gen0_size_ptr = heap_size - min_gen0_size;
+      *gen0_size_ptr =
+        MAX2((uintx)align_size_down(*gen0_size_ptr, min_alignment()),
+             min_alignment());
+      assert(*gen0_size_ptr > 0, "Min gen0 is too large");
+      result = true;
+    } else {
+      *gen1_size_ptr = heap_size - *gen0_size_ptr;
+      *gen1_size_ptr =
+        MAX2((uintx)align_size_down(*gen1_size_ptr, min_alignment()),
+                       min_alignment());
+    }
+  }
+  return result;
+}
 
-  size_t new_size = MIN2(MAX2(desired_new_size, _min_gen0_size), max_new_size);
-
-  _initial_gen0_size = new_size;
-  _max_gen0_size = max_new_size;
-}
+// Minimum sizes of the generations may be different than
+// the initial sizes.  An inconsistently is permitted here
+// in the total size that can be specified explicitly by
+// command line specification of OldSize and NewSize and
+// also a command line specification of -Xms.  Issue a warning
+// but allow the values to pass.
 
 void TwoGenerationCollectorPolicy::initialize_size_info() {
   GenCollectorPolicy::initialize_size_info();
 
-  // Minimum sizes of the generations may be different than
-  // the initial sizes.  An inconsistently is permitted here
-  // in the total size that can be specified explicitly by
-  // command line specification of OldSize and NewSize and
-  // also a command line specification of -Xms.  Issue a warning
-  // but allow the values to pass.
-  if (!FLAG_IS_DEFAULT(OldSize)) {
-    _min_gen1_size = OldSize;
+  // At this point the minimum, initial and maximum sizes
+  // of the overall heap and of gen0 have been determined.
+  // The maximum gen1 size can be determined from the maximum gen0
+  // and maximum heap size since not explicit flags exits
+  // for setting the gen1 maximum.
+  _max_gen1_size = max_heap_byte_size() - _max_gen0_size;
+  _max_gen1_size =
+    MAX2((uintx)align_size_down(_max_gen1_size, min_alignment()),
+         min_alignment());
+  // If no explicit command line flag has been set for the
+  // gen1 size, use what is left for gen1.
+  if (FLAG_IS_DEFAULT(OldSize) || FLAG_IS_ERGO(OldSize)) {
+    // The user has not specified any value or ergonomics
+    // has chosen a value (which may or may not be consistent
+    // with the overall heap size).  In either case make
+    // the minimum, maximum and initial sizes consistent
+    // with the gen0 sizes and the overall heap sizes.
+    assert(min_heap_byte_size() > _min_gen0_size,
+      "gen0 has an unexpected minimum size");
+    set_min_gen1_size(min_heap_byte_size() - min_gen0_size());
+    set_min_gen1_size(
+      MAX2((uintx)align_size_down(_min_gen1_size, min_alignment()),
+           min_alignment()));
+    set_initial_gen1_size(initial_heap_byte_size() - initial_gen0_size());
+    set_initial_gen1_size(
+      MAX2((uintx)align_size_down(_initial_gen1_size, min_alignment()),
+           min_alignment()));
+
+  } else {
+    // It's been explicitly set on the command line.  Use the
+    // OldSize and then determine the consequences.
+    set_min_gen1_size(OldSize);
+    set_initial_gen1_size(OldSize);
+
+    // If the user has explicitly set an OldSize that is inconsistent
+    // with other command line flags, issue a warning.
     // The generation minimums and the overall heap mimimum should
     // be within one heap alignment.
-    if ((_min_gen1_size + _min_gen0_size + max_alignment()) <
-         _min_heap_byte_size) {
+    if ((_min_gen1_size + _min_gen0_size + min_alignment()) <
+           min_heap_byte_size()) {
       warning("Inconsistency between minimum heap size and minimum "
-        "generation sizes: using min heap = " SIZE_FORMAT,
-        _min_heap_byte_size);
+          "generation sizes: using minimum heap = " SIZE_FORMAT,
+          min_heap_byte_size());
     }
-  } else {
-    _min_gen1_size = _min_heap_byte_size - _min_gen0_size;
+    if ((OldSize > _max_gen1_size)) {
+      warning("Inconsistency between maximum heap size and maximum "
+          "generation sizes: using maximum heap = " SIZE_FORMAT
+          " -XX:OldSize flag is being ignored",
+          max_heap_byte_size());
   }
+    // If there is an inconsistency between the OldSize and the minimum and/or
+    // initial size of gen0, since OldSize was explicitly set, OldSize wins.
+    if (adjust_gen0_sizes(&_min_gen0_size, &_min_gen1_size,
+                          min_heap_byte_size(), OldSize)) {
+      if (PrintGCDetails && Verbose) {
+        gclog_or_tty->print_cr("Minimum gen0 " SIZE_FORMAT "  Initial gen0 "
+              SIZE_FORMAT "  Maximum gen0 " SIZE_FORMAT,
+              min_gen0_size(), initial_gen0_size(), max_gen0_size());
+      }
+    }
+    // Initial size
+    if (adjust_gen0_sizes(&_initial_gen0_size, &_initial_gen1_size,
+                         initial_heap_byte_size(), OldSize)) {
+      if (PrintGCDetails && Verbose) {
+        gclog_or_tty->print_cr("Minimum gen0 " SIZE_FORMAT "  Initial gen0 "
+          SIZE_FORMAT "  Maximum gen0 " SIZE_FORMAT,
+          min_gen0_size(), initial_gen0_size(), max_gen0_size());
+      }
+    }
+  }
+  // Enforce the maximum gen1 size.
+  set_min_gen1_size(MIN2(_min_gen1_size, _max_gen1_size));
 
-  _initial_gen1_size = _initial_heap_byte_size - _initial_gen0_size;
-  _max_gen1_size = _max_heap_byte_size - _max_gen0_size;
+  // Check that min gen1 <= initial gen1 <= max gen1
+  set_initial_gen1_size(MAX2(_initial_gen1_size, _min_gen1_size));
+  set_initial_gen1_size(MIN2(_initial_gen1_size, _max_gen1_size));
+
+  if (PrintGCDetails && Verbose) {
+    gclog_or_tty->print_cr("Minimum gen1 " SIZE_FORMAT "  Initial gen1 "
+      SIZE_FORMAT "  Maximum gen1 " SIZE_FORMAT,
+      min_gen1_size(), initial_gen1_size(), max_gen1_size());
+  }
 }
 
 HeapWord* GenCollectorPolicy::mem_allocate_work(size_t size,
--- a/hotspot/src/share/vm/memory/collectorPolicy.hpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/memory/collectorPolicy.hpp	Wed Apr 30 07:03:08 2008 -0700
@@ -82,8 +82,11 @@
   size_t max_alignment()                       { return _max_alignment; }
 
   size_t initial_heap_byte_size() { return _initial_heap_byte_size; }
+  void set_initial_heap_byte_size(size_t v) { _initial_heap_byte_size = v; }
   size_t max_heap_byte_size()     { return _max_heap_byte_size; }
+  void set_max_heap_byte_size(size_t v) { _max_heap_byte_size = v; }
   size_t min_heap_byte_size()     { return _min_heap_byte_size; }
+  void set_min_heap_byte_size(size_t v) { _min_heap_byte_size = v; }
 
   enum Name {
     CollectorPolicyKind,
@@ -182,8 +185,24 @@
   // compute max heap alignment
   size_t compute_max_alignment();
 
+ // Scale the base_size by NewRation according to
+ //     result = base_size / (NewRatio + 1)
+ // and align by min_alignment()
+ size_t scale_by_NewRatio_aligned(size_t base_size);
+
+ // Bound the value by the given maximum minus the
+ // min_alignment.
+ size_t bound_minus_alignment(size_t desired_size, size_t maximum_size);
 
  public:
+  // Accessors
+  size_t min_gen0_size() { return _min_gen0_size; }
+  void set_min_gen0_size(size_t v) { _min_gen0_size = v; }
+  size_t initial_gen0_size() { return _initial_gen0_size; }
+  void set_initial_gen0_size(size_t v) { _initial_gen0_size = v; }
+  size_t max_gen0_size() { return _max_gen0_size; }
+  void set_max_gen0_size(size_t v) { _max_gen0_size = v; }
+
   virtual int number_of_generations() = 0;
 
   virtual GenerationSpec **generations()       {
@@ -236,6 +255,14 @@
   void initialize_generations()                { ShouldNotReachHere(); }
 
  public:
+  // Accessors
+  size_t min_gen1_size() { return _min_gen1_size; }
+  void set_min_gen1_size(size_t v) { _min_gen1_size = v; }
+  size_t initial_gen1_size() { return _initial_gen1_size; }
+  void set_initial_gen1_size(size_t v) { _initial_gen1_size = v; }
+  size_t max_gen1_size() { return _max_gen1_size; }
+  void set_max_gen1_size(size_t v) { _max_gen1_size = v; }
+
   // Inherited methods
   TwoGenerationCollectorPolicy* as_two_generation_policy() { return this; }
 
@@ -246,6 +273,10 @@
   virtual CollectorPolicy::Name kind() {
     return CollectorPolicy::TwoGenerationCollectorPolicyKind;
   }
+
+  // Returns true is gen0 sizes were adjusted
+  bool adjust_gen0_sizes(size_t* gen0_size_ptr, size_t* gen1_size_ptr,
+                               size_t heap_size, size_t min_gen1_size);
 };
 
 class MarkSweepPolicy : public TwoGenerationCollectorPolicy {
--- a/hotspot/src/share/vm/memory/compactingPermGenGen.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/memory/compactingPermGenGen.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -26,9 +26,27 @@
 #include "incls/_compactingPermGenGen.cpp.incl"
 
 
-// Recursively adjust all pointers in an object and all objects by
-// referenced it.  Clear marks on objects in order to prevent visiting
-// any object twice.
+// An ObjectClosure helper: Recursively adjust all pointers in an object
+// and all objects by referenced it. Clear marks on objects in order to
+// prevent visiting any object twice. This helper is used when the
+// RedefineClasses() API has been called.
+
+class AdjustSharedObjectClosure : public ObjectClosure {
+public:
+  void do_object(oop obj) {
+    if (obj->is_shared_readwrite()) {
+      if (obj->mark()->is_marked()) {
+        obj->init_mark();         // Don't revisit this object.
+        obj->adjust_pointers();   // Adjust this object's references.
+      }
+    }
+  }
+};
+
+
+// An OopClosure helper: Recursively adjust all pointers in an object
+// and all objects by referenced it. Clear marks on objects in order
+// to prevent visiting any object twice.
 
 class RecursiveAdjustSharedObjectClosure : public OopClosure {
 public:
@@ -274,15 +292,34 @@
 // objects in the space will page in more objects than we need.
 // Instead, use the system dictionary as strong roots into the read
 // write space.
+//
+// If a RedefineClasses() call has been made, then we have to iterate
+// over the entire shared read-write space in order to find all the
+// objects that need to be forwarded. For example, it is possible for
+// an nmethod to be found and marked in GC phase-1 only for the nmethod
+// to be freed by the time we reach GC phase-3. The underlying method
+// is still marked, but we can't (easily) find it in GC phase-3 so we
+// blow up in GC phase-4. With RedefineClasses() we want replaced code
+// (EMCP or obsolete) to go away (i.e., be collectible) once it is no
+// longer being executed by any thread so we keep minimal attachments
+// to the replaced code. However, we can't guarantee when those EMCP
+// or obsolete methods will be collected so they may still be out there
+// even after we've severed our minimal attachments.
 
 void CompactingPermGenGen::pre_adjust_pointers() {
   if (spec()->enable_shared_spaces()) {
-    RecursiveAdjustSharedObjectClosure blk;
-    Universe::oops_do(&blk);
-    StringTable::oops_do(&blk);
-    SystemDictionary::always_strong_classes_do(&blk);
-    TraversePlaceholdersClosure tpc;
-    SystemDictionary::placeholders_do(&tpc);
+    if (JvmtiExport::has_redefined_a_class()) {
+      // RedefineClasses() requires a brute force approach
+      AdjustSharedObjectClosure blk;
+      rw_space()->object_iterate(&blk);
+    } else {
+      RecursiveAdjustSharedObjectClosure blk;
+      Universe::oops_do(&blk);
+      StringTable::oops_do(&blk);
+      SystemDictionary::always_strong_classes_do(&blk);
+      TraversePlaceholdersClosure tpc;
+      SystemDictionary::placeholders_do(&tpc);
+    }
   }
 }
 
--- a/hotspot/src/share/vm/memory/genRemSet.hpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/memory/genRemSet.hpp	Wed Apr 30 07:03:08 2008 -0700
@@ -91,8 +91,15 @@
   virtual void verify() = 0;
 
   // Verify that the remembered set has no entries for
-  // the heap interval denoted by mr.
-  virtual void verify_empty(MemRegion mr) = 0;
+  // the heap interval denoted by mr.  If there are any
+  // alignment constraints on the remembered set, only the
+  // part of the region that is aligned is checked.
+  //
+  //   alignment boundaries
+  //   +--------+-------+--------+-------+
+  //         [ region mr              )
+  //            [ part checked   )
+  virtual void verify_aligned_region_empty(MemRegion mr) = 0;
 
   // If appropriate, print some information about the remset on "tty".
   virtual void print() {}
--- a/hotspot/src/share/vm/memory/heap.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/memory/heap.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -102,8 +102,9 @@
   _log2_segment_size = exact_log2(segment_size);
 
   // Reserve and initialize space for _memory.
-  const size_t page_size = os::page_size_for_region(committed_size,
-                                                    reserved_size, 8);
+  const size_t page_size = os::can_execute_large_page_memory() ?
+          os::page_size_for_region(committed_size, reserved_size, 8) :
+          os::vm_page_size();
   const size_t granularity = os::vm_allocation_granularity();
   const size_t r_align = MAX2(page_size, granularity);
   const size_t r_size = align_size_up(reserved_size, r_align);
@@ -111,7 +112,7 @@
 
   const size_t rs_align = page_size == (size_t) os::vm_page_size() ? 0 :
     MAX2(page_size, granularity);
-  ReservedSpace rs(r_size, rs_align, false);
+  ReservedSpace rs(r_size, rs_align, rs_align > 0);
   os::trace_page_sizes("code heap", committed_size, reserved_size, page_size,
                        rs.base(), rs.size());
   if (!_memory.initialize(rs, c_size)) {
--- a/hotspot/src/share/vm/memory/heapInspection.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/memory/heapInspection.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -65,7 +65,7 @@
       name = "<no name>";
   }
   // simplify the formatting (ILP32 vs LP64) - always cast the numbers to 64-bit
-  st->print_cr("%13" FORMAT64_MODIFIER "d  %13" FORMAT64_MODIFIER "u  %s",
+  st->print_cr(INT64_FORMAT_W(13) "  " UINT64_FORMAT_W(13) "  %s",
                (jlong)  _instance_count,
                (julong) _instance_words * HeapWordSize,
                name);
@@ -80,7 +80,10 @@
     elt = elt->next();
   }
   elt = new KlassInfoEntry(k, list());
-  set_list(elt);
+  // We may be out of space to allocate the new entry.
+  if (elt != NULL) {
+    set_list(elt);
+  }
   return elt;
 }
 
@@ -103,21 +106,25 @@
 }
 
 KlassInfoTable::KlassInfoTable(int size, HeapWord* ref) {
-  _size = size;
+  _size = 0;
   _ref = ref;
-  _buckets = NEW_C_HEAP_ARRAY(KlassInfoBucket, _size);
-
-  for (int index = 0; index < _size; index++) {
-    _buckets[index].initialize();
+  _buckets = NEW_C_HEAP_ARRAY(KlassInfoBucket, size);
+  if (_buckets != NULL) {
+    _size = size;
+    for (int index = 0; index < _size; index++) {
+      _buckets[index].initialize();
+    }
   }
 }
 
 KlassInfoTable::~KlassInfoTable() {
-  for (int index = 0; index < _size; index++) {
-    _buckets[index].empty();
+  if (_buckets != NULL) {
+    for (int index = 0; index < _size; index++) {
+      _buckets[index].empty();
+    }
+    FREE_C_HEAP_ARRAY(KlassInfoBucket, _buckets);
+    _size = 0;
   }
-  FREE_C_HEAP_ARRAY(KlassInfoBucket, _buckets);
-  _size = 0;
 }
 
 uint KlassInfoTable::hash(klassOop p) {
@@ -127,19 +134,32 @@
 
 KlassInfoEntry* KlassInfoTable::lookup(const klassOop k) {
   uint         idx = hash(k) % _size;
+  assert(_buckets != NULL, "Allocation failure should have been caught");
   KlassInfoEntry*  e   = _buckets[idx].lookup(k);
-  assert(k == e->klass(), "must be equal");
+  // Lookup may fail if this is a new klass for which we
+  // could not allocate space for an new entry.
+  assert(e == NULL || k == e->klass(), "must be equal");
   return e;
 }
 
-void KlassInfoTable::record_instance(const oop obj) {
+// Return false if the entry could not be recorded on account
+// of running out of space required to create a new entry.
+bool KlassInfoTable::record_instance(const oop obj) {
   klassOop      k = obj->klass();
   KlassInfoEntry* elt = lookup(k);
-  elt->set_count(elt->count() + 1);
-  elt->set_words(elt->words() + obj->size());
+  // elt may be NULL if it's a new klass for which we
+  // could not allocate space for a new entry in the hashtable.
+  if (elt != NULL) {
+    elt->set_count(elt->count() + 1);
+    elt->set_words(elt->words() + obj->size());
+    return true;
+  } else {
+    return false;
+  }
 }
 
 void KlassInfoTable::iterate(KlassInfoClosure* cic) {
+  assert(_size == 0 || _buckets != NULL, "Allocation failure should have been caught");
   for (int index = 0; index < _size; index++) {
     _buckets[index].iterate(cic);
   }
@@ -176,7 +196,7 @@
     total += elements()->at(i)->count();
     totalw += elements()->at(i)->words();
   }
-  st->print_cr("Total %13" FORMAT64_MODIFIER "d  %13" FORMAT64_MODIFIER "u",
+  st->print_cr("Total " INT64_FORMAT_W(13) "  " UINT64_FORMAT_W(13),
                total, totalw * HeapWordSize);
 }
 
@@ -199,12 +219,18 @@
 class RecordInstanceClosure : public ObjectClosure {
  private:
   KlassInfoTable* _cit;
+  size_t _missed_count;
  public:
-  RecordInstanceClosure(KlassInfoTable* cit) : _cit(cit) {}
+  RecordInstanceClosure(KlassInfoTable* cit) :
+    _cit(cit), _missed_count(0) {}
 
   void do_object(oop obj) {
-    _cit->record_instance(obj);
+    if (!_cit->record_instance(obj)) {
+      _missed_count++;
+    }
   }
+
+  size_t missed_count() { return _missed_count; }
 };
 
 void HeapInspection::heap_inspection(outputStream* st) {
@@ -230,21 +256,32 @@
       ShouldNotReachHere(); // Unexpected heap kind for this op
   }
   // Collect klass instance info
+  KlassInfoTable cit(KlassInfoTable::cit_size, ref);
+  if (!cit.allocation_failed()) {
+    // Iterate over objects in the heap
+    RecordInstanceClosure ric(&cit);
+    Universe::heap()->object_iterate(&ric);
 
-  // Iterate over objects in the heap
-  KlassInfoTable cit(KlassInfoTable::cit_size, ref);
-  RecordInstanceClosure ric(&cit);
-  Universe::heap()->object_iterate(&ric);
-
-  // Sort and print klass instance info
-  KlassInfoHisto histo("\n"
-                   " num     #instances         #bytes  class name\n"
-                   "----------------------------------------------",
-                   KlassInfoHisto::histo_initial_size);
-  HistoClosure hc(&histo);
-  cit.iterate(&hc);
-  histo.sort();
-  histo.print_on(st);
+    // Report if certain classes are not counted because of
+    // running out of C-heap for the histogram.
+    size_t missed_count = ric.missed_count();
+    if (missed_count != 0) {
+      st->print_cr("WARNING: Ran out of C-heap; undercounted " SIZE_FORMAT
+                   " total instances in data below",
+                   missed_count);
+    }
+    // Sort and print klass instance info
+    KlassInfoHisto histo("\n"
+                     " num     #instances         #bytes  class name\n"
+                     "----------------------------------------------",
+                     KlassInfoHisto::histo_initial_size);
+    HistoClosure hc(&histo);
+    cit.iterate(&hc);
+    histo.sort();
+    histo.print_on(st);
+  } else {
+    st->print_cr("WARNING: Ran out of C-heap; histogram not generated");
+  }
   st->flush();
 
   if (Universe::heap()->kind() == CollectedHeap::GenCollectedHeap) {
--- a/hotspot/src/share/vm/memory/heapInspection.hpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/memory/heapInspection.hpp	Wed Apr 30 07:03:08 2008 -0700
@@ -98,8 +98,9 @@
   };
   KlassInfoTable(int size, HeapWord* ref);
   ~KlassInfoTable();
-  void record_instance(const oop obj);
+  bool record_instance(const oop obj);
   void iterate(KlassInfoClosure* cic);
+  bool allocation_failed() { return _buckets == NULL; }
 };
 
 class KlassInfoHisto : public StackObj {
--- a/hotspot/src/share/vm/memory/referenceProcessor.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/memory/referenceProcessor.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -85,7 +85,7 @@
   ReferenceProcessor* rp =
     new ReferenceProcessor(span, atomic_discovery,
                            mt_discovery, mt_degree,
-                           mt_processing);
+                           mt_processing && (parallel_gc_threads > 0));
   if (rp == NULL) {
     vm_exit_during_initialization("Could not allocate ReferenceProcessor object");
   }
--- a/hotspot/src/share/vm/memory/tenuredGeneration.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/memory/tenuredGeneration.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -409,10 +409,11 @@
 void TenuredGeneration::verify_alloc_buffers_clean() {
   if (UseParNewGC) {
     for (uint i = 0; i < ParallelGCThreads; i++) {
-      _rs->verify_empty(_alloc_buffers[i]->range());
+      _rs->verify_aligned_region_empty(_alloc_buffers[i]->range());
     }
   }
 }
+
 #else  // SERIALGC
 void TenuredGeneration::retire_alloc_buffers_before_full_gc() {}
 void TenuredGeneration::verify_alloc_buffers_clean() {}
--- a/hotspot/src/share/vm/oops/arrayOop.hpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/oops/arrayOop.hpp	Wed Apr 30 07:03:08 2008 -0700
@@ -58,11 +58,11 @@
   // alignments.  It gets the scale from the type2aelembytes array.
   static int32_t max_array_length(BasicType type) {
     assert(type >= 0 && type < T_CONFLICT, "wrong type");
-    assert(type2aelembytes[type] != 0, "wrong type");
+    assert(type2aelembytes(type) != 0, "wrong type");
     // We use max_jint, since object_size is internally represented by an 'int'
     // This gives us an upper bound of max_jint words for the size of the oop.
     int32_t max_words = (max_jint - header_size(type) - 2);
-    int elembytes = (type == T_OBJECT) ? T_OBJECT_aelem_bytes : type2aelembytes[type];
+    int elembytes = (type == T_OBJECT) ? T_OBJECT_aelem_bytes : type2aelembytes(type);
     jlong len = ((jlong)max_words * HeapWordSize) / elembytes;
     return (len > max_jint) ? max_jint : (int32_t)len;
   }
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -791,17 +791,39 @@
 }
 
 
+static int compare_fields_by_offset(int* a, int* b) {
+  return a[0] - b[0];
+}
+
 void instanceKlass::do_nonstatic_fields(FieldClosure* cl) {
-  fieldDescriptor fd;
   instanceKlass* super = superklass();
   if (super != NULL) {
     super->do_nonstatic_fields(cl);
   }
+  fieldDescriptor fd;
   int length = fields()->length();
+  // In DebugInfo nonstatic fields are sorted by offset.
+  int* fields_sorted = NEW_C_HEAP_ARRAY(int, 2*(length+1));
+  int j = 0;
   for (int i = 0; i < length; i += next_offset) {
     fd.initialize(as_klassOop(), i);
-    if (!(fd.is_static())) cl->do_field(&fd);
+    if (!fd.is_static()) {
+      fields_sorted[j + 0] = fd.offset();
+      fields_sorted[j + 1] = i;
+      j += 2;
+    }
   }
+  if (j > 0) {
+    length = j;
+    // _sort_Fn is defined in growableArray.hpp.
+    qsort(fields_sorted, length/2, 2*sizeof(int), (_sort_Fn)compare_fields_by_offset);
+    for (int i = 0; i < length; i += 2) {
+      fd.initialize(as_klassOop(), fields_sorted[i + 1]);
+      assert(!fd.is_static() && fd.offset() == fields_sorted[i], "only nonstatic fields");
+      cl->do_field(&fd);
+    }
+  }
+  FREE_C_HEAP_ARRAY(int, fields_sorted);
 }
 
 
@@ -950,7 +972,6 @@
     // These allocations will have to be freed if they are unused.
 
     // Allocate a new array of methods.
-    jmethodID* to_dealloc_jmeths = NULL;
     jmethodID* new_jmeths = NULL;
     if (length <= idnum) {
       // A new array will be needed (unless some other thread beats us to it)
@@ -961,7 +982,6 @@
     }
 
     // Allocate a new method ID.
-    jmethodID to_dealloc_id = NULL;
     jmethodID new_id = NULL;
     if (method_h->is_old() && !method_h->is_obsolete()) {
       // The method passed in is old (but not obsolete), we need to use the current version
@@ -975,40 +995,51 @@
       new_id = JNIHandles::make_jmethod_id(method_h);
     }
 
-    {
+    if (Threads::number_of_threads() == 0 || SafepointSynchronize::is_at_safepoint()) {
+      // No need and unsafe to lock the JmethodIdCreation_lock at safepoint.
+      id = get_jmethod_id(ik_h, idnum, new_id, new_jmeths);
+    } else {
       MutexLocker ml(JmethodIdCreation_lock);
+      id = get_jmethod_id(ik_h, idnum, new_id, new_jmeths);
+    }
+  }
+  return id;
+}
 
-      // We must not go to a safepoint while holding this lock.
-      debug_only(No_Safepoint_Verifier nosafepoints;)
 
-      // Retry lookup after we got the lock
-      jmeths = ik_h->methods_jmethod_ids_acquire();
-      if (jmeths == NULL || (length = (size_t)jmeths[0]) <= idnum) {
-        if (jmeths != NULL) {
-          // We have grown the array: copy the existing entries, and delete the old array
-          for (size_t index = 0; index < length; index++) {
-            new_jmeths[index+1] = jmeths[index+1];
-          }
-          to_dealloc_jmeths = jmeths; // using the new jmeths, deallocate the old one
-        }
-        ik_h->release_set_methods_jmethod_ids(jmeths = new_jmeths);
-      } else {
-        id = jmeths[idnum+1];
-        to_dealloc_jmeths = new_jmeths; // using the old jmeths, deallocate the new one
+jmethodID instanceKlass::get_jmethod_id(instanceKlassHandle ik_h, size_t idnum,
+                                        jmethodID new_id, jmethodID* new_jmeths) {
+  // Retry lookup after we got the lock or ensured we are at safepoint
+  jmethodID* jmeths = ik_h->methods_jmethod_ids_acquire();
+  jmethodID  id                = NULL;
+  jmethodID  to_dealloc_id     = NULL;
+  jmethodID* to_dealloc_jmeths = NULL;
+  size_t     length;
+
+  if (jmeths == NULL || (length = (size_t)jmeths[0]) <= idnum) {
+    if (jmeths != NULL) {
+      // We have grown the array: copy the existing entries, and delete the old array
+      for (size_t index = 0; index < length; index++) {
+        new_jmeths[index+1] = jmeths[index+1];
       }
-      if (id == NULL) {
-        id = new_id;
-        jmeths[idnum+1] = id;  // install the new method ID
-      } else {
-        to_dealloc_id = new_id; // the new id wasn't used, mark it for deallocation
-      }
+      to_dealloc_jmeths = jmeths; // using the new jmeths, deallocate the old one
     }
+    ik_h->release_set_methods_jmethod_ids(jmeths = new_jmeths);
+  } else {
+    id = jmeths[idnum+1];
+    to_dealloc_jmeths = new_jmeths; // using the old jmeths, deallocate the new one
+  }
+  if (id == NULL) {
+    id = new_id;
+    jmeths[idnum+1] = id;  // install the new method ID
+  } else {
+    to_dealloc_id = new_id; // the new id wasn't used, mark it for deallocation
+  }
 
-    // Free up unneeded or no longer needed resources
-    FreeHeap(to_dealloc_jmeths);
-    if (to_dealloc_id != NULL) {
-      JNIHandles::destroy_jmethod_id(to_dealloc_id);
-    }
+  // Free up unneeded or no longer needed resources
+  FreeHeap(to_dealloc_jmeths);
+  if (to_dealloc_id != NULL) {
+    JNIHandles::destroy_jmethod_id(to_dealloc_id);
   }
   return id;
 }
@@ -2165,12 +2196,20 @@
   RC_TRACE(0x00000100, ("adding previous version ref for %s @%d, EMCP_cnt=%d",
     ikh->external_name(), _previous_versions->length(), emcp_method_count));
   constantPoolHandle cp_h(ikh->constants());
-  jweak cp_ref = JNIHandles::make_weak_global(cp_h);
+  jobject cp_ref;
+  if (cp_h->is_shared()) {
+    // a shared ConstantPool requires a regular reference; a weak
+    // reference would be collectible
+    cp_ref = JNIHandles::make_global(cp_h);
+  } else {
+    cp_ref = JNIHandles::make_weak_global(cp_h);
+  }
   PreviousVersionNode * pv_node = NULL;
   objArrayOop old_methods = ikh->methods();
 
   if (emcp_method_count == 0) {
-    pv_node = new PreviousVersionNode(cp_ref, NULL);
+    // non-shared ConstantPool gets a weak reference
+    pv_node = new PreviousVersionNode(cp_ref, !cp_h->is_shared(), NULL);
     RC_TRACE(0x00000400,
       ("add: all methods are obsolete; flushing any EMCP weak refs"));
   } else {
@@ -2190,7 +2229,8 @@
         }
       }
     }
-    pv_node = new PreviousVersionNode(cp_ref, method_refs);
+    // non-shared ConstantPool gets a weak reference
+    pv_node = new PreviousVersionNode(cp_ref, !cp_h->is_shared(), method_refs);
   }
 
   _previous_versions->append(pv_node);
@@ -2208,7 +2248,7 @@
     // check the previous versions array for a GC'ed weak refs
     pv_node = _previous_versions->at(i);
     cp_ref = pv_node->prev_constant_pool();
-    assert(cp_ref != NULL, "weak cp ref was unexpectedly cleared");
+    assert(cp_ref != NULL, "cp ref was unexpectedly cleared");
     if (cp_ref == NULL) {
       delete pv_node;
       _previous_versions->remove_at(i);
@@ -2281,7 +2321,7 @@
           // check the previous versions array for a GC'ed weak refs
           pv_node = _previous_versions->at(j);
           cp_ref = pv_node->prev_constant_pool();
-          assert(cp_ref != NULL, "weak cp ref was unexpectedly cleared");
+          assert(cp_ref != NULL, "cp ref was unexpectedly cleared");
           if (cp_ref == NULL) {
             delete pv_node;
             _previous_versions->remove_at(j);
@@ -2379,8 +2419,8 @@
     // been GC'ed
     PreviousVersionNode * pv_node = _previous_versions->at(i);
 
-    jweak cp_ref = pv_node->prev_constant_pool();
-    assert(cp_ref != NULL, "weak reference was unexpectedly cleared");
+    jobject cp_ref = pv_node->prev_constant_pool();
+    assert(cp_ref != NULL, "cp reference was unexpectedly cleared");
     if (cp_ref == NULL) {
       continue;  // robustness
     }
@@ -2440,10 +2480,11 @@
 
 // Construct a PreviousVersionNode entry for the array hung off
 // the instanceKlass.
-PreviousVersionNode::PreviousVersionNode(jweak prev_constant_pool,
-  GrowableArray<jweak>* prev_EMCP_methods) {
+PreviousVersionNode::PreviousVersionNode(jobject prev_constant_pool,
+  bool prev_cp_is_weak, GrowableArray<jweak>* prev_EMCP_methods) {
 
   _prev_constant_pool = prev_constant_pool;
+  _prev_cp_is_weak = prev_cp_is_weak;
   _prev_EMCP_methods = prev_EMCP_methods;
 }
 
@@ -2451,7 +2492,11 @@
 // Destroy a PreviousVersionNode
 PreviousVersionNode::~PreviousVersionNode() {
   if (_prev_constant_pool != NULL) {
-    JNIHandles::destroy_weak_global(_prev_constant_pool);
+    if (_prev_cp_is_weak) {
+      JNIHandles::destroy_weak_global(_prev_constant_pool);
+    } else {
+      JNIHandles::destroy_global(_prev_constant_pool);
+    }
   }
 
   if (_prev_EMCP_methods != NULL) {
@@ -2471,8 +2516,8 @@
   _prev_constant_pool_handle = constantPoolHandle();  // NULL handle
   _prev_EMCP_method_handles = NULL;
 
-  jweak cp_ref = pv_node->prev_constant_pool();
-  assert(cp_ref != NULL, "weak constant pool ref was unexpectedly cleared");
+  jobject cp_ref = pv_node->prev_constant_pool();
+  assert(cp_ref != NULL, "constant pool ref was unexpectedly cleared");
   if (cp_ref == NULL) {
     return;  // robustness
   }
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp	Wed Apr 30 07:03:08 2008 -0700
@@ -432,6 +432,8 @@
                                                         _enclosing_method_method_index = method_index; }
 
   // jmethodID support
+  static jmethodID get_jmethod_id(instanceKlassHandle ik_h, size_t idnum,
+                                  jmethodID new_id, jmethodID* new_jmeths);
   static jmethodID jmethod_id_for_impl(instanceKlassHandle ik_h, methodHandle method_h);
   jmethodID jmethod_id_or_null(methodOop method);
 
@@ -838,11 +840,20 @@
 // A collection point for interesting information about the previous
 // version(s) of an instanceKlass. This class uses weak references to
 // the information so that the information may be collected as needed
-// by the system. A GrowableArray of PreviousVersionNodes is attached
+// by the system. If the information is shared, then a regular
+// reference must be used because a weak reference would be seen as
+// collectible. A GrowableArray of PreviousVersionNodes is attached
 // to the instanceKlass as needed. See PreviousVersionWalker below.
 class PreviousVersionNode : public CHeapObj {
  private:
-  jweak _prev_constant_pool;
+  // A shared ConstantPool is never collected so we'll always have
+  // a reference to it so we can update items in the cache. We'll
+  // have a weak reference to a non-shared ConstantPool until all
+  // of the methods (EMCP or obsolete) have been collected; the
+  // non-shared ConstantPool becomes collectible at that point.
+  jobject _prev_constant_pool;  // regular or weak reference
+  bool    _prev_cp_is_weak;     // true if not a shared ConstantPool
+
   // If the previous version of the instanceKlass doesn't have any
   // EMCP methods, then _prev_EMCP_methods will be NULL. If all the
   // EMCP methods have been collected, then _prev_EMCP_methods can
@@ -850,10 +861,10 @@
   GrowableArray<jweak>* _prev_EMCP_methods;
 
 public:
-  PreviousVersionNode(jweak prev_constant_pool,
+  PreviousVersionNode(jobject prev_constant_pool, bool prev_cp_is_weak,
     GrowableArray<jweak>* prev_EMCP_methods);
   ~PreviousVersionNode();
-  jweak prev_constant_pool() const {
+  jobject prev_constant_pool() const {
     return _prev_constant_pool;
   }
   GrowableArray<jweak>* prev_EMCP_methods() const {
--- a/hotspot/src/share/vm/oops/klass.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/oops/klass.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -182,7 +182,7 @@
   assert(etype >= T_BOOLEAN && etype <= T_OBJECT, "valid etype");
   // Note that T_ARRAY is not allowed here.
   int  hsize = arrayOopDesc::base_offset_in_bytes(etype);
-  int  esize = type2aelembytes[etype];
+  int  esize = type2aelembytes(etype);
   bool isobj = (etype == T_OBJECT);
   int  tag   =  isobj ? _lh_array_tag_obj_value : _lh_array_tag_type_value;
   int lh = array_layout_helper(tag, hsize, etype, exact_log2(esize));
--- a/hotspot/src/share/vm/oops/klassVtable.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/oops/klassVtable.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -735,7 +735,7 @@
     }
   }
 
-  // This lenght of the itable was either zero, or it has not yet been initialized.
+  // The length of the itable was either zero, or it has not yet been initialized.
   _table_offset      = 0;
   _size_offset_table = 0;
   _size_method_table = 0;
@@ -870,16 +870,19 @@
 
 // Initialization
 void klassItable::initialize_itable(bool checkconstraints, TRAPS) {
-  // Cannot be setup doing bootstrapping
-  if (Universe::is_bootstrapping()) return;
+  // Cannot be setup doing bootstrapping, interfaces don't have
+  // itables, and klass with only ones entry have empty itables
+  if (Universe::is_bootstrapping() ||
+      _klass->is_interface() ||
+      _klass->itable_length() == itableOffsetEntry::size()) return;
 
-  int num_interfaces = nof_interfaces();
+  // There's alway an extra itable entry so we can null-terminate it.
+  guarantee(size_offset_table() >= 1, "too small");
+  int num_interfaces = size_offset_table() - 1;
   if (num_interfaces > 0) {
-    if (TraceItables) tty->print_cr("%3d: Initializing itables for %s", ++initialize_count, _klass->name()->as_C_string());
+    if (TraceItables) tty->print_cr("%3d: Initializing itables for %s", ++initialize_count,
+                                    _klass->name()->as_C_string());
 
-    // In debug mode, we got an extra NULL/NULL entry
-    debug_only(num_interfaces--);
-    assert(num_interfaces > 0, "to few interfaces in offset itable");
 
     // Interate through all interfaces
     int i;
@@ -890,12 +893,10 @@
       initialize_itable_for_interface(ioe->offset(), interf_h, checkconstraints, CHECK);
     }
 
-#ifdef ASSERT
-    // Check that the last entry is empty
-    itableOffsetEntry* ioe = offset_entry(i);
-    assert(ioe->interface_klass() == NULL && ioe->offset() == 0, "terminator entry missing");
-#endif
   }
+  // Check that the last entry is empty
+  itableOffsetEntry* ioe = offset_entry(size_offset_table() - 1);
+  guarantee(ioe->interface_klass() == NULL && ioe->offset() == 0, "terminator entry missing");
 }
 
 
@@ -972,7 +973,7 @@
   }
 }
 
-// Update entry for specic methodOop
+// Update entry for specific methodOop
 void klassItable::initialize_with_method(methodOop m) {
   itableMethodEntry* ime = method_entry(0);
   for(int i = 0; i < _size_method_table; i++) {
@@ -1085,12 +1086,8 @@
   CountInterfacesClosure cic;
   visit_all_interfaces(transitive_interfaces(), &cic);
 
-  // Add one extra entry in debug mode, so we can null-terminate the table
-  int nof_methods    = cic.nof_methods();
-  int nof_interfaces = cic.nof_interfaces();
-  debug_only(if (nof_interfaces > 0) nof_interfaces++);
-
-  int itable_size = calc_itable_size(nof_interfaces, nof_methods);
+  // There's alway an extra itable entry so we can null-terminate it.
+  int itable_size = calc_itable_size(cic.nof_interfaces() + 1, cic.nof_methods());
 
   // Statistics
   update_stats(itable_size * HeapWordSize);
@@ -1110,8 +1107,8 @@
   int nof_methods    = cic.nof_methods();
   int nof_interfaces = cic.nof_interfaces();
 
-  // Add one extra entry in debug mode, so we can null-terminate the table
-  debug_only(if (nof_interfaces > 0) nof_interfaces++);
+  // Add one extra entry so we can null-terminate the table
+  nof_interfaces++;
 
   assert(compute_itable_size(objArrayHandle(klass->transitive_interfaces())) ==
          calc_itable_size(nof_interfaces, nof_methods),
--- a/hotspot/src/share/vm/oops/klassVtable.hpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/oops/klassVtable.hpp	Wed Apr 30 07:03:08 2008 -0700
@@ -259,7 +259,7 @@
   itableMethodEntry* method_entry(int i) { assert(0 <= i && i <= _size_method_table, "index out of bounds");
                                            return &((itableMethodEntry*)method_start())[i]; }
 
-  int nof_interfaces()                   { return _size_offset_table; }
+  int size_offset_table()                { return _size_offset_table; }
 
   // Initialization
   void initialize_itable(bool checkconstraints, TRAPS);
--- a/hotspot/src/share/vm/oops/markOop.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/oops/markOop.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -37,3 +37,32 @@
     st->print("age %d)", age());
   }
 }
+
+
+// Give advice about whether the oop that contains this markOop
+// should be cached or not.
+bool markOopDesc::should_not_be_cached() const {
+  // the cast is because decode_pointer() isn't marked const
+  if (is_marked() && ((markOopDesc *)this)->decode_pointer() != NULL) {
+    // If the oop containing this markOop is being forwarded, then
+    // we are in the middle of GC and we do not want the containing
+    // oop to be added to a cache. We have no way of knowing whether
+    // the cache has already been visited by the current GC phase so
+    // we don't know whether the forwarded oop will be properly
+    // processed in this phase. If the forwarded oop is not properly
+    // processed, then we'll see strange crashes or asserts during
+    // the next GC run because the markOop will contain an unexpected
+    // value.
+    //
+    // This situation has been seen when we are GC'ing a methodOop
+    // because we use the methodOop while we're GC'ing it. Scary
+    // stuff. Some of the uses the methodOop cause the methodOop to
+    // be added to the OopMapCache in the instanceKlass as a side
+    // effect. This check lets the cache maintainer know when a
+    // cache addition would not be safe.
+    return true;
+  }
+
+  // caching the containing oop should be just fine
+  return false;
+}
--- a/hotspot/src/share/vm/oops/markOop.hpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/oops/markOop.hpp	Wed Apr 30 07:03:08 2008 -0700
@@ -357,4 +357,7 @@
 
   // Recover address of oop from encoded form used in mark
   inline void* decode_pointer() { if (UseBiasedLocking && has_bias_pattern()) return NULL; return clear_lock_bits(); }
+
+  // see the definition in markOop.cpp for the gory details
+  bool should_not_be_cached() const;
 };
--- a/hotspot/src/share/vm/oops/methodDataOop.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/oops/methodDataOop.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -32,7 +32,7 @@
 
 // Some types of data layouts need a length field.
 bool DataLayout::needs_array_len(u1 tag) {
-  return (tag == multi_branch_data_tag);
+  return (tag == multi_branch_data_tag) || (tag == arg_info_data_tag);
 }
 
 // Perform generic initialization of the data.  More specific
@@ -404,6 +404,17 @@
 }
 #endif
 
+#ifndef PRODUCT
+void ArgInfoData::print_data_on(outputStream* st) {
+  print_shared(st, "ArgInfoData");
+  int nargs = number_of_args();
+  for (int i = 0; i < nargs; i++) {
+    st->print("  0x%x", arg_modified(i));
+  }
+  st->cr();
+}
+
+#endif
 // ==================================================================
 // methodDataOop
 //
@@ -508,6 +519,9 @@
   int extra_data_count = compute_extra_data_count(data_size, empty_bc_count);
   object_size += extra_data_count * DataLayout::compute_size_in_bytes(0);
 
+  // Add a cell to record information about modified arguments.
+  int arg_size = method->size_of_parameters();
+  object_size += DataLayout::compute_size_in_bytes(arg_size+1);
   return object_size;
 }
 
@@ -626,6 +640,8 @@
     return new BranchData(data_layout);
   case DataLayout::multi_branch_data_tag:
     return new MultiBranchData(data_layout);
+  case DataLayout::arg_info_data_tag:
+    return new ArgInfoData(data_layout);
   };
 }
 
@@ -681,7 +697,17 @@
 
   // Add some extra DataLayout cells (at least one) to track stray traps.
   int extra_data_count = compute_extra_data_count(data_size, empty_bc_count);
-  object_size += extra_data_count * DataLayout::compute_size_in_bytes(0);
+  int extra_size = extra_data_count * DataLayout::compute_size_in_bytes(0);
+
+  // Add a cell to record information about modified arguments.
+  // Set up _args_modified array after traps cells so that
+  // the code for traps cells works.
+  DataLayout *dp = data_layout_at(data_size + extra_size);
+
+  int arg_size = method->size_of_parameters();
+  dp->initialize(DataLayout::arg_info_data_tag, 0, arg_size+1);
+
+  object_size += extra_size + DataLayout::compute_size_in_bytes(arg_size+1);
 
   // Set an initial hint. Don't use set_hint_di() because
   // first_di() may be out of bounds if data_size is 0.
@@ -764,6 +790,10 @@
     // No need for "OrderAccess::load_acquire" ops,
     // since the data structure is monotonic.
     if (dp->tag() == DataLayout::no_tag)  break;
+    if (dp->tag() == DataLayout::arg_info_data_tag) {
+      dp = end; // ArgInfoData is at the end of extra data section.
+      break;
+    }
     if (dp->bci() == bci) {
       assert(dp->tag() == DataLayout::bit_data_tag, "sane");
       return new BitData(dp);
@@ -785,6 +815,16 @@
   return NULL;
 }
 
+ArgInfoData *methodDataOopDesc::arg_info() {
+  DataLayout* dp    = extra_data_base();
+  DataLayout* end   = extra_data_limit();
+  for (; dp < end; dp = next_extra(dp)) {
+    if (dp->tag() == DataLayout::arg_info_data_tag)
+      return new ArgInfoData(dp);
+  }
+  return NULL;
+}
+
 #ifndef PRODUCT
 void methodDataOopDesc::print_data_on(outputStream* st) {
   ResourceMark rm;
@@ -794,15 +834,20 @@
     st->fill_to(6);
     data->print_data_on(st);
   }
+  st->print_cr("--- Extra data:");
   DataLayout* dp    = extra_data_base();
   DataLayout* end   = extra_data_limit();
   for (; dp < end; dp = next_extra(dp)) {
     // No need for "OrderAccess::load_acquire" ops,
     // since the data structure is monotonic.
-    if (dp->tag() == DataLayout::no_tag)  break;
-    if (dp == extra_data_base())
-      st->print_cr("--- Extra data:");
-    data = new BitData(dp);
+    if (dp->tag() == DataLayout::no_tag)  continue;
+    if (dp->tag() == DataLayout::bit_data_tag) {
+      data = new BitData(dp);
+    } else {
+      assert(dp->tag() == DataLayout::arg_info_data_tag, "must be BitData or ArgInfo");
+      data = new ArgInfoData(dp);
+      dp = end; // ArgInfoData is at the end of extra data section.
+    }
     st->print("%d", dp_to_di(data->dp()));
     st->fill_to(6);
     data->print_data_on(st);
--- a/hotspot/src/share/vm/oops/methodDataOop.hpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/oops/methodDataOop.hpp	Wed Apr 30 07:03:08 2008 -0700
@@ -101,7 +101,8 @@
     virtual_call_data_tag,
     ret_data_tag,
     branch_data_tag,
-    multi_branch_data_tag
+    multi_branch_data_tag,
+    arg_info_data_tag
   };
 
   enum {
@@ -245,6 +246,7 @@
 class     BranchData;
 class   ArrayData;
 class     MultiBranchData;
+class     ArgInfoData;
 
 
 // ProfileData
@@ -376,6 +378,8 @@
   virtual bool is_BranchData()      { return false; }
   virtual bool is_ArrayData()       { return false; }
   virtual bool is_MultiBranchData() { return false; }
+  virtual bool is_ArgInfoData()     { return false; }
+
 
   BitData* as_BitData() {
     assert(is_BitData(), "wrong type");
@@ -413,6 +417,10 @@
     assert(is_MultiBranchData(), "wrong type");
     return is_MultiBranchData() ? (MultiBranchData*)this : NULL;
   }
+  ArgInfoData* as_ArgInfoData() {
+    assert(is_ArgInfoData(), "wrong type");
+    return is_ArgInfoData() ? (ArgInfoData*)this : NULL;
+  }
 
 
   // Subclass specific initialization
@@ -1047,6 +1055,33 @@
 #endif
 };
 
+class ArgInfoData : public ArrayData {
+
+public:
+  ArgInfoData(DataLayout* layout) : ArrayData(layout) {
+    assert(layout->tag() == DataLayout::arg_info_data_tag, "wrong type");
+  }
+
+  virtual bool is_ArgInfoData() { return true; }
+
+
+  int number_of_args() {
+    return array_len();
+  }
+
+  uint arg_modified(int arg) {
+    return array_uint_at(arg);
+  }
+
+  void set_arg_modified(int arg, uint val) {
+    array_set_int_at(arg, val);
+  }
+
+#ifndef PRODUCT
+  void print_data_on(outputStream* st);
+#endif
+};
+
 // methodDataOop
 //
 // A methodDataOop holds information which has been collected about
@@ -1183,6 +1218,9 @@
   // Find or create an extra ProfileData:
   ProfileData* bci_to_extra_data(int bci, bool create_if_missing);
 
+  // return the argument info cell
+  ArgInfoData *arg_info();
+
 public:
   static int header_size() {
     return sizeof(methodDataOopDesc)/wordSize;
@@ -1215,18 +1253,28 @@
   // Support for interprocedural escape analysis, from Thomas Kotzmann.
   enum EscapeFlag {
     estimated    = 1 << 0,
-    return_local = 1 << 1
+    return_local = 1 << 1,
+    return_allocated = 1 << 2,
+    allocated_escapes = 1 << 3,
+    unknown_modified = 1 << 4
   };
 
   intx eflags()                                  { return _eflags; }
   intx arg_local()                               { return _arg_local; }
   intx arg_stack()                               { return _arg_stack; }
   intx arg_returned()                            { return _arg_returned; }
+  uint arg_modified(int a)                       { ArgInfoData *aid = arg_info();
+                                                   assert(a >= 0 && a < aid->number_of_args(), "valid argument number");
+                                                   return aid->arg_modified(a); }
 
   void set_eflags(intx v)                        { _eflags = v; }
   void set_arg_local(intx v)                     { _arg_local = v; }
   void set_arg_stack(intx v)                     { _arg_stack = v; }
   void set_arg_returned(intx v)                  { _arg_returned = v; }
+  void set_arg_modified(int a, uint v)           { ArgInfoData *aid = arg_info();
+                                                   assert(a >= 0 && a < aid->number_of_args(), "valid argument number");
+
+                                                   aid->set_arg_modified(a, v); }
 
   void clear_escape_info()                       { _eflags = _arg_local = _arg_stack = _arg_returned = 0; }
 
--- a/hotspot/src/share/vm/oops/methodOop.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/oops/methodOop.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -765,6 +765,28 @@
 }
 
 
+// give advice about whether this methodOop should be cached or not
+bool methodOopDesc::should_not_be_cached() const {
+  if (is_old()) {
+    // This method has been redefined. It is either EMCP or obsolete
+    // and we don't want to cache it because that would pin the method
+    // down and prevent it from being collectible if and when it
+    // finishes executing.
+    return true;
+  }
+
+  if (mark()->should_not_be_cached()) {
+    // It is either not safe or not a good idea to cache this
+    // method at this time because of the state of the embedded
+    // markOop. See markOop.cpp for the gory details.
+    return true;
+  }
+
+  // caching this method should be just fine
+  return false;
+}
+
+
 methodHandle methodOopDesc:: clone_with_new_data(methodHandle m, u_char* new_code, int new_code_length,
                                                 u_char* new_compressed_linenumber_table, int new_compressed_linenumber_size, TRAPS) {
   // Code below does not work for native methods - they should never get rewritten anyway
--- a/hotspot/src/share/vm/oops/methodOop.hpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/oops/methodOop.hpp	Wed Apr 30 07:03:08 2008 -0700
@@ -524,6 +524,8 @@
   void set_is_old()                                 { _access_flags.set_is_old(); }
   bool is_obsolete() const                          { return access_flags().is_obsolete(); }
   void set_is_obsolete()                            { _access_flags.set_is_obsolete(); }
+  // see the definition in methodOop.cpp for the gory details
+  bool should_not_be_cached() const;
 
   // JVMTI Native method prefixing support:
   bool is_prefixed_native() const                   { return access_flags().is_prefixed_native(); }
--- a/hotspot/src/share/vm/opto/addnode.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/opto/addnode.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -505,15 +505,25 @@
       const Type *temp_t2 = phase->type( in(Offset) );
       if( temp_t2 == Type::TOP ) return NULL;
       const TypeX *t2 = temp_t2->is_intptr_t();
+      Node* address;
+      Node* offset;
       if( t2->is_con() ) {
         // The Add of the flattened expression
-        set_req(Address, addp->in(Address));
-        set_req(Offset , phase->MakeConX(t2->get_con() + t12->get_con()));
-        return this;                    // Made progress
+        address = addp->in(Address);
+        offset  = phase->MakeConX(t2->get_con() + t12->get_con());
+      } else {
+        // Else move the constant to the right.  ((A+con)+B) into ((A+B)+con)
+        address = phase->transform(new (phase->C, 4) AddPNode(in(Base),addp->in(Address),in(Offset)));
+        offset  = addp->in(Offset);
       }
-      // Else move the constant to the right.  ((A+con)+B) into ((A+B)+con)
-      set_req(Address, phase->transform(new (phase->C, 4) AddPNode(in(Base),addp->in(Address),in(Offset))));
-      set_req(Offset , addp->in(Offset));
+      PhaseIterGVN *igvn = phase->is_IterGVN();
+      if( igvn ) {
+        set_req_X(Address,address,igvn);
+        set_req_X(Offset,offset,igvn);
+      } else {
+        set_req(Address,address);
+        set_req(Offset,offset);
+      }
       return this;
     }
   }
@@ -608,6 +618,28 @@
   return NULL;
 }
 
+//------------------------------unpack_offsets----------------------------------
+// Collect the AddP offset values into the elements array, giving up
+// if there are more than length.
+int AddPNode::unpack_offsets(Node* elements[], int length) {
+  int count = 0;
+  Node* addr = this;
+  Node* base = addr->in(AddPNode::Base);
+  while (addr->is_AddP()) {
+    if (addr->in(AddPNode::Base) != base) {
+      // give up
+      return -1;
+    }
+    elements[count++] = addr->in(AddPNode::Offset);
+    if (count == length) {
+      // give up
+      return -1;
+    }
+    addr = addr->in(AddPNode::Address);
+  }
+  return count;
+}
+
 //------------------------------match_edge-------------------------------------
 // Do we Match on this edge index or not?  Do not match base pointer edge
 uint AddPNode::match_edge(uint idx) const {
--- a/hotspot/src/share/vm/opto/addnode.hpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/opto/addnode.hpp	Wed Apr 30 07:03:08 2008 -0700
@@ -144,6 +144,11 @@
   static Node* Ideal_base_and_offset(Node* ptr, PhaseTransform* phase,
                                      // second return value:
                                      intptr_t& offset);
+
+  // Collect the AddP offset values into the elements array, giving up
+  // if there are more than length.
+  int unpack_offsets(Node* elements[], int length);
+
   // Do not match base-ptr edge
   virtual uint match_edge(uint idx) const;
   static const Type *mach_bottom_type(const MachNode* n);  // used by ad_<arch>.hpp
--- a/hotspot/src/share/vm/opto/bytecodeInfo.cpp	Wed Apr 30 12:32:05 2008 +0400
+++ b/hotspot/src/share/vm/opto/bytecodeInfo.cpp	Wed Apr 30 07:03:08 2008 -0700
@@ -79,8 +79,20 @@
   for (int i = depth; i != 0; --i) tty->print("  ");
 }
 
+static bool is_init_with_ea(ciMethod* callee_method,
+                            ciMethod* caller_method, Compile* C) {
+  // True when EA is ON and a java constructor is called or
+  // a super constructor is called from an inlined java constructor.
+  return DoEscapeAnalysis && EliminateAllocations &&
+         ( callee_method->is_initializer() ||
+           (caller_method->is_initializer() &&
+            caller_method != C->method() &&
+            caller_method->holder()->is_subclass_of(callee_method->holder()))
+         );
+}
+
 // positive filter: should send be inlined?  returns NULL, if yes, or rejection msg
-const char* InlineTree::shouldInline(ciMethod* callee_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const {
+const char* InlineTree::shouldInline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const {
   // Allows targeted inlining
   if(callee_method->should_inline()) {
     *wci_result = *(WarmCallInfo::always_hot());
@@ -97,7 +109,8 @@
   int size     = callee_method->code_size();
 
   // Check for too many throws (and not too huge)
-  if(callee_method->interpreter_throwout_count() > InlineThrowCount && size < InlineThrowMaxSize ) {
+  if(callee_method->interpreter_throwout_count() > InlineThrowCount &&
+     size < InlineThrowMaxSize ) {
     wci_result->set_profit(wci_result->profit() * 100);
     if (PrintInlining && Verbose) {
       print_indent(inline_depth());
@@ -114,8 +127,12 @@
   int invoke_count     = method()->interpreter_invocation_count();
   assert( invoke_count != 0, "Require invokation count greater than zero");
   int freq = call_site_count/invoke_count;
+
   // bump the max size if the call is frequent
-  if ((freq >= InlineFrequencyRatio) || (call_site_count >= InlineFrequencyCount)) {
+  if ((freq >= InlineFrequencyRatio) ||
+      (call_site_count >= InlineFrequencyCount) ||
+      is_init_with_ea(callee_method, caller_method, C)) {
+
     max_size = C->freq_inline_size();
     if (size <= max_size && TraceFrequencyInlining) {
       print_indent(inline_depth());
@@ -126,7 +143,8 @@
     }
   } else {
     // Not hot.  Check for medium-sized pre-existing nmethod at cold sites.
-    if (callee_method->has_compiled_code() && callee_method->instructions_size() > InlineSmallCode/4)
+    if (callee_method->has_compiled_code() &&
+        callee_method->instructions_size() > InlineSmallCode/4)
       return "already compiled into a medium method";
   }
   if (size > max_size) {
@@ -139,7 +157,7 @@
 
 
 // negative filter: should send NOT be inlined?  returns NULL, ok to inline, or rejection msg
-const char* InlineTree::shouldNotInline(ciMethod *callee_method, WarmCallInfo* wci_result) const {
+const char* InlineTree::shouldNotInline(ciMethod *callee_method, ciMethod* caller_method, WarmCallInfo* wci_result) const {
   // negative filter: should send NOT be inlined?  returns NULL (--> inline) or rejection msg
   if (!UseOldInlining) {
     const char* fail = NULL;
@@ -204,9 +222,23 @@
 
   // use frequency-based objections only for non-trivial methods
   if (callee_method->code_size() <= MaxTrivialSize) return NULL;
-  if (UseInterpreter && !CompileTheWorld) { // don't use counts with -Xcomp or CTW
-    if (!callee_method->has_compiled_code() && !callee_method->was_executed_more_than(0)) return "never executed";
-    if (!callee_method->was_executed_more_than(MIN2(MinInliningThreshold, CompileThreshold >> 1))) return "executed < MinInliningThreshold times";
+
+  // don't use counts with -Xcomp or CTW
+  if (UseInterpreter && !CompileTheWorld) {
+
+    if (!callee_method->has_compiled_code() &&
+        !callee_method->was_executed_more_than(0)) {
+      return "never executed";
+    }
+
+    if (is_init_with_ea(callee_method, caller_method, C)) {
+
+      // Escape Analysis: inline all executed constructors
+
+    } else if (!callee_method->was_executed_more_than(MIN2(MinInliningThreshold,
+                                                           CompileThreshold >> 1))) {
+      return "executed < MinInliningThreshold times";
+    }
   }
 
   if (callee_method->should_not_inline()) {
@@ -219,8 +251,7 @@
 //-----------------------------try_to_inline-----------------------------------
 // return NULL if ok, reason for not inlining otherwise
 // Relocated from "InliningClosure::try_to_inline"
-const char* InlineTree::try_to_inline(ciMethod* callee_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) {
-  ciMethod* caller_method = method();
+const char* InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) {
 
   // Old algorithm had funny accumulating BC-size counters
   if (UseOldInlining && ClipInlining
@@ -229,25 +260,47 @@
   }
 
   const char *msg = NULL;
-  if ((msg = shouldInline(callee_method, caller_bci, profile, wci_result)) != NULL) return msg;
-  if ((msg = shouldNotInline(callee_method,                   wci_result)) != NULL) return msg;
+  if ((msg = shouldInline(callee_method, caller_method, caller_bci,
+                          profile, wci_result)) != NULL) {
+    return msg;
+  }
+  if ((msg = shouldNotInline(callee_method, caller_method,
+                             wci_result)) != NULL) {
+    return msg;
+  }
 
   bool is_accessor = InlineAccessors && callee_method->is_accessor();
 
   // suppress a few checks for accessors and trivial methods
   if (!is_accessor && callee_method->code_size() > MaxTrivialSize) {
+
     // don't inline into giant methods
-    if (C->unique() > (uint)NodeCountInliningCutoff) return "NodeCountInliningCutoff";
+    if (C->unique() > (uint)NodeCountInliningCutoff) {
+      return "NodeCountInliningCutoff";
+    }
 
-    // don't inline unreached call sites
-    if (profile.count() == 0)                        return "call site not reached";
+    if ((!UseInterpreter || CompileTheWorld) &&
+        is_init_with_ea(callee_method, caller_method, C)) {
+
+      // Escape Analysis stress testing when running Xcomp or CTW:
+      // inline constructors even if they are not reached.
+
+    } else if (profile.count() == 0) {
+      // don't inline unreached call sites
+      return "call site not reached";