Merge
authorlana
Fri, 30 Mar 2012 16:57:50 -0700
changeset 12304 2dc3af8dd124
parent 12302 0c8557ba0b8f (current diff)
parent 12251 a6e6d42203e6 (diff)
child 12305 e10f44345be4
Merge
corba/make/tools/src/build/tools/stripproperties/StripProperties.java
langtools/make/tools/CompileProperties/CompileProperties.java
langtools/make/tools/CompileProperties/CompilePropertiesTask.java
langtools/make/tools/GenStubs/GenStubs.java
langtools/make/tools/SelectTool/SelectToolTask.java
langtools/test/jprt.config
--- a/.hgignore	Fri Mar 30 15:43:13 2012 -0700
+++ b/.hgignore	Fri Mar 30 16:57:50 2012 -0700
@@ -3,3 +3,4 @@
 /nbproject/private/
 ^webrev
 ^.hgtip
+.DS_Store
--- a/.hgtags	Fri Mar 30 15:43:13 2012 -0700
+++ b/.hgtags	Fri Mar 30 16:57:50 2012 -0700
@@ -150,3 +150,7 @@
 6c805d8ed4e5449ea5e4d158c7bdbd7b0b70efd1 jdk8-b26
 c51754cddc037b9609e202b9ed38363d8683e7a8 jdk8-b27
 16ba58282d117247f480aae7a79b88141ade52a3 jdk8-b28
+e070119aa56ee4dc5506c19d2c4d2eecab8ad429 jdk8-b29
+23da7804aca0c9c4e6e86532a1453125a76d95ee jdk8-b30
+bac81e9f7d57b75fba5ab31b571f3fe0dc08af69 jdk8-b31
+2c5208ccb863db936eab523f49450b3fcd230348 jdk8-b32
--- a/.hgtags-top-repo	Fri Mar 30 15:43:13 2012 -0700
+++ b/.hgtags-top-repo	Fri Mar 30 16:57:50 2012 -0700
@@ -150,3 +150,7 @@
 2accafff224ae39caf5f532c305251ba624bf2c0 jdk8-b26
 1533dfab9903e4edcfead3b0192643f38c418b9b jdk8-b27
 6e2541d60f4e342b5b67140271d7611643929dc3 jdk8-b28
+41460de042580bc4a4ce3f863779c66f39cb8578 jdk8-b29
+6cea54809b51db92979c22fd8aa8fcb1cb13d12e jdk8-b30
+0b66f43b89a6c0ac1c15d7ec51992c541cdc9089 jdk8-b31
+88176171e940f02916a312c265a34c32552a8376 jdk8-b32
--- a/corba/.hgignore	Fri Mar 30 15:43:13 2012 -0700
+++ b/corba/.hgignore	Fri Mar 30 16:57:50 2012 -0700
@@ -2,3 +2,4 @@
 ^dist/
 /nbproject/private/
 ^.hgtip
+.DS_Store
--- a/corba/.hgtags	Fri Mar 30 15:43:13 2012 -0700
+++ b/corba/.hgtags	Fri Mar 30 16:57:50 2012 -0700
@@ -150,3 +150,7 @@
 79f709a099f40c08f76567fa6d813f9009a69826 jdk8-b26
 4fffe75e4edd39a2517f10b743941bf94edb143d jdk8-b27
 2082eb35d49a9c2aab90b8d4fd31cefb7a23b82e jdk8-b28
+6117395d422682f89d228347e319fcaac7edc729 jdk8-b29
+4605f8418bf562e78be79b25b6b8a5110281acae jdk8-b30
+1954151dfae8f73db24e396380f7c02bdd47c486 jdk8-b31
+5d820cb6b1afd75b619e7fd69e4f2b0eb1d5d6a1 jdk8-b32
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/corba/make/common/Defs-bsd.gmk	Fri Mar 30 16:57:50 2012 -0700
@@ -0,0 +1,46 @@
+#
+# Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+#
+# Makefile to specify compiler flags for programs and libraries
+# targeted to BSD.  Should not contain any rules.
+#
+
+# Warning: the following variables are overriden by Defs.gmk. Set
+# values will be silently ignored:
+#   CFLAGS        (set $(OTHER_CFLAGS) instead)
+#   CPPFLAGS      (set $(OTHER_CPPFLAGS) instead)
+#   CXXFLAGS      (set $(OTHER_CXXFLAGS) instead)
+#   LDFLAGS       (set $(OTHER_LDFAGS) instead)
+#   LDLIBS        (set $(EXTRA_LIBS) instead)
+#   LDLIBS_COMMON (set $(EXTRA_LIBS) instead)
+
+# Get shared JDK settings
+include $(BUILDDIR)/common/shared/Defs.gmk
+
+ifndef PLATFORM_SRC
+  PLATFORM_SRC = $(TOPDIR)/src/solaris
+endif # PLATFORM_SRC
+
--- a/corba/make/common/internal/Resources.gmk	Fri Mar 30 15:43:13 2012 -0700
+++ b/corba/make/common/internal/Resources.gmk	Fri Mar 30 16:57:50 2012 -0700
@@ -149,8 +149,8 @@
 # Strip the properties files
 strip_all_props: $(STRIPPROPERTIES_JARFILE) $(STRIP_PROP_options)
 	@if [ -s $(STRIP_PROP_options) ] ; then \
-          $(ECHO) "$(BOOT_JAVA_CMD) -jar $(STRIPPROPERTIES_JARFILE) -optionsfile $(STRIP_PROP_options)" ; \
-          $(BOOT_JAVA_CMD) -jar $(STRIPPROPERTIES_JARFILE) -optionsfile $(STRIP_PROP_options) ; \
+          $(ECHO) "$(BOOT_JAVA_CMD) -jar $(STRIPPROPERTIES_JARFILE) @$(STRIP_PROP_options)" ; \
+          $(BOOT_JAVA_CMD) -jar $(STRIPPROPERTIES_JARFILE) @$(STRIP_PROP_options) ; \
         fi
 	@$(java-vm-cleanup)
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/corba/make/common/shared/Defs-bsd.gmk	Fri Mar 30 16:57:50 2012 -0700
@@ -0,0 +1,131 @@
+#
+# Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+#
+# Definitions for Bsd.
+#
+
+# Default for COMPILER_WARNINGS_FATAL on Bsd (C & C++ compiler warnings)
+ifndef COMPILER_WARNINGS_FATAL
+  COMPILER_WARNINGS_FATAL=false
+endif
+
+# Bsd should use parallel compilation for best build times
+ifndef COMPILE_APPROACH
+  COMPILE_APPROACH = parallel
+endif
+
+# Indication that we are doing an incremental build.
+#    This may trigger the creation of make depend files.
+ifndef INCREMENTAL_BUILD
+  INCREMENTAL_BUILD = false
+endif
+
+# FullPath just makes sure it never ends with a / and no duplicates
+define FullPath
+$(shell cd $1 2> $(DEV_NULL) && pwd)
+endef
+
+# OptFullPath: Absolute path name of a dir that might not initially exist.
+define OptFullPath
+$(shell if [ "$1" != "" -a -d "$1" ]; then (cd $1 && pwd); else echo "$1"; fi)
+endef
+
+# Location on system where jdk installs might be
+USRJDKINSTANCES_PATH =$(PACKAGE_PATH)
+
+# UNIXCOMMAND_PATH: path to where the most common Unix commands are.
+#  NOTE: Must end with / so that it could be empty, allowing PATH usage.
+ifneq "$(origin ALT_UNIXCOMMAND_PATH)" "undefined"
+  UNIXCOMMAND_PATH :=$(call PrefixPath,$(ALT_UNIXCOMMAND_PATH))
+else
+  UNIXCOMMAND_PATH  = /bin/
+endif
+
+# USRBIN_PATH: path to where the most common Unix commands are.
+#  NOTE: Must end with / so that it could be empty, allowing PATH usage.
+ifneq "$(origin ALT_USRBIN_PATH)" "undefined"
+  USRBIN_PATH :=$(call PrefixPath,$(ALT_USRBIN_PATH))
+else
+  USRBIN_PATH  = /usr/bin/
+endif
+
+# UNIXCCS_PATH: path to where the Solaris ported UNIX commands can be found
+#  NOTE: Must end with / so that it could be empty, allowing PATH usage.
+ifneq "$(origin ALT_UNIXCCS_PATH)" "undefined"
+  UNIXCCS_PATH :=$(call PrefixPath,$(ALT_UNIXCCS_PATH))
+else
+  UNIXCCS_PATH = /usr/ccs/bin/
+endif
+
+# SLASH_JAVA: location of all network accessable files
+ifdef ALT_SLASH_JAVA
+  SLASH_JAVA  :=$(ALT_SLASH_JAVA)
+else
+  SLASH_JAVA  := $(call DirExists,/java,/java,/NOT-SET)
+endif
+
+# JDK_DEVTOOLS_DIR: common path for all the java devtools
+ifdef ALT_JDK_DEVTOOLS_DIR
+  JDK_DEVTOOLS_DIR  =$(ALT_JDK_DEVTOOLS_DIR)
+else
+  JDK_DEVTOOLS_DIR =$(SLASH_JAVA)/devtools
+endif
+
+# DEVTOOLS_PATH: for other tools required for building (such as zip, etc.)
+#  NOTE: Must end with / so that it could be empty, allowing PATH usage.
+ifneq "$(origin ALT_DEVTOOLS_PATH)" "undefined"
+  DEVTOOLS_PATH :=$(call PrefixPath,$(ALT_DEVTOOLS_PATH))
+else
+  DEVTOOLS_PATH =$(PACKAGE_PATH)/bin/
+endif
+
+# _BOOTDIR1: First choice for a Bootstrap JDK, previous released JDK.
+# _BOOTDIR2: Second choice
+ifndef ALT_BOOTDIR
+  _BOOTDIR1  =$(SLASH_JAVA)/re/jdk/$(PREVIOUS_JDK_VERSION)/archive/fcs/binaries/$(PLATFORM)-$(ARCH)
+  _BOOTDIR2  =$(USRJDKINSTANCES_PATH)/jdk$(PREVIOUS_JDK_VERSION)
+endif
+
+# Import JDK images allow for partial builds, components not built are
+#    imported (or copied from) these import areas when needed.
+
+# BUILD_JDK_IMPORT_PATH: location of JDK install trees to import for
+#   multiple platforms, e.g. windows-i586, solaris-sparc, bsd-586, etc.
+ifdef ALT_BUILD_JDK_IMPORT_PATH
+  BUILD_JDK_IMPORT_PATH  :=$(call FullPath,$(ALT_BUILD_JDK_IMPORT_PATH))
+else
+  BUILD_JDK_IMPORT_PATH   = $(PROMOTED_BUILD_BINARIES)
+endif
+BUILD_JDK_IMPORT_PATH:=$(call AltCheckValue,BUILD_JDK_IMPORT_PATH)
+
+# JDK_IMPORT_PATH: location of JDK install tree (this version) to import
+ifdef ALT_JDK_IMPORT_PATH
+  JDK_IMPORT_PATH  :=$(call FullPath,$(ALT_JDK_IMPORT_PATH))
+else
+  JDK_IMPORT_PATH   = $(BUILD_JDK_IMPORT_PATH)/$(PLATFORM)-$(ARCH)$(_JDK_IMPORT_VARIANT)
+endif
+JDK_IMPORT_PATH:=$(call AltCheckValue,JDK_IMPORT_PATH)
+
--- a/corba/make/common/shared/Defs-utils.gmk	Fri Mar 30 15:43:13 2012 -0700
+++ b/corba/make/common/shared/Defs-utils.gmk	Fri Mar 30 16:57:50 2012 -0700
@@ -31,7 +31,7 @@
 # These input UTILS_* variables can be defined at anytime, ideally once.
 #         Unix Commands: Normally /bin/, /usr/bin/. or C:/mksnt/mksnt/
 #            UTILS_COMMAND_PATH
-#         /usr/bin/ 
+#         /usr/bin/
 #            UTILS_USR_BIN_PATH
 #         /usr/ccs/bin/ (sccs, m4, lex, yacc, as, ar, strip, mcs)
 #            UTILS_CCS_BIN_PATH
@@ -53,6 +53,13 @@
   UTILS_DEVTOOL_PATH=$(USRBIN_PATH)
 endif
 
+ifeq ($(PLATFORM),bsd)
+  UTILS_COMMAND_PATH=$(UNIXCOMMAND_PATH)
+  UTILS_USR_BIN_PATH=$(USRBIN_PATH)
+  UTILS_CCS_BIN_PATH=$(USRBIN_PATH)
+  UTILS_DEVTOOL_PATH=$(DEVTOOLS_PATH)
+endif
+
 ifeq ($(PLATFORM),solaris)
   UTILS_COMMAND_PATH=$(UNIXCOMMAND_PATH)
   UTILS_USR_BIN_PATH=$(UNIXCOMMAND_PATH)
@@ -166,15 +173,15 @@
   # Also, some distribution (Ubuntu, Debian, others?) place the rpm command
   # itself in /usr/bin rather than it's traditional home in /bin.
   RPM=$(firstword $(wildcard $(UTILS_COMMAND_PATH)rpm) \
-		  $(wildcard $(UTILS_USR_BIN_PATH)rpm))
+                  $(wildcard $(UTILS_USR_BIN_PATH)rpm))
   RPMBUILD=$(firstword $(wildcard $(UTILS_COMMAND_PATH)rpmbuild) \
-		       $(wildcard $(UTILS_USR_BIN_PATH)rpmbuild) \
-		       $(wildcard $(UTILS_COMMAND_PATH)rpm) \
-		       $(wildcard $(UTILS_USR_BIN_PATH)rpm))
+                       $(wildcard $(UTILS_USR_BIN_PATH)rpmbuild) \
+                       $(wildcard $(UTILS_COMMAND_PATH)rpm) \
+                       $(wildcard $(UTILS_USR_BIN_PATH)rpm))
   # Most Linux distros have "sort" in /bin.  Ubuntu, Debian and perhaps
   # others have it in /usr/bin.
   SORT=$(firstword $(wildcard $(UTILS_COMMAND_PATH)sort) \
-		   $(wildcard $(UTILS_USR_BIN_PATH)sort))
+                   $(wildcard $(UTILS_USR_BIN_PATH)sort))
   NAWK           = $(USRBIN_PATH)gawk
   # Intrinsic unix command, with backslash-escaped character interpretation
   ECHO           = /bin/echo -e
@@ -198,3 +205,34 @@
   ECHO           = /usr/bin/echo
 endif
 
+# BSD specific
+ifeq ($(PLATFORM),bsd)
+  BASENAME     = $(UTILS_USR_BIN_PATH)basename
+  EGREP        = $(UTILS_USR_BIN_PATH)egrep
+  EXPR         = $(UTILS_COMMAND_PATH)expr
+  FMT          = $(UTILS_USR_BIN_PATH)fmt
+  GREP         = $(UTILS_USR_BIN_PATH)grep
+  GUNZIP       = $(UTILS_USR_BIN_PATH)gunzip
+  ID           = $(UTILS_USR_BIN_PATH)id
+  MSGFMT       = $(UTILS_DEVTOOL_PATH)msgfmt
+  SED          = $(UTILS_USR_BIN_PATH)sed
+  SORT         = $(UTILS_USR_BIN_PATH)sort
+  TEST         = $(UTILS_COMMAND_PATH)test
+  TOUCH        = $(UTILS_USR_BIN_PATH)touch
+  TRUE         = $(UTILS_USR_BIN_PATH)true
+  UNAME        = $(UTILS_USR_BIN_PATH)uname
+  # BSD OS_VENDOR specific
+  ifeq ($(OS_VENDOR), Apple)
+    NAWK       = $(UTILS_USR_BIN_PATH)awk
+    UNZIPSFX   = $(UTILS_USR_BIN_PATH)unzipsfx
+    ZIPEXE     = $(UTILS_USR_BIN_PATH)zip
+  else
+    UNZIP      = $(UTILS_DEVTOOL_PATH)unzip
+  endif
+  ifeq ($(OS_VENDOR), OpenBSD)
+    NAWK       = $(UTILS_USR_BIN_PATH)awk
+  else
+    CPIO       = $(UTILS_USR_BIN_PATH)cpio
+    TAR        = $(UTILS_USR_BIN_PATH)tar
+  endif
+endif
--- a/corba/make/common/shared/Platform.gmk	Fri Mar 30 15:43:13 2012 -0700
+++ b/corba/make/common/shared/Platform.gmk	Fri Mar 30 16:57:50 2012 -0700
@@ -62,8 +62,8 @@
 #     CLASSPATH_SEPARATOR         separator in classpath, ; or :
 #     BUNDLE_FILE_SUFFIX          suffix for bundles: .tar or .tar.gz
 #     ISA_DIR                     solaris only: /sparcv9 or /amd64
-#     REQUIRED_WINDOWS_NAME       windows only: basic name of windows 
-#     REQUIRED_WINDOWS_VERSION    windows only: specific version of windows 
+#     REQUIRED_WINDOWS_NAME       windows only: basic name of windows
+#     REQUIRED_WINDOWS_VERSION    windows only: specific version of windows
 #     USING_CYGWIN                windows only: true or false
 #     WINDOWS_NT_VERSION_STRING   windows only: long version name
 #     REQUIRED_OS_VERSION         required OS version, e.g. 5.10, 2.4
@@ -135,7 +135,7 @@
   BUNDLE_FILE_SUFFIX=.tar
   # Required Solaris version
   REQUIRED_OS_VERSION = 5.10
-  # Minimum disk space needed as determined by running 'du -sk' on 
+  # Minimum disk space needed as determined by running 'du -sk' on
   #    a fully built workspace.
   ifeq ($(ARCH_FAMILY), sparc)
     REQUIRED_FREE_SPACE=1300000
@@ -207,7 +207,7 @@
 
   # Suffix for file bundles used in previous release
   BUNDLE_FILE_SUFFIX=.tar.gz
-  # Minimum disk space needed as determined by running 'du -sk' on 
+  # Minimum disk space needed as determined by running 'du -sk' on
   #    a fully built workspace.
   REQUIRED_FREE_SPACE=1460000
   LINUX_VERSION_INFO = /etc/redhat-release
@@ -231,6 +231,98 @@
   MB_OF_MEMORY := $(shell free -m | fgrep Mem: | sed -e 's@\ \ *@ @g' | cut -d' ' -f2)
 endif
 
+ifeq ($(SYSTEM_UNAME), FreeBSD)
+  PLATFORM = bsd
+  OS_NAME = freebsd
+  OS_VENDOR = FreeBSD
+  REQUIRED_OS_VERSION = 6.0
+endif
+
+ifeq ($(SYSTEM_UNAME), Darwin)
+  PLATFORM = bsd
+  OS_NAME = darwin
+  OS_VENDOR = Apple
+  REQUIRED_OS_VERSION = 8.0
+endif
+
+ifeq ($(SYSTEM_UNAME), NetBSD)
+  PLATFORM = bsd
+  OS_NAME = netbsd
+  OS_VENDOR = NetBSD
+  REQUIRED_OS_VERSION = 3.0
+endif
+
+ifeq ($(SYSTEM_UNAME), OpenBSD)
+  PLATFORM = bsd
+  OS_NAME = openbsd
+  OS_VENDOR = OpenBSD
+  REQUIRED_OS_VERSION = 4.9
+endif
+
+# Platform settings specific to BSD
+ifeq ($(PLATFORM), bsd)
+  OS_VERSION := $(shell uname -r)
+  # Arch and OS name/version
+  mach := $(shell uname -m)
+  archExpr = case "$(mach)" in \
+                i[3-9]86) \
+                    echo i586 \
+                    ;; \
+                sparc64) \
+                    echo sparcv9 \
+                    ;; \
+                sparc*) \
+                    echo sparc \
+                    ;; \
+                x86_64) \
+                    echo amd64 \
+                    ;; \
+                "Power Macintosh") \
+                    echo ppc \
+                    ;; \
+                *) \
+                    echo $(mach) \
+                    ;; \
+      esac
+  ARCH        := $(shell $(archExpr) )
+  ARCH_FAMILY := $(ARCH)
+
+  # Darwin x86 builds are i386/amd64 universal.
+  ifeq ($(SYSTEM_UNAME), Darwin)
+    ifneq ($(ARCH), ppc)
+      ARCH=universal
+    endif
+  endif
+
+  # i586, sparc, and ppc are 32 bit, amd64 and sparc64 are 64
+  ifneq (,$(findstring $(ARCH), i586 sparc ppc universal))
+    ARCH_DATA_MODEL=32
+  else
+    ARCH_DATA_MODEL=64
+  endif
+
+  ifeq ($(ARCH), i586)
+    LIBARCH = i386
+  else
+    LIBARCH = $(ARCH)
+  endif
+
+  # Value of Java os.arch property
+  ARCHPROP  = $(LIBARCH)
+
+  # Suffix for file bundles used in previous release
+  BUNDLE_FILE_SUFFIX=.tar.gz
+  # Minimum disk space needed as determined by running 'du -sk' on
+  #    a fully built workspace.
+  REQUIRED_FREE_SPACE=1500000
+  # How much RAM does this machine have:
+  ifeq ($(OS_VENDOR), OpenBSD)
+    MB_OF_MEMORY=$(shell sysctl -n hw.physmem | awk '{print int($$NF / 1048576); }' )
+  else
+    MB_OF_MEMORY=$(shell (sysctl -n hw.physmem64 2> /dev/null || sysctl -n hw.physmem) | awk '{print int($$NF / 1048576); }' )
+  endif
+endif
+
 # Windows with and without CYGWIN will be slightly different
 ifeq ($(SYSTEM_UNAME), Windows_NT)
   PLATFORM = windows
@@ -327,7 +419,7 @@
   endif
   # Suffix for file bundles used in previous release
   BUNDLE_FILE_SUFFIX=.tar
-  # Minimum disk space needed as determined by running 'du -sk' on 
+  # Minimum disk space needed as determined by running 'du -sk' on
   #    a fully built workspace.
   REQUIRED_FREE_SPACE=500000
   # How much RAM does this machine have:
@@ -335,8 +427,8 @@
     MB_OF_MEMORY := $(shell \
       if [ -f "C:/cygwin/bin/free.exe" ] ; then \
         ( C:/cygwin/bin/bash.exe -c "C:/cygwin/bin/free.exe -m" ) | \
-	  grep Mem: | \
-	  sed -e 's@\ \ *@ @g' | cut -d' ' -f2 ; \
+          grep Mem: | \
+          sed -e 's@\ \ *@ @g' | cut -d' ' -f2 ; \
       else \
         echo "512"; \
       fi)
@@ -392,7 +484,7 @@
   # Where is unwanted output to be delivered?
   DEV_NULL = /dev/null
   export DEV_NULL
-  # Character used between entries in classpath 
+  # Character used between entries in classpath
   CLASSPATH_SEPARATOR = :
   # User name determination (set _USER)
   ifndef USER
--- a/corba/make/tools/src/build/tools/stripproperties/StripProperties.java	Fri Mar 30 15:43:13 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,280 +0,0 @@
-/*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package build.tools.stripproperties;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedWriter;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Properties;
-
-/**
- * Reads a properties file from standard input and writes an equivalent
- * properties file without comments to standard output.
- */
-public class StripProperties {
-
-    private static void error(String msg, Exception e) {
-        System.err.println("ERROR: stripproperties: " + msg);
-        if ( e != null ) {
-            System.err.println("EXCEPTION: " + e.toString());
-            e.printStackTrace();
-        }
-    }
-
-    private static List<String> parseOptions(String args[]) {
-        List<String> files = new ArrayList<String>();
-        for ( int i = 0; i < args.length ; i++ ) {
-            if ( "-optionsfile".equals(args[i]) && i+1 < args.length ) {
-                String filename = args[++i];
-                FileInputStream finput = null;
-                byte contents[] = null;
-                try {
-                    finput = new FileInputStream(filename);
-                    int byteCount = finput.available();
-                    if ( byteCount <= 0 ) {
-                        error("The -optionsfile file is empty", null);
-                        files = null;
-                    } else {
-                        contents = new byte[byteCount];
-                        int bytesRead = finput.read(contents);
-                        if ( byteCount != bytesRead ) {
-                            error("Cannot read all of -optionsfile file", null);
-                            files = null;
-                        }
-                    }
-                } catch ( IOException e ) {
-                    error("cannot open " + filename, e);
-                    files = null;
-                }
-                if ( finput != null ) {
-                    try {
-                        finput.close();
-                    } catch ( IOException e ) {
-                        files = null;
-                        error("cannot close " + filename, e);
-                    }
-                }
-                if ( files != null && contents != null ) {
-                    String tokens[] = (new String(contents)).split("\\s+");
-                    if ( tokens.length > 0 ) {
-                        List<String> ofiles = parseOptions(tokens);
-                        if ( ofiles != null ) {
-                            files.addAll(ofiles);
-                        } else {
-                            error("No files found in file", null);
-                            files = null;
-                        }
-                    }
-                }
-                if ( files == null ) {
-                    break;
-                }
-            } else {
-                files.add(args[i]);
-            }
-        }
-        return files;
-    }
-
-    private static boolean stripFiles(List<String> files) {
-        boolean ok = true;
-        for ( String file : files ) {
-
-            Properties prop = new Properties();
-            InputStream in = null;
-            try {
-                in = new BufferedInputStream(new FileInputStream(file));
-                prop.load(in);
-            } catch ( FileNotFoundException e ) {
-                error("Cannot access file " + file, e);
-                ok = false;
-            } catch ( IOException e ) {
-                error("IO exception processing file " + file, e);
-                ok = false;
-            }
-            if ( in != null ) {
-                try {
-                    in.close();
-                } catch ( IOException e ) {
-                    error("IO exception closing file " + file, e);
-                    ok = false;
-                }
-            }
-            if ( !ok ) {
-                break;
-            }
-
-            OutputStream out = null;
-            try {
-                out = new FileOutputStream(file);
-                storeProperties(prop, out);
-                out.flush();
-            } catch ( IOException e ) {
-                error("IO exception processing file " + file, e);
-                ok = false;
-            }
-            if ( out != null ) {
-                try {
-                    out.close();
-                } catch ( IOException e ) {
-                    error("IO exception closing file " + file, e);
-                    ok = false;
-                }
-            }
-            if ( !ok ) {
-                break;
-            }
-
-        }
-        return ok;
-    }
-
-    /**
-     * Strip the properties filenames supplied, replacing their contents.
-     * @param args Names of properties files to process and replace contents
-     */
-    public static void main(String args[]) {
-        List<String> files = parseOptions(args);
-        if ( files == null || !stripFiles(files) ) {
-            System.exit(1);
-        }
-    }
-
-    // --- code below here is adapted from java.util.Properties ---
-
-    private static final String specialSaveChars = "=: \t\r\n\f#!";
-
-    /*
-     * Converts unicodes to encoded &#92;uxxxx
-     * and writes out any of the characters in specialSaveChars
-     * with a preceding slash
-     */
-    private static String saveConvert(String theString, boolean escapeSpace) {
-        int len = theString.length();
-        StringBuffer outBuffer = new StringBuffer(len*2);
-
-        for(int x=0; x<len; x++) {
-            char aChar = theString.charAt(x);
-            switch(aChar) {
-                case ' ':
-                    if (x == 0 || escapeSpace) {
-                        outBuffer.append('\\');
-                    }
-                    outBuffer.append(' ');
-                    break;
-                case '\\':
-                    outBuffer.append('\\');
-                    outBuffer.append('\\');
-                    break;
-                case '\t':
-                    outBuffer.append('\\');
-                    outBuffer.append('t');
-                    break;
-                case '\n':
-                    outBuffer.append('\\');
-                    outBuffer.append('n');
-                    break;
-                case '\r':
-                    outBuffer.append('\\');
-                    outBuffer.append('r');
-                    break;
-                case '\f':
-                    outBuffer.append('\\');
-                    outBuffer.append('f');
-                    break;
-                default:
-                    if ((aChar < 0x0020) || (aChar == 0x007e) || (aChar > 0x00ff)) {
-                        outBuffer.append('\\');
-                        outBuffer.append('u');
-                        outBuffer.append(toHex((aChar >> 12) & 0xF));
-                        outBuffer.append(toHex((aChar >>  8) & 0xF));
-                        outBuffer.append(toHex((aChar >>  4) & 0xF));
-                        outBuffer.append(toHex( aChar        & 0xF));
-                    } else {
-                        if (specialSaveChars.indexOf(aChar) != -1) {
-                            outBuffer.append('\\');
-                        }
-                        outBuffer.append(aChar);
-                    }
-            }
-        }
-        return outBuffer.toString();
-    }
-
-    /**
-     * Writes the content of <code>properties</code> to <code>out</code>.
-     * The format is that of Properties.store with the following modifications:
-     * <ul>
-     * <li>No header or date is written
-     * <li>Latin-1 characters are written as single bytes, not escape sequences
-     * <li>Line breaks are indicated by a single \n independent of platform
-     * <ul>
-     */
-    private static void storeProperties(Properties properties, OutputStream out)
-    throws IOException {
-        BufferedWriter awriter;
-        awriter = new BufferedWriter(new OutputStreamWriter(out, "8859_1"));
-        for (Enumeration e = properties.keys(); e.hasMoreElements();) {
-            String key = (String)e.nextElement();
-            String val = (String)properties.get(key);
-            key = saveConvert(key, true);
-
-            /* No need to escape embedded and trailing spaces for value, hence
-             * pass false to flag.
-             */
-            val = saveConvert(val, false);
-            writeln(awriter, key + "=" + val);
-        }
-        awriter.flush();
-    }
-
-    private static void writeln(BufferedWriter bw, String s) throws IOException {
-        bw.write(s);
-        bw.write("\n");
-    }
-
-    /**
-     * Convert a nibble to a hex character
-     * @param   nibble  the nibble to convert.
-     */
-    private static char toHex(int nibble) {
-        return hexDigit[(nibble & 0xF)];
-    }
-
-    /** A table of hex digits */
-    private static final char[] hexDigit = {
-        '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
-    };
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/corba/make/tools/src/build/tools/stripproperties/StripPropertiesCorba.java	Fri Mar 30 16:57:50 2012 -0700
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package build.tools.stripproperties;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedWriter;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * Reads a properties file from standard input and writes an equivalent
+ * properties file without comments to standard output.
+ */
+public class StripPropertiesCorba {
+
+    private static void error(String msg, Exception e) {
+        System.err.println("ERROR: stripproperties: " + msg);
+        if ( e != null ) {
+            System.err.println("EXCEPTION: " + e.toString());
+            e.printStackTrace();
+        }
+    }
+
+    private static List<String> infiles = new ArrayList<String>();
+    private static List<String> outfiles = new ArrayList<String>();
+
+    private static boolean parseOptions(String args[]) {
+        boolean ok = true;
+
+        for ( int i = 0; i < args.length ; i++ ) {
+            if ( "-clean".equals(args[i]) && i+2 < args.length ) {
+                infiles.add(args[++i]);
+                outfiles.add(args[++i]);
+            } else if ( args[i].charAt(0)=='@') {
+                String filename = args[i].substring(1);
+                FileInputStream finput = null;
+                byte contents[] = null;
+                try {
+                    finput = new FileInputStream(filename);
+                    int byteCount = finput.available();
+                    if ( byteCount <= 0 ) {
+                        error("The @file is empty", null);
+                        ok = false;
+                    } else {
+                        contents = new byte[byteCount];
+                        int bytesRead = finput.read(contents);
+                        if ( byteCount != bytesRead ) {
+                            error("Cannot read all of @file", null);
+                            ok = false;
+                        }
+                    }
+                } catch ( IOException e ) {
+                    error("cannot open " + filename, e);
+                    ok = false;
+                }
+                if ( finput != null ) {
+                    try {
+                        finput.close();
+                    } catch ( IOException e ) {
+                        ok = false;
+                        error("cannot close " + filename, e);
+                    }
+                }
+                if ( ok && contents != null ) {
+                    String tokens[] = (new String(contents)).split("\\s+");
+                    if ( tokens.length > 0 ) {
+                        ok = parseOptions(tokens);
+                    }
+                }
+                if ( !ok ) {
+                    break;
+                }
+            } else {
+                infiles.add(args[i]);
+                outfiles.add(args[i]);
+            }
+        }
+        return ok;
+    }
+
+    private static boolean stripFiles(List<String> infiles, List<String> outfiles) {
+        boolean ok = true;
+        Iterator<String> inIter  = infiles.iterator();
+        Iterator<String> outIter = outfiles.iterator();
+
+        for (; inIter.hasNext(); ) {
+            String infile = inIter.next();
+            String outfile = outIter.next();
+
+            Properties prop = new Properties();
+            InputStream in = null;
+            try {
+                in = new BufferedInputStream(new FileInputStream(infile));
+                prop.load(in);
+            } catch ( FileNotFoundException e ) {
+                error("Cannot access file " + infile, e);
+                ok = false;
+            } catch ( IOException e ) {
+                error("IO exception processing file " + infile, e);
+                ok = false;
+            }
+            if ( in != null ) {
+                try {
+                    in.close();
+                } catch ( IOException e ) {
+                    error("IO exception closing file " + infile, e);
+                    ok = false;
+                }
+            }
+            if ( !ok ) {
+                break;
+            }
+
+            OutputStream out = null;
+            try {
+                out = new FileOutputStream(outfile);
+                storeProperties(prop, out);
+                out.flush();
+            } catch ( IOException e ) {
+                error("IO exception processing file " + outfile, e);
+                ok = false;
+            }
+            if ( out != null ) {
+                try {
+                    out.close();
+                } catch ( IOException e ) {
+                    error("IO exception closing file " + outfile, e);
+                    ok = false;
+                }
+            }
+            if ( !ok ) {
+                break;
+            }
+
+        }
+        return ok;
+    }
+
+    /**
+     * Strip the properties filenames supplied, replacing their contents.
+     * @param args Names of properties files to process and replace contents
+     */
+    public static void main(String args[]) {
+        boolean ok = parseOptions(args);
+        if ( !ok || !stripFiles(infiles, outfiles) ) {
+            System.exit(1);
+        }
+    }
+
+    // --- code below here is adapted from java.util.Properties ---
+
+    private static final String specialSaveChars = "=: \t\r\n\f#!";
+
+    /*
+     * Converts unicodes to encoded &#92;uxxxx
+     * and writes out any of the characters in specialSaveChars
+     * with a preceding slash
+     */
+    private static String saveConvert(String theString, boolean escapeSpace) {
+        int len = theString.length();
+        StringBuffer outBuffer = new StringBuffer(len*2);
+
+        for(int x=0; x<len; x++) {
+            char aChar = theString.charAt(x);
+            switch(aChar) {
+                case ' ':
+                    if (x == 0 || escapeSpace) {
+                        outBuffer.append('\\');
+                    }
+                    outBuffer.append(' ');
+                    break;
+                case '\\':
+                    outBuffer.append('\\');
+                    outBuffer.append('\\');
+                    break;
+                case '\t':
+                    outBuffer.append('\\');
+                    outBuffer.append('t');
+                    break;
+                case '\n':
+                    outBuffer.append('\\');
+                    outBuffer.append('n');
+                    break;
+                case '\r':
+                    outBuffer.append('\\');
+                    outBuffer.append('r');
+                    break;
+                case '\f':
+                    outBuffer.append('\\');
+                    outBuffer.append('f');
+                    break;
+                default:
+                    if ((aChar < 0x0020) || (aChar == 0x007e) || (aChar > 0x00ff)) {
+                        outBuffer.append('\\');
+                        outBuffer.append('u');
+                        outBuffer.append(toHex((aChar >> 12) & 0xF));
+                        outBuffer.append(toHex((aChar >>  8) & 0xF));
+                        outBuffer.append(toHex((aChar >>  4) & 0xF));
+                        outBuffer.append(toHex( aChar        & 0xF));
+                    } else {
+                        if (specialSaveChars.indexOf(aChar) != -1) {
+                            outBuffer.append('\\');
+                        }
+                        outBuffer.append(aChar);
+                    }
+            }
+        }
+        return outBuffer.toString();
+    }
+
+    /**
+     * Writes the content of <code>properties</code> to <code>out</code>.
+     * The format is that of Properties.store with the following modifications:
+     * <ul>
+     * <li>No header or date is written
+     * <li>Latin-1 characters are written as single bytes, not escape sequences
+     * <li>Line breaks are indicated by a single \n independent of platform
+     * <ul>
+     */
+    private static void storeProperties(Properties properties, OutputStream out)
+    throws IOException {
+        BufferedWriter awriter;
+        awriter = new BufferedWriter(new OutputStreamWriter(out, "8859_1"));
+        for (Enumeration<Object> e = properties.keys(); e.hasMoreElements();) {
+            String key = (String)e.nextElement();
+            String val = (String)properties.get(key);
+            key = saveConvert(key, true);
+
+            /* No need to escape embedded and trailing spaces for value, hence
+             * pass false to flag.
+             */
+            val = saveConvert(val, false);
+            writeln(awriter, key + "=" + val);
+        }
+        awriter.flush();
+    }
+
+    private static void writeln(BufferedWriter bw, String s) throws IOException {
+        bw.write(s);
+        bw.write("\n");
+    }
+
+    /**
+     * Convert a nibble to a hex character
+     * @param   nibble  the nibble to convert.
+     */
+    private static char toHex(int nibble) {
+        return hexDigit[(nibble & 0xF)];
+    }
+
+    /** A table of hex digits */
+    private static final char[] hexDigit = {
+        '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
+    };
+}
--- a/corba/make/tools/strip_properties/Makefile	Fri Mar 30 15:43:13 2012 -0700
+++ b/corba/make/tools/strip_properties/Makefile	Fri Mar 30 16:57:50 2012 -0700
@@ -34,7 +34,7 @@
 include $(BUILDDIR)/common/Defs.gmk
 
 BUILDTOOL_SOURCE_ROOT = $(BUILDDIR)/tools/src
-BUILDTOOL_MAIN        = $(PKGDIR)/StripProperties.java
+BUILDTOOL_MAIN        = $(PKGDIR)/StripPropertiesCorba.java
 
 #
 # Build tool jar rules.
--- a/hotspot/.hgtags	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/.hgtags	Fri Mar 30 16:57:50 2012 -0700
@@ -228,3 +228,11 @@
 975c4105f1e2ef1190a75b77124033f1fd4290b5 hs24-b01
 b183b0863611b85dbac16f3b08b40ba978756d19 jdk8-b28
 030b5306d60f140e822e4a6d301744cb110ff0c8 hs24-b02
+b45b5c564098c58ea69e7cff3f7d341f0254dd1d jdk8-b29
+d61761bf305031c94f7f8eca49abd978b7d3c5da jdk8-b30
+dfae0140457cfb2c381d7679735fbedbae862c62 hs24-b03
+f4767e53d6e0d5da7e3f1775904076cce54247c1 hs24-b04
+0cd147eaa673d1642b2f466f5dc257cf192db524 jdk8-b31
+27863e4586de38be7dd17da4163f542038f4d1d7 hs24-b05
+25410a347ebb0bef166c4338a90d9dea82463a20 jdk8-b32
+cd47da9383cd932cb2b659064057feafa2a91134 hs24-b06
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/jdi/ConnectorImpl.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/jdi/ConnectorImpl.java	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -217,8 +217,8 @@
     }
 
     protected void checkNativeLink(SecurityManager sm, String os) {
-        if (os.equals("SunOS") || os.equals("Linux")) {
-            // link "saproc" - SA native library on SunOS and Linux?
+        if (os.equals("SunOS") || os.equals("Linux") || os.contains("OS X")) {
+            // link "saproc" - SA native library on SunOS, Linux, and Mac OS X
             sm.checkLink("saproc");
         } else if (os.startsWith("Windows")) {
             // link "sawindbg" - SA native library on Windows.
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java	Fri Mar 30 16:57:50 2012 -0700
@@ -359,6 +359,12 @@
     public static final int innerClassNextOffset = 4;
   };
 
+  public static interface EnclosingMethodAttributeOffset {
+    public static final int enclosing_method_class_index_offset = 0;
+    public static final int enclosing_method_method_index_offset = 1;
+    public static final int enclosing_method_attribute_size = 2;
+  };
+
   // refer to compute_modifier_flags in VM code.
   public long computeModifierFlags() {
     long access = getAccessFlags();
@@ -367,9 +373,14 @@
     int length = ( innerClassList == null)? 0 : (int) innerClassList.getLength();
     if (length > 0) {
        if (Assert.ASSERTS_ENABLED) {
-          Assert.that(length % InnerClassAttributeOffset.innerClassNextOffset == 0, "just checking");
+          Assert.that(length % InnerClassAttributeOffset.innerClassNextOffset == 0 ||
+                      length % InnerClassAttributeOffset.innerClassNextOffset == EnclosingMethodAttributeOffset.enclosing_method_attribute_size,
+                      "just checking");
        }
        for (int i = 0; i < length; i += InnerClassAttributeOffset.innerClassNextOffset) {
+          if (i == length - EnclosingMethodAttributeOffset.enclosing_method_attribute_size) {
+              break;
+          }
           int ioff = innerClassList.getShortAt(i +
                          InnerClassAttributeOffset.innerClassInnerClassInfoOffset);
           // 'ioff' can be zero.
@@ -419,9 +430,14 @@
     int length = ( innerClassList == null)? 0 : (int) innerClassList.getLength();
     if (length > 0) {
        if (Assert.ASSERTS_ENABLED) {
-         Assert.that(length % InnerClassAttributeOffset.innerClassNextOffset == 0, "just checking");
+         Assert.that(length % InnerClassAttributeOffset.innerClassNextOffset == 0 ||
+                     length % InnerClassAttributeOffset.innerClassNextOffset == EnclosingMethodAttributeOffset.enclosing_method_attribute_size,
+                     "just checking");
        }
        for (int i = 0; i < length; i += InnerClassAttributeOffset.innerClassNextOffset) {
+         if (i == length - EnclosingMethodAttributeOffset.enclosing_method_attribute_size) {
+             break;
+         }
          int ioff = innerClassList.getShortAt(i +
                         InnerClassAttributeOffset.innerClassInnerClassInfoOffset);
          // 'ioff' can be zero.
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -43,7 +43,7 @@
       return "bsd";
     } else if (os.equals("OpenBSD")) {
       return "bsd";
-    } else if (os.equals("Darwin") || os.startsWith("Mac OS X")) {
+    } else if (os.equals("Darwin") || os.contains("OS X")) {
       return "bsd";
     } else if (os.startsWith("Windows")) {
       return "win32";
@@ -52,17 +52,17 @@
     }
   }
 
-  /* Returns "sparc" if on SPARC, "x86" if on x86. */
+  /* Returns "sparc" for SPARC based platforms and "x86" for x86 based
+     platforms. Otherwise returns the value of os.arch.  If the value
+     is not recognized as supported, an exception is thrown instead. */
   public static String getCPU() throws UnsupportedPlatformException {
     String cpu = System.getProperty("os.arch");
-    if (cpu.equals("i386")) {
+    if (cpu.equals("i386") || cpu.equals("x86")) {
       return "x86";
-    } else if (cpu.equals("sparc") || cpu.equals("x86") || cpu.equals("ia64")) {
+    } else if (cpu.equals("sparc") || cpu.equals("sparcv9")) {
+      return "sparc";
+    } else if (cpu.equals("ia64") || cpu.equals("amd64") || cpu.equals("x86_64")) {
       return cpu;
-    } else if (cpu.equals("sparcv9")) {
-      return "sparc";
-    } else if (cpu.equals("x86_64") || cpu.equals("amd64")) {
-      return "amd64";
     } else {
       throw new UnsupportedPlatformException("CPU type " + cpu + " not yet supported");
     }
--- a/hotspot/make/Makefile	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/make/Makefile	Fri Mar 30 16:57:50 2012 -0700
@@ -271,23 +271,25 @@
 ZERO_DIR=$(ZERO_BASE_DIR)/$(VM_SUBDIR)
 SHARK_DIR=$(SHARK_BASE_DIR)/$(VM_SUBDIR)
 
-# Misc files and generated files need to come from C1 or C2 area
-ifeq ($(ZERO_BUILD), true)
-ifeq ($(SHARK_BUILD), true)
-  MISC_DIR=$(SHARK_DIR)
-  GEN_DIR=$(SHARK_BASE_DIR)/generated
-else
-  MISC_DIR=$(ZERO_DIR)
-  GEN_DIR=$(ZERO_BASE_DIR)/generated
+ifeq ($(JVM_VARIANT_SERVER), true)
+    MISC_DIR=$(C2_DIR)
+    GEN_DIR=$(C2_BASE_DIR)/generated
+endif
+ifeq ($(JVM_VARIANT_CLIENT), true)
+    MISC_DIR=$(C1_DIR)
+    GEN_DIR=$(C1_BASE_DIR)/generated
 endif
-else
-ifeq ($(ARCH_DATA_MODEL), 32)
-  MISC_DIR=$(C1_DIR)
-  GEN_DIR=$(C1_BASE_DIR)/generated
-else
-  MISC_DIR=$(C2_DIR)
-  GEN_DIR=$(C2_BASE_DIR)/generated
+ifeq ($(JVM_VARIANT_KERNEL), true)
+    MISC_DIR=$(C2_DIR)
+    GEN_DIR=$(C2_BASE_DIR)/generated
 endif
+ifeq ($(JVM_VARIANT_ZEROSHARK), true)
+    MISC_DIR=$(SHARK_DIR)
+    GEN_DIR=$(SHARK_BASE_DIR)/generated
+endif
+ifeq ($(JVM_VARIANT_ZERO), true)
+    MISC_DIR=$(ZERO_DIR)
+    GEN_DIR=$(ZERO_BASE_DIR)/generated
 endif
 
 # Bin files (windows)
@@ -332,52 +334,55 @@
 
 # Shared Library
 ifneq ($(OSNAME),windows)
-  ifeq ($(ZERO_BUILD), true)
-    ifeq ($(SHARK_BUILD), true)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(SHARK_DIR)/%.$(LIBRARY_SUFFIX)
-	$(install-file)
-$(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX):       $(SHARK_DIR)/%.$(LIBRARY_SUFFIX)
-	$(install-file)
-    else
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(ZERO_DIR)/%.$(LIBRARY_SUFFIX)
-	$(install-file)
-$(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX):       $(ZERO_DIR)/%.$(LIBRARY_SUFFIX)
-	$(install-file)
+    ifeq ($(JVM_VARIANT_SERVER), true)
+        $(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(C2_DIR)/%.$(LIBRARY_SUFFIX)
+		$(install-file)
+        $(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX):       $(C2_DIR)/%.$(LIBRARY_SUFFIX)
+		$(install-file)
+        $(EXPORT_SERVER_DIR)/64/%.$(LIBRARY_SUFFIX):    $(C2_DIR)/%.$(LIBRARY_SUFFIX)
+		$(install-file)
+        $(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: 		$(C2_DIR)/%.debuginfo
+		$(install-file)
+        $(EXPORT_SERVER_DIR)/%.debuginfo:       		$(C2_DIR)/%.debuginfo
+		$(install-file)
+        $(EXPORT_SERVER_DIR)/64/%.debuginfo:    		$(C2_DIR)/%.debuginfo
+		$(install-file)
     endif
-  else
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(C1_DIR)/%.$(LIBRARY_SUFFIX)
-	$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(C2_DIR)/%.$(LIBRARY_SUFFIX)
-	$(install-file)
-$(EXPORT_CLIENT_DIR)/%.$(LIBRARY_SUFFIX):       $(C1_DIR)/%.$(LIBRARY_SUFFIX)
-	$(install-file)
-$(EXPORT_CLIENT_DIR)/64/%.$(LIBRARY_SUFFIX):    $(C1_DIR)/%.$(LIBRARY_SUFFIX)
-	$(install-file)
-$(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX):       $(C2_DIR)/%.$(LIBRARY_SUFFIX)
-	$(install-file)
-$(EXPORT_SERVER_DIR)/64/%.$(LIBRARY_SUFFIX):    $(C2_DIR)/%.$(LIBRARY_SUFFIX)
-	$(install-file)
-
-# Debug info for shared library
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: $(C1_DIR)/%.debuginfo
-	$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: $(C2_DIR)/%.debuginfo
-	$(install-file)
-$(EXPORT_CLIENT_DIR)/%.debuginfo:       $(C1_DIR)/%.debuginfo
-	$(install-file)
-$(EXPORT_CLIENT_DIR)/64/%.debuginfo:    $(C1_DIR)/%.debuginfo
-	$(install-file)
-$(EXPORT_SERVER_DIR)/%.debuginfo:       $(C2_DIR)/%.debuginfo
-	$(install-file)
-$(EXPORT_SERVER_DIR)/64/%.debuginfo:    $(C2_DIR)/%.debuginfo
-	$(install-file)
-  endif
+    ifeq ($(JVM_VARIANT_CLIENT), true)
+        $(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(C1_DIR)/%.$(LIBRARY_SUFFIX)
+		$(install-file)
+        $(EXPORT_CLIENT_DIR)/%.$(LIBRARY_SUFFIX):       $(C1_DIR)/%.$(LIBRARY_SUFFIX)
+		$(install-file)
+        $(EXPORT_CLIENT_DIR)/64/%.$(LIBRARY_SUFFIX):    $(C1_DIR)/%.$(LIBRARY_SUFFIX)
+		$(install-file)
+        $(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: 		$(C1_DIR)/%.debuginfo
+		$(install-file)
+        $(EXPORT_CLIENT_DIR)/%.debuginfo:       		$(C1_DIR)/%.debuginfo
+		$(install-file)
+        $(EXPORT_CLIENT_DIR)/64/%.debuginfo:    		$(C1_DIR)/%.debuginfo
+		$(install-file)
+    endif
+    ifeq ($(JVM_VARIANT_ZEROSHARK), true)
+        $(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(SHARK_DIR)/%.$(LIBRARY_SUFFIX)
+		$(install-file)
+        $(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX):       $(SHARK_DIR)/%.$(LIBRARY_SUFFIX)
+		$(install-file)
+    endif
+    ifeq ($(JVM_VARIANT_ZERO), true)
+        $(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(ZERO_DIR)/%.$(LIBRARY_SUFFIX)
+		$(install-file)
+        $(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX):       $(ZERO_DIR)/%.$(LIBRARY_SUFFIX)
+		$(install-file)
+    endif
 endif
 
 # Jar file (sa-jdi.jar)
 $(EXPORT_LIB_DIR)/%.jar: $(GEN_DIR)/%.jar
 	$(install-file)
 
+$(EXPORT_JRE_LIB_DIR)/%.jar: $(GEN_DIR)/%.jar
+	$(install-file)
+
 # Include files (jvmti.h, jvmticmlr.h, jni.h, $(JDK_INCLUDE_SUBDIR)/jni_md.h, jmm.h, jfr.h)
 $(EXPORT_INCLUDE_DIR)/%: $(GEN_DIR)/jvmtifiles/%
 	$(install-file)
@@ -447,18 +452,19 @@
 	 ($(CD) $(JDK_IMAGE_DIR) && $(TAR) -xf -)
 
 test_jdk:
-    ifeq ($(ARCH_DATA_MODEL), 32)
-      ifneq ($(ZERO_BUILD), true)
-	$(JDK_IMAGE_DIR)/bin/java -d32 -client -Xinternalversion
-	$(JDK_IMAGE_DIR)/bin/java -d32 -client -version
-      endif
-	$(JDK_IMAGE_DIR)/bin/java -d32 -server -Xinternalversion
-	$(JDK_IMAGE_DIR)/bin/java -d32 -server -version
-    endif
-    ifeq ($(ARCH_DATA_MODEL), 64)
-	$(JDK_IMAGE_DIR)/bin/java -d64 -server -Xinternalversion
-	$(JDK_IMAGE_DIR)/bin/java -d64 -server -version
-    endif
+  ifeq ($(JVM_VARIANT_CLIENT), true)
+	$(JDK_IMAGE_DIR)/bin/java -d$(ARCH_DATA_MODEL) -client -Xinternalversion
+	$(JDK_IMAGE_DIR)/bin/java -d$(ARCH_DATA_MODEL) -client -version
+  endif
+  ifeq ($(findstring true, $(JVM_VARIANT_SERVER)\
+		$(JVM_VARIANT_ZERO)$(JVM_VARIANT_ZEROSHARK)), true)
+	$(JDK_IMAGE_DIR)/bin/java -d$(ARCH_DATA_MODEL) -server -Xinternalversion
+	$(JDK_IMAGE_DIR)/bin/java -d$(ARCH_DATA_MODEL) -server -version
+  endif
+  ifeq ($(JVM_VARIANT_KERNEL), true)
+	$(JDK_IMAGE_DIR)/bin/java -d$(ARCH_DATA_MODEL) -kernel -Xinternalversion
+	$(JDK_IMAGE_DIR)/bin/java -d$(ARCH_DATA_MODEL) -kernel -version
+  endif
 
 copy_product_jdk::
 	$(RM) -r $(JDK_IMAGE_DIR)
--- a/hotspot/make/bsd/Makefile	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/make/bsd/Makefile	Fri Mar 30 16:57:50 2012 -0700
@@ -188,7 +188,7 @@
 # in the build.sh script:
 TARGETS           = debug jvmg fastdebug optimized profiled product
 
-ifeq ($(ZERO_BUILD), true)
+ifeq ($(findstring true, $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
   SUBDIR_DOCS     = $(OSNAME)_$(VARIANTARCH)_docs
 else
   SUBDIR_DOCS     = $(OSNAME)_$(BUILDARCH)_docs
--- a/hotspot/make/bsd/makefiles/buildtree.make	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/make/bsd/makefiles/buildtree.make	Fri Mar 30 16:57:50 2012 -0700
@@ -69,7 +69,7 @@
 # For now, until the compiler is less wobbly:
 TESTFLAGS	= -Xbatch -showversion
 
-ifeq ($(ZERO_BUILD), true)
+ifeq ($(findstring true, $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
   PLATFORM_FILE = $(shell dirname $(shell dirname $(shell pwd)))/platform_zero
 else
   ifdef USE_SUNCC
--- a/hotspot/make/bsd/makefiles/defs.make	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/make/bsd/makefiles/defs.make	Fri Mar 30 16:57:50 2012 -0700
@@ -38,7 +38,7 @@
 endif
 
 # zero
-ifeq ($(ZERO_BUILD), true)
+ifeq ($(findstring true, $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
   ifeq ($(ARCH_DATA_MODEL), 64)
     MAKE_ARGS      += LP64=1
   endif
@@ -124,6 +124,18 @@
   HS_ARCH          = ppc
 endif
 
+# On 32 bit bsd we build server and client, on 64 bit just server.
+ifeq ($(JVM_VARIANTS),)
+  ifeq ($(ARCH_DATA_MODEL), 32)
+    JVM_VARIANTS:=client,server
+    JVM_VARIANT_CLIENT:=true
+    JVM_VARIANT_SERVER:=true
+  else
+    JVM_VARIANTS:=server
+    JVM_VARIANT_SERVER:=true
+  endif
+endif
+
 JDK_INCLUDE_SUBDIR=bsd
 
 # Library suffix
@@ -144,16 +156,16 @@
 EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server
 EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client
 
-ifndef BUILD_CLIENT_ONLY
-EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
-EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.$(LIBRARY_SUFFIX)
+EXPORT_LIST += $(EXPORT_JRE_LIB_DIR)/wb.jar
+
+ifeq ($(findstring true, $(JVM_VARIANT_SERVER) $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
+  EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
+  EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.$(LIBRARY_SUFFIX)
 endif
 
-ifneq ($(ZERO_BUILD), true)
-  ifeq ($(ARCH_DATA_MODEL), 32)
-    EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt
-    EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.$(LIBRARY_SUFFIX)
-  endif
+ifeq ($(JVM_VARIANT_CLIENT),true)
+  EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt
+  EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.$(LIBRARY_SUFFIX)
 endif
 
 # Serviceability Binaries
--- a/hotspot/make/bsd/makefiles/gcc.make	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/make/bsd/makefiles/gcc.make	Fri Mar 30 16:57:50 2012 -0700
@@ -105,11 +105,12 @@
 VM_PICFLAG/AOUT   =
 VM_PICFLAG        = $(VM_PICFLAG/$(LINK_INTO))
 
-ifeq ($(ZERO_BUILD), true)
-CFLAGS += $(LIBFFI_CFLAGS)
+ifeq ($(JVM_VARIANT_ZERO), true)
+  CFLAGS += $(LIBFFI_CFLAGS)
 endif
-ifeq ($(SHARK_BUILD), true)
-CFLAGS += $(LLVM_CFLAGS)
+ifeq ($(JVM_VARIANT_ZEROSHARK), true)
+  CFLAGS += $(LIBFFI_CFLAGS)
+  CFLAGS += $(LLVM_CFLAGS)
 endif
 CFLAGS += $(VM_PICFLAG)
 CFLAGS += -fno-rtti
--- a/hotspot/make/bsd/makefiles/vm.make	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/make/bsd/makefiles/vm.make	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -42,7 +42,7 @@
 -include $(DEP_DIR)/*.d
 
 # read machine-specific adjustments (%%% should do this via buildtree.make?)
-ifeq ($(ZERO_BUILD), true)
+ifeq ($(findstring true, $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
   include $(MAKEFILES_DIR)/zeroshark.make
 else
   include $(MAKEFILES_DIR)/$(BUILDARCH).make
@@ -271,12 +271,12 @@
 
   LIBS_VM                  += $(LIBS)
 endif
-ifeq ($(ZERO_BUILD), true)
+ifeq ($(JVM_VARIANT_ZERO), true)
   LIBS_VM += $(LIBFFI_LIBS)
 endif
-ifeq ($(SHARK_BUILD), true)
+ifeq ($(JVM_VARIANT_ZEROSHARK), true)
+  LIBS_VM   += $(LIBFFI_LIBS) $(LLVM_LIBS)
   LFLAGS_VM += $(LLVM_LDFLAGS)
-  LIBS_VM   += $(LLVM_LIBS)
 endif
 
 
@@ -335,6 +335,9 @@
 # Serviceability agent
 include $(MAKEFILES_DIR)/saproc.make
 
+# Whitebox testing API
+include $(MAKEFILES_DIR)/wb.make
+
 #----------------------------------------------------------------------
 
 ifeq ($(OS_VENDOR), Darwin)
@@ -342,10 +345,10 @@
 	dsymutil $(LIBJVM)
 
 # no libjvm_db for macosx
-build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(BUILDLIBSAPROC) dtraceCheck $(LIBJVM).dSYM
+build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(BUILDLIBSAPROC) dtraceCheck $(LIBJVM).dSYM $(WB_JAR)
 	echo "Doing vm.make build:"
 else
-build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(BUILDLIBSAPROC)
+build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(BUILDLIBSAPROC) $(WB_JAR)
 endif
 
 install: install_jvm install_jsig install_saproc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/make/bsd/makefiles/wb.make	Fri Mar 30 16:57:50 2012 -0700
@@ -0,0 +1,46 @@
+#
+# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#  
+#
+
+# Rules to build whitebox testing library, used by vm.make
+WB = wb
+
+WBSRCDIR = $(GAMMADIR)/src/share/tools/whitebox
+
+WB_JAR = $(GENERATED)/$(WB).jar
+
+WB_JAVA_SRCS = $(shell find $(WBSRCDIR) -name '*.java')
+WB_JAVA_CLASSDIR = $(GENERATED)/wb/classes
+
+WB_JAVA_CLASSES  = $(patsubst $(WBSRCDIR)/%,$(WB_JAVA_CLASSDIR)/%, \
+	$(patsubst %.java,%.class,$(WB_JAVA_SRCS)))
+
+$(WB_JAVA_CLASSDIR)/%.class: $(WBSRCDIR)/%.java $(WB_JAVA_CLASSDIR)
+	$(REMOTE) $(COMPILE.JAVAC) -nowarn -d $(WB_JAVA_CLASSDIR) $<
+
+$(WB_JAR): $(WB_JAVA_CLASSES)
+	$(QUIETLY) $(REMOTE) $(RUN.JAR) cf $@ -C $(WB_JAVA_CLASSDIR)/ .
+
+$(WB_JAVA_CLASSDIR):
+	$(QUIETLY) mkdir -p $@
+
--- a/hotspot/make/defs.make	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/make/defs.make	Fri Mar 30 16:57:50 2012 -0700
@@ -55,6 +55,27 @@
 @$(RM) $@
 endef
 
+# Default values for JVM_VARIANT* variables if configure hasn't set
+# it already.
+ifeq ($(JVM_VARIANTS),)
+  ifeq ($(ZERO_BUILD), true)
+    ifeq ($(SHARK_BUILD), true)
+      JVM_VARIANTS:=zeroshark
+      JVM_VARIANT_ZEROSHARK:=true
+    else
+      JVM_VARIANTS:=zero
+      JVM_VARIANT_ZERO:=true
+    endif
+  else
+    # A default is needed
+    ifeq ($(BUILD_CLIENT_ONLY), true)
+      JVM_VARIANTS:=client
+      JVM_VARIANT_CLIENT:=true
+    endif
+    # Further defaults are platform and arch specific
+  endif
+endif
+
 # Directory paths and user name
 # Unless GAMMADIR is set on the command line, search upward from
 # the current directory for a parent directory containing "src/share/vm".
--- a/hotspot/make/hotspot_version	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/make/hotspot_version	Fri Mar 30 16:57:50 2012 -0700
@@ -35,7 +35,7 @@
 
 HS_MAJOR_VER=24
 HS_MINOR_VER=0
-HS_BUILD_NUMBER=02
+HS_BUILD_NUMBER=06
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=8
--- a/hotspot/make/jprt.properties	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/make/jprt.properties	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -54,58 +54,72 @@
 # Define the Solaris platforms we want for the various releases
 jprt.my.solaris.sparc.jdk8=solaris_sparc_5.10
 jprt.my.solaris.sparc.jdk7=solaris_sparc_5.10
+jprt.my.solaris.sparc.jdk7u4=${jprt.my.solaris.sparc.jdk7}
 jprt.my.solaris.sparc=${jprt.my.solaris.sparc.${jprt.tools.default.release}}
 
 jprt.my.solaris.sparcv9.jdk8=solaris_sparcv9_5.10
 jprt.my.solaris.sparcv9.jdk7=solaris_sparcv9_5.10
+jprt.my.solaris.sparcv9.jdk7u4=${jprt.my.solaris.sparcv9.jdk7}
 jprt.my.solaris.sparcv9=${jprt.my.solaris.sparcv9.${jprt.tools.default.release}}
 
 jprt.my.solaris.i586.jdk8=solaris_i586_5.10
 jprt.my.solaris.i586.jdk7=solaris_i586_5.10
+jprt.my.solaris.i586.jdk7u4=${jprt.my.solaris.i586.jdk7}
 jprt.my.solaris.i586=${jprt.my.solaris.i586.${jprt.tools.default.release}}
 
 jprt.my.solaris.x64.jdk8=solaris_x64_5.10
 jprt.my.solaris.x64.jdk7=solaris_x64_5.10
+jprt.my.solaris.x64.jdk7u4=${jprt.my.solaris.x64.jdk7}
 jprt.my.solaris.x64=${jprt.my.solaris.x64.${jprt.tools.default.release}}
 
 jprt.my.linux.i586.jdk8=linux_i586_2.6
 jprt.my.linux.i586.jdk7=linux_i586_2.6
+jprt.my.linux.i586.jdk7u4=${jprt.my.linux.i586.jdk7}
 jprt.my.linux.i586=${jprt.my.linux.i586.${jprt.tools.default.release}}
 
 jprt.my.linux.x64.jdk8=linux_x64_2.6
 jprt.my.linux.x64.jdk7=linux_x64_2.6
+jprt.my.linux.x64.jdk7u4=${jprt.my.linux.x64.jdk7}
 jprt.my.linux.x64=${jprt.my.linux.x64.${jprt.tools.default.release}}
 
 jprt.my.linux.ppc.jdk8=linux_ppc_2.6
 jprt.my.linux.ppc.jdk7=linux_ppc_2.6
+jprt.my.linux.ppc.jdk7u4=${jprt.my.linux.ppc.jdk7}
 jprt.my.linux.ppc=${jprt.my.linux.ppc.${jprt.tools.default.release}}
 
 jprt.my.linux.ppcv2.jdk8=linux_ppcv2_2.6
 jprt.my.linux.ppcv2.jdk7=linux_ppcv2_2.6
+jprt.my.linux.ppcv2.jdk7u4=${jprt.my.linux.ppcv2.jdk7}
 jprt.my.linux.ppcv2=${jprt.my.linux.ppcv2.${jprt.tools.default.release}}
 
 jprt.my.linux.ppcsflt.jdk8=linux_ppcsflt_2.6
 jprt.my.linux.ppcsflt.jdk7=linux_ppcsflt_2.6
+jprt.my.linux.ppcsflt.jdk7u4=${jprt.my.linux.ppcsflt.jdk7}
 jprt.my.linux.ppcsflt=${jprt.my.linux.ppcsflt.${jprt.tools.default.release}}
 
 jprt.my.linux.armvfp.jdk8=linux_armvfp_2.6
 jprt.my.linux.armvfp.jdk7=linux_armvfp_2.6
+jprt.my.linux.armvfp.jdk7u4=${jprt.my.linux.armvfp.jdk7}
 jprt.my.linux.armvfp=${jprt.my.linux.armvfp.${jprt.tools.default.release}}
 
 jprt.my.linux.armsflt.jdk8=linux_armsflt_2.6
 jprt.my.linux.armsflt.jdk7=linux_armsflt_2.6
+jprt.my.linux.armsflt.jdk7u4=${jprt.my.linux.armsflt.jdk7}
 jprt.my.linux.armsflt=${jprt.my.linux.armsflt.${jprt.tools.default.release}}
 
 jprt.my.macosx.x64.jdk8=macosx_x64_10.7
 jprt.my.macosx.x64.jdk7=macosx_x64_10.7
+jprt.my.macosx.x64.jdk7u4=${jprt.my.macosx.x64.jdk7}
 jprt.my.macosx.x64=${jprt.my.macosx.x64.${jprt.tools.default.release}}
 
 jprt.my.windows.i586.jdk8=windows_i586_5.1
 jprt.my.windows.i586.jdk7=windows_i586_5.1
+jprt.my.windows.i586.jdk7u4=${jprt.my.windows.i586.jdk7}
 jprt.my.windows.i586=${jprt.my.windows.i586.${jprt.tools.default.release}}
 
 jprt.my.windows.x64.jdk8=windows_x64_5.2
 jprt.my.windows.x64.jdk7=windows_x64_5.2
+jprt.my.windows.x64.jdk7u4=${jprt.my.windows.x64.jdk7}
 jprt.my.windows.x64=${jprt.my.windows.x64.${jprt.tools.default.release}}
 
 # Standard list of jprt build targets for this source tree
@@ -139,16 +153,7 @@
 
 jprt.build.targets.jdk8=${jprt.build.targets.all}
 jprt.build.targets.jdk7=${jprt.build.targets.all}
-jprt.build.targets.jdk7temp=${jprt.build.targets.all}
-jprt.build.targets.jdk7b107=${jprt.build.targets.all}
-jprt.build.targets.jdk6=${jprt.build.targets.standard}
-jprt.build.targets.jdk6perf=${jprt.build.targets.standard}
-jprt.build.targets.jdk6u10=${jprt.build.targets.standard}
-jprt.build.targets.jdk6u14=${jprt.build.targets.standard}
-jprt.build.targets.jdk6u18=${jprt.build.targets.standard}
-jprt.build.targets.jdk6u20=${jprt.build.targets.standard}
-jprt.build.targets.ejdk6=${jprt.build.targets.all}
-jprt.build.targets.ejdk7=${jprt.build.targets.all}
+jprt.build.targets.jdk7u4=${jprt.build.targets.all}
 jprt.build.targets=${jprt.build.targets.${jprt.tools.default.release}}
 
 # Subset lists of test targets for this source tree
@@ -441,6 +446,7 @@
 
 jprt.test.targets.jdk8=${jprt.test.targets.standard}
 jprt.test.targets.jdk7=${jprt.test.targets.standard}
+jprt.test.targets.jdk7u4=${jprt.test.targets.jdk7}
 jprt.test.targets=${jprt.test.targets.${jprt.tools.default.release}}
 
 # The default test/Makefile targets that should be run
@@ -474,16 +480,32 @@
   ${jprt.my.macosx.x64}-fastdebug-c2-internalvmtests, \
   ${jprt.my.windows.i586}-fastdebug-c2-internalvmtests, \
   ${jprt.my.windows.x64}-fastdebug-c2-internalvmtests
-  
+
+jprt.make.rule.test.targets.standard.wbapi = \
+  ${jprt.my.solaris.sparc}-{product|fastdebug}-c2-wbapitest, \
+  ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-wbapitest, \
+  ${jprt.my.solaris.i586}-{product|fastdebug}-c2-wbapitest, \
+  ${jprt.my.solaris.x64}-{product|fastdebug}-c2-wbapitest, \
+  ${jprt.my.linux.i586}-{product|fastdebug}-c2-wbapitest, \
+  ${jprt.my.linux.x64}-{product|fastdebug}-c2-wbapitest, \
+  ${jprt.my.windows.i586}-{product|fastdebug}-c2-wbapitest, \
+  ${jprt.my.windows.x64}-{product|fastdebug}-c2-wbapitest, \
+  ${jprt.my.solaris.sparc}-{product|fastdebug}-c1-wbapitest, \
+  ${jprt.my.solaris.i586}-{product|fastdebug}-c1-wbapitest, \
+  ${jprt.my.linux.i586}-{product|fastdebug}-c1-wbapitest, \
+  ${jprt.my.windows.i586}-{product|fastdebug}-c1-wbapitest
+
 jprt.make.rule.test.targets.standard = \
   ${jprt.make.rule.test.targets.standard.client}, \
   ${jprt.make.rule.test.targets.standard.server}, \
-  ${jprt.make.rule.test.targets.standard.internalvmtests}
+  ${jprt.make.rule.test.targets.standard.internalvmtests}, \
+  ${jprt.make.rule.test.targets.standard.wbapi}
 
 jprt.make.rule.test.targets.embedded = \
   ${jprt.make.rule.test.targets.standard.client}
 
 jprt.make.rule.test.targets.jdk8=${jprt.make.rule.test.targets.standard}
 jprt.make.rule.test.targets.jdk7=${jprt.make.rule.test.targets.standard}
+jprt.make.rule.test.targets.jdk7u4=${jprt.make.rule.test.targets.jdk7}
 jprt.make.rule.test.targets=${jprt.make.rule.test.targets.${jprt.tools.default.release}}
 
--- a/hotspot/make/linux/Makefile	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/make/linux/Makefile	Fri Mar 30 16:57:50 2012 -0700
@@ -188,7 +188,7 @@
 # in the build.sh script:
 TARGETS           = debug jvmg fastdebug optimized profiled product
 
-ifeq ($(ZERO_BUILD), true)
+ifeq ($(findstring true, $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
   SUBDIR_DOCS     = $(OSNAME)_$(VARIANTARCH)_docs
 else
   SUBDIR_DOCS     = $(OSNAME)_$(BUILDARCH)_docs
--- a/hotspot/make/linux/makefiles/buildtree.make	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/make/linux/makefiles/buildtree.make	Fri Mar 30 16:57:50 2012 -0700
@@ -66,7 +66,7 @@
 # For now, until the compiler is less wobbly:
 TESTFLAGS	= -Xbatch -showversion
 
-ifeq ($(ZERO_BUILD), true)
+ifeq ($(findstring true, $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
   PLATFORM_FILE = $(shell dirname $(shell dirname $(shell pwd)))/platform_zero
 else
   ifdef USE_SUNCC
--- a/hotspot/make/linux/makefiles/defs.make	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/make/linux/makefiles/defs.make	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -38,7 +38,7 @@
 endif
 
 # zero
-ifeq ($(ZERO_BUILD), true)
+ifeq ($(findstring true, $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
   ifeq ($(ARCH_DATA_MODEL), 64)
     MAKE_ARGS      += LP64=1
   endif
@@ -114,6 +114,18 @@
   HS_ARCH          = ppc
 endif
 
+# On 32 bit linux we build server and client, on 64 bit just server.
+ifeq ($(JVM_VARIANTS),)
+  ifeq ($(ARCH_DATA_MODEL), 32)
+    JVM_VARIANTS:=client,server
+    JVM_VARIANT_CLIENT:=true
+    JVM_VARIANT_SERVER:=true
+  else
+    JVM_VARIANTS:=server
+    JVM_VARIANT_SERVER:=true
+  endif
+endif
+
 # determine if HotSpot is being built in JDK6 or earlier version
 JDK6_OR_EARLIER=0
 ifeq "$(shell expr \( '$(JDK_MAJOR_VERSION)' != '' \& '$(JDK_MINOR_VERSION)' != '' \& '$(JDK_MICRO_VERSION)' != '' \))" "1"
@@ -193,22 +205,22 @@
 EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server
 EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client
 
-ifndef BUILD_CLIENT_ONLY
-EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
-EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.$(LIBRARY_SUFFIX)
+EXPORT_LIST += $(EXPORT_JRE_LIB_DIR)/wb.jar
+
+ifeq ($(findstring true, $(JVM_VARIANT_SERVER) $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
+  EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
+  EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.$(LIBRARY_SUFFIX)
   ifneq ($(OBJCOPY),)
     EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.debuginfo
   endif
 endif
 
-ifneq ($(ZERO_BUILD), true)
-  ifeq ($(ARCH_DATA_MODEL), 32)
-    EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt
-    EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.$(LIBRARY_SUFFIX)
-    ifneq ($(OBJCOPY),)
-      EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.debuginfo
-    endif
-  endif
+ifeq ($(JVM_VARIANT_CLIENT),true)
+  EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt
+  EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.$(LIBRARY_SUFFIX)
+  ifneq ($(OBJCOPY),)
+    EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.debuginfo
+  endif 
 endif
 
 # Serviceability Binaries
--- a/hotspot/make/linux/makefiles/gcc.make	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/make/linux/makefiles/gcc.make	Fri Mar 30 16:57:50 2012 -0700
@@ -72,10 +72,11 @@
 VM_PICFLAG/AOUT   =
 VM_PICFLAG        = $(VM_PICFLAG/$(LINK_INTO))
 
-ifeq ($(ZERO_BUILD), true)
+ifeq ($(JVM_VARIANT_ZERO), true)
 CFLAGS += $(LIBFFI_CFLAGS)
 endif
-ifeq ($(SHARK_BUILD), true)
+ifeq ($(JVM_VARIANT_ZEROSHARK), true)
+CFLAGS += $(LIBFFI_CFLAGS)
 CFLAGS += $(LLVM_CFLAGS)
 endif
 CFLAGS += $(VM_PICFLAG)
--- a/hotspot/make/linux/makefiles/vm.make	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/make/linux/makefiles/vm.make	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -42,7 +42,7 @@
 -include $(DEP_DIR)/*.d
 
 # read machine-specific adjustments (%%% should do this via buildtree.make?)
-ifeq ($(ZERO_BUILD), true)
+ifeq ($(findstring true, $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
   include $(MAKEFILES_DIR)/zeroshark.make
 else
   include $(MAKEFILES_DIR)/$(BUILDARCH).make
@@ -236,7 +236,7 @@
 vm.def: $(Res_Files) $(Obj_Files)
 	sh $(GAMMADIR)/make/linux/makefiles/build_vm_def.sh *.o > $@
 
-ifeq ($(SHARK_BUILD), true)
+ifeq ($(JVM_VARIANT_ZEROSHARK), true)
   STATIC_CXX = false
 else
   ifeq ($(ZERO_LIBARCH), ppc64)
@@ -268,12 +268,12 @@
 
   LIBS_VM                  += $(LIBS)
 endif
-ifeq ($(ZERO_BUILD), true)
+ifeq ($(JVM_VARIANT_ZERO), true)
   LIBS_VM += $(LIBFFI_LIBS)
 endif
-ifeq ($(SHARK_BUILD), true)
+ifeq ($(JVM_VARIANT_ZEROSHARK), true)
+  LIBS_VM   += $(LIBFFI_LIBS) $(LLVM_LIBS)
   LFLAGS_VM += $(LLVM_LDFLAGS)
-  LIBS_VM   += $(LLVM_LIBS)
 endif
 
 LINK_VM = $(LINK_LIB.CC)
@@ -368,9 +368,12 @@
 # Serviceability agent
 include $(MAKEFILES_DIR)/saproc.make
 
+# Whitebox testing API
+include $(MAKEFILES_DIR)/wb.make
+
 #----------------------------------------------------------------------
 
-build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(BUILDLIBSAPROC)
+build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(BUILDLIBSAPROC) $(WB_JAR)
 
 install: install_jvm install_jsig install_saproc
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/make/linux/makefiles/wb.make	Fri Mar 30 16:57:50 2012 -0700
@@ -0,0 +1,46 @@
+#
+# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#  
+#
+
+# Rules to build whitebox testing library, used by vm.make
+WB = wb
+
+WBSRCDIR = $(GAMMADIR)/src/share/tools/whitebox
+
+WB_JAR = $(GENERATED)/$(WB).jar
+
+WB_JAVA_SRCS = $(shell find $(WBSRCDIR) -name '*.java')
+WB_JAVA_CLASSDIR = $(GENERATED)/wb/classes
+
+WB_JAVA_CLASSES  = $(patsubst $(WBSRCDIR)/%,$(WB_JAVA_CLASSDIR)/%, \
+	$(patsubst %.java,%.class,$(WB_JAVA_SRCS)))
+
+$(WB_JAVA_CLASSDIR)/%.class: $(WBSRCDIR)/%.java $(WB_JAVA_CLASSDIR)
+	$(REMOTE) $(COMPILE.JAVAC) -nowarn -d $(WB_JAVA_CLASSDIR) $<
+
+$(WB_JAR): $(WB_JAVA_CLASSES)
+	$(QUIETLY) $(REMOTE) $(RUN.JAR) cf $@ -C $(WB_JAVA_CLASSDIR)/ .
+
+$(WB_JAVA_CLASSDIR):
+	$(QUIETLY) mkdir -p $@
+
--- a/hotspot/make/solaris/makefiles/defs.make	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/make/solaris/makefiles/defs.make	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -59,6 +59,18 @@
   endif
 endif
 
+# On 32 bit solaris we build server and client, on 64 bit just server.
+ifeq ($(JVM_VARIANTS),)
+  ifeq ($(ARCH_DATA_MODEL), 32)
+    JVM_VARIANTS:=client,server
+    JVM_VARIANT_CLIENT:=true
+    JVM_VARIANT_SERVER:=true
+  else
+    JVM_VARIANTS:=server
+    JVM_VARIANT_SERVER:=true
+  endif
+endif
+
 # determine if HotSpot is being built in JDK6 or earlier version
 JDK6_OR_EARLIER=0
 ifeq "$(shell expr \( '$(JDK_MAJOR_VERSION)' != '' \& '$(JDK_MINOR_VERSION)' != '' \& '$(JDK_MICRO_VERSION)' != '' \))" "1"
@@ -148,40 +160,42 @@
   EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.debuginfo
 endif
 
+EXPORT_LIST += $(EXPORT_JRE_LIB_DIR)/wb.jar
+
 EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server
 EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client
 
-ifneq ($(BUILD_CLIENT_ONLY),true)
-EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
-EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.$(LIBRARY_SUFFIX)
-EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_db.$(LIBRARY_SUFFIX)
-EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_dtrace.$(LIBRARY_SUFFIX)
+ifeq ($(JVM_VARIANT_SERVER),true)
+  EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
+  EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.$(LIBRARY_SUFFIX)
+  EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_db.$(LIBRARY_SUFFIX)
+  EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_dtrace.$(LIBRARY_SUFFIX)
+  ifeq ($(ARCH_DATA_MODEL),32)
+    EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_db.$(LIBRARY_SUFFIX)
+    EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_dtrace.$(LIBRARY_SUFFIX)
+  endif
   ifneq ($(OBJCOPY),)
     EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.debuginfo
     EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_db.debuginfo
     EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_dtrace.debuginfo
   endif
 endif
-ifeq ($(ARCH_DATA_MODEL), 32)
+ifeq ($(JVM_VARIANT_CLIENT),true)
   EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt
   EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.$(LIBRARY_SUFFIX) 
   EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_db.$(LIBRARY_SUFFIX) 
   EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_dtrace.$(LIBRARY_SUFFIX)
-  EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_db.$(LIBRARY_SUFFIX)
-  EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_dtrace.$(LIBRARY_SUFFIX)
+  ifeq ($(ARCH_DATA_MODEL),32)
+    EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_db.$(LIBRARY_SUFFIX)
+    EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_dtrace.$(LIBRARY_SUFFIX)
+  endif
   ifneq ($(OBJCOPY),)
     EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.debuginfo
     EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_db.debuginfo
     EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_dtrace.debuginfo
-    EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_db.debuginfo
-    EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_dtrace.debuginfo
-  endif
-  ifneq ($(BUILD_CLIENT_ONLY), true)
-    EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_db.$(LIBRARY_SUFFIX)
-    EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_dtrace.$(LIBRARY_SUFFIX)
-    ifneq ($(OBJCOPY),)
-      EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_db.debuginfo
-      EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_dtrace.debuginfo
+    ifeq ($(ARCH_DATA_MODEL),32)
+      EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_db.debuginfo
+      EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_dtrace.debuginfo
     endif
   endif
 endif
--- a/hotspot/make/solaris/makefiles/vm.make	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/make/solaris/makefiles/vm.make	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -321,9 +321,12 @@
 # Serviceability agent
 include $(MAKEFILES_DIR)/saproc.make
 
+# Whitebox testing API
+include $(MAKEFILES_DIR)/wb.make
+
 #----------------------------------------------------------------------
 
-build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(LIBJVM_DTRACE) $(BUILDLIBSAPROC) dtraceCheck
+build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(LIBJVM_DTRACE) $(BUILDLIBSAPROC) dtraceCheck $(WB_JAR)
 
 install: install_jvm install_jsig install_saproc
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/make/solaris/makefiles/wb.make	Fri Mar 30 16:57:50 2012 -0700
@@ -0,0 +1,46 @@
+#
+# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# Rules to build whitebox testing library, used by vm.make
+
+WB = wb
+
+WBSRCDIR = $(GAMMADIR)/src/share/tools/whitebox
+
+WB_JAR = $(GENERATED)/$(WB).jar
+
+WB_JAVA_SRCS = $(shell find $(WBSRCDIR) -name '*.java')
+WB_JAVA_CLASSDIR = $(GENERATED)/wb/classes
+
+WB_JAVA_CLASSES  = $(patsubst $(WBSRCDIR)/%,$(WB_JAVA_CLASSDIR)/%, \
+	$(patsubst %.java,%.class,$(WB_JAVA_SRCS)))
+
+$(WB_JAVA_CLASSDIR)/%.class: $(WBSRCDIR)/%.java $(WB_JAVA_CLASSDIR)
+	$(REMOTE) $(COMPILE.JAVAC) -nowarn -d $(WB_JAVA_CLASSDIR) $<
+
+$(WB_JAR): $(WB_JAVA_CLASSES)
+	$(QUIETLY) $(REMOTE) $(RUN.JAR) cf $@ -C $(WB_JAVA_CLASSDIR)/ .
+
+$(WB_JAVA_CLASSDIR):
+	$(QUIETLY) mkdir -p $@
+
--- a/hotspot/make/windows/makefiles/debug.make	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/make/windows/makefiles/debug.make	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,7 @@
 BUILD_PCH_FILE=_build_pch_file.obj
 !endif
 
-default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA
+default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA wb
 
 !include ../local.make
 !include compile.make
@@ -65,3 +65,4 @@
 !include $(WorkSpace)/make/windows/makefiles/shared.make
 !include $(WorkSpace)/make/windows/makefiles/sa.make
 !include $(WorkSpace)/make/windows/makefiles/launcher.make
+!include $(WorkSpace)/make/windows/makefiles/wb.make
--- a/hotspot/make/windows/makefiles/defs.make	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/make/windows/makefiles/defs.make	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -107,6 +107,19 @@
   endif
 endif
 
+# On 32 bit windows we build server, client and kernel, on 64 bit just server.
+ifeq ($(JVM_VARIANTS),)
+  ifeq ($(ARCH_DATA_MODEL), 32)
+    JVM_VARIANTS:=client,server,kernel
+    JVM_VARIANT_CLIENT:=true
+    JVM_VARIANT_SERVER:=true
+    JVM_VARIANT_KERNEL:=true
+  else
+    JVM_VARIANTS:=server
+    JVM_VARIANT_SERVER:=true
+  endif
+endif
+
 JDK_INCLUDE_SUBDIR=win32
 
 # Library suffix
@@ -177,23 +190,28 @@
 EXPORT_CLIENT_DIR = $(EXPORT_JRE_BIN_DIR)/client
 EXPORT_KERNEL_DIR = $(EXPORT_JRE_BIN_DIR)/kernel
 
-EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
-EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.$(LIBRARY_SUFFIX)
-EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.pdb
-EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.map
-EXPORT_LIST += $(EXPORT_LIB_DIR)/jvm.lib
-ifeq ($(ARCH_DATA_MODEL), 32)
+ifeq ($(JVM_VARIANT_SERVER),true)
+  EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
+  EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.$(LIBRARY_SUFFIX)
+  EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.pdb
+  EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.map
+  EXPORT_LIST += $(EXPORT_LIB_DIR)/jvm.lib
+endif
+ifeq ($(JVM_VARIANT_CLIENT),true)
   EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt
   EXPORT_LIST += $(EXPORT_CLIENT_DIR)/jvm.$(LIBRARY_SUFFIX)
   EXPORT_LIST += $(EXPORT_CLIENT_DIR)/jvm.pdb
   EXPORT_LIST += $(EXPORT_CLIENT_DIR)/jvm.map
-  # kernel vm
+endif
+ifeq ($(JVM_VARIANT_KERNEL),true)
   EXPORT_LIST += $(EXPORT_KERNEL_DIR)/Xusage.txt
   EXPORT_LIST += $(EXPORT_KERNEL_DIR)/jvm.$(LIBRARY_SUFFIX)
   EXPORT_LIST += $(EXPORT_KERNEL_DIR)/jvm.pdb
   EXPORT_LIST += $(EXPORT_KERNEL_DIR)/jvm.map
 endif
 
+EXPORT_LIST += $(EXPORT_JRE_LIB_DIR)/wb.jar
+
 ifeq ($(BUILD_WIN_SA), 1)
   EXPORT_LIST += $(EXPORT_JRE_BIN_DIR)/sawindbg.$(LIBRARY_SUFFIX)
   EXPORT_LIST += $(EXPORT_JRE_BIN_DIR)/sawindbg.pdb
--- a/hotspot/make/windows/makefiles/fastdebug.make	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/make/windows/makefiles/fastdebug.make	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,7 @@
 BUILD_PCH_FILE=_build_pch_file.obj
 !endif
 
-default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA
+default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA wb
 
 !include ../local.make
 !include compile.make
@@ -65,3 +65,4 @@
 !include $(WorkSpace)/make/windows/makefiles/shared.make
 !include $(WorkSpace)/make/windows/makefiles/sa.make
 !include $(WorkSpace)/make/windows/makefiles/launcher.make
+!include $(WorkSpace)/make/windows/makefiles/wb.make
--- a/hotspot/make/windows/makefiles/product.make	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/make/windows/makefiles/product.make	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -32,7 +32,7 @@
 BUILD_PCH_FILE=_build_pch_file.obj
 !endif
 
-default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA
+default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA wb
 
 !include ../local.make
 !include compile.make
@@ -76,3 +76,4 @@
 !include $(WorkSpace)/make/windows/makefiles/shared.make
 !include $(WorkSpace)/make/windows/makefiles/sa.make
 !include $(WorkSpace)/make/windows/makefiles/launcher.make
+!include $(WorkSpace)/make/windows/makefiles/wb.make
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/make/windows/makefiles/wb.make	Fri Mar 30 16:57:50 2012 -0700
@@ -0,0 +1,54 @@
+#
+# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#  
+#
+
+# This makefile is used to build the whitebox testing lib
+# and compile the tests which use it
+
+!include $(WorkSpace)/make/windows/makefiles/rules.make
+
+WBSRCDIR = $(WorkSpace)/src/share/tools/whitebox
+
+# turn GENERATED into a windows path to get sane dependencies
+WB_CLASSES=$(GENERATED:/=\)\wb\classes
+WB_JAR=$(GENERATED:/=\)\wb.jar
+
+# call recursive make to do wildcard expansion
+.SUFFIXES : .java .class
+wb_java_srcs: $(WorkSpace)\src\share\tools\whitebox\sun\hotspot\*.java $(WB_CLASSES)
+	$(MAKE) -f $(WorkSpace)\make\windows\makefiles\$(BUILD_FLAVOR).make $(**:.java=.class)
+
+
+{$(WorkSpace)\src\share\tools\whitebox\sun\hotspot}.java.class::
+	$(COMPILE_JAVAC) -d $(WB_CLASSES) $<
+
+$(WB_JAR): wb_java_srcs
+	$(RUN_JAR) cf $@ -C $(WB_CLASSES) .
+
+# turn $@ to a unix path because mkdir in PATH is cygwin/mks mkdir
+$(WB_CLASSES):
+	mkdir -p $(@:\=/)
+
+# main target to build wb
+wb: $(WB_JAR)
+
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp	Fri Mar 30 16:57:50 2012 -0700
@@ -2221,7 +2221,7 @@
   // traps as per trap.h (SPARC ABI?)
 
   void breakpoint_trap();
-  void breakpoint_trap(Condition c, CC cc = icc);
+  void breakpoint_trap(Condition c, CC cc);
   void flush_windows_trap();
   void clean_windows_trap();
   void get_psr_trap();
--- a/hotspot/src/cpu/sparc/vm/cppInterpreter_sparc.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/cpu/sparc/vm/cppInterpreter_sparc.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -1187,7 +1187,7 @@
 
   #ifdef ASSERT
     __ tst(O1);
-    __ breakpoint_trap(Assembler::zero);
+    __ breakpoint_trap(Assembler::zero, Assembler::ptr_cc);
   #endif // ASSERT
 
     const int entry_size            = frame::interpreter_frame_monitor_size() * wordSize;
--- a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -3325,7 +3325,7 @@
   // make sure that the frames are aligned properly
 #ifndef _LP64
   __ btst(wordSize*2-1, SP);
-  __ breakpoint_trap(Assembler::notZero);
+  __ breakpoint_trap(Assembler::notZero, Assembler::ptr_cc);
 #endif
   #endif
 
@@ -3407,7 +3407,7 @@
 #ifdef ASSERT
   // make sure that there is at least one entry in the array
   __ tst(O4array_size);
-  __ breakpoint_trap(Assembler::zero);
+  __ breakpoint_trap(Assembler::zero, Assembler::icc);
 #endif
 
   // Now push the new interpreter frames
--- a/hotspot/src/cpu/sparc/vm/sparc.ad	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad	Fri Mar 30 16:57:50 2012 -0700
@@ -1832,6 +1832,8 @@
   case Op_CountLeadingZerosL:
   case Op_CountTrailingZerosI:
   case Op_CountTrailingZerosL:
+  case Op_PopCountI:
+  case Op_PopCountL:
     if (!UsePopCountInstruction)
       return false;
     break;
--- a/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -379,7 +379,7 @@
 
 #ifdef ASSERT
     __ tst(O0);
-    __ breakpoint_trap(Assembler::zero);
+    __ breakpoint_trap(Assembler::zero, Assembler::ptr_cc);
 #endif // ASSERT
 
     __ bind(done);
@@ -2050,7 +2050,7 @@
   AddressLiteral stop_at(&StopInterpreterAt);
   __ load_ptr_contents(stop_at, G4_scratch);
   __ cmp(G3_scratch, G4_scratch);
-  __ breakpoint_trap(Assembler::equal);
+  __ breakpoint_trap(Assembler::equal, Assembler::icc);
 }
 #endif // not PRODUCT
 #endif // !CC_INTERP
--- a/hotspot/src/cpu/x86/vm/x86_32.ad	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/cpu/x86/vm/x86_32.ad	Fri Mar 30 16:57:50 2012 -0700
@@ -1293,6 +1293,14 @@
   if (!has_match_rule(opcode))
     return false;
 
+  switch (opcode) {
+    case Op_PopCountI:
+    case Op_PopCountL:
+      if (!UsePopCountInstruction)
+        return false;
+    break;
+  }
+  
   return true;  // Per default match rules are supported.
 }
 
--- a/hotspot/src/cpu/x86/vm/x86_64.ad	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/cpu/x86/vm/x86_64.ad	Fri Mar 30 16:57:50 2012 -0700
@@ -1714,6 +1714,14 @@
   if (!has_match_rule(opcode))
     return false;
 
+  switch (opcode) {
+    case Op_PopCountI:
+    case Op_PopCountL:
+      if (!UsePopCountInstruction)
+        return false;
+    break;
+  }
+
   return true;  // Per default match rules are supported.
 }
 
--- a/hotspot/src/os/bsd/vm/attachListener_bsd.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/os/bsd/vm/attachListener_bsd.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -206,10 +206,15 @@
   // put in listen mode, set permissions, and rename into place
   res = ::listen(listener, 5);
   if (res == 0) {
-      RESTARTABLE(::chmod(initial_path, S_IREAD|S_IWRITE), res);
+    RESTARTABLE(::chmod(initial_path, S_IREAD|S_IWRITE), res);
+    if (res == 0) {
+      // make sure the file is owned by the effective user and effective group
+      // (this is the default on linux, but not on mac os)
+      RESTARTABLE(::chown(initial_path, geteuid(), getegid()), res);
       if (res == 0) {
-          res = ::rename(initial_path, path);
+        res = ::rename(initial_path, path);
       }
+    }
   }
   if (res == -1) {
     RESTARTABLE(::close(listener), res);
--- a/hotspot/src/os/linux/vm/os_linux.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/os/linux/vm/os_linux.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -2547,7 +2547,14 @@
 }
 
 void os::free_memory(char *addr, size_t bytes, size_t alignment_hint) {
-  commit_memory(addr, bytes, alignment_hint, false);
+  // This method works by doing an mmap over an existing mmaping and effectively discarding
+  // the existing pages. However it won't work for SHM-based large pages that cannot be
+  // uncommitted at all. We don't do anything in this case to avoid creating a segment with
+  // small pages on top of the SHM segment. This method always works for small pages, so we
+  // allow that in any case.
+  if (alignment_hint <= (size_t)os::vm_page_size() || !UseSHM) {
+    commit_memory(addr, bytes, alignment_hint, false);
+  }
 }
 
 void os::numa_make_global(char *addr, size_t bytes) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/whitebox/sun/hotspot/WhiteBox.java	Fri Mar 30 16:57:50 2012 -0700
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.hotspot;
+import java.security.BasicPermission;
+
+public class WhiteBox {
+
+  @SuppressWarnings("serial")
+  public static class WhiteBoxPermission extends BasicPermission {
+    public WhiteBoxPermission(String s) {
+      super(s);
+    }
+  }
+
+  private WhiteBox() {}
+  private static final WhiteBox instance = new WhiteBox();
+  private static native void registerNatives();
+
+  /**
+   * Returns the singleton WhiteBox instance.
+   *
+   * The returned WhiteBox object should be carefully guarded
+   * by the caller, since it can be used to read and write data
+   * at arbitrary memory addresses. It must never be passed to
+   * untrusted code.
+   */
+  public synchronized static WhiteBox getWhiteBox() {
+    SecurityManager sm = System.getSecurityManager();
+    if (sm != null) {
+      sm.checkPermission(new WhiteBoxPermission("getInstance"));
+    }
+    return instance;
+  }
+
+  static {
+    registerNatives();
+  }
+
+  // Memory
+  public native long getObjectAddress(Object o);
+  public native int  getHeapOopSize();
+
+  // G1
+  public native boolean g1InConcurrentMark();
+  public native boolean g1IsHumongous(Object o);
+  public native long    g1NumFreeRegions();
+  public native int     g1RegionSize();
+}
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -1306,6 +1306,7 @@
       if (sw.dest_offset_at(i) < 0) has_bb = true;
     }
     // add default successor
+    if (sw.default_offset() < 0) has_bb = true;
     sux->at_put(i, block_at(bci() + sw.default_offset()));
     ValueStack* state_before = has_bb ? copy_state_before() : NULL;
     Instruction* res = append(new TableSwitch(ipop(), sux, sw.low_key(), state_before, has_bb));
@@ -1350,6 +1351,7 @@
       keys->at_put(i, pair.match());
     }
     // add default successor
+    if (sw.default_offset() < 0) has_bb = true;
     sux->at_put(i, block_at(bci() + sw.default_offset()));
     ValueStack* state_before = has_bb ? copy_state_before() : NULL;
     Instruction* res = append(new LookupSwitch(ipop(), sux, keys, state_before, has_bb));
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -2315,13 +2315,32 @@
 #define RECOGNIZED_INNER_CLASS_MODIFIERS (JVM_RECOGNIZED_CLASS_MODIFIERS | JVM_ACC_PRIVATE | JVM_ACC_PROTECTED | JVM_ACC_STATIC)
 
 // Return number of classes in the inner classes attribute table
-u2 ClassFileParser::parse_classfile_inner_classes_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS) {
+u2 ClassFileParser::parse_classfile_inner_classes_attribute(u1* inner_classes_attribute_start,
+                                                            bool parsed_enclosingmethod_attribute,
+                                                            u2 enclosing_method_class_index,
+                                                            u2 enclosing_method_method_index,
+                                                            constantPoolHandle cp,
+                                                            instanceKlassHandle k, TRAPS) {
   ClassFileStream* cfs = stream();
-  cfs->guarantee_more(2, CHECK_0);  // length
-  u2 length = cfs->get_u2_fast();
-
-  // 4-tuples of shorts [inner_class_info_index, outer_class_info_index, inner_name_index, inner_class_access_flags]
-  typeArrayOop ic = oopFactory::new_permanent_shortArray(length*4, CHECK_0);
+  u1* current_mark = cfs->current();
+  u2 length = 0;
+  if (inner_classes_attribute_start != NULL) {
+    cfs->set_current(inner_classes_attribute_start);
+    cfs->guarantee_more(2, CHECK_0);  // length
+    length = cfs->get_u2_fast();
+  }
+
+  // 4-tuples of shorts of inner classes data and 2 shorts of enclosing
+  // method data:
+  //   [inner_class_info_index,
+  //    outer_class_info_index,
+  //    inner_name_index,
+  //    inner_class_access_flags,
+  //    ...
+  //    enclosing_method_class_index,
+  //    enclosing_method_method_index]
+  int size = length * 4 + (parsed_enclosingmethod_attribute ? 2 : 0);
+  typeArrayOop ic = oopFactory::new_permanent_shortArray(size, CHECK_0);
   typeArrayHandle inner_classes(THREAD, ic);
   int index = 0;
   int cp_size = cp->length();
@@ -2372,8 +2391,8 @@
 
   // 4347400: make sure there's no duplicate entry in the classes array
   if (_need_verify && _major_version >= JAVA_1_5_VERSION) {
-    for(int i = 0; i < inner_classes->length(); i += 4) {
-      for(int j = i + 4; j < inner_classes->length(); j += 4) {
+    for(int i = 0; i < length * 4; i += 4) {
+      for(int j = i + 4; j < length * 4; j += 4) {
         guarantee_property((inner_classes->ushort_at(i)   != inner_classes->ushort_at(j) ||
                             inner_classes->ushort_at(i+1) != inner_classes->ushort_at(j+1) ||
                             inner_classes->ushort_at(i+2) != inner_classes->ushort_at(j+2) ||
@@ -2384,8 +2403,19 @@
     }
   }
 
+  // Set EnclosingMethod class and method indexes.
+  if (parsed_enclosingmethod_attribute) {
+    inner_classes->short_at_put(index++, enclosing_method_class_index);
+    inner_classes->short_at_put(index++, enclosing_method_method_index);
+  }
+  assert(index == size, "wrong size");
+
   // Update instanceKlass with inner class info.
   k->set_inner_classes(inner_classes());
+
+  // Restore buffer's current position.
+  cfs->set_current(current_mark);
+
   return length;
 }
 
@@ -2490,6 +2520,10 @@
   int runtime_visible_annotations_length = 0;
   u1* runtime_invisible_annotations = NULL;
   int runtime_invisible_annotations_length = 0;
+  u1* inner_classes_attribute_start = NULL;
+  u4  inner_classes_attribute_length = 0;
+  u2  enclosing_method_class_index = 0;
+  u2  enclosing_method_method_index = 0;
   // Iterate over attributes
   while (attributes_count--) {
     cfs->guarantee_more(6, CHECK);  // attribute_name_index, attribute_length
@@ -2522,11 +2556,9 @@
       } else {
         parsed_innerclasses_attribute = true;
       }
-      u2 num_of_classes = parse_classfile_inner_classes_attribute(cp, k, CHECK);
-      if (_need_verify && _major_version >= JAVA_1_5_VERSION) {
-        guarantee_property(attribute_length == sizeof(num_of_classes) + 4 * sizeof(u2) * num_of_classes,
-                          "Wrong InnerClasses attribute length in class file %s", CHECK);
-      }
+      inner_classes_attribute_start = cfs->get_u1_buffer();
+      inner_classes_attribute_length = attribute_length;
+      cfs->skip_u1(inner_classes_attribute_length, CHECK);
     } else if (tag == vmSymbols::tag_synthetic()) {
       // Check for Synthetic tag
       // Shouldn't we check that the synthetic flags wasn't already set? - not required in spec
@@ -2568,22 +2600,21 @@
           parsed_enclosingmethod_attribute = true;
         }
         cfs->guarantee_more(4, CHECK);  // class_index, method_index
-        u2 class_index  = cfs->get_u2_fast();
-        u2 method_index = cfs->get_u2_fast();
-        if (class_index == 0) {
+        enclosing_method_class_index  = cfs->get_u2_fast();
+        enclosing_method_method_index = cfs->get_u2_fast();
+        if (enclosing_method_class_index == 0) {
           classfile_parse_error("Invalid class index in EnclosingMethod attribute in class file %s", CHECK);
         }
         // Validate the constant pool indices and types
-        if (!cp->is_within_bounds(class_index) ||
-            !is_klass_reference(cp, class_index)) {
+        if (!cp->is_within_bounds(enclosing_method_class_index) ||
+            !is_klass_reference(cp, enclosing_method_class_index)) {
           classfile_parse_error("Invalid or out-of-bounds class index in EnclosingMethod attribute in class file %s", CHECK);
         }
-        if (method_index != 0 &&
-            (!cp->is_within_bounds(method_index) ||
-             !cp->tag_at(method_index).is_name_and_type())) {
+        if (enclosing_method_method_index != 0 &&
+            (!cp->is_within_bounds(enclosing_method_method_index) ||
+             !cp->tag_at(enclosing_method_method_index).is_name_and_type())) {
           classfile_parse_error("Invalid or out-of-bounds method index in EnclosingMethod attribute in class file %s", CHECK);
         }
-        k->set_enclosing_method_indices(class_index, method_index);
       } else if (tag == vmSymbols::tag_bootstrap_methods() &&
                  _major_version >= Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
         if (parsed_bootstrap_methods_attribute)
@@ -2606,6 +2637,20 @@
                                                      CHECK);
   k->set_class_annotations(annotations());
 
+  if (parsed_innerclasses_attribute || parsed_enclosingmethod_attribute) {
+    u2 num_of_classes = parse_classfile_inner_classes_attribute(
+                            inner_classes_attribute_start,
+                            parsed_innerclasses_attribute,
+                            enclosing_method_class_index,
+                            enclosing_method_method_index,
+                            cp, k, CHECK);
+    if (parsed_innerclasses_attribute &&_need_verify && _major_version >= JAVA_1_5_VERSION) {
+      guarantee_property(
+        inner_classes_attribute_length == sizeof(num_of_classes) + 4 * sizeof(u2) * num_of_classes,
+        "Wrong InnerClasses attribute length in class file %s", CHECK);
+    }
+  }
+
   if (_max_bootstrap_specifier_index >= 0) {
     guarantee_property(parsed_bootstrap_methods_attribute,
                        "Missing BootstrapMethods attribute in class file %s", CHECK);
--- a/hotspot/src/share/vm/classfile/classFileParser.hpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.hpp	Fri Mar 30 16:57:50 2012 -0700
@@ -130,7 +130,11 @@
   void parse_classfile_sourcefile_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS);
   void parse_classfile_source_debug_extension_attribute(constantPoolHandle cp,
                                                 instanceKlassHandle k, int length, TRAPS);
-  u2   parse_classfile_inner_classes_attribute(constantPoolHandle cp,
+  u2   parse_classfile_inner_classes_attribute(u1* inner_classes_attribute_start,
+                                               bool parsed_enclosingmethod_attribute,
+                                               u2 enclosing_method_class_index,
+                                               u2 enclosing_method_method_index,
+                                               constantPoolHandle cp,
                                                instanceKlassHandle k, TRAPS);
   void parse_classfile_attributes(constantPoolHandle cp, instanceKlassHandle k, TRAPS);
   void parse_classfile_synthetic_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS);
--- a/hotspot/src/share/vm/gc_implementation/g1/collectionSetChooser.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/collectionSetChooser.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -285,7 +285,7 @@
   // that the result is the same during all mixed GCs that follow a cycle.
 
   const size_t region_num = (size_t) _length;
-  const size_t gc_num = (size_t) G1MaxMixedGCNum;
+  const size_t gc_num = (size_t) G1MixedGCCountTarget;
   size_t result = region_num / gc_num;
   // emulate ceiling
   if (result * gc_num < region_num) {
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -155,7 +155,7 @@
 
           CMCheckpointRootsFinalClosure final_cl(_cm);
           sprintf(verbose_str, "GC remark");
-          VM_CGC_Operation op(&final_cl, verbose_str);
+          VM_CGC_Operation op(&final_cl, verbose_str, true /* needs_pll */);
           VMThread::execute(&op);
         }
         if (cm()->restart_for_overflow() &&
@@ -189,7 +189,7 @@
 
         CMCleanUp cl_cl(_cm);
         sprintf(verbose_str, "GC cleanup");
-        VM_CGC_Operation op(&cl_cl, verbose_str);
+        VM_CGC_Operation op(&cl_cl, verbose_str, false /* needs_pll */);
         VMThread::execute(&op);
       } else {
         // We don't want to update the marking status if a GC pause
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -993,7 +993,7 @@
     // iteration (after taking the Heap_lock).
     result = _mutator_alloc_region.attempt_allocation(word_size,
                                                       false /* bot_updates */);
-    if (result != NULL ){
+    if (result != NULL) {
       return result;
     }
 
@@ -2437,20 +2437,22 @@
                                  true,  /* should_initiate_conc_mark */
                                  g1_policy()->max_pause_time_ms(),
                                  cause);
+
       VMThread::execute(&op);
       if (!op.pause_succeeded()) {
-        // Another GC got scheduled and prevented us from scheduling
-        // the initial-mark GC. It's unlikely that the GC that
-        // pre-empted us was also an initial-mark GC. So, we'll retry
-        // the initial-mark GC.
-
         if (full_gc_count_before == total_full_collections()) {
-          retry_gc = true;
+          retry_gc = op.should_retry_gc();
         } else {
           // A Full GC happened while we were trying to schedule the
           // initial-mark GC. No point in starting a new cycle given
           // that the whole heap was collected anyway.
         }
+
+        if (retry_gc) {
+          if (GC_locker::is_active_and_needs_gc()) {
+            GC_locker::stall_until_clear();
+          }
+        }
       }
     } else {
       if (cause == GCCause::_gc_locker
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -2608,7 +2608,7 @@
   size_t reclaimable_bytes = cset_chooser->remainingReclaimableBytes();
   size_t capacity_bytes = _g1->capacity();
   double perc = (double) reclaimable_bytes * 100.0 / (double) capacity_bytes;
-  double threshold = (double) G1OldReclaimableThresholdPercent;
+  double threshold = (double) G1HeapWastePercent;
   if (perc < threshold) {
     ergo_verbose4(ErgoMixedGCs,
               false_action_str,
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp	Fri Mar 30 16:57:50 2012 -0700
@@ -940,10 +940,9 @@
     return _bytes_copied_during_gc;
   }
 
-  // Determine whether the next GC should be mixed. Called to determine
-  // whether to start mixed GCs or whether to carry on doing mixed
-  // GCs. The two action strings are used in the ergo output when the
-  // method returns true or false.
+  // Determine whether there are candidate regions so that the
+  // next GC should be mixed. The two action strings are used
+  // in the ergo output when the method returns true or false.
   bool next_gc_should_be_mixed(const char* true_action_str,
                                const char* false_action_str);
 
--- a/hotspot/src/share/vm/gc_implementation/g1/g1MonitoringSupport.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1MonitoringSupport.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -44,7 +44,9 @@
                G1MonitoringSupport::pad_capacity(0, 3) /* min_capacity */,
                G1MonitoringSupport::pad_capacity(g1mm->young_gen_max(), 3),
                G1MonitoringSupport::pad_capacity(0, 3) /* curr_capacity */) {
-  update_all();
+  if (UsePerfData) {
+    update_all();
+  }
 }
 
 G1OldGenerationCounters::G1OldGenerationCounters(G1MonitoringSupport* g1mm,
@@ -53,7 +55,9 @@
                G1MonitoringSupport::pad_capacity(0) /* min_capacity */,
                G1MonitoringSupport::pad_capacity(g1mm->old_gen_max()),
                G1MonitoringSupport::pad_capacity(0) /* curr_capacity */) {
-  update_all();
+  if (UsePerfData) {
+    update_all();
+  }
 }
 
 void G1YoungGenerationCounters::update_all() {
@@ -149,10 +153,6 @@
     pad_capacity(0) /* max_capacity */,
     pad_capacity(0) /* init_capacity */,
     _young_collection_counters);
-  // Given that this survivor space is not used, we update it here
-  // once to reflect that its used space is 0 so that we don't have to
-  // worry about updating it again later.
-  _from_counters->update_used(0);
 
   //  name "generation.0.space.2"
   // See _old_space_counters for additional counters
@@ -160,6 +160,13 @@
     pad_capacity(overall_reserved()) /* max_capacity */,
     pad_capacity(survivor_space_committed()) /* init_capacity */,
     _young_collection_counters);
+
+  if (UsePerfData) {
+    // Given that this survivor space is not used, we update it here
+    // once to reflect that its used space is 0 so that we don't have to
+    // worry about updating it again later.
+    _from_counters->update_used(0);
+  }
 }
 
 void G1MonitoringSupport::recalculate_sizes() {
--- a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp	Fri Mar 30 16:57:50 2012 -0700
@@ -299,17 +299,16 @@
           "Percentage (0-100) of the heap size to use as maximum "          \
           "young gen size.")                                                \
                                                                             \
-  develop(uintx, G1OldCSetRegionLiveThresholdPercent, 95,                   \
+  develop(uintx, G1OldCSetRegionLiveThresholdPercent, 90,                   \
           "Threshold for regions to be added to the collection set. "       \
           "Regions with more live bytes that this will not be collected.")  \
                                                                             \
-  develop(uintx, G1OldReclaimableThresholdPercent, 1,                       \
-          "Threshold for the remaining old reclaimable bytes, expressed "   \
-          "as a percentage of the heap size. If the old reclaimable bytes " \
-          "are under this we will not collect them with more mixed GCs.")   \
+  product(uintx, G1HeapWastePercent, 5,                                     \
+          "Amount of space, expressed as a percentage of the heap size, "   \
+          "that G1 is willing not to collect to avoid expensive GCs.")      \
                                                                             \
-  develop(uintx, G1MaxMixedGCNum, 4,                                        \
-          "The maximum desired number of mixed GCs after a marking cycle.") \
+  product(uintx, G1MixedGCCountTarget, 4,                                   \
+          "The target number of mixed GCs after a marking cycle.")          \
                                                                             \
   develop(uintx, G1OldCSetRegionThresholdPercent, 10,                       \
           "An upper bound for the number of old CSet regions expressed "    \
--- a/hotspot/src/share/vm/gc_implementation/g1/survRateGroup.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/survRateGroup.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -38,33 +38,36 @@
     _summary_surv_rates(NULL),
     _surv_rate(NULL),
     _accum_surv_rate_pred(NULL),
-    _surv_rate_pred(NULL)
-{
+    _surv_rate_pred(NULL),
+    _stats_arrays_length(0) {
   reset();
   if (summary_surv_rates_len > 0) {
     size_t length = summary_surv_rates_len;
-      _summary_surv_rates = NEW_C_HEAP_ARRAY(NumberSeq*, length);
-    if (_summary_surv_rates == NULL) {
-      vm_exit_out_of_memory(sizeof(NumberSeq*) * length,
-                            "Not enough space for surv rate summary");
+    _summary_surv_rates = NEW_C_HEAP_ARRAY(NumberSeq*, length);
+    for (size_t i = 0; i < length; ++i) {
+      _summary_surv_rates[i] = new NumberSeq();
     }
-    for (size_t i = 0; i < length; ++i)
-      _summary_surv_rates[i] = new NumberSeq();
   }
 
   start_adding_regions();
 }
 
-
-void SurvRateGroup::reset()
-{
+void SurvRateGroup::reset() {
   _all_regions_allocated = 0;
   _setup_seq_num         = 0;
-  _stats_arrays_length   = 0;
   _accum_surv_rate       = 0.0;
   _last_pred             = 0.0;
   // the following will set up the arrays with length 1
   _region_num            = 1;
+
+  // The call to stop_adding_regions() will use "new" to refill
+  // the _surv_rate_pred array, so we need to make sure to call
+  // "delete".
+  for (size_t i = 0; i < _stats_arrays_length; ++i) {
+    delete _surv_rate_pred[i];
+  }
+  _stats_arrays_length = 0;
+
   stop_adding_regions();
   guarantee( _stats_arrays_length == 1, "invariant" );
   guarantee( _surv_rate_pred[0] != NULL, "invariant" );
@@ -73,72 +76,47 @@
   _region_num = 0;
 }
 
-
 void
 SurvRateGroup::start_adding_regions() {
   _setup_seq_num   = _stats_arrays_length;
   _region_num      = 0;
   _accum_surv_rate = 0.0;
-
-#if 0
-  gclog_or_tty->print_cr("[%s] start adding regions, seq num %d, length %d",
-                         _name, _setup_seq_num, _region_num);
-#endif // 0
 }
 
 void
 SurvRateGroup::stop_adding_regions() {
-
-#if 0
-  gclog_or_tty->print_cr("[%s] stop adding regions, length %d", _name, _region_num);
-#endif // 0
-
   if (_region_num > _stats_arrays_length) {
     double* old_surv_rate = _surv_rate;
     double* old_accum_surv_rate_pred = _accum_surv_rate_pred;
     TruncatedSeq** old_surv_rate_pred = _surv_rate_pred;
 
     _surv_rate = NEW_C_HEAP_ARRAY(double, _region_num);
-    if (_surv_rate == NULL) {
-      vm_exit_out_of_memory(sizeof(double) * _region_num,
-                            "Not enough space for surv rate array.");
-    }
     _accum_surv_rate_pred = NEW_C_HEAP_ARRAY(double, _region_num);
-    if (_accum_surv_rate_pred == NULL) {
-      vm_exit_out_of_memory(sizeof(double) * _region_num,
-                         "Not enough space for accum surv rate pred array.");
-    }
     _surv_rate_pred = NEW_C_HEAP_ARRAY(TruncatedSeq*, _region_num);
-    if (_surv_rate == NULL) {
-      vm_exit_out_of_memory(sizeof(TruncatedSeq*) * _region_num,
-                            "Not enough space for surv rate pred array.");
-    }
 
-    for (size_t i = 0; i < _stats_arrays_length; ++i)
+    for (size_t i = 0; i < _stats_arrays_length; ++i) {
       _surv_rate_pred[i] = old_surv_rate_pred[i];
-
-#if 0
-    gclog_or_tty->print_cr("[%s] stop adding regions, new seqs %d to %d",
-                  _name, _array_length, _region_num - 1);
-#endif // 0
-
+    }
     for (size_t i = _stats_arrays_length; i < _region_num; ++i) {
       _surv_rate_pred[i] = new TruncatedSeq(10);
-      // _surv_rate_pred[i]->add(last_pred);
     }
 
     _stats_arrays_length = _region_num;
 
-    if (old_surv_rate != NULL)
+    if (old_surv_rate != NULL) {
       FREE_C_HEAP_ARRAY(double, old_surv_rate);
-    if (old_accum_surv_rate_pred != NULL)
+    }
+    if (old_accum_surv_rate_pred != NULL) {
       FREE_C_HEAP_ARRAY(double, old_accum_surv_rate_pred);
-    if (old_surv_rate_pred != NULL)
-      FREE_C_HEAP_ARRAY(NumberSeq*, old_surv_rate_pred);
+    }
+    if (old_surv_rate_pred != NULL) {
+      FREE_C_HEAP_ARRAY(TruncatedSeq*, old_surv_rate_pred);
+    }
   }
 
-  for (size_t i = 0; i < _stats_arrays_length; ++i)
+  for (size_t i = 0; i < _stats_arrays_length; ++i) {
     _surv_rate[i] = 0.0;
+  }
 }
 
 double
@@ -187,12 +165,6 @@
 SurvRateGroup::all_surviving_words_recorded(bool propagate) {
   if (propagate && _region_num > 0) { // conservative
     double surv_rate = _surv_rate_pred[_region_num-1]->last();
-
-#if 0
-    gclog_or_tty->print_cr("propagating %1.2lf from %d to %d",
-                  surv_rate, _curr_length, _array_length - 1);
-#endif // 0
-
     for (size_t i = _region_num; i < _stats_arrays_length; ++i) {
       guarantee( _surv_rate[i] <= 0.00001,
                  "the slot should not have been updated" );
--- a/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -34,7 +34,8 @@
 VM_G1CollectForAllocation::VM_G1CollectForAllocation(
                                                   unsigned int gc_count_before,
                                                   size_t word_size)
-  : VM_G1OperationWithAllocRequest(gc_count_before, word_size) {
+  : VM_G1OperationWithAllocRequest(gc_count_before, word_size,
+                                   GCCause::_allocation_failure) {
   guarantee(word_size > 0, "an allocation should always be requested");
 }
 
@@ -57,9 +58,10 @@
                                       bool           should_initiate_conc_mark,
                                       double         target_pause_time_ms,
                                       GCCause::Cause gc_cause)
-  : VM_G1OperationWithAllocRequest(gc_count_before, word_size),
+  : VM_G1OperationWithAllocRequest(gc_count_before, word_size, gc_cause),
     _should_initiate_conc_mark(should_initiate_conc_mark),
     _target_pause_time_ms(target_pause_time_ms),
+    _should_retry_gc(false),
     _full_collections_completed_before(0) {
   guarantee(target_pause_time_ms > 0.0,
             err_msg("target_pause_time_ms = %1.6lf should be positive",
@@ -70,6 +72,22 @@
   _gc_cause = gc_cause;
 }
 
+bool VM_G1IncCollectionPause::doit_prologue() {
+  bool res = VM_GC_Operation::doit_prologue();
+  if (!res) {
+    if (_should_initiate_conc_mark) {
+      // The prologue can fail for a couple of reasons. The first is that another GC
+      // got scheduled and prevented the scheduling of the initial mark GC. The
+      // second is that the GC locker may be active and the heap can't be expanded.
+      // In both cases we want to retry the GC so that the initial mark pause is
+      // actually scheduled. In the second case, however, we should stall until
+      // until the GC locker is no longer active and then retry the initial mark GC.
+      _should_retry_gc = true;
+    }
+  }
+  return res;
+}
+
 void VM_G1IncCollectionPause::doit() {
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
   assert(!_should_initiate_conc_mark ||
@@ -106,11 +124,25 @@
     // next GC pause to be an initial mark; it returns false if a
     // marking cycle is already in progress.
     //
-    // If a marking cycle is already in progress just return and skip
-    // the pause - the requesting thread should block in doit_epilogue
-    // until the marking cycle is complete.
+    // If a marking cycle is already in progress just return and skip the
+    // pause below - if the reason for requesting this initial mark pause
+    // was due to a System.gc() then the requesting thread should block in
+    // doit_epilogue() until the marking cycle is complete.
+    //
+    // If this initial mark pause was requested as part of a humongous
+    // allocation then we know that the marking cycle must just have
+    // been started by another thread (possibly also allocating a humongous
+    // object) as there was no active marking cycle when the requesting
+    // thread checked before calling collect() in
+    // attempt_allocation_humongous(). Retrying the GC, in this case,
+    // will cause the requesting thread to spin inside collect() until the
+    // just started marking cycle is complete - which may be a while. So
+    // we do NOT retry the GC.
     if (!res) {
-      assert(_word_size == 0, "ExplicitGCInvokesConcurrent shouldn't be allocating");
+      assert(_word_size == 0, "Concurrent Full GC/Humongous Object IM shouldn't be allocating");
+      if (_gc_cause != GCCause::_g1_humongous_allocation) {
+        _should_retry_gc = true;
+      }
       return;
     }
   }
@@ -123,6 +155,13 @@
                                       true /* expect_null_cur_alloc_region */);
   } else {
     assert(_result == NULL, "invariant");
+    if (!_pause_succeeded) {
+      // Another possible reason reason for the pause to not be successful
+      // is that, again, the GC locker is active (and has become active
+      // since the prologue was executed). In this case we should retry
+      // the pause after waiting for the GC locker to become inactive.
+      _should_retry_gc = true;
+    }
   }
 }
 
@@ -168,6 +207,7 @@
 }
 
 void VM_CGC_Operation::acquire_pending_list_lock() {
+  assert(_needs_pll, "don't call this otherwise");
   // The caller may block while communicating
   // with the SLT thread in order to acquire/release the PLL.
   ConcurrentMarkThread::slt()->
@@ -175,6 +215,7 @@
 }
 
 void VM_CGC_Operation::release_and_notify_pending_list_lock() {
+  assert(_needs_pll, "don't call this otherwise");
   // The caller may block while communicating
   // with the SLT thread in order to acquire/release the PLL.
   ConcurrentMarkThread::slt()->
@@ -198,7 +239,9 @@
 bool VM_CGC_Operation::doit_prologue() {
   // Note the relative order of the locks must match that in
   // VM_GC_Operation::doit_prologue() or deadlocks can occur
-  acquire_pending_list_lock();
+  if (_needs_pll) {
+    acquire_pending_list_lock();
+  }
 
   Heap_lock->lock();
   SharedHeap::heap()->_thread_holds_heap_lock_for_gc = true;
@@ -210,5 +253,7 @@
   // VM_GC_Operation::doit_epilogue()
   SharedHeap::heap()->_thread_holds_heap_lock_for_gc = false;
   Heap_lock->unlock();
-  release_and_notify_pending_list_lock();
+  if (_needs_pll) {
+    release_and_notify_pending_list_lock();
+  }
 }
--- a/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.hpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.hpp	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -43,8 +43,9 @@
 
 public:
   VM_G1OperationWithAllocRequest(unsigned int gc_count_before,
-                                 size_t       word_size)
-    : VM_GC_Operation(gc_count_before, GCCause::_allocation_failure),
+                                 size_t       word_size,
+                                 GCCause::Cause gc_cause)
+    : VM_GC_Operation(gc_count_before, gc_cause),
       _word_size(word_size), _result(NULL), _pause_succeeded(false) { }
   HeapWord* result() { return _result; }
   bool pause_succeeded() { return _pause_succeeded; }
@@ -77,6 +78,7 @@
 class VM_G1IncCollectionPause: public VM_G1OperationWithAllocRequest {
 private:
   bool         _should_initiate_conc_mark;
+  bool         _should_retry_gc;
   double       _target_pause_time_ms;
   unsigned int _full_collections_completed_before;
 public:
@@ -86,11 +88,13 @@
                           double         target_pause_time_ms,
                           GCCause::Cause gc_cause);
   virtual VMOp_Type type() const { return VMOp_G1IncCollectionPause; }
+  virtual bool doit_prologue();
   virtual void doit();
   virtual void doit_epilogue();
   virtual const char* name() const {
     return "garbage-first incremental collection pause";
   }
+  bool should_retry_gc() const { return _should_retry_gc; }
 };
 
 // Concurrent GC stop-the-world operations such as remark and cleanup;
@@ -98,6 +102,7 @@
 class VM_CGC_Operation: public VM_Operation {
   VoidClosure* _cl;
   const char* _printGCMessage;
+  bool _needs_pll;
 
 protected:
   // java.lang.ref.Reference support
@@ -105,8 +110,8 @@
   void release_and_notify_pending_list_lock();
 
 public:
-  VM_CGC_Operation(VoidClosure* cl, const char *printGCMsg)
-    : _cl(cl), _printGCMessage(printGCMsg) { }
+  VM_CGC_Operation(VoidClosure* cl, const char *printGCMsg, bool needs_pll)
+    : _cl(cl), _printGCMessage(printGCMsg), _needs_pll(needs_pll) { }
   virtual VMOp_Type type() const { return VMOp_CGC_Operation; }
   virtual void doit();
   virtual bool doit_prologue();
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp	Fri Mar 30 16:57:50 2012 -0700
@@ -25,6 +25,7 @@
 #ifndef SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSPROMOTIONMANAGER_INLINE_HPP
 #define SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSPROMOTIONMANAGER_INLINE_HPP
 
+#include "gc_implementation/parallelScavenge/psOldGen.hpp"
 #include "gc_implementation/parallelScavenge/psPromotionManager.hpp"
 #include "gc_implementation/parallelScavenge/psScavenge.hpp"
 
--- a/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -1,6 +1,6 @@
 
 /*
- * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -91,29 +91,37 @@
     MutableSpace *s = ls->space();
     if (s->top() < top()) { // For all spaces preceding the one containing top()
       if (s->free_in_words() > 0) {
-        size_t area_touched_words = pointer_delta(s->end(), s->top());
-        CollectedHeap::fill_with_object(s->top(), area_touched_words);
+        intptr_t cur_top = (intptr_t)s->top();
+        size_t words_left_to_fill = pointer_delta(s->end(), s->top());;
+        while (words_left_to_fill > 0) {
+          size_t words_to_fill = MIN2(words_left_to_fill, CollectedHeap::filler_array_max_size());
+          assert(words_to_fill >= CollectedHeap::min_fill_size(),
+            err_msg("Remaining size ("SIZE_FORMAT ") is too small to fill (based on " SIZE_FORMAT " and " SIZE_FORMAT ")",
+            words_to_fill, words_left_to_fill, CollectedHeap::filler_array_max_size()));
+          CollectedHeap::fill_with_object((HeapWord*)cur_top, words_to_fill);
+          if (!os::numa_has_static_binding()) {
+            size_t touched_words = words_to_fill;
 #ifndef ASSERT
-        if (!ZapUnusedHeapArea) {
-          area_touched_words = MIN2((size_t)align_object_size(typeArrayOopDesc::header_size(T_INT)),
-                                    area_touched_words);
-        }
+            if (!ZapUnusedHeapArea) {
+              touched_words = MIN2((size_t)align_object_size(typeArrayOopDesc::header_size(T_INT)),
+                touched_words);
+            }
 #endif
-        if (!os::numa_has_static_binding()) {
-          MemRegion invalid;
-          HeapWord *crossing_start = (HeapWord*)round_to((intptr_t)s->top(), os::vm_page_size());
-          HeapWord *crossing_end = (HeapWord*)round_to((intptr_t)(s->top() + area_touched_words),
-                                                       os::vm_page_size());
-          if (crossing_start != crossing_end) {
-            // If object header crossed a small page boundary we mark the area
-            // as invalid rounding it to a page_size().
-            HeapWord *start = MAX2((HeapWord*)round_down((intptr_t)s->top(), page_size()), s->bottom());
-            HeapWord *end = MIN2((HeapWord*)round_to((intptr_t)(s->top() + area_touched_words), page_size()),
-                                 s->end());
-            invalid = MemRegion(start, end);
+            MemRegion invalid;
+            HeapWord *crossing_start = (HeapWord*)round_to(cur_top, os::vm_page_size());
+            HeapWord *crossing_end = (HeapWord*)round_to(cur_top + touched_words, os::vm_page_size());
+            if (crossing_start != crossing_end) {
+              // If object header crossed a small page boundary we mark the area
+              // as invalid rounding it to a page_size().
+              HeapWord *start = MAX2((HeapWord*)round_down(cur_top, page_size()), s->bottom());
+              HeapWord *end = MIN2((HeapWord*)round_to(cur_top + touched_words, page_size()), s->end());
+              invalid = MemRegion(start, end);
+            }
+
+            ls->add_invalid_region(invalid);
           }
-
-          ls->add_invalid_region(invalid);
+          cur_top = cur_top + (words_to_fill * HeapWordSize);
+          words_left_to_fill -= words_to_fill;
         }
       }
     } else {
--- a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -85,7 +85,7 @@
   const size_t max_len = size_t(arrayOopDesc::max_array_length(T_INT));
   const size_t elements_per_word = HeapWordSize / sizeof(jint);
   _filler_array_max_size = align_object_size(filler_array_hdr_size() +
-                                             max_len * elements_per_word);
+                                             max_len / elements_per_word);
 
   _barrier_set = NULL;
   _is_gc_active = false;
@@ -303,10 +303,6 @@
   return align_object_size(filler_array_hdr_size()); // align to MinObjAlignment
 }
 
-size_t CollectedHeap::filler_array_max_size() {
-  return _filler_array_max_size;
-}
-
 #ifdef ASSERT
 void CollectedHeap::fill_args_check(HeapWord* start, size_t words)
 {
@@ -333,10 +329,11 @@
 
   const size_t payload_size = words - filler_array_hdr_size();
   const size_t len = payload_size * HeapWordSize / sizeof(jint);
+  assert((int)len >= 0, err_msg("size too large " SIZE_FORMAT " becomes %d", words, (int)len));
 
   // Set the length first for concurrent GC.
   ((arrayOop)start)->set_length((int)len);
-  post_allocation_setup_common(Universe::intArrayKlassObj(), start, words);
+  post_allocation_setup_common(Universe::intArrayKlassObj(), start);
   DEBUG_ONLY(zap_filler_array(start, words, zap);)
 }
 
@@ -349,8 +346,7 @@
     fill_with_array(start, words, zap);
   } else if (words > 0) {
     assert(words == min_fill_size(), "unaligned size");
-    post_allocation_setup_common(SystemDictionary::Object_klass(), start,
-                                 words);
+    post_allocation_setup_common(SystemDictionary::Object_klass(), start);
   }
 }
 
@@ -480,7 +476,7 @@
     assert(ScavengeRootsInCode > 0, "must be");
     obj = common_mem_allocate_init(size, CHECK_NULL);
   }
-  post_allocation_setup_common(klass, obj, size);
+  post_allocation_setup_common(klass, obj);
   assert(Universe::is_bootstrapping() ||
          !((oop)obj)->blueprint()->oop_is_array(), "must not be an array");
   NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size));
--- a/hotspot/src/share/vm/gc_interface/collectedHeap.hpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/gc_interface/collectedHeap.hpp	Fri Mar 30 16:57:50 2012 -0700
@@ -128,7 +128,6 @@
   // Reinitialize tlabs before resuming mutators.
   virtual void resize_all_tlabs();
 
- protected:
   // Allocate from the current thread's TLAB, with broken-out slow path.
   inline static HeapWord* allocate_from_tlab(Thread* thread, size_t size);
   static HeapWord* allocate_from_tlab_slow(Thread* thread, size_t size);
@@ -150,18 +149,14 @@
   inline static HeapWord* common_permanent_mem_allocate_init(size_t size, TRAPS);
 
   // Helper functions for (VM) allocation.
-  inline static void post_allocation_setup_common(KlassHandle klass,
-                                                  HeapWord* obj, size_t size);
+  inline static void post_allocation_setup_common(KlassHandle klass, HeapWord* obj);
   inline static void post_allocation_setup_no_klass_install(KlassHandle klass,
-                                                            HeapWord* objPtr,
-                                                            size_t size);
+                                                            HeapWord* objPtr);
 
-  inline static void post_allocation_setup_obj(KlassHandle klass,
-                                               HeapWord* obj, size_t size);
+  inline static void post_allocation_setup_obj(KlassHandle klass, HeapWord* obj);
 
   inline static void post_allocation_setup_array(KlassHandle klass,
-                                                 HeapWord* obj, size_t size,
-                                                 int length);
+                                                 HeapWord* obj, int length);
 
   // Clears an allocated object.
   inline static void init_obj(HeapWord* obj, size_t size);
@@ -169,7 +164,6 @@
   // Filler object utilities.
   static inline size_t filler_array_hdr_size();
   static inline size_t filler_array_min_size();
-  static inline size_t filler_array_max_size();
 
   DEBUG_ONLY(static void fill_args_check(HeapWord* start, size_t words);)
   DEBUG_ONLY(static void zap_filler_array(HeapWord* start, size_t words, bool zap = true);)
@@ -197,6 +191,10 @@
     G1CollectedHeap
   };
 
+  static inline size_t filler_array_max_size() {
+    return _filler_array_max_size;
+  }
+
   virtual CollectedHeap::Name kind() const { return CollectedHeap::Abstract; }
 
   /**
@@ -366,9 +364,7 @@
   inline static oop permanent_obj_allocate_no_klass_install(KlassHandle klass,
                                                             int size,
                                                             TRAPS);
-  inline static void post_allocation_install_obj_klass(KlassHandle klass,
-                                                       oop obj,
-                                                       int size);
+  inline static void post_allocation_install_obj_klass(KlassHandle klass, oop obj);
   inline static oop permanent_array_allocate(KlassHandle klass, int size, int length, TRAPS);
 
   // Raw memory allocation facilities
@@ -662,9 +658,6 @@
     }
   }
 
-  // Allocate GCHeapLog during VM startup
-  static void initialize_heap_log();
-
   // Heap verification
   virtual void verify(bool allow_dirty, bool silent, VerifyOption option) = 0;
 
--- a/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -50,15 +50,13 @@
 // Inline allocation implementations.
 
 void CollectedHeap::post_allocation_setup_common(KlassHandle klass,
-                                                 HeapWord* obj,
-                                                 size_t size) {
-  post_allocation_setup_no_klass_install(klass, obj, size);
-  post_allocation_install_obj_klass(klass, oop(obj), (int) size);
+                                                 HeapWord* obj) {
+  post_allocation_setup_no_klass_install(klass, obj);
+  post_allocation_install_obj_klass(klass, oop(obj));
 }
 
 void CollectedHeap::post_allocation_setup_no_klass_install(KlassHandle klass,
-                                                           HeapWord* objPtr,
-                                                           size_t size) {
+                                                           HeapWord* objPtr) {
   oop obj = (oop)objPtr;
 
   assert(obj != NULL, "NULL object pointer");
@@ -71,8 +69,7 @@
 }
 
 void CollectedHeap::post_allocation_install_obj_klass(KlassHandle klass,
-                                                   oop obj,
-                                                   int size) {
+                                                   oop obj) {
   // These asserts are kind of complicated because of klassKlass
   // and the beginning of the world.
   assert(klass() != NULL || !Universe::is_fully_initialized(), "NULL klass");
@@ -101,9 +98,8 @@
 }
 
 void CollectedHeap::post_allocation_setup_obj(KlassHandle klass,
-                                              HeapWord* obj,
-                                              size_t size) {
-  post_allocation_setup_common(klass, obj, size);
+                                              HeapWord* obj) {
+  post_allocation_setup_common(klass, obj);
   assert(Universe::is_bootstrapping() ||
          !((oop)obj)->blueprint()->oop_is_array(), "must not be an array");
   // notify jvmti and dtrace
@@ -112,14 +108,13 @@
 
 void CollectedHeap::post_allocation_setup_array(KlassHandle klass,
                                                 HeapWord* obj,
-                                                size_t size,
                                                 int length) {
   // Set array length before setting the _klass field
   // in post_allocation_setup_common() because the klass field
   // indicates that the object is parsable by concurrent GC.
   assert(length >= 0, "length should be non-negative");
   ((arrayOop)obj)->set_length(length);
-  post_allocation_setup_common(klass, obj, size);
+  post_allocation_setup_common(klass, obj);
   assert(((oop)obj)->blueprint()->oop_is_array(), "must be an array");
   // notify jvmti and dtrace (must be after length is set for dtrace)
   post_allocation_notify(klass, (oop)obj);
@@ -256,7 +251,7 @@
   assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
   assert(size >= 0, "int won't convert to size_t");
   HeapWord* obj = common_mem_allocate_init(size, CHECK_NULL);
-  post_allocation_setup_obj(klass, obj, size);
+  post_allocation_setup_obj(klass, obj);
   NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size));
   return (oop)obj;
 }
@@ -269,7 +264,7 @@
   assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
   assert(size >= 0, "int won't convert to size_t");
   HeapWord* obj = common_mem_allocate_init(size, CHECK_NULL);
-  post_allocation_setup_array(klass, obj, size, length);
+  post_allocation_setup_array(klass, obj, length);
   NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size));
   return (oop)obj;
 }
@@ -283,7 +278,7 @@
   assert(size >= 0, "int won't convert to size_t");
   HeapWord* obj = common_mem_allocate_noinit(size, CHECK_NULL);
   ((oop)obj)->set_klass_gap(0);
-  post_allocation_setup_array(klass, obj, size, length);
+  post_allocation_setup_array(klass, obj, length);
 #ifndef PRODUCT
   const size_t hs = oopDesc::header_size()+1;
   Universe::heap()->check_for_non_bad_heap_word_value(obj+hs, size-hs);
@@ -293,7 +288,7 @@
 
 oop CollectedHeap::permanent_obj_allocate(KlassHandle klass, int size, TRAPS) {
   oop obj = permanent_obj_allocate_no_klass_install(klass, size, CHECK_NULL);
-  post_allocation_install_obj_klass(klass, obj, size);
+  post_allocation_install_obj_klass(klass, obj);
   NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value((HeapWord*) obj,
                                                               size));
   return obj;
@@ -306,7 +301,7 @@
   assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
   assert(size >= 0, "int won't convert to size_t");
   HeapWord* obj = common_permanent_mem_allocate_init(size, CHECK_NULL);
-  post_allocation_setup_no_klass_install(klass, obj, size);
+  post_allocation_setup_no_klass_install(klass, obj);
 #ifndef PRODUCT
   const size_t hs = oopDesc::header_size();
   Universe::heap()->check_for_bad_heap_word_value(obj+hs, size-hs);
@@ -322,7 +317,7 @@
   assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
   assert(size >= 0, "int won't convert to size_t");
   HeapWord* obj = common_permanent_mem_allocate_init(size, CHECK_NULL);
-  post_allocation_setup_array(klass, obj, size, length);
+  post_allocation_setup_array(klass, obj, length);
   NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size));
   return (oop)obj;
 }
--- a/hotspot/src/share/vm/memory/cardTableModRefBS.hpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/memory/cardTableModRefBS.hpp	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -72,6 +72,9 @@
     CT_MR_BS_last_reserved      = 16
   };
 
+  // a word's worth (row) of clean card values
+  static const intptr_t clean_card_row = (intptr_t)(-1);
+
   // dirty and precleaned are equivalent wrt younger_refs_iter.
   static bool card_is_dirty_wrt_gen_iter(jbyte cv) {
     return cv == dirty_card || cv == precleaned_card;
--- a/hotspot/src/share/vm/memory/cardTableRS.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/memory/cardTableRS.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -173,6 +173,10 @@
             SharedHeap::heap()->workers()->active_workers()), "Mismatch");
 }
 
+bool ClearNoncleanCardWrapper::is_word_aligned(jbyte* entry) {
+  return (((intptr_t)entry) & (BytesPerWord-1)) == 0;
+}
+
 void ClearNoncleanCardWrapper::do_MemRegion(MemRegion mr) {
   assert(mr.word_size() > 0, "Error");
   assert(_ct->is_aligned(mr.start()), "mr.start() should be card aligned");
@@ -194,6 +198,17 @@
         const MemRegion mrd(start_of_non_clean, end_of_non_clean);
         _dirty_card_closure->do_MemRegion(mrd);
       }
+
+      // fast forward through potential continuous whole-word range of clean cards beginning at a word-boundary
+      if (is_word_aligned(cur_entry)) {
+        jbyte* cur_row = cur_entry - BytesPerWord;
+        while (cur_row >= limit && *((intptr_t*)cur_row) ==  CardTableRS::clean_card_row()) {
+          cur_row -= BytesPerWord;
+        }
+        cur_entry = cur_row + BytesPerWord;
+        cur_hw = _ct->addr_for(cur_entry);
+      }
+
       // Reset the dirty window, while continuing to look
       // for the next dirty card that will start a
       // new dirty window.
--- a/hotspot/src/share/vm/memory/cardTableRS.hpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/memory/cardTableRS.hpp	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -45,6 +45,10 @@
     return CardTableModRefBS::clean_card;
   }
 
+  static intptr_t clean_card_row() {
+    return CardTableModRefBS::clean_card_row;
+  }
+
   static bool
   card_is_dirty_wrt_gen_iter(jbyte cv) {
     return CardTableModRefBS::card_is_dirty_wrt_gen_iter(cv);
@@ -176,6 +180,8 @@
   // Work methods called by the clear_card()
   inline bool clear_card_serial(jbyte* entry);
   inline bool clear_card_parallel(jbyte* entry);
+  // check alignment of pointer
+  bool is_word_aligned(jbyte* entry);
 
 public:
   ClearNoncleanCardWrapper(DirtyCardToOopClosure* dirty_card_closure, CardTableRS* ct);
--- a/hotspot/src/share/vm/memory/dump.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/memory/dump.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -297,16 +297,14 @@
 
       if (obj->blueprint()->oop_is_instanceKlass()) {
         instanceKlass* ik = instanceKlass::cast((klassOop)obj);
-        typeArrayOop inner_classes = ik->inner_classes();
-        if (inner_classes != NULL) {
-          constantPoolOop constants = ik->constants();
-          int n = inner_classes->length();
-          for (int i = 0; i < n; i += instanceKlass::inner_class_next_offset) {
-            int ioff = i + instanceKlass::inner_class_inner_name_offset;
-            int index = inner_classes->ushort_at(ioff);
-            if (index != 0) {
-              _closure->do_symbol(constants->symbol_at_addr(index));
-            }
+        instanceKlassHandle ik_h((klassOop)obj);
+        InnerClassesIterator iter(ik_h);
+        constantPoolOop constants = ik->constants();
+        for (; !iter.done(); iter.next()) {
+          int index = iter.inner_name_index();
+
+          if (index != 0) {
+            _closure->do_symbol(constants->symbol_at_addr(index));
           }
         }
       }
--- a/hotspot/src/share/vm/oops/arrayKlass.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/oops/arrayKlass.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -153,6 +153,7 @@
   }
   if (length > arrayOopDesc::max_array_length(T_ARRAY)) {
     report_java_out_of_memory("Requested array size exceeds VM limit");
+    JvmtiExport::post_array_size_exhausted();
     THROW_OOP_0(Universe::out_of_memory_error_array_size());
   }
   int size = objArrayOopDesc::object_size(length);
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -669,6 +669,7 @@
   if (length < 0) THROW_0(vmSymbols::java_lang_NegativeArraySizeException());
   if (length > arrayOopDesc::max_array_length(T_OBJECT)) {
     report_java_out_of_memory("Requested array size exceeds VM limit");
+    JvmtiExport::post_array_size_exhausted();
     THROW_OOP_0(Universe::out_of_memory_error_array_size());
   }
   int size = objArrayOopDesc::object_size(length);
@@ -1132,6 +1133,36 @@
   return probe;
 }
 
+u2 instanceKlass::enclosing_method_data(int offset) {
+  typeArrayOop inner_class_list = inner_classes();
+  if (inner_class_list == NULL) {
+    return 0;
+  }
+  int length = inner_class_list->length();
+  if (length % inner_class_next_offset == 0) {
+    return 0;
+  } else {
+    int index = length - enclosing_method_attribute_size;
+    typeArrayHandle inner_class_list_h(inner_class_list);
+    assert(offset < enclosing_method_attribute_size, "invalid offset");
+    return inner_class_list_h->ushort_at(index + offset);
+  }
+}
+
+void instanceKlass::set_enclosing_method_indices(u2 class_index,
+                                                 u2 method_index) {
+  typeArrayOop inner_class_list = inner_classes();
+  assert (inner_class_list != NULL, "_inner_classes list is not set up");
+  int length = inner_class_list->length();
+  if (length % inner_class_next_offset == enclosing_method_attribute_size) {
+    int index = length - enclosing_method_attribute_size;
+    typeArrayHandle inner_class_list_h(inner_class_list);
+    inner_class_list_h->ushort_at_put(
+      index + enclosing_method_class_index_offset, class_index);
+    inner_class_list_h->ushort_at_put(
+      index + enclosing_method_method_index_offset, method_index);
+  }
+}
 
 // Lookup or create a jmethodID.
 // This code is called by the VMThread and JavaThreads so the
@@ -2106,28 +2137,21 @@
   jint access = access_flags().as_int();
 
   // But check if it happens to be member class.
-  typeArrayOop inner_class_list = inner_classes();
-  int length = (inner_class_list == NULL) ? 0 : inner_class_list->length();
-  assert (length % instanceKlass::inner_class_next_offset == 0, "just checking");
-  if (length > 0) {
-    typeArrayHandle inner_class_list_h(THREAD, inner_class_list);
-    instanceKlassHandle ik(THREAD, k);
-    for (int i = 0; i < length; i += instanceKlass::inner_class_next_offset) {
-      int ioff = inner_class_list_h->ushort_at(
-                      i + instanceKlass::inner_class_inner_class_info_offset);
-
-      // Inner class attribute can be zero, skip it.
-      // Strange but true:  JVM spec. allows null inner class refs.
-      if (ioff == 0) continue;
-
-      // only look at classes that are already loaded
-      // since we are looking for the flags for our self.
-      Symbol* inner_name = ik->constants()->klass_name_at(ioff);
-      if ((ik->name() == inner_name)) {
-        // This is really a member class.
-        access = inner_class_list_h->ushort_at(i + instanceKlass::inner_class_access_flags_offset);
-        break;
-      }
+  instanceKlassHandle ik(THREAD, k);
+  InnerClassesIterator iter(ik);
+  for (; !iter.done(); iter.next()) {
+    int ioff = iter.inner_class_info_index();
+    // Inner class attribute can be zero, skip it.
+    // Strange but true:  JVM spec. allows null inner class refs.
+    if (ioff == 0) continue;
+
+    // only look at classes that are already loaded
+    // since we are looking for the flags for our self.
+    Symbol* inner_name = ik->constants()->klass_name_at(ioff);
+    if ((ik->name() == inner_name)) {
+      // This is really a member class.
+      access = iter.inner_access_flags();
+      break;
     }
   }
   // Remember to strip ACC_SUPER bit
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp	Fri Mar 30 16:57:50 2012 -0700
@@ -188,7 +188,17 @@
   klassOop        _host_klass;
   // Class signers.
   objArrayOop     _signers;
-  // inner_classes attribute.
+  // The InnerClasses attribute and EnclosingMethod attribute. The
+  // _inner_classes is an array of shorts. If the class has InnerClasses
+  // attribute, then the _inner_classes array begins with 4-tuples of shorts
+  // [inner_class_info_index, outer_class_info_index,
+  // inner_name_index, inner_class_access_flags] for the InnerClasses
+  // attribute. If the EnclosingMethod attribute exists, it occupies the
+  // last two shorts [class_index, method_index] of the array. If only
+  // the InnerClasses attribute exists, the _inner_classes array length is
+  // number_of_inner_classes * 4. If the class has both InnerClasses
+  // and EnclosingMethod attributes the _inner_classes array length is
+  // number_of_inner_classes * 4 + enclosing_method_attribute_size.
   typeArrayOop    _inner_classes;
   // Implementors of this interface (not valid if it overflows)
   klassOop        _implementors[implementors_limit];
@@ -251,8 +261,6 @@
   // Array of interesting part(s) of the previous version(s) of this
   // instanceKlass. See PreviousVersionWalker below.
   GrowableArray<PreviousVersionNode *>* _previous_versions;
-  u2              _enclosing_method_class_index;  // Constant pool index for class of enclosing method, or 0 if none
-  u2              _enclosing_method_method_index; // Constant pool index for name and type of enclosing method, or 0 if none
   // JVMTI fields can be moved to their own structure - see 6315920
   unsigned char * _cached_class_file_bytes;       // JVMTI: cached class file, before retransformable agent modified it in CFLH
   jint            _cached_class_file_len;         // JVMTI: length of above
@@ -351,6 +359,12 @@
     inner_class_next_offset = 4
   };
 
+  enum EnclosingMethodAttributeOffset {
+    enclosing_method_class_index_offset = 0,
+    enclosing_method_method_index_offset = 1,
+    enclosing_method_attribute_size = 2
+  };
+
   // method override check
   bool is_override(methodHandle super_method, Handle targetclassloader, Symbol* targetclassname, TRAPS);
 
@@ -533,11 +547,15 @@
   Symbol* generic_signature() const                   { return _generic_signature; }
   void set_generic_signature(Symbol* sig)             { _generic_signature = sig; }
 
-  u2 enclosing_method_class_index() const             { return _enclosing_method_class_index; }
-  u2 enclosing_method_method_index() const            { return _enclosing_method_method_index; }
+  u2 enclosing_method_data(int offset);
+  u2 enclosing_method_class_index() {
+    return enclosing_method_data(enclosing_method_class_index_offset);
+  }
+  u2 enclosing_method_method_index() {
+    return enclosing_method_data(enclosing_method_method_index_offset);
+  }
   void set_enclosing_method_indices(u2 class_index,
-                                    u2 method_index)  { _enclosing_method_class_index  = class_index;
-                                                        _enclosing_method_method_index = method_index; }
+                                    u2 method_index);
 
   // jmethodID support
   static jmethodID get_jmethod_id(instanceKlassHandle ik_h,
@@ -1053,4 +1071,83 @@
   nmethod* get_nmethod()                  { return _nmethod; }
 };
 
+// An iterator that's used to access the inner classes indices in the
+// instanceKlass::_inner_classes array.
+class InnerClassesIterator : public StackObj {
+ private:
+  typeArrayHandle _inner_classes;
+  int _length;
+  int _idx;
+ public:
+
+  InnerClassesIterator(instanceKlassHandle k) {
+    _inner_classes = k->inner_classes();
+    if (k->inner_classes() != NULL) {
+      _length = _inner_classes->length();
+      // The inner class array's length should be the multiple of
+      // inner_class_next_offset if it only contains the InnerClasses
+      // attribute data, or it should be
+      // n*inner_class_next_offset+enclosing_method_attribute_size
+      // if it also contains the EnclosingMethod data.
+      assert((_length % instanceKlass::inner_class_next_offset == 0 ||
+              _length % instanceKlass::inner_class_next_offset == instanceKlass::enclosing_method_attribute_size),
+             "just checking");
+      // Remove the enclosing_method portion if exists.
+      if (_length % instanceKlass::inner_class_next_offset == instanceKlass::enclosing_method_attribute_size) {
+        _length -= instanceKlass::enclosing_method_attribute_size;
+      }
+    } else {
+      _length = 0;
+    }
+    _idx = 0;
+  }
+
+  int length() const {
+    return _length;
+  }
+
+  void next() {
+    _idx += instanceKlass::inner_class_next_offset;
+  }
+
+  bool done() const {
+    return (_idx >= _length);
+  }
+
+  u2 inner_class_info_index() const {
+    return _inner_classes->ushort_at(
+               _idx + instanceKlass::inner_class_inner_class_info_offset);
+  }
+
+  void set_inner_class_info_index(u2 index) {
+    _inner_classes->ushort_at_put(
+               _idx + instanceKlass::inner_class_inner_class_info_offset, index);
+  }
+
+  u2 outer_class_info_index() const {
+    return _inner_classes->ushort_at(
+               _idx + instanceKlass::inner_class_outer_class_info_offset);
+  }
+
+  void set_outer_class_info_index(u2 index) {
+    _inner_classes->ushort_at_put(
+               _idx + instanceKlass::inner_class_outer_class_info_offset, index);
+  }
+
+  u2 inner_name_index() const {
+    return _inner_classes->ushort_at(
+               _idx + instanceKlass::inner_class_inner_name_offset);
+  }
+
+  void set_inner_name_index(u2 index) {
+    _inner_classes->ushort_at_put(
+               _idx + instanceKlass::inner_class_inner_name_offset, index);
+  }
+
+  u2 inner_access_flags() const {
+    return _inner_classes->ushort_at(
+               _idx + instanceKlass::inner_class_access_flags_offset);
+  }
+};
+
 #endif // SHARE_VM_OOPS_INSTANCEKLASS_HPP
--- a/hotspot/src/share/vm/oops/instanceKlassKlass.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/oops/instanceKlassKlass.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -416,7 +416,6 @@
     ik->set_methods_annotations(NULL);
     ik->set_methods_parameter_annotations(NULL);
     ik->set_methods_default_annotations(NULL);
-    ik->set_enclosing_method_indices(0, 0);
     ik->set_jvmti_cached_class_field_map(NULL);
     ik->set_initial_method_idnum(0);
     assert(k()->is_parsable(), "should be parsable here.");
--- a/hotspot/src/share/vm/oops/klass.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/oops/klass.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -174,10 +174,9 @@
 }
 
 void Klass_vtbl::post_new_init_klass(KlassHandle& klass,
-                                     klassOop new_klass,
-                                     int size) const {
+                                     klassOop new_klass) const {
   assert(!new_klass->klass_part()->null_vtbl(), "Not a complete klass");
-  CollectedHeap::post_allocation_install_obj_klass(klass, new_klass, size);
+  CollectedHeap::post_allocation_install_obj_klass(klass, new_klass);
 }
 
 void* Klass_vtbl::operator new(size_t ignored, KlassHandle& klass,
--- a/hotspot/src/share/vm/oops/klass.hpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/oops/klass.hpp	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -149,7 +149,7 @@
   // by the shared "base_create" subroutines.
   //
   virtual void* allocate_permanent(KlassHandle& klass, int size, TRAPS) const = 0;
-  void post_new_init_klass(KlassHandle& klass, klassOop obj, int size) const;
+  void post_new_init_klass(KlassHandle& klass, klassOop obj) const;
 
   // Every subclass on which vtbl_value is called must include this macro.
   // Delay the installation of the klassKlass pointer until after the
@@ -160,7 +160,7 @@
     if (HAS_PENDING_EXCEPTION) return NULL;                                   \
     klassOop new_klass = ((Klass*) result)->as_klassOop();                    \
     OrderAccess::storestore();                                                \
-    post_new_init_klass(klass_klass, new_klass, size);                        \
+    post_new_init_klass(klass_klass, new_klass);                              \
     return result;                                                            \
   }
 
--- a/hotspot/src/share/vm/oops/objArrayKlass.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/oops/objArrayKlass.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -68,6 +68,7 @@
       return a;
     } else {
       report_java_out_of_memory("Requested array size exceeds VM limit");
+      JvmtiExport::post_array_size_exhausted();
       THROW_OOP_0(Universe::out_of_memory_error_array_size());
     }
   } else {
--- a/hotspot/src/share/vm/oops/typeArrayKlass.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/oops/typeArrayKlass.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -93,6 +93,7 @@
       return t;
     } else {
       report_java_out_of_memory("Requested array size exceeds VM limit");
+      JvmtiExport::post_array_size_exhausted();
       THROW_OOP_0(Universe::out_of_memory_error_array_size());
     }
   } else {
--- a/hotspot/src/share/vm/opto/bytecodeInfo.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/opto/bytecodeInfo.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -257,6 +257,18 @@
       return "exception method";
   }
 
+  if (callee_method->should_not_inline()) {
+    return "disallowed by CompilerOracle";
+  }
+
+  if (UseStringCache) {
+    // Do not inline StringCache::profile() method used only at the beginning.
+    if (callee_method->name() == ciSymbol::profile_name() &&
+        callee_method->holder()->name() == ciSymbol::java_lang_StringCache()) {
+      return "profiling method";
+    }
+  }
+
   // use frequency-based objections only for non-trivial methods
   if (callee_method->code_size_for_inlining() <= MaxTrivialSize) return NULL;
 
@@ -278,18 +290,6 @@
     }
   }
 
-  if (callee_method->should_not_inline()) {
-    return "disallowed by CompilerOracle";
-  }
-
-  if (UseStringCache) {
-    // Do not inline StringCache::profile() method used only at the beginning.
-    if (callee_method->name() == ciSymbol::profile_name() &&
-        callee_method->holder()->name() == ciSymbol::java_lang_StringCache()) {
-      return "profiling method";
-    }
-  }
-
   return NULL;
 }
 
--- a/hotspot/src/share/vm/opto/c2_globals.hpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/opto/c2_globals.hpp	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -465,6 +465,9 @@
   notproduct(bool, PrintOptimizePtrCompare, false,                          \
           "Print information about optimized pointers compare")             \
                                                                             \
+  notproduct(bool, VerifyConnectionGraph , true,                            \
+          "Verify Connection Graph construction in Escape Analysis")        \
+                                                                            \
   product(bool, UseOptoBiasInlining, true,                                  \
           "Generate biased locking code in C2 ideal graph")                 \
                                                                             \
--- a/hotspot/src/share/vm/opto/callnode.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/opto/callnode.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1538,10 +1538,7 @@
     // If we are locking an unescaped object, the lock/unlock is unnecessary
     //
     ConnectionGraph *cgr = phase->C->congraph();
-    PointsToNode::EscapeState es = PointsToNode::GlobalEscape;
-    if (cgr != NULL)
-      es = cgr->escape_state(obj_node());
-    if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) {
+    if (cgr != NULL && cgr->not_global_escape(obj_node())) {
       assert(!is_eliminated() || is_coarsened(), "sanity");
       // The lock could be marked eliminated by lock coarsening
       // code during first IGVN before EA. Replace coarsened flag
@@ -1680,10 +1677,7 @@
     // If we are unlocking an unescaped object, the lock/unlock is unnecessary.
     //
     ConnectionGraph *cgr = phase->C->congraph();
-    PointsToNode::EscapeState es = PointsToNode::GlobalEscape;
-    if (cgr != NULL)
-      es = cgr->escape_state(obj_node());
-    if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) {
+    if (cgr != NULL && cgr->not_global_escape(obj_node())) {
       assert(!is_eliminated() || is_coarsened(), "sanity");
       // The lock could be marked eliminated by lock coarsening
       // code during first IGVN before EA. Replace coarsened flag
--- a/hotspot/src/share/vm/opto/callnode.hpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/opto/callnode.hpp	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -546,6 +546,12 @@
   // or result projection is there are several CheckCastPP
   // or returns NULL if there is no one.
   Node *result_cast();
+  // Does this node returns pointer?
+  bool returns_pointer() const {
+    const TypeTuple *r = tf()->range();
+    return (r->cnt() > TypeFunc::Parms &&
+            r->field_at(TypeFunc::Parms)->isa_ptr());
+  }
 
   // Collect all the interesting edges from a call for use in
   // replacing the call by something else.  Used by macro expansion
--- a/hotspot/src/share/vm/opto/compile.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/opto/compile.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1707,7 +1707,6 @@
       if (major_progress()) print_method("PhaseIdealLoop before EA", 2);
       if (failing())  return;
     }
-    TracePhase t2("escapeAnalysis", &_t_escapeAnalysis, true);
     ConnectionGraph::do_analysis(this, &igvn);
 
     if (failing())  return;
@@ -1719,6 +1718,7 @@
     if (failing())  return;
 
     if (congraph() != NULL && macro_count() > 0) {
+      NOT_PRODUCT( TracePhase t2("macroEliminate", &_t_macroEliminate, TimeCompiler); )
       PhaseMacroExpand mexp(igvn);
       mexp.eliminate_macro_nodes();
       igvn.set_delay_transform(false);
@@ -1875,10 +1875,10 @@
 
     cfg.Estimate_Block_Frequency();
     cfg.GlobalCodeMotion(m,unique(),proj_list);
+    if (failing())  return;
 
     print_method("Global code motion", 2);
 
-    if (failing())  return;
     NOT_PRODUCT( verify_graph_edges(); )
 
     debug_only( cfg.verify(); )
--- a/hotspot/src/share/vm/opto/compile.hpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/opto/compile.hpp	Fri Mar 30 16:57:50 2012 -0700
@@ -631,7 +631,7 @@
 
   // Decide how to build a call.
   // The profile factor is a discount to apply to this site's interp. profile.
-  CallGenerator*    call_generator(ciMethod* call_method, int vtable_index, bool call_is_virtual, JVMState* jvms, bool allow_inline, float profile_factor);
+  CallGenerator*    call_generator(ciMethod* call_method, int vtable_index, bool call_is_virtual, JVMState* jvms, bool allow_inline, float profile_factor, bool allow_intrinsics = true);
   bool should_delay_inlining(ciMethod* call_method, JVMState* jvms);
 
   // Report if there were too many traps at a current method and bci.
--- a/hotspot/src/share/vm/opto/doCall.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/opto/doCall.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -61,7 +61,7 @@
 
 CallGenerator* Compile::call_generator(ciMethod* call_method, int vtable_index, bool call_is_virtual,
                                        JVMState* jvms, bool allow_inline,
-                                       float prof_factor) {
+                                       float prof_factor, bool allow_intrinsics) {
   ciMethod*       caller   = jvms->method();
   int             bci      = jvms->bci();
   Bytecodes::Code bytecode = caller->java_code_at_bci(bci);
@@ -108,7 +108,7 @@
   // then we return it as the inlined version of the call.
   // We do this before the strict f.p. check below because the
   // intrinsics handle strict f.p. correctly.
-  if (allow_inline) {
+  if (allow_inline && allow_intrinsics) {
     CallGenerator* cg = find_intrinsic(call_method, call_is_virtual);
     if (cg != NULL)  return cg;
   }
@@ -455,21 +455,12 @@
     // cg->generate(), we are committed.  If it fails, the whole
     // compilation task is compromised.
     if (failing())  return;
-#ifndef PRODUCT
-    if (PrintOpto || PrintOptoInlining || PrintInlining) {
-      // Only one fall-back, so if an intrinsic fails, ignore any bytecodes.
-      if (cg->is_intrinsic() && call_method->code_size() > 0) {
-        tty->print("Bailed out of intrinsic, will not inline: ");
-        call_method->print_name(); tty->cr();
-      }
-    }
-#endif
+
     // This can happen if a library intrinsic is available, but refuses
     // the call site, perhaps because it did not match a pattern the
-    // intrinsic was expecting to optimize.  The fallback position is
-    // to call out-of-line.
-    try_inline = false;  // Inline tactic bailed out.
-    cg = C->call_generator(call_method, vtable_index, call_is_virtual, jvms, try_inline, prof_factor());
+    // intrinsic was expecting to optimize. Should always be possible to
+    // get a normal java call that may inline in that case
+    cg = C->call_generator(call_method, vtable_index, call_is_virtual, jvms, try_inline, prof_factor(), /* allow_intrinsics= */ false);
     if ((new_jvms = cg->generate(jvms)) == NULL) {
       guarantee(failing(), "call failed to generate:  calls should work");
       return;
--- a/hotspot/src/share/vm/opto/escape.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/opto/escape.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "ci/bcEscapeAnalyzer.hpp"
+#include "compiler/compileLog.hpp"
 #include "libadt/vectset.hpp"
 #include "memory/allocation.hpp"
 #include "opto/c2compiler.hpp"
@@ -34,125 +35,1935 @@
 #include "opto/phaseX.hpp"
 #include "opto/rootnode.hpp"
 
-void PointsToNode::add_edge(uint targIdx, PointsToNode::EdgeType et) {
-  uint v = (targIdx << EdgeShift) + ((uint) et);
-  if (_edges == NULL) {
-     Arena *a = Compile::current()->comp_arena();
-    _edges = new(a) GrowableArray<uint>(a, INITIAL_EDGE_COUNT, 0, 0);
-  }
-  _edges->append_if_missing(v);
-}
-
-void PointsToNode::remove_edge(uint targIdx, PointsToNode::EdgeType et) {
-  uint v = (targIdx << EdgeShift) + ((uint) et);
-
-  _edges->remove(v);
-}
-
-#ifndef PRODUCT
-static const char *node_type_names[] = {
-  "UnknownType",
-  "JavaObject",
-  "LocalVar",
-  "Field"
-};
-
-static const char *esc_names[] = {
-  "UnknownEscape",
-  "NoEscape",
-  "ArgEscape",
-  "GlobalEscape"
-};
-
-static const char *edge_type_suffix[] = {
- "?", // UnknownEdge
- "P", // PointsToEdge
- "D", // DeferredEdge
- "F"  // FieldEdge
-};
-
-void PointsToNode::dump(bool print_state) const {
-  NodeType nt = node_type();
-  tty->print("%s ", node_type_names[(int) nt]);
-  if (print_state) {
-    EscapeState es = escape_state();
-    tty->print("%s %s ", esc_names[(int) es], _scalar_replaceable ? "":"NSR");
-  }
-  tty->print("[[");
-  for (uint i = 0; i < edge_count(); i++) {
-    tty->print(" %d%s", edge_target(i), edge_type_suffix[(int) edge_type(i)]);
-  }
-  tty->print("]]  ");
-  if (_node == NULL)
-    tty->print_cr("<null>");
-  else
-    _node->dump();
-}
-#endif
-
 ConnectionGraph::ConnectionGraph(Compile * C, PhaseIterGVN *igvn) :
-  _nodes(C->comp_arena(), C->unique(), C->unique(), PointsToNode()),
-  _processed(C->comp_arena()),
-  pt_ptset(C->comp_arena()),
-  pt_visited(C->comp_arena()),
-  pt_worklist(C->comp_arena(), 4, 0, 0),
+  _nodes(C->comp_arena(), C->unique(), C->unique(), NULL),
   _collecting(true),
-  _progress(false),
+  _verify(false),
   _compile(C),
   _igvn(igvn),
   _node_map(C->comp_arena()) {
-
-  _phantom_object = C->top()->_idx,
-  add_node(C->top(), PointsToNode::JavaObject, PointsToNode::GlobalEscape,true);
-
+  // Add unknown java object.
+  add_java_object(C->top(), PointsToNode::GlobalEscape);
+  phantom_obj = ptnode_adr(C->top()->_idx)->as_JavaObject();
   // Add ConP(#NULL) and ConN(#NULL) nodes.
   Node* oop_null = igvn->zerocon(T_OBJECT);
-  _oop_null = oop_null->_idx;
-  assert(_oop_null < nodes_size(), "should be created already");
-  add_node(oop_null, PointsToNode::JavaObject, PointsToNode::NoEscape, true);
-
+  assert(oop_null->_idx < nodes_size(), "should be created already");
+  add_java_object(oop_null, PointsToNode::NoEscape);
+  null_obj = ptnode_adr(oop_null->_idx)->as_JavaObject();
   if (UseCompressedOops) {
     Node* noop_null = igvn->zerocon(T_NARROWOOP);
-    _noop_null = noop_null->_idx;
-    assert(_noop_null < nodes_size(), "should be created already");
-    add_node(noop_null, PointsToNode::JavaObject, PointsToNode::NoEscape, true);
-  } else {
-    _noop_null = _oop_null; // Should be initialized
+    assert(noop_null->_idx < nodes_size(), "should be created already");
+    map_ideal_node(noop_null, null_obj);
   }
   _pcmp_neq = NULL; // Should be initialized
   _pcmp_eq  = NULL;
 }
 
-void ConnectionGraph::add_pointsto_edge(uint from_i, uint to_i) {
-  PointsToNode *f = ptnode_adr(from_i);
-  PointsToNode *t = ptnode_adr(to_i);
+bool ConnectionGraph::has_candidates(Compile *C) {
+  // EA brings benefits only when the code has allocations and/or locks which
+  // are represented by ideal Macro nodes.
+  int cnt = C->macro_count();
+  for( int i=0; i < cnt; i++ ) {
+    Node *n = C->macro_node(i);
+    if ( n->is_Allocate() )
+      return true;
+    if( n->is_Lock() ) {
+      Node* obj = n->as_Lock()->obj_node()->uncast();
+      if( !(obj->is_Parm() || obj->is_Con()) )
+        return true;
+    }
+  }
+  return false;
+}
+
+void ConnectionGraph::do_analysis(Compile *C, PhaseIterGVN *igvn) {
+  Compile::TracePhase t2("escapeAnalysis", &Phase::_t_escapeAnalysis, true);
+  ResourceMark rm;
+
+  // Add ConP#NULL and ConN#NULL nodes before ConnectionGraph construction
+  // to create space for them in ConnectionGraph::_nodes[].
+  Node* oop_null = igvn->zerocon(T_OBJECT);
+  Node* noop_null = igvn->zerocon(T_NARROWOOP);
+  ConnectionGraph* congraph = new(C->comp_arena()) ConnectionGraph(C, igvn);
+  // Perform escape analysis
+  if (congraph->compute_escape()) {
+    // There are non escaping objects.
+    C->set_congraph(congraph);
+  }
+  // Cleanup.
+  if (oop_null->outcnt() == 0)
+    igvn->hash_delete(oop_null);
+  if (noop_null->outcnt() == 0)
+    igvn->hash_delete(noop_null);
+}
+
+bool ConnectionGraph::compute_escape() {
+  Compile* C = _compile;
+  PhaseGVN* igvn = _igvn;
+
+  // Worklists used by EA.
+  Unique_Node_List delayed_worklist;
+  GrowableArray<Node*> alloc_worklist;
+  GrowableArray<Node*> ptr_cmp_worklist;
+  GrowableArray<Node*> storestore_worklist;
+  GrowableArray<PointsToNode*>   ptnodes_worklist;
+  GrowableArray<JavaObjectNode*> java_objects_worklist;
+  GrowableArray<JavaObjectNode*> non_escaped_worklist;
+  GrowableArray<FieldNode*>      oop_fields_worklist;
+  DEBUG_ONLY( GrowableArray<Node*> addp_worklist; )
+
+  { Compile::TracePhase t3("connectionGraph", &Phase::_t_connectionGraph, true);
+
+  // 1. Populate Connection Graph (CG) with PointsTo nodes.
+  ideal_nodes.map(C->unique(), NULL);  // preallocate space
+  // Initialize worklist
+  if (C->root() != NULL) {
+    ideal_nodes.push(C->root());
+  }
+  for( uint next = 0; next < ideal_nodes.size(); ++next ) {
+    Node* n = ideal_nodes.at(next);
+    // Create PointsTo nodes and add them to Connection Graph. Called
+    // only once per ideal node since ideal_nodes is Unique_Node list.
+    add_node_to_connection_graph(n, &delayed_worklist);
+    PointsToNode* ptn = ptnode_adr(n->_idx);
+    if (ptn != NULL) {
+      ptnodes_worklist.append(ptn);
+      if (ptn->is_JavaObject()) {
+        java_objects_worklist.append(ptn->as_JavaObject());
+        if ((n->is_Allocate() || n->is_CallStaticJava()) &&
+            (ptn->escape_state() < PointsToNode::GlobalEscape)) {
+          // Only allocations and java static calls results are interesting.
+          non_escaped_worklist.append(ptn->as_JavaObject());
+        }
+      } else if (ptn->is_Field() && ptn->as_Field()->is_oop()) {
+        oop_fields_worklist.append(ptn->as_Field());
+      }
+    }
+    if (n->is_MergeMem()) {
+      // Collect all MergeMem nodes to add memory slices for
+      // scalar replaceable objects in split_unique_types().
+      _mergemem_worklist.append(n->as_MergeMem());
+    } else if (OptimizePtrCompare && n->is_Cmp() &&
+               (n->Opcode() == Op_CmpP || n->Opcode() == Op_CmpN)) {
+      // Collect compare pointers nodes.
+      ptr_cmp_worklist.append(n);
+    } else if (n->is_MemBarStoreStore()) {
+      // Collect all MemBarStoreStore nodes so that depending on the
+      // escape status of the associated Allocate node some of them
+      // may be eliminated.
+      storestore_worklist.append(n);
+#ifdef ASSERT
+    } else if(n->is_AddP()) {
+      // Collect address nodes for graph verification.
+      addp_worklist.append(n);
+#endif
+    }
+    for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
+      Node* m = n->fast_out(i);   // Get user
+      ideal_nodes.push(m);
+    }
+  }
+  if (non_escaped_worklist.length() == 0) {
+    _collecting = false;
+    return false; // Nothing to do.
+  }
+  // Add final simple edges to graph.
+  while(delayed_worklist.size() > 0) {
+    Node* n = delayed_worklist.pop();
+    add_final_edges(n);
+  }
+  int ptnodes_length = ptnodes_worklist.length();
+
+#ifdef ASSERT
+  if (VerifyConnectionGraph) {
+    // Verify that no new simple edges could be created and all
+    // local vars has edges.
+    _verify = true;
+    for (int next = 0; next < ptnodes_length; ++next) {
+      PointsToNode* ptn = ptnodes_worklist.at(next);
+      add_final_edges(ptn->ideal_node());
+      if (ptn->is_LocalVar() && ptn->edge_count() == 0) {
+        ptn->dump();
+        assert(ptn->as_LocalVar()->edge_count() > 0, "sanity");
+      }
+    }
+    _verify = false;
+  }
+#endif
+
+  // 2. Finish Graph construction by propagating references to all
+  //    java objects through graph.
+  if (!complete_connection_graph(ptnodes_worklist, non_escaped_worklist,
+                                 java_objects_worklist, oop_fields_worklist)) {
+    // All objects escaped or hit time or iterations limits.
+    _collecting = false;
+    return false;
+  }
+
+  // 3. Adjust scalar_replaceable state of nonescaping objects and push
+  //    scalar replaceable allocations on alloc_worklist for processing
+  //    in split_unique_types().
+  int non_escaped_length = non_escaped_worklist.length();
+  for (int next = 0; next < non_escaped_length; next++) {
+    JavaObjectNode* ptn = non_escaped_worklist.at(next);
+    if (ptn->escape_state() == PointsToNode::NoEscape &&
+        ptn->scalar_replaceable()) {
+      adjust_scalar_replaceable_state(ptn);
+      if (ptn->scalar_replaceable()) {
+        alloc_worklist.append(ptn->ideal_node());
+      }
+    }
+  }
+
+#ifdef ASSERT
+  if (VerifyConnectionGraph) {
+    // Verify that graph is complete - no new edges could be added or needed.
+    verify_connection_graph(ptnodes_worklist, non_escaped_worklist,
+                            java_objects_worklist, addp_worklist);
+  }
+  assert(C->unique() == nodes_size(), "no new ideal nodes should be added during ConnectionGraph build");
+  assert(null_obj->escape_state() == PointsToNode::NoEscape &&
+         null_obj->edge_count() == 0 &&
+         !null_obj->arraycopy_src() &&
+         !null_obj->arraycopy_dst(), "sanity");
+#endif
+
+  _collecting = false;
+
+  } // TracePhase t3("connectionGraph")
+
+  // 4. Optimize ideal graph based on EA information.
+  bool has_non_escaping_obj = (non_escaped_worklist.length() > 0);
+  if (has_non_escaping_obj) {
+    optimize_ideal_graph(ptr_cmp_worklist, storestore_worklist);
+  }
+
+#ifndef PRODUCT
+  if (PrintEscapeAnalysis) {
+    dump(ptnodes_worklist); // Dump ConnectionGraph
+  }
+#endif
+
+  bool has_scalar_replaceable_candidates = (alloc_worklist.length() > 0);
+#ifdef ASSERT
+  if (VerifyConnectionGraph) {
+    int alloc_length = alloc_worklist.length();
+    for (int next = 0; next < alloc_length; ++next) {
+      Node* n = alloc_worklist.at(next);
+      PointsToNode* ptn = ptnode_adr(n->_idx);
+      assert(ptn->escape_state() == PointsToNode::NoEscape && ptn->scalar_replaceable(), "sanity");
+    }
+  }
+#endif
+
+  // 5. Separate memory graph for scalar replaceable allcations.
+  if (has_scalar_replaceable_candidates &&
+      C->AliasLevel() >= 3 && EliminateAllocations) {
+    // Now use the escape information to create unique types for
+    // scalar replaceable objects.
+    split_unique_types(alloc_worklist);
+    if (C->failing())  return false;
+    C->print_method("After Escape Analysis", 2);
+
+#ifdef ASSERT
+  } else if (Verbose && (PrintEscapeAnalysis || PrintEliminateAllocations)) {
+    tty->print("=== No allocations eliminated for ");
+    C->method()->print_short_name();
+    if(!EliminateAllocations) {
+      tty->print(" since EliminateAllocations is off ===");
+    } else if(!has_scalar_replaceable_candidates) {
+      tty->print(" since there are no scalar replaceable candidates ===");
+    } else if(C->AliasLevel() < 3) {
+      tty->print(" since AliasLevel < 3 ===");
+    }
+    tty->cr();
+#endif
+  }
+  return has_non_escaping_obj;
+}
+
+// Populate Connection Graph with PointsTo nodes and create simple
+// connection graph edges.
+void ConnectionGraph::add_node_to_connection_graph(Node *n, Unique_Node_List *delayed_worklist) {
+  assert(!_verify, "this method sould not be called for verification");
+  PhaseGVN* igvn = _igvn;
+  uint n_idx = n->_idx;
+  PointsToNode* n_ptn = ptnode_adr(n_idx);
+  if (n_ptn != NULL)
+    return; // No need to redefine PointsTo node during first iteration.
+
+  if (n->is_Call()) {
+    // Arguments to allocation and locking don't escape.
+    if (n->is_AbstractLock()) {
+      // Put Lock and Unlock nodes on IGVN worklist to process them during
+      // first IGVN optimization when escape information is still available.
+      record_for_optimizer(n);
+    } else if (n->is_Allocate()) {
+      add_call_node(n->as_Call());
+      record_for_optimizer(n);
+    } else {
+      if (n->is_CallStaticJava()) {
+        const char* name = n->as_CallStaticJava()->_name;
+        if (name != NULL && strcmp(name, "uncommon_trap") == 0)
+          return; // Skip uncommon traps
+      }
+      // Don't mark as processed since call's arguments have to be processed.
+      delayed_worklist->push(n);
+      // Check if a call returns an object.
+      if (n->as_Call()->returns_pointer() &&
+          n->as_Call()->proj_out(TypeFunc::Parms) != NULL) {
+        add_call_node(n->as_Call());
+      }
+    }
+    return;
+  }
+  // Put this check here to process call arguments since some call nodes
+  // point to phantom_obj.
+  if (n_ptn == phantom_obj || n_ptn == null_obj)
+    return; // Skip predefined nodes.
 
-  assert(f->node_type() != PointsToNode::UnknownType && t->node_type() != PointsToNode::UnknownType, "node types must be set");
-  assert(f->node_type() == PointsToNode::LocalVar || f->node_type() == PointsToNode::Field, "invalid source of PointsTo edge");
-  assert(t->node_type() == PointsToNode::JavaObject, "invalid destination of PointsTo edge");
-  if (to_i == _phantom_object) { // Quick test for most common object
-    if (f->has_unknown_ptr()) {
-      return;
+  int opcode = n->Opcode();
+  switch (opcode) {
+    case Op_AddP: {
+      Node* base = get_addp_base(n);
+      PointsToNode* ptn_base = ptnode_adr(base->_idx);
+      // Field nodes are created for all field types. They are used in
+      // adjust_scalar_replaceable_state() and split_unique_types().
+      // Note, non-oop fields will have only base edges in Connection
+      // Graph because such fields are not used for oop loads and stores.
+      int offset = address_offset(n, igvn);
+      add_field(n, PointsToNode::NoEscape, offset);
+      if (ptn_base == NULL) {
+        delayed_worklist->push(n); // Process it later.
+      } else {
+        n_ptn = ptnode_adr(n_idx);
+        add_base(n_ptn->as_Field(), ptn_base);
+      }
+      break;
+    }
+    case Op_CastX2P: {
+      map_ideal_node(n, phantom_obj);
+      break;
+    }
+    case Op_CastPP:
+    case Op_CheckCastPP:
+    case Op_EncodeP:
+    case Op_DecodeN: {
+      add_local_var_and_edge(n, PointsToNode::NoEscape,
+                             n->in(1), delayed_worklist);
+      break;
+    }
+    case Op_CMoveP: {
+      add_local_var(n, PointsToNode::NoEscape);
+      // Do not add edges during first iteration because some could be
+      // not defined yet.
+      delayed_worklist->push(n);
+      break;
+    }
+    case Op_ConP:
+    case Op_ConN: {
+      // assume all oop constants globally escape except for null
+      PointsToNode::EscapeState es;
+      if (igvn->type(n) == TypePtr::NULL_PTR ||
+          igvn->type(n) == TypeNarrowOop::NULL_PTR) {
+        es = PointsToNode::NoEscape;
+      } else {
+        es = PointsToNode::GlobalEscape;
+      }
+      add_java_object(n, es);
+      break;
+    }
+    case Op_CreateEx: {
+      // assume that all exception objects globally escape
+      add_java_object(n, PointsToNode::GlobalEscape);
+      break;
+    }
+    case Op_LoadKlass:
+    case Op_LoadNKlass: {
+      // Unknown class is loaded
+      map_ideal_node(n, phantom_obj);
+      break;
+    }
+    case Op_LoadP:
+    case Op_LoadN:
+    case Op_LoadPLocked: {
+      // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
+      // ThreadLocal has RawPrt type.
+      const Type* t = igvn->type(n);
+      if (t->make_ptr() != NULL) {
+        Node* adr = n->in(MemNode::Address);
+#ifdef ASSERT
+        if (!adr->is_AddP()) {
+          assert(igvn->type(adr)->isa_rawptr(), "sanity");
+        } else {
+          assert((ptnode_adr(adr->_idx) == NULL ||
+                  ptnode_adr(adr->_idx)->as_Field()->is_oop()), "sanity");
+        }
+#endif
+        add_local_var_and_edge(n, PointsToNode::NoEscape,
+                               adr, delayed_worklist);
+      }
+      break;
+    }
+    case Op_Parm: {
+      map_ideal_node(n, phantom_obj);
+      break;
+    }
+    case Op_PartialSubtypeCheck: {
+      // Produces Null or notNull and is used in only in CmpP so
+      // phantom_obj could be used.
+      map_ideal_node(n, phantom_obj); // Result is unknown
+      break;
+    }
+    case Op_Phi: {
+      // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
+      // ThreadLocal has RawPrt type.
+      const Type* t = n->as_Phi()->type();
+      if (t->make_ptr() != NULL) {
+        add_local_var(n, PointsToNode::NoEscape);
+        // Do not add edges during first iteration because some could be
+        // not defined yet.
+        delayed_worklist->push(n);
+      }
+      break;
+    }
+    case Op_Proj: {
+      // we are only interested in the oop result projection from a call
+      if (n->as_Proj()->_con == TypeFunc::Parms && n->in(0)->is_Call() &&
+          n->in(0)->as_Call()->returns_pointer()) {
+        add_local_var_and_edge(n, PointsToNode::NoEscape,
+                               n->in(0), delayed_worklist);
+      }
+      break;
+    }
+    case Op_Rethrow: // Exception object escapes
+    case Op_Return: {
+      if (n->req() > TypeFunc::Parms &&
+          igvn->type(n->in(TypeFunc::Parms))->isa_oopptr()) {
+        // Treat Return value as LocalVar with GlobalEscape escape state.
+        add_local_var_and_edge(n, PointsToNode::GlobalEscape,
+                               n->in(TypeFunc::Parms), delayed_worklist);
+      }
+      break;
+    }
+    case Op_StoreP:
+    case Op_StoreN:
+    case Op_StorePConditional:
+    case Op_CompareAndSwapP:
+    case Op_CompareAndSwapN: {
+      Node* adr = n->in(MemNode::Address);
+      const Type *adr_type = igvn->type(adr);
+      adr_type = adr_type->make_ptr();
+      if (adr_type->isa_oopptr() ||
+          (opcode == Op_StoreP || opcode == Op_StoreN) &&
+                        (adr_type == TypeRawPtr::NOTNULL &&
+                         adr->in(AddPNode::Address)->is_Proj() &&
+                         adr->in(AddPNode::Address)->in(0)->is_Allocate())) {
+        delayed_worklist->push(n); // Process it later.
+#ifdef ASSERT
+        assert(adr->is_AddP(), "expecting an AddP");
+        if (adr_type == TypeRawPtr::NOTNULL) {
+          // Verify a raw address for a store captured by Initialize node.
+          int offs = (int)igvn->find_intptr_t_con(adr->in(AddPNode::Offset), Type::OffsetBot);
+          assert(offs != Type::OffsetBot, "offset must be a constant");
+        }
+#endif
+      } else {
+        // Ignore copy the displaced header to the BoxNode (OSR compilation).
+        if (adr->is_BoxLock())
+          break;
+        // Stored value escapes in unsafe access.
+        if ((opcode == Op_StoreP) && (adr_type == TypeRawPtr::BOTTOM)) {
+          // Pointer stores in G1 barriers looks like unsafe access.
+          // Ignore such stores to be able scalar replace non-escaping
+          // allocations.
+          if (UseG1GC && adr->is_AddP()) {
+            Node* base = get_addp_base(adr);
+            if (base->Opcode() == Op_LoadP &&
+                base->in(MemNode::Address)->is_AddP()) {
+              adr = base->in(MemNode::Address);
+              Node* tls = get_addp_base(adr);
+              if (tls->Opcode() == Op_ThreadLocal) {
+                int offs = (int)igvn->find_intptr_t_con(adr->in(AddPNode::Offset), Type::OffsetBot);
+                if (offs == in_bytes(JavaThread::satb_mark_queue_offset() +
+                                     PtrQueue::byte_offset_of_buf())) {
+                  break; // G1 pre barier previous oop value store.
+                }
+                if (offs == in_bytes(JavaThread::dirty_card_queue_offset() +
+                                     PtrQueue::byte_offset_of_buf())) {
+                  break; // G1 post barier card address store.
+                }
+              }
+            }
+          }
+          delayed_worklist->push(n); // Process unsafe access later.
+          break;
+        }
+#ifdef ASSERT
+        n->dump(1);
+        assert(false, "not unsafe or G1 barrier raw StoreP");
+#endif
+      }
+      break;
+    }
+    case Op_AryEq:
+    case Op_StrComp:
+    case Op_StrEquals:
+    case Op_StrIndexOf: {
+      add_local_var(n, PointsToNode::ArgEscape);
+      delayed_worklist->push(n); // Process it later.
+      break;
+    }
+    case Op_ThreadLocal: {
+      add_java_object(n, PointsToNode::ArgEscape);
+      break;
+    }
+    default:
+      ; // Do nothing for nodes not related to EA.
+  }
+  return;
+}
+
+#ifdef ASSERT
+#define ELSE_FAIL(name)                               \
+      /* Should not be called for not pointer type. */  \
+      n->dump(1);                                       \
+      assert(false, name);                              \
+      break;
+#else
+#define ELSE_FAIL(name) \
+      break;
+#endif
+
+// Add final simple edges to graph.
+void ConnectionGraph::add_final_edges(Node *n) {
+  PointsToNode* n_ptn = ptnode_adr(n->_idx);
+#ifdef ASSERT
+  if (_verify && n_ptn->is_JavaObject())
+    return; // This method does not change graph for JavaObject.
+#endif
+
+  if (n->is_Call()) {
+    process_call_arguments(n->as_Call());
+    return;
+  }
+  assert(n->is_Store() || n->is_LoadStore() ||
+         (n_ptn != NULL) && (n_ptn->ideal_node() != NULL),
+         "node should be registered already");
+  int opcode = n->Opcode();
+  switch (opcode) {
+    case Op_AddP: {
+      Node* base = get_addp_base(n);
+      PointsToNode* ptn_base = ptnode_adr(base->_idx);
+      assert(ptn_base != NULL, "field's base should be registered");
+      add_base(n_ptn->as_Field(), ptn_base);
+      break;
+    }
+    case Op_CastPP:
+    case Op_CheckCastPP:
+    case Op_EncodeP:
+    case Op_DecodeN: {
+      add_local_var_and_edge(n, PointsToNode::NoEscape,
+                             n->in(1), NULL);
+      break;
+    }
+    case Op_CMoveP: {
+      for (uint i = CMoveNode::IfFalse; i < n->req(); i++) {
+        Node* in = n->in(i);
+        if (in == NULL)
+          continue;  // ignore NULL
+        Node* uncast_in = in->uncast();
+        if (uncast_in->is_top() || uncast_in == n)
+          continue;  // ignore top or inputs which go back this node
+        PointsToNode* ptn = ptnode_adr(in->_idx);
+        assert(ptn != NULL, "node should be registered");
+        add_edge(n_ptn, ptn);
+      }
+      break;
+    }
+    case Op_LoadP:
+    case Op_LoadN:
+    case Op_LoadPLocked: {
+      // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
+      // ThreadLocal has RawPrt type.
+      const Type* t = _igvn->type(n);
+      if (t->make_ptr() != NULL) {
+        Node* adr = n->in(MemNode::Address);
+        add_local_var_and_edge(n, PointsToNode::NoEscape, adr, NULL);
+        break;
+      }
+      ELSE_FAIL("Op_LoadP");
+    }
+    case Op_Phi: {
+      // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
+      // ThreadLocal has RawPrt type.
+      const Type* t = n->as_Phi()->type();
+      if (t->make_ptr() != NULL) {
+        for (uint i = 1; i < n->req(); i++) {
+          Node* in = n->in(i);
+          if (in == NULL)
+            continue;  // ignore NULL
+          Node* uncast_in = in->uncast();
+          if (uncast_in->is_top() || uncast_in == n)
+            continue;  // ignore top or inputs which go back this node
+          PointsToNode* ptn = ptnode_adr(in->_idx);
+          assert(ptn != NULL, "node should be registered");
+          add_edge(n_ptn, ptn);
+        }
+        break;
+      }
+      ELSE_FAIL("Op_Phi");
+    }
+    case Op_Proj: {
+      // we are only interested in the oop result projection from a call
+      if (n->as_Proj()->_con == TypeFunc::Parms && n->in(0)->is_Call() &&
+          n->in(0)->as_Call()->returns_pointer()) {
+        add_local_var_and_edge(n, PointsToNode::NoEscape, n->in(0), NULL);
+        break;
+      }
+      ELSE_FAIL("Op_Proj");
+    }
+    case Op_Rethrow: // Exception object escapes
+    case Op_Return: {
+      if (n->req() > TypeFunc::Parms &&
+          _igvn->type(n->in(TypeFunc::Parms))->isa_oopptr()) {
+        // Treat Return value as LocalVar with GlobalEscape escape state.
+        add_local_var_and_edge(n, PointsToNode::GlobalEscape,
+                               n->in(TypeFunc::Parms), NULL);
+        break;
+      }
+      ELSE_FAIL("Op_Return");
+    }
+    case Op_StoreP:
+    case Op_StoreN:
+    case Op_StorePConditional:
+    case Op_CompareAndSwapP:
+    case Op_CompareAndSwapN: {
+      Node* adr = n->in(MemNode::Address);
+      const Type *adr_type = _igvn->type(adr);
+      adr_type = adr_type->make_ptr();
+      if (adr_type->isa_oopptr() ||
+          (opcode == Op_StoreP || opcode == Op_StoreN) &&
+                        (adr_type == TypeRawPtr::NOTNULL &&
+                         adr->in(AddPNode::Address)->is_Proj() &&
+                         adr->in(AddPNode::Address)->in(0)->is_Allocate())) {
+        // Point Address to Value
+        PointsToNode* adr_ptn = ptnode_adr(adr->_idx);
+        assert(adr_ptn != NULL &&
+               adr_ptn->as_Field()->is_oop(), "node should be registered");
+        Node *val = n->in(MemNode::ValueIn);
+        PointsToNode* ptn = ptnode_adr(val->_idx);
+        assert(ptn != NULL, "node should be registered");
+        add_edge(adr_ptn, ptn);
+        break;
+      } else if ((opcode == Op_StoreP) && (adr_type == TypeRawPtr::BOTTOM)) {
+        // Stored value escapes in unsafe access.
+        Node *val = n->in(MemNode::ValueIn);
+        PointsToNode* ptn = ptnode_adr(val->_idx);
+        assert(ptn != NULL, "node should be registered");
+        ptn->set_escape_state(PointsToNode::GlobalEscape);
+        // Add edge to object for unsafe access with offset.
+        PointsToNode* adr_ptn = ptnode_adr(adr->_idx);
+        assert(adr_ptn != NULL, "node should be registered");
+        if (adr_ptn->is_Field()) {
+          assert(adr_ptn->as_Field()->is_oop(), "should be oop field");
+          add_edge(adr_ptn, ptn);
+        }
+        break;
+      }
+      ELSE_FAIL("Op_StoreP");
+    }
+    case Op_AryEq:
+    case Op_StrComp:
+    case Op_StrEquals:
+    case Op_StrIndexOf: {
+      // char[] arrays passed to string intrinsic do not escape but
+      // they are not scalar replaceable. Adjust escape state for them.
+      // Start from in(2) edge since in(1) is memory edge.
+      for (uint i = 2; i < n->req(); i++) {
+        Node* adr = n->in(i);
+        const Type* at = _igvn->type(adr);
+        if (!adr->is_top() && at->isa_ptr()) {
+          assert(at == Type::TOP || at == TypePtr::NULL_PTR ||
+                 at->isa_ptr() != NULL, "expecting a pointer");
+          if (adr->is_AddP()) {
+            adr = get_addp_base(adr);
+          }
+          PointsToNode* ptn = ptnode_adr(adr->_idx);
+          assert(ptn != NULL, "node should be registered");
+          add_edge(n_ptn, ptn);
+        }
+      }
+      break;
+    }
+    default: {
+      // This method should be called only for EA specific nodes which may
+      // miss some edges when they were created.
+#ifdef ASSERT
+      n->dump(1);
+#endif
+      guarantee(false, "unknown node");
+    }
+  }
+  return;
+}
+
+void ConnectionGraph::add_call_node(CallNode* call) {
+  assert(call->returns_pointer(), "only for call which returns pointer");
+  uint call_idx = call->_idx;
+  if (call->is_Allocate()) {
+    Node* k = call->in(AllocateNode::KlassNode);
+    const TypeKlassPtr* kt = k->bottom_type()->isa_klassptr();
+    assert(kt != NULL, "TypeKlassPtr  required.");
+    ciKlass* cik = kt->klass();
+    PointsToNode::EscapeState es = PointsToNode::NoEscape;
+    bool scalar_replaceable = true;
+    if (call->is_AllocateArray()) {
+      if (!cik->is_array_klass()) { // StressReflectiveCode
+        es = PointsToNode::GlobalEscape;
+      } else {
+        int length = call->in(AllocateNode::ALength)->find_int_con(-1);
+        if (length < 0 || length > EliminateAllocationArraySizeLimit) {
+          // Not scalar replaceable if the length is not constant or too big.
+          scalar_replaceable = false;
+        }
+      }
+    } else {  // Allocate instance
+      if (cik->is_subclass_of(_compile->env()->Thread_klass()) ||
+         !cik->is_instance_klass() || // StressReflectiveCode
+          cik->as_instance_klass()->has_finalizer()) {
+        es = PointsToNode::GlobalEscape;
+      }
+    }
+    add_java_object(call, es);
+    PointsToNode* ptn = ptnode_adr(call_idx);
+    if (!scalar_replaceable && ptn->scalar_replaceable()) {
+      ptn->set_scalar_replaceable(false);
+    }
+  } else if (call->is_CallStaticJava()) {
+    // Call nodes could be different types:
+    //
+    // 1. CallDynamicJavaNode (what happened during call is unknown):
+    //
+    //    - mapped to GlobalEscape JavaObject node if oop is returned;
+    //
+    //    - all oop arguments are escaping globally;
+    //
+    // 2. CallStaticJavaNode (execute bytecode analysis if possible):
+    //
+    //    - the same as CallDynamicJavaNode if can't do bytecode analysis;
+    //
+    //    - mapped to GlobalEscape JavaObject node if unknown oop is returned;
+    //    - mapped to NoEscape JavaObject node if non-escaping object allocated
+    //      during call is returned;
+    //    - mapped to ArgEscape LocalVar node pointed to object arguments
+    //      which are returned and does not escape during call;
+    //
+    //    - oop arguments escaping status is defined by bytecode analysis;
+    //
+    // For a static call, we know exactly what method is being called.
+    // Use bytecode estimator to record whether the call's return value escapes.
+    ciMethod* meth = call->as_CallJava()->method();
+    if (meth == NULL) {
+      const char* name = call->as_CallStaticJava()->_name;
+      assert(strncmp(name, "_multianewarray", 15) == 0, "TODO: add failed case check");
+      // Returns a newly allocated unescaped object.
+      add_java_object(call, PointsToNode::NoEscape);
+      ptnode_adr(call_idx)->set_scalar_replaceable(false);
     } else {
-      f->set_has_unknown_ptr();
+      BCEscapeAnalyzer* call_analyzer = meth->get_bcea();
+      call_analyzer->copy_dependencies(_compile->dependencies());
+      if (call_analyzer->is_return_allocated()) {
+        // Returns a newly allocated unescaped object, simply
+        // update dependency information.
+        // Mark it as NoEscape so that objects referenced by
+        // it's fields will be marked as NoEscape at least.
+        add_java_object(call, PointsToNode::NoEscape);
+        ptnode_adr(call_idx)->set_scalar_replaceable(false);
+      } else {
+        // Determine whether any arguments are returned.
+        const TypeTuple* d = call->tf()->domain();
+        bool ret_arg = false;
+        for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
+          if (d->field_at(i)->isa_ptr() != NULL &&
+              call_analyzer->is_arg_returned(i - TypeFunc::Parms)) {
+            ret_arg = true;
+            break;
+          }
+        }
+        if (ret_arg) {
+          add_local_var(call, PointsToNode::ArgEscape);
+        } else {
+          // Returns unknown object.
+          map_ideal_node(call, phantom_obj);
+        }
+      }
+    }
+  } else {
+    // An other type of call, assume the worst case:
+    // returned value is unknown and globally escapes.
+    assert(call->Opcode() == Op_CallDynamicJava, "add failed case check");
+    map_ideal_node(call, phantom_obj);
+  }
+}
+
+void ConnectionGraph::process_call_arguments(CallNode *call) {
+    bool is_arraycopy = false;
+    switch (call->Opcode()) {
+#ifdef ASSERT
+    case Op_Allocate:
+    case Op_AllocateArray:
+    case Op_Lock:
+    case Op_Unlock:
+      assert(false, "should be done already");
+      break;
+#endif
+    case Op_CallLeafNoFP:
+      is_arraycopy = (call->as_CallLeaf()->_name != NULL &&
+                      strstr(call->as_CallLeaf()->_name, "arraycopy") != 0);
+      // fall through
+    case Op_CallLeaf: {
+      // Stub calls, objects do not escape but they are not scale replaceable.
+      // Adjust escape state for outgoing arguments.
+      const TypeTuple * d = call->tf()->domain();
+      bool src_has_oops = false;
+      for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
+        const Type* at = d->field_at(i);
+        Node *arg = call->in(i);
+        const Type *aat = _igvn->type(arg);
+        if (arg->is_top() || !at->isa_ptr() || !aat->isa_ptr())
+          continue;
+        if (arg->is_AddP()) {
+          //
+          // The inline_native_clone() case when the arraycopy stub is called
+          // after the allocation before Initialize and CheckCastPP nodes.
+          // Or normal arraycopy for object arrays case.
+          //
+          // Set AddP's base (Allocate) as not scalar replaceable since
+          // pointer to the base (with offset) is passed as argument.
+          //
+          arg = get_addp_base(arg);
+        }
+        PointsToNode* arg_ptn = ptnode_adr(arg->_idx);
+        assert(arg_ptn != NULL, "should be registered");
+        PointsToNode::EscapeState arg_esc = arg_ptn->escape_state();
+        if (is_arraycopy || arg_esc < PointsToNode::ArgEscape) {
+          assert(aat == Type::TOP || aat == TypePtr::NULL_PTR ||
+                 aat->isa_ptr() != NULL, "expecting an Ptr");
+          bool arg_has_oops = aat->isa_oopptr() &&
+                              (aat->isa_oopptr()->klass() == NULL || aat->isa_instptr() ||
+                               (aat->isa_aryptr() && aat->isa_aryptr()->klass()->is_obj_array_klass()));
+          if (i == TypeFunc::Parms) {
+            src_has_oops = arg_has_oops;
+          }
+          //
+          // src or dst could be j.l.Object when other is basic type array:
+          //
+          //   arraycopy(char[],0,Object*,0,size);
+          //   arraycopy(Object*,0,char[],0,size);
+          //
+          // Don't add edges in such cases.
+          //
+          bool arg_is_arraycopy_dest = src_has_oops && is_arraycopy &&
+                                       arg_has_oops && (i > TypeFunc::Parms);
+#ifdef ASSERT
+          if (!(is_arraycopy ||
+                call->as_CallLeaf()->_name != NULL &&
+                (strcmp(call->as_CallLeaf()->_name, "g1_wb_pre")  == 0 ||
+                 strcmp(call->as_CallLeaf()->_name, "g1_wb_post") == 0 ))
+          ) {
+            call->dump();
+            assert(false, "EA: unexpected CallLeaf");
+          }
+#endif
+          // Always process arraycopy's destination object since
+          // we need to add all possible edges to references in
+          // source object.
+          if (arg_esc >= PointsToNode::ArgEscape &&
+              !arg_is_arraycopy_dest) {
+            continue;
+          }
+          set_escape_state(arg_ptn, PointsToNode::ArgEscape);
+          if (arg_is_arraycopy_dest) {
+            Node* src = call->in(TypeFunc::Parms);
+            if (src->is_AddP()) {
+              src = get_addp_base(src);
+            }
+            PointsToNode* src_ptn = ptnode_adr(src->_idx);
+            assert(src_ptn != NULL, "should be registered");
+            if (arg_ptn != src_ptn) {
+              // Special arraycopy edge:
+              // A destination object's field can't have the source object
+              // as base since objects escape states are not related.
+              // Only escape state of destination object's fields affects
+              // escape state of fields in source object.
+              add_arraycopy(call, PointsToNode::ArgEscape, src_ptn, arg_ptn);
+            }
+          }
+        }
+      }
+      break;
+    }
+    case Op_CallStaticJava: {
+      // For a static call, we know exactly what method is being called.
+      // Use bytecode estimator to record the call's escape affects
+#ifdef ASSERT
+      const char* name = call->as_CallStaticJava()->_name;
+      assert((name == NULL || strcmp(name, "uncommon_trap") != 0), "normal calls only");
+#endif
+      ciMethod* meth = call->as_CallJava()->method();
+      BCEscapeAnalyzer* call_analyzer = (meth !=NULL) ? meth->get_bcea() : NULL;
+      // fall-through if not a Java method or no analyzer information
+      if (call_analyzer != NULL) {
+        PointsToNode* call_ptn = ptnode_adr(call->_idx);
+        const TypeTuple* d = call->tf()->domain();
+        for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
+          const Type* at = d->field_at(i);
+          int k = i - TypeFunc::Parms;
+          Node* arg = call->in(i);
+          PointsToNode* arg_ptn = ptnode_adr(arg->_idx);
+          if (at->isa_ptr() != NULL &&
+              call_analyzer->is_arg_returned(k)) {
+            // The call returns arguments.
+            if (call_ptn != NULL) { // Is call's result used?
+              assert(call_ptn->is_LocalVar(), "node should be registered");
+              assert(arg_ptn != NULL, "node should be registered");
+              add_edge(call_ptn, arg_ptn);
+            }
+          }
+          if (at->isa_oopptr() != NULL &&
+              arg_ptn->escape_state() < PointsToNode::GlobalEscape) {
+            if (!call_analyzer->is_arg_stack(k)) {
+              // The argument global escapes
+              set_escape_state(arg_ptn, PointsToNode::GlobalEscape);
+            } else {
+              set_escape_state(arg_ptn, PointsToNode::ArgEscape);
+              if (!call_analyzer->is_arg_local(k)) {
+                // The argument itself doesn't escape, but any fields might
+                set_fields_escape_state(arg_ptn, PointsToNode::GlobalEscape);
+              }
+            }
+          }
+        }
+        if (call_ptn != NULL && call_ptn->is_LocalVar()) {
+          // The call returns arguments.
+          assert(call_ptn->edge_count() > 0, "sanity");
+          if (!call_analyzer->is_return_local()) {
+            // Returns also unknown object.
+            add_edge(call_ptn, phantom_obj);
+          }
+        }
+        break;
+      }
+    }
+    default: {
+      // Fall-through here if not a Java method or no analyzer information
+      // or some other type of call, assume the worst case: all arguments
+      // globally escape.
+      const TypeTuple* d = call->tf()->domain();
+      for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
+        const Type* at = d->field_at(i);
+        if (at->isa_oopptr() != NULL) {
+          Node* arg = call->in(i);
+          if (arg->is_AddP()) {
+            arg = get_addp_base(arg);
+          }
+          assert(ptnode_adr(arg->_idx) != NULL, "should be defined already");
+          set_escape_state(ptnode_adr(arg->_idx), PointsToNode::GlobalEscape);
+        }
+      }
     }
   }
-  add_edge(f, to_i, PointsToNode::PointsToEdge);
+}
+
+
+// Finish Graph construction.
+bool ConnectionGraph::complete_connection_graph(
+                         GrowableArray<PointsToNode*>&   ptnodes_worklist,
+                         GrowableArray<JavaObjectNode*>& non_escaped_worklist,
+                         GrowableArray<JavaObjectNode*>& java_objects_worklist,
+                         GrowableArray<FieldNode*>&      oop_fields_worklist) {
+  // Normally only 1-3 passes needed to build Connection Graph depending
+  // on graph complexity. Observed 8 passes in jvm2008 compiler.compiler.
+  // Set limit to 20 to catch situation when something did go wrong and
+  // bailout Escape Analysis.
+  // Also limit build time to 30 sec (60 in debug VM).
+#define CG_BUILD_ITER_LIMIT 20
+#ifdef ASSERT
+#define CG_BUILD_TIME_LIMIT 60.0
+#else
+#define CG_BUILD_TIME_LIMIT 30.0
+#endif
+
+  // Propagate GlobalEscape and ArgEscape escape states and check that
+  // we still have non-escaping objects. The method pushs on _worklist
+  // Field nodes which reference phantom_object.
+  if (!find_non_escaped_objects(ptnodes_worklist, non_escaped_worklist)) {
+    return false; // Nothing to do.
+  }
+  // Now propagate references to all JavaObject nodes.
+  int java_objects_length = java_objects_worklist.length();
+  elapsedTimer time;
+  int new_edges = 1;
+  int iterations = 0;
+  do {
+    while ((new_edges > 0) &&
+          (iterations++   < CG_BUILD_ITER_LIMIT) &&
+          (time.seconds() < CG_BUILD_TIME_LIMIT)) {
+      time.start();
+      new_edges = 0;
+      // Propagate references to phantom_object for nodes pushed on _worklist
+      // by find_non_escaped_objects() and find_field_value().
+      new_edges += add_java_object_edges(phantom_obj, false);
+      for (int next = 0; next < java_objects_length; ++next) {
+        JavaObjectNode* ptn = java_objects_worklist.at(next);
+        new_edges += add_java_object_edges(ptn, true);
+      }
+      if (new_edges > 0) {
+        // Update escape states on each iteration if graph was updated.
+        if (!find_non_escaped_objects(ptnodes_worklist, non_escaped_worklist)) {
+          return false; // Nothing to do.
+        }
+      }
+      time.stop();
+    }
+    if ((iterations     < CG_BUILD_ITER_LIMIT) &&
+        (time.seconds() < CG_BUILD_TIME_LIMIT)) {
+      time.start();
+      // Find fields which have unknown value.
+      int fields_length = oop_fields_worklist.length();
+      for (int next = 0; next < fields_length; next++) {
+        FieldNode* field = oop_fields_worklist.at(next);
+        if (field->edge_count() == 0) {
+          new_edges += find_field_value(field);
+          // This code may added new edges to phantom_object.
+          // Need an other cycle to propagate references to phantom_object.
+        }
+      }
+      time.stop();
+    } else {
+      new_edges = 0; // Bailout
+    }
+  } while (new_edges > 0);
+
+  // Bailout if passed limits.
+  if ((iterations     >= CG_BUILD_ITER_LIMIT) ||
+      (time.seconds() >= CG_BUILD_TIME_LIMIT)) {
+    Compile* C = _compile;
+    if (C->log() != NULL) {
+      C->log()->begin_elem("connectionGraph_bailout reason='reached ");
+      C->log()->text("%s", (iterations >= CG_BUILD_ITER_LIMIT) ? "iterations" : "time");
+      C->log()->end_elem(" limit'");
+    }
+    assert(false, err_msg("infinite EA connection graph build (%f sec, %d iterations) with %d nodes and worklist size %d",
+           time.seconds(), iterations, nodes_size(), ptnodes_worklist.length()));
+    // Possible infinite build_connection_graph loop,
+    // bailout (no changes to ideal graph were made).
+    return false;
+  }
+#ifdef ASSERT
+  if (Verbose && PrintEscapeAnalysis) {
+    tty->print_cr("EA: %d iterations to build connection graph with %d nodes and worklist size %d",
+                  iterations, nodes_size(), ptnodes_worklist.length());
+  }
+#endif
+
+#undef CG_BUILD_ITER_LIMIT
+#undef CG_BUILD_TIME_LIMIT
+
+  // Find fields initialized by NULL for non-escaping Allocations.
+  int non_escaped_length = non_escaped_worklist.length();
+  for (int next = 0; next < non_escaped_length; next++) {
+    JavaObjectNode* ptn = non_escaped_worklist.at(next);
+    PointsToNode::EscapeState es = ptn->escape_state();
+    assert(es <= PointsToNode::ArgEscape, "sanity");
+    if (es == PointsToNode::NoEscape) {
+      if (find_init_values(ptn, null_obj, _igvn) > 0) {
+        // Adding references to NULL object does not change escape states
+        // since it does not escape. Also no fields are added to NULL object.
+        add_java_object_edges(null_obj, false);
+      }
+    }
+    Node* n = ptn->ideal_node();
+    if (n->is_Allocate()) {
+      // The object allocated by this Allocate node will never be
+      // seen by an other thread. Mark it so that when it is
+      // expanded no MemBarStoreStore is added.
+      InitializeNode* ini = n->as_Allocate()->initialization();
+      if (ini != NULL)
+        ini->set_does_not_escape();
+    }
+  }
+  return true; // Finished graph construction.
+}
+
+// Propagate GlobalEscape and ArgEscape escape states to all nodes
+// and check that we still have non-escaping java objects.
+bool ConnectionGraph::find_non_escaped_objects(GrowableArray<PointsToNode*>& ptnodes_worklist,
+                                               GrowableArray<JavaObjectNode*>& non_escaped_worklist) {
+  GrowableArray<PointsToNode*> escape_worklist;
+  // First, put all nodes with GlobalEscape and ArgEscape states on worklist.
+  int ptnodes_length = ptnodes_worklist.length();
+  for (int next = 0; next < ptnodes_length; ++next) {
+    PointsToNode* ptn = ptnodes_worklist.at(next);
+    if (ptn->escape_state() >= PointsToNode::ArgEscape ||
+        ptn->fields_escape_state() >= PointsToNode::ArgEscape) {
+      escape_worklist.push(ptn);
+    }
+  }
+  // Set escape states to referenced nodes (edges list).
+  while (escape_worklist.length() > 0) {
+    PointsToNode* ptn = escape_worklist.pop();
+    PointsToNode::EscapeState es  = ptn->escape_state();
+    PointsToNode::EscapeState field_es = ptn->fields_escape_state();
+    if (ptn->is_Field() && ptn->as_Field()->is_oop() &&
+        es >= PointsToNode::ArgEscape) {
+      // GlobalEscape or ArgEscape state of field means it has unknown value.
+      if (add_edge(ptn, phantom_obj)) {
+        // New edge was added
+        add_field_uses_to_worklist(ptn->as_Field());
+      }
+    }
+    for (EdgeIterator i(ptn); i.has_next(); i.next()) {
+      PointsToNode* e = i.get();
+      if (e->is_Arraycopy()) {
+        assert(ptn->arraycopy_dst(), "sanity");
+        // Propagate only fields escape state through arraycopy edge.
+        if (e->fields_escape_state() < field_es) {
+          set_fields_escape_state(e, field_es);
+          escape_worklist.push(e);
+        }
+      } else if (es >= field_es) {
+        // fields_escape_state is also set to 'es' if it is less than 'es'.
+        if (e->escape_state() < es) {
+          set_escape_state(e, es);
+          escape_worklist.push(e);
+        }
+      } else {
+        // Propagate field escape state.
+        bool es_changed = false;
+        if (e->fields_escape_state() < field_es) {
+          set_fields_escape_state(e, field_es);
+          es_changed = true;
+        }
+        if ((e->escape_state() < field_es) &&
+            e->is_Field() && ptn->is_JavaObject() &&
+            e->as_Field()->is_oop()) {
+          // Change escape state of referenced fileds.
+          set_escape_state(e, field_es);
+          es_changed = true;;
+        } else if (e->escape_state() < es) {
+          set_escape_state(e, es);
+          es_changed = true;;
+        }
+        if (es_changed) {
+          escape_worklist.push(e);
+        }
+      }
+    }
+  }
+  // Remove escaped objects from non_escaped list.
+  for (int next = non_escaped_worklist.length()-1; next >= 0 ; --next) {
+    JavaObjectNode* ptn = non_escaped_worklist.at(next);
+    if (ptn->escape_state() >= PointsToNode::GlobalEscape) {
+      non_escaped_worklist.delete_at(next);
+    }
+    if (ptn->escape_state() == PointsToNode::NoEscape) {
+      // Find fields in non-escaped allocations which have unknown value.
+      find_init_values(ptn, phantom_obj, NULL);
+    }
+  }
+  return (non_escaped_worklist.length() > 0);
+}
+
+// Add all references to JavaObject node by walking over all uses.
+int ConnectionGraph::add_java_object_edges(JavaObjectNode* jobj, bool populate_worklist) {
+  int new_edges = 0;
+  if (populate_worklist) {
+    // Populate _worklist by uses of jobj's uses.
+    for (UseIterator i(jobj); i.has_next(); i.next()) {
+      PointsToNode* use = i.get();
+      if (use->is_Arraycopy())
+        continue;
+      add_uses_to_worklist(use);
+      if (use->is_Field() && use->as_Field()->is_oop()) {
+        // Put on worklist all field's uses (loads) and
+        // related field nodes (same base and offset).
+        add_field_uses_to_worklist(use->as_Field());
+      }
+    }
+  }
+  while(_worklist.length() > 0) {
+    PointsToNode* use = _worklist.pop();
+    if (PointsToNode::is_base_use(use)) {
+      // Add reference from jobj to field and from field to jobj (field's base).
+      use = PointsToNode::get_use_node(use)->as_Field();
+      if (add_base(use->as_Field(), jobj)) {
+        new_edges++;
+      }
+      continue;
+    }
+    assert(!use->is_JavaObject(), "sanity");
+    if (use->is_Arraycopy()) {
+      if (jobj == null_obj) // NULL object does not have field edges
+        continue;
+      // Added edge from Arraycopy node to arraycopy's source java object
+      if (add_edge(use, jobj)) {
+        jobj->set_arraycopy_src();
+        new_edges++;
+      }
+      // and stop here.
+      continue;
+    }
+    if (!add_edge(use, jobj))
+      continue; // No new edge added, there was such edge already.
+    new_edges++;
+    if (use->is_LocalVar()) {
+      add_uses_to_worklist(use);
+      if (use->arraycopy_dst()) {
+        for (EdgeIterator i(use); i.has_next(); i.next()) {
+          PointsToNode* e = i.get();
+          if (e->is_Arraycopy()) {
+            if (jobj == null_obj) // NULL object does not have field edges
+              continue;
+            // Add edge from arraycopy's destination java object to Arraycopy node.
+            if (add_edge(jobj, e)) {
+              new_edges++;
+              jobj->set_arraycopy_dst();
+            }
+          }
+        }
+      }
+    } else {
+      // Added new edge to stored in field values.
+      // Put on worklist all field's uses (loads) and
+      // related field nodes (same base and offset).
+      add_field_uses_to_worklist(use->as_Field());
+    }
+  }
+  return new_edges;
+}
+
+// Put on worklist all related field nodes.
+void ConnectionGraph::add_field_uses_to_worklist(FieldNode* field) {
+  assert(field->is_oop(), "sanity");
+  int offset = field->offset();
+  add_uses_to_worklist(field);
+  // Loop over all bases of this field and push on worklist Field nodes
+  // with the same offset and base (since they may reference the same field).
+  for (BaseIterator i(field); i.has_next(); i.next()) {
+    PointsToNode* base = i.get();
+    add_fields_to_worklist(field, base);
+    // Check if the base was source object of arraycopy and go over arraycopy's
+    // destination objects since values stored to a field of source object are
+    // accessable by uses (loads) of fields of destination objects.
+    if (base->arraycopy_src()) {
+      for (UseIterator j(base); j.has_next(); j.next()) {
+        PointsToNode* arycp = j.get();
+        if (arycp->is_Arraycopy()) {
+          for (UseIterator k(arycp); k.has_next(); k.next()) {
+            PointsToNode* abase = k.get();
+            if (abase->arraycopy_dst() && abase != base) {
+              // Look for the same arracopy reference.
+              add_fields_to_worklist(field, abase);
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+// Put on worklist all related field nodes.
+void ConnectionGraph::add_fields_to_worklist(FieldNode* field, PointsToNode* base) {
+  int offset = field->offset();
+  if (base->is_LocalVar()) {
+    for (UseIterator j(base); j.has_next(); j.next()) {
+      PointsToNode* f = j.get();
+      if (PointsToNode::is_base_use(f)) { // Field
+        f = PointsToNode::get_use_node(f);
+        if (f == field || !f->as_Field()->is_oop())
+          continue;
+        int offs = f->as_Field()->offset();
+        if (offs == offset || offset == Type::OffsetBot || offs == Type::OffsetBot) {
+          add_to_worklist(f);
+        }
+      }
+    }
+  } else {
+    assert(base->is_JavaObject(), "sanity");
+    if (// Skip phantom_object since it is only used to indicate that
+        // this field's content globally escapes.
+        (base != phantom_obj) &&
+        // NULL object node does not have fields.
+        (base != null_obj)) {
+      for (EdgeIterator i(base); i.has_next(); i.next()) {
+        PointsToNode* f = i.get();
+        // Skip arraycopy edge since store to destination object field
+        // does not update value in source object field.
+        if (f->is_Arraycopy()) {
+          assert(base->arraycopy_dst(), "sanity");
+          continue;
+        }
+        if (f == field || !f->as_Field()->is_oop())
+          continue;
+        int offs = f->as_Field()->offset();
+        if (offs == offset || offset == Type::OffsetBot || offs == Type::OffsetBot) {
+          add_to_worklist(f);
+        }
+      }
+    }
+  }
+}
+
+// Find fields which have unknown value.
+int ConnectionGraph::find_field_value(FieldNode* field) {
+  // Escaped fields should have init value already.
+  assert(field->escape_state() == PointsToNode::NoEscape, "sanity");
+  int new_edges = 0;
+  for (BaseIterator i(field); i.has_next(); i.next()) {
+    PointsToNode* base = i.get();
+    if (base->is_JavaObject()) {
+      // Skip Allocate's fields which will be processed later.
+      if (base->ideal_node()->is_Allocate())
+        return 0;
+      assert(base == null_obj, "only NULL ptr base expected here");
+    }
+  }
+  if (add_edge(field, phantom_obj)) {
+    // New edge was added
+    new_edges++;
+    add_field_uses_to_worklist(field);
+  }
+  return new_edges;
+}
+
+// Find fields initializing values for allocations.
+int ConnectionGraph::find_init_values(JavaObjectNode* pta, PointsToNode* init_val, PhaseTransform* phase) {
+  assert(pta->escape_state() == PointsToNode::NoEscape, "Not escaped Allocate nodes only");
+  int new_edges = 0;
+  Node* alloc = pta->ideal_node();
+  if (init_val == phantom_obj) {
+    // Do nothing for Allocate nodes since its fields values are "known".
+    if (alloc->is_Allocate())
+      return 0;
+    assert(alloc->as_CallStaticJava(), "sanity");
+#ifdef ASSERT
+    if (alloc->as_CallStaticJava()->method() == NULL) {
+      const char* name = alloc->as_CallStaticJava()->_name;
+      assert(strncmp(name, "_multianewarray", 15) == 0, "sanity");
+    }
+#endif
+    // Non-escaped allocation returned from Java or runtime call have
+    // unknown values in fields.
+    for (EdgeIterator i(pta); i.has_next(); i.next()) {
+      PointsToNode* ptn = i.get();
+      if (ptn->is_Field() && ptn->as_Field()->is_oop()) {
+        if (add_edge(ptn, phantom_obj)) {
+          // New edge was added
+          new_edges++;
+          add_field_uses_to_worklist(ptn->as_Field());
+        }
+      }
+    }
+    return new_edges;
+  }
+  assert(init_val == null_obj, "sanity");
+  // Do nothing for Call nodes since its fields values are unknown.
+  if (!alloc->is_Allocate())
+    return 0;
+
+  InitializeNode* ini = alloc->as_Allocate()->initialization();
+  Compile* C = _compile;
+  bool visited_bottom_offset = false;
+  GrowableArray<int> offsets_worklist;
+
+  // Check if an oop field's initializing value is recorded and add
+  // a corresponding NULL if field's value if it is not recorded.
+  // Connection Graph does not record a default initialization by NULL
+  // captured by Initialize node.
+  //
+  for (EdgeIterator i(pta); i.has_next(); i.next()) {
+    PointsToNode* ptn = i.get(); // Field (AddP)
+    if (!ptn->is_Field() || !ptn->as_Field()->is_oop())
+      continue; // Not oop field
+    int offset = ptn->as_Field()->offset();
+    if (offset == Type::OffsetBot) {
+      if (!visited_bottom_offset) {
+        // OffsetBot is used to reference array's element,
+        // always add reference to NULL to all Field nodes since we don't
+        // known which element is referenced.
+        if (add_edge(ptn, null_obj)) {
+          // New edge was added
+          new_edges++;
+          add_field_uses_to_worklist(ptn->as_Field());
+          visited_bottom_offset = true;
+        }
+      }
+    } else {
+      // Check only oop fields.
+      const Type* adr_type = ptn->ideal_node()->as_AddP()->bottom_type();
+      if (adr_type->isa_rawptr()) {
+#ifdef ASSERT
+        // Raw pointers are used for initializing stores so skip it
+        // since it should be recorded already
+        Node* base = get_addp_base(ptn->ideal_node());
+        assert(adr_type->isa_rawptr() && base->is_Proj() &&
+               (base->in(0) == alloc),"unexpected pointer type");
+#endif
+        continue;
+      }
+      if (!offsets_worklist.contains(offset)) {
+        offsets_worklist.append(offset);
+        Node* value = NULL;
+        if (ini != NULL) {
+          BasicType ft = UseCompressedOops ? T_NARROWOOP : T_OBJECT;
+          Node* store = ini->find_captured_store(offset, type2aelembytes(ft), phase);
+          if (store != NULL && store->is_Store()) {
+            value = store->in(MemNode::ValueIn);
+          } else {
+            // There could be initializing stores which follow allocation.
+            // For example, a volatile field store is not collected
+            // by Initialize node.
+            //
+            // Need to check for dependent loads to separate such stores from
+            // stores which follow loads. For now, add initial value NULL so
+            // that compare pointers optimization works correctly.
+          }
+        }
+        if (value == NULL) {
+          // A field's initializing value was not recorded. Add NULL.
+          if (add_edge(ptn, null_obj)) {
+            // New edge was added
+            new_edges++;
+            add_field_uses_to_worklist(ptn->as_Field());
+          }
+        }
+      }
+    }
+  }
+  return new_edges;
 }
 
-void ConnectionGraph::add_deferred_edge(uint from_i, uint to_i) {
-  PointsToNode *f = ptnode_adr(from_i);
-  PointsToNode *t = ptnode_adr(to_i);
+// Adjust scalar_replaceable state after Connection Graph is built.
+void ConnectionGraph::adjust_scalar_replaceable_state(JavaObjectNode* jobj) {
+  // Search for non-escaping objects which are not scalar replaceable
+  // and mark them to propagate the state to referenced objects.
+
+  // 1. An object is not scalar replaceable if the field into which it is
+  // stored has unknown offset (stored into unknown element of an array).
+  //
+  for (UseIterator i(jobj); i.has_next(); i.next()) {
+    PointsToNode* use = i.get();
+    assert(!use->is_Arraycopy(), "sanity");
+    if (use->is_Field()) {
+      FieldNode* field = use->as_Field();
+      assert(field->is_oop() && field->scalar_replaceable() &&
+             field->fields_escape_state() == PointsToNode::NoEscape, "sanity");
+      if (field->offset() == Type::OffsetBot) {
+        jobj->set_scalar_replaceable(false);
+        return;
+      }
+    }
+    assert(use->is_Field() || use->is_LocalVar(), "sanity");
+    // 2. An object is not scalar replaceable if it is merged with other objects.
+    for (EdgeIterator j(use); j.has_next(); j.next()) {
+      PointsToNode* ptn = j.get();
+      if (ptn->is_JavaObject() && ptn != jobj) {
+        // Mark all objects.
+        jobj->set_scalar_replaceable(false);
+         ptn->set_scalar_replaceable(false);
+      }
+    }
+    if (!jobj->scalar_replaceable()) {
+      return;
+    }
+  }
+
+  for (EdgeIterator j(jobj); j.has_next(); j.next()) {
+    // Non-escaping object node should point only to field nodes.
+    FieldNode* field = j.get()->as_Field();
+    int offset = field->as_Field()->offset();
+
+    // 3. An object is not scalar replaceable if it has a field with unknown
+    // offset (array's element is accessed in loop).
+    if (offset == Type::OffsetBot) {
+      jobj->set_scalar_replaceable(false);
+      return;
+    }
+    // 4. Currently an object is not scalar replaceable if a LoadStore node
+    // access its field since the field value is unknown after it.
+    //
+    Node* n = field->ideal_node();
+    for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
+      if (n->fast_out(i)->is_LoadStore()) {
+        jobj->set_scalar_replaceable(false);
+        return;
+      }
+    }
+
+    // 5. Or the address may point to more then one object. This may produce
+    // the false positive result (set not scalar replaceable)
+    // since the flow-insensitive escape analysis can't separate
+    // the case when stores overwrite the field's value from the case
+    // when stores happened on different control branches.
+    //
+    // Note: it will disable scalar replacement in some cases:
+    //
+    //    Point p[] = new Point[1];
+    //    p[0] = new Point(); // Will be not scalar replaced
+    //
+    // but it will save us from incorrect optimizations in next cases:
+    //
+    //    Point p[] = new Point[1];
+    //    if ( x ) p[0] = new Point(); // Will be not scalar replaced
+    //
+    if (field->base_count() > 1) {
+      for (BaseIterator i(field); i.has_next(); i.next()) {
+        PointsToNode* base = i.get();
+        // Don't take into account LocalVar nodes which
+        // may point to only one object which should be also
+        // this field's base by now.
+        if (base->is_JavaObject() && base != jobj) {
+          // Mark all bases.
+          jobj->set_scalar_replaceable(false);
+          base->set_scalar_replaceable(false);
+        }
+      }
+    }
+  }
+}
+
+#ifdef ASSERT
+void ConnectionGraph::verify_connection_graph(
+                         GrowableArray<PointsToNode*>&   ptnodes_worklist,
+                         GrowableArray<JavaObjectNode*>& non_escaped_worklist,
+                         GrowableArray<JavaObjectNode*>& java_objects_worklist,
+                         GrowableArray<Node*>& addp_worklist) {
+  // Verify that graph is complete - no new edges could be added.
+  int java_objects_length = java_objects_worklist.length();
+  int non_escaped_length  = non_escaped_worklist.length();
+  int new_edges = 0;
+  for (int next = 0; next < java_objects_length; ++next) {
+    JavaObjectNode* ptn = java_objects_worklist.at(next);
+    new_edges += add_java_object_edges(ptn, true);
+  }
+  assert(new_edges == 0, "graph was not complete");
+  // Verify that escape state is final.
+  int length = non_escaped_worklist.length();
+  find_non_escaped_objects(ptnodes_worklist, non_escaped_worklist);
+  assert((non_escaped_length == non_escaped_worklist.length()) &&
+         (non_escaped_length == length) &&
+         (_worklist.length() == 0), "escape state was not final");
+
+  // Verify fields information.
+  int addp_length = addp_worklist.length();
+  for (int next = 0; next < addp_length; ++next ) {
+    Node* n = addp_worklist.at(next);
+    FieldNode* field = ptnode_adr(n->_idx)->as_Field();
+    if (field->is_oop()) {
+      // Verify that field has all bases
+      Node* base = get_addp_base(n);
+      PointsToNode* ptn = ptnode_adr(base->_idx);
+      if (ptn->is_JavaObject()) {
+        assert(field->has_base(ptn->as_JavaObject()), "sanity");
+      } else {
+        assert(ptn->is_LocalVar(), "sanity");
+        for (EdgeIterator i(ptn); i.has_next(); i.next()) {
+          PointsToNode* e = i.get();
+          if (e->is_JavaObject()) {
+            assert(field->has_base(e->as_JavaObject()), "sanity");
+          }
+        }
+      }
+      // Verify that all fields have initializing values.
+      if (field->edge_count() == 0) {
+        field->dump();
+        assert(field->edge_count() > 0, "sanity");
+      }
+    }
+  }
+}
+#endif
+
+// Optimize ideal graph.
+void ConnectionGraph::optimize_ideal_graph(GrowableArray<Node*>& ptr_cmp_worklist,
+                                           GrowableArray<Node*>& storestore_worklist) {
+  Compile* C = _compile;
+  PhaseIterGVN* igvn = _igvn;
+  if (EliminateLocks) {
+    // Mark locks before changing ideal graph.
+    int cnt = C->macro_count();
+    for( int i=0; i < cnt; i++ ) {
+      Node *n = C->macro_node(i);
+      if (n->is_AbstractLock()) { // Lock and Unlock nodes
+        AbstractLockNode* alock = n->as_AbstractLock();
+        if (!alock->is_non_esc_obj()) {
+          if (not_global_escape(alock->obj_node())) {
+            assert(!alock->is_eliminated() || alock->is_coarsened(), "sanity");
+            // The lock could be marked eliminated by lock coarsening
+            // code during first IGVN before EA. Replace coarsened flag
+            // to eliminate all associated locks/unlocks.
+            alock->set_non_esc_obj();
+          }
+        }
+      }
+    }
+  }
+
+  if (OptimizePtrCompare) {
+    // Add ConI(#CC_GT) and ConI(#CC_EQ).
+    _pcmp_neq = igvn->makecon(TypeInt::CC_GT);
+    _pcmp_eq = igvn->makecon(TypeInt::CC_EQ);
+    // Optimize objects compare.
+    while (ptr_cmp_worklist.length() != 0) {
+      Node *n = ptr_cmp_worklist.pop();
+      Node *res = optimize_ptr_compare(n);
+      if (res != NULL) {
+#ifndef PRODUCT
+        if (PrintOptimizePtrCompare) {
+          tty->print_cr("++++ Replaced: %d %s(%d,%d) --> %s", n->_idx, (n->Opcode() == Op_CmpP ? "CmpP" : "CmpN"), n->in(1)->_idx, n->in(2)->_idx, (res == _pcmp_eq ? "EQ" : "NotEQ"));
+          if (Verbose) {
+            n->dump(1);
+          }
+        }
+#endif
+        igvn->replace_node(n, res);
+      }
+    }
+    // cleanup
+    if (_pcmp_neq->outcnt() == 0)
+      igvn->hash_delete(_pcmp_neq);
+    if (_pcmp_eq->outcnt()  == 0)
+      igvn->hash_delete(_pcmp_eq);
+  }
+
+  // For MemBarStoreStore nodes added in library_call.cpp, check
+  // escape status of associated AllocateNode and optimize out
+  // MemBarStoreStore node if the allocated object never escapes.
+  while (storestore_worklist.length() != 0) {
+    Node *n = storestore_worklist.pop();
+    MemBarStoreStoreNode *storestore = n ->as_MemBarStoreStore();
+    Node *alloc = storestore->in(MemBarNode::Precedent)->in(0);
+    assert (alloc->is_Allocate(), "storestore should point to AllocateNode");
+    if (not_global_escape(alloc)) {
+      MemBarNode* mb = MemBarNode::make(C, Op_MemBarCPUOrder, Compile::AliasIdxBot);
+      mb->init_req(TypeFunc::Memory, storestore->in(TypeFunc::Memory));
+      mb->init_req(TypeFunc::Control, storestore->in(TypeFunc::Control));
+      igvn->register_new_node_with_optimizer(mb);
+      igvn->replace_node(storestore, mb);
+    }
+  }
+}
+
+// Optimize objects compare.
+Node* ConnectionGraph::optimize_ptr_compare(Node* n) {
+  assert(OptimizePtrCompare, "sanity");
+  PointsToNode* ptn1 = ptnode_adr(n->in(1)->_idx);
+  PointsToNode* ptn2 = ptnode_adr(n->in(2)->_idx);
+  JavaObjectNode* jobj1 = unique_java_object(n->in(1));
+  JavaObjectNode* jobj2 = unique_java_object(n->in(2));
+  assert(ptn1->is_JavaObject() || ptn1->is_LocalVar(), "sanity");
+  assert(ptn2->is_JavaObject() || ptn2->is_LocalVar(), "sanity");
 
-  assert(f->node_type() != PointsToNode::UnknownType && t->node_type() != PointsToNode::UnknownType, "node types must be set");
-  assert(f->node_type() == PointsToNode::LocalVar || f->node_type() == PointsToNode::Field, "invalid source of Deferred edge");
-  assert(t->node_type() == PointsToNode::LocalVar || t->node_type() == PointsToNode::Field, "invalid destination of Deferred edge");
-  // don't add a self-referential edge, this can occur during removal of
-  // deferred edges
-  if (from_i != to_i)
-    add_edge(f, to_i, PointsToNode::DeferredEdge);
+  // Check simple cases first.
+  if (jobj1 != NULL) {
+    if (jobj1->escape_state() == PointsToNode::NoEscape) {
+      if (jobj1 == jobj2) {
+        // Comparing the same not escaping object.
+        return _pcmp_eq;
+      }
+      Node* obj = jobj1->ideal_node();
+      // Comparing not escaping allocation.
+      if ((obj->is_Allocate() || obj->is_CallStaticJava()) &&
+          !ptn2->points_to(jobj1)) {
+        return _pcmp_neq; // This includes nullness check.
+      }
+    }
+  }
+  if (jobj2 != NULL) {
+    if (jobj2->escape_state() == PointsToNode::NoEscape) {
+      Node* obj = jobj2->ideal_node();
+      // Comparing not escaping allocation.
+      if ((obj->is_Allocate() || obj->is_CallStaticJava()) &&
+          !ptn1->points_to(jobj2)) {
+        return _pcmp_neq; // This includes nullness check.
+      }
+    }
+  }
+  if (jobj1 != NULL && jobj1 != phantom_obj &&
+      jobj2 != NULL && jobj2 != phantom_obj &&
+      jobj1->ideal_node()->is_Con() &&
+      jobj2->ideal_node()->is_Con()) {
+    // Klass or String constants compare. Need to be careful with
+    // compressed pointers - compare types of ConN and ConP instead of nodes.
+    const Type* t1 = jobj1->ideal_node()->bottom_type()->make_ptr();
+    const Type* t2 = jobj2->ideal_node()->bottom_type()->make_ptr();
+    assert(t1 != NULL && t2 != NULL, "sanity");
+    if (t1->make_ptr() == t2->make_ptr()) {
+      return _pcmp_eq;
+    } else {
+      return _pcmp_neq;
+    }
+  }
+  if (ptn1->meet(ptn2)) {
+    return NULL; // Sets are not disjoint
+  }
+
+  // Sets are disjoint.
+  bool set1_has_unknown_ptr = ptn1->points_to(phantom_obj);
+  bool set2_has_unknown_ptr = ptn2->points_to(phantom_obj);
+  bool set1_has_null_ptr    = ptn1->points_to(null_obj);
+  bool set2_has_null_ptr    = ptn2->points_to(null_obj);
+  if (set1_has_unknown_ptr && set2_has_null_ptr ||
+      set2_has_unknown_ptr && set1_has_null_ptr) {
+    // Check nullness of unknown object.
+    return NULL;
+  }
+
+  // Disjointness by itself is not sufficient since
+  // alias analysis is not complete for escaped objects.
+  // Disjoint sets are definitely unrelated only when
+  // at least one set has only not escaping allocations.
+  if (!set1_has_unknown_ptr && !set1_has_null_ptr) {
+    if (ptn1->non_escaping_allocation()) {
+      return _pcmp_neq;
+    }
+  }
+  if (!set2_has_unknown_ptr && !set2_has_null_ptr) {
+    if (ptn2->non_escaping_allocation()) {
+      return _pcmp_neq;
+    }
+  }
+  return NULL;
+}
+
+// Connection Graph constuction functions.
+
+void ConnectionGraph::add_local_var(Node *n, PointsToNode::EscapeState es) {
+  PointsToNode* ptadr = _nodes.at(n->_idx);
+  if (ptadr != NULL) {
+    assert(ptadr->is_LocalVar() && ptadr->ideal_node() == n, "sanity");
+    return;
+  }
+  Compile* C = _compile;
+  ptadr = new (C->comp_arena()) LocalVarNode(C, n, es);
+  _nodes.at_put(n->_idx, ptadr);
+}
+
+void ConnectionGraph::add_java_object(Node *n, PointsToNode::EscapeState es) {
+  PointsToNode* ptadr = _nodes.at(n->_idx);
+  if (ptadr != NULL) {
+    assert(ptadr->is_JavaObject() && ptadr->ideal_node() == n, "sanity");
+    return;
+  }
+  Compile* C = _compile;
+  ptadr = new (C->comp_arena()) JavaObjectNode(C, n, es);
+  _nodes.at_put(n->_idx, ptadr);
+}
+
+void ConnectionGraph::add_field(Node *n, PointsToNode::EscapeState es, int offset) {
+  PointsToNode* ptadr = _nodes.at(n->_idx);
+  if (ptadr != NULL) {
+    assert(ptadr->is_Field() && ptadr->ideal_node() == n, "sanity");
+    return;
+  }
+  Compile* C = _compile;
+  bool is_oop = is_oop_field(n, offset);
+  FieldNode* field = new (C->comp_arena()) FieldNode(C, n, es, offset, is_oop);
+  _nodes.at_put(n->_idx, field);
+}
+
+void ConnectionGraph::add_arraycopy(Node *n, PointsToNode::EscapeState es,
+                                    PointsToNode* src, PointsToNode* dst) {
+  assert(!src->is_Field() && !dst->is_Field(), "only for JavaObject and LocalVar");
+  assert((src != null_obj) && (dst != null_obj), "not for ConP NULL");
+  PointsToNode* ptadr = _nodes.at(n->_idx);
+  if (ptadr != NULL) {
+    assert(ptadr->is_Arraycopy() && ptadr->ideal_node() == n, "sanity");
+    return;
+  }
+  Compile* C = _compile;
+  ptadr = new (C->comp_arena()) ArraycopyNode(C, n, es);
+  _nodes.at_put(n->_idx, ptadr);
+  // Add edge from arraycopy node to source object.
+  (void)add_edge(ptadr, src);
+  src->set_arraycopy_src();
+  // Add edge from destination object to arraycopy node.
+  (void)add_edge(dst, ptadr);
+  dst->set_arraycopy_dst();
 }
 
+bool ConnectionGraph::is_oop_field(Node* n, int offset) {
+  const Type* adr_type = n->as_AddP()->bottom_type();
+  BasicType bt = T_INT;
+  if (offset == Type::OffsetBot) {
+    // Check only oop fields.
+    if (!adr_type->isa_aryptr() ||
+        (adr_type->isa_aryptr()->klass() == NULL) ||
+         adr_type->isa_aryptr()->klass()->is_obj_array_klass()) {
+      // OffsetBot is used to reference array's element. Ignore first AddP.
+      if (find_second_addp(n, n->in(AddPNode::Base)) == NULL) {
+        bt = T_OBJECT;
+      }
+    }
+  } else if (offset != oopDesc::klass_offset_in_bytes()) {
+    if (adr_type->isa_instptr()) {
+      ciField* field = _compile->alias_type(adr_type->isa_instptr())->field();
+      if (field != NULL) {
+        bt = field->layout_type();
+      } else {
+        // Ignore non field load (for example, klass load)
+      }
+    } else if (adr_type->isa_aryptr()) {
+      if (offset == arrayOopDesc::length_offset_in_bytes()) {
+        // Ignore array length load.
+      } else if (find_second_addp(n, n->in(AddPNode::Base)) != NULL) {
+        // Ignore first AddP.
+      } else {
+        const Type* elemtype = adr_type->isa_aryptr()->elem();
+        bt = elemtype->array_element_basic_type();
+      }
+    } else if (adr_type->isa_rawptr() || adr_type->isa_klassptr()) {
+      // Allocation initialization, ThreadLocal field access, unsafe access
+      for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
+        int opcode = n->fast_out(i)->Opcode();
+        if (opcode == Op_StoreP || opcode == Op_LoadP ||
+            opcode == Op_StoreN || opcode == Op_LoadN) {
+          bt = T_OBJECT;
+        }
+      }
+    }
+  }
+  return (bt == T_OBJECT || bt == T_NARROWOOP || bt == T_ARRAY);
+}
+
+// Returns unique pointed java object or NULL.
+JavaObjectNode* ConnectionGraph::unique_java_object(Node *n) {
+  assert(!_collecting, "should not call when contructed graph");
+  // If the node was created after the escape computation we can't answer.
+  uint idx = n->_idx;
+  if (idx >= nodes_size()) {
+    return NULL;
+  }
+  PointsToNode* ptn = ptnode_adr(idx);
+  if (ptn->is_JavaObject()) {
+    return ptn->as_JavaObject();
+  }
+  assert(ptn->is_LocalVar(), "sanity");
+  // Check all java objects it points to.
+  JavaObjectNode* jobj = NULL;
+  for (EdgeIterator i(ptn); i.has_next(); i.next()) {
+    PointsToNode* e = i.get();
+    if (e->is_JavaObject()) {
+      if (jobj == NULL) {
+        jobj = e->as_JavaObject();
+      } else if (jobj != e) {
+        return NULL;
+      }
+    }
+  }
+  return jobj;
+}
+
+// Return true if this node points only to non-escaping allocations.
+bool PointsToNode::non_escaping_allocation() {
+  if (is_JavaObject()) {
+    Node* n = ideal_node();
+    if (n->is_Allocate() || n->is_CallStaticJava()) {
+      return (escape_state() == PointsToNode::NoEscape);
+    } else {
+      return false;
+    }
+  }
+  assert(is_LocalVar(), "sanity");
+  // Check all java objects it points to.
+  for (EdgeIterator i(this); i.has_next(); i.next()) {
+    PointsToNode* e = i.get();
+    if (e->is_JavaObject()) {
+      Node* n = e->ideal_node();
+      if ((e->escape_state() != PointsToNode::NoEscape) ||
+          !(n->is_Allocate() || n->is_CallStaticJava())) {
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
+// Return true if we know the node does not escape globally.
+bool ConnectionGraph::not_global_escape(Node *n) {
+  assert(!_collecting, "should not call during graph construction");
+  // If the node was created after the escape computation we can't answer.
+  uint idx = n->_idx;
+  if (idx >= nodes_size()) {
+    return false;
+  }
+  PointsToNode* ptn = ptnode_adr(idx);
+  PointsToNode::EscapeState es = ptn->escape_state();
+  // If we have already computed a value, return it.
+  if (es >= PointsToNode::GlobalEscape)
+    return false;
+  if (ptn->is_JavaObject()) {
+    return true; // (es < PointsToNode::GlobalEscape);
+  }
+  assert(ptn->is_LocalVar(), "sanity");
+  // Check all java objects it points to.
+  for (EdgeIterator i(ptn); i.has_next(); i.next()) {
+    if (i.get()->escape_state() >= PointsToNode::GlobalEscape)
+      return false;
+  }
+  return true;
+}
+
+
+// Helper functions
+
+// Return true if this node points to specified node or nodes it points to.
+bool PointsToNode::points_to(JavaObjectNode* ptn) const {
+  if (is_JavaObject()) {
+    return (this == ptn);
+  }
+  assert(is_LocalVar(), "sanity");
+  for (EdgeIterator i(this); i.has_next(); i.next()) {
+    if (i.get() == ptn)
+      return true;
+  }
+  return false;
+}
+
+// Return true if one node points to an other.
+bool PointsToNode::meet(PointsToNode* ptn) {
+  if (this == ptn) {
+    return true;
+  } else if (ptn->is_JavaObject()) {
+    return this->points_to(ptn->as_JavaObject());
+  } else if (this->is_JavaObject()) {
+    return ptn->points_to(this->as_JavaObject());
+  }
+  assert(this->is_LocalVar() && ptn->is_LocalVar(), "sanity");
+  int ptn_count =  ptn->edge_count();
+  for (EdgeIterator i(this); i.has_next(); i.next()) {
+    PointsToNode* this_e = i.get();
+    for (int j = 0; j < ptn_count; j++) {
+      if (this_e == ptn->edge(j))
+        return true;
+    }
+  }
+  return false;
+}
+
+#ifdef ASSERT
+// Return true if bases point to this java object.
+bool FieldNode::has_base(JavaObjectNode* jobj) const {
+  for (BaseIterator i(this); i.has_next(); i.next()) {
+    if (i.get() == jobj)
+      return true;
+  }
+  return false;
+}
+#endif
+
 int ConnectionGraph::address_offset(Node* adr, PhaseTransform *phase) {
   const Type *adr_type = phase->type(adr);
   if (adr->is_AddP() && adr_type->isa_oopptr() == NULL &&
@@ -171,286 +1982,7 @@
   return t_ptr->offset();
 }
 
-void ConnectionGraph::add_field_edge(uint from_i, uint to_i, int offset) {
-  // Don't add fields to NULL pointer.
-  if (is_null_ptr(from_i))
-    return;
-  PointsToNode *f = ptnode_adr(from_i);
-  PointsToNode *t = ptnode_adr(to_i);
-
-  assert(f->node_type() != PointsToNode::UnknownType && t->node_type() != PointsToNode::UnknownType, "node types must be set");
-  assert(f->node_type() == PointsToNode::JavaObject, "invalid destination of Field edge");
-  assert(t->node_type() == PointsToNode::Field, "invalid destination of Field edge");
-  assert (t->offset() == -1 || t->offset() == offset, "conflicting field offsets");
-  t->set_offset(offset);
-
-  add_edge(f, to_i, PointsToNode::FieldEdge);
-}
-
-void ConnectionGraph::set_escape_state(uint ni, PointsToNode::EscapeState es) {
-  // Don't change non-escaping state of NULL pointer.
-  if (is_null_ptr(ni))
-    return;
-  PointsToNode *npt = ptnode_adr(ni);
-  PointsToNode::EscapeState old_es = npt->escape_state();
-  if (es > old_es)
-    npt->set_escape_state(es);
-}
-
-void ConnectionGraph::add_node(Node *n, PointsToNode::NodeType nt,
-                               PointsToNode::EscapeState es, bool done) {
-  PointsToNode* ptadr = ptnode_adr(n->_idx);
-  ptadr->_node = n;
-  ptadr->set_node_type(nt);
-
-  // inline set_escape_state(idx, es);
-  PointsToNode::EscapeState old_es = ptadr->escape_state();
-  if (es > old_es)
-    ptadr->set_escape_state(es);
-
-  if (done)
-    _processed.set(n->_idx);
-}
-
-PointsToNode::EscapeState ConnectionGraph::escape_state(Node *n) {
-  uint idx = n->_idx;
-  PointsToNode::EscapeState es;
-
-  // If we are still collecting or there were no non-escaping allocations
-  // we don't know the answer yet
-  if (_collecting)
-    return PointsToNode::UnknownEscape;
-
-  // if the node was created after the escape computation, return
-  // UnknownEscape
-  if (idx >= nodes_size())
-    return PointsToNode::UnknownEscape;
-
-  es = ptnode_adr(idx)->escape_state();
-
-  // if we have already computed a value, return it
-  if (es != PointsToNode::UnknownEscape &&
-      ptnode_adr(idx)->node_type() == PointsToNode::JavaObject)
-    return es;
-
-  // PointsTo() calls n->uncast() which can return a new ideal node.
-  if (n->uncast()->_idx >= nodes_size())
-    return PointsToNode::UnknownEscape;
-
-  PointsToNode::EscapeState orig_es = es;
-
-  // compute max escape state of anything this node could point to
-  for(VectorSetI i(PointsTo(n)); i.test() && es != PointsToNode::GlobalEscape; ++i) {
-    uint pt = i.elem;
-    PointsToNode::EscapeState pes = ptnode_adr(pt)->escape_state();
-    if (pes > es)
-      es = pes;
-  }
-  if (orig_es != es) {
-    // cache the computed escape state
-    assert(es > orig_es, "should have computed an escape state");
-    set_escape_state(idx, es);
-  } // orig_es could be PointsToNode::UnknownEscape
-  return es;
-}
-
-VectorSet* ConnectionGraph::PointsTo(Node * n) {
-  pt_ptset.Reset();
-  pt_visited.Reset();
-  pt_worklist.clear();
-
-#ifdef ASSERT
-  Node *orig_n = n;
-#endif
-
-  n = n->uncast();
-  PointsToNode* npt = ptnode_adr(n->_idx);
-
-  // If we have a JavaObject, return just that object
-  if (npt->node_type() == PointsToNode::JavaObject) {
-    pt_ptset.set(n->_idx);
-    return &pt_ptset;
-  }
-#ifdef ASSERT
-  if (npt->_node == NULL) {
-    if (orig_n != n)
-      orig_n->dump();
-    n->dump();
-    assert(npt->_node != NULL, "unregistered node");
-  }
-#endif
-  pt_worklist.push(n->_idx);
-  while(pt_worklist.length() > 0) {
-    int ni = pt_worklist.pop();
-    if (pt_visited.test_set(ni))
-      continue;
-
-    PointsToNode* pn = ptnode_adr(ni);
-    // ensure that all inputs of a Phi have been processed
-    assert(!_collecting || !pn->_node->is_Phi() || _processed.test(ni),"");
-
-    int edges_processed = 0;
-    uint e_cnt = pn->edge_count();
-    for (uint e = 0; e < e_cnt; e++) {
-      uint etgt = pn->edge_target(e);
-      PointsToNode::EdgeType et = pn->edge_type(e);
-      if (et == PointsToNode::PointsToEdge) {
-        pt_ptset.set(etgt);
-        edges_processed++;
-      } else if (et == PointsToNode::DeferredEdge) {
-        pt_worklist.push(etgt);
-        edges_processed++;
-      } else {
-        assert(false,"neither PointsToEdge or DeferredEdge");
-      }
-    }
-    if (edges_processed == 0) {
-      // no deferred or pointsto edges found.  Assume the value was set
-      // outside this method.  Add the phantom object to the pointsto set.
-      pt_ptset.set(_phantom_object);
-    }
-  }
-  return &pt_ptset;
-}
-
-void ConnectionGraph::remove_deferred(uint ni, GrowableArray<uint>* deferred_edges, VectorSet* visited) {
-  // This method is most expensive during ConnectionGraph construction.
-  // Reuse vectorSet and an additional growable array for deferred edges.
-  deferred_edges->clear();
-  visited->Reset();
-
-  visited->set(ni);
-  PointsToNode *ptn = ptnode_adr(ni);
-  assert(ptn->node_type() == PointsToNode::LocalVar ||
-         ptn->node_type() == PointsToNode::Field, "sanity");
-  assert(ptn->edge_count() != 0, "should have at least phantom_object");
-
-  // Mark current edges as visited and move deferred edges to separate array.
-  for (uint i = 0; i < ptn->edge_count(); ) {
-    uint t = ptn->edge_target(i);
-#ifdef ASSERT
-    assert(!visited->test_set(t), "expecting no duplications");
-#else
-    visited->set(t);
-#endif
-    if (ptn->edge_type(i) == PointsToNode::DeferredEdge) {
-      ptn->remove_edge(t, PointsToNode::DeferredEdge);
-      deferred_edges->append(t);
-    } else {
-      i++;
-    }
-  }
-  for (int next = 0; next < deferred_edges->length(); ++next) {
-    uint t = deferred_edges->at(next);
-    PointsToNode *ptt = ptnode_adr(t);
-    uint e_cnt = ptt->edge_count();
-    assert(e_cnt != 0, "should have at least phantom_object");
-    for (uint e = 0; e < e_cnt; e++) {
-      uint etgt = ptt->edge_target(e);
-      if (visited->test_set(etgt))
-        continue;
-
-      PointsToNode::EdgeType et = ptt->edge_type(e);
-      if (et == PointsToNode::PointsToEdge) {
-        add_pointsto_edge(ni, etgt);
-      } else if (et == PointsToNode::DeferredEdge) {
-        deferred_edges->append(etgt);
-      } else {
-        assert(false,"invalid connection graph");
-      }
-    }
-  }
-  if (ptn->edge_count() == 0) {
-    // No pointsto edges found after deferred edges are removed.
-    // For example, in the next case where call is replaced
-    // with uncommon trap and as result array's load references
-    // itself through deferred edges:
-    //
-    // A a = b[i];
-    // if (c!=null) a = c.foo();
-    // b[i] = a;
-    //
-    // Assume the value was set outside this method and
-    // add edge to phantom object.
-    add_pointsto_edge(ni, _phantom_object);
-  }
-}
-
-
-//  Add an edge to node given by "to_i" from any field of adr_i whose offset
-//  matches "offset"  A deferred edge is added if to_i is a LocalVar, and
-//  a pointsto edge is added if it is a JavaObject
-
-void ConnectionGraph::add_edge_from_fields(uint adr_i, uint to_i, int offs) {
-  // No fields for NULL pointer.
-  if (is_null_ptr(adr_i)) {
-    return;
-  }
-  PointsToNode* an = ptnode_adr(adr_i);
-  PointsToNode* to = ptnode_adr(to_i);
-  bool deferred = (to->node_type() == PointsToNode::LocalVar);
-  bool escaped  = (to_i == _phantom_object) && (offs == Type::OffsetTop);
-  if (escaped) {
-    // Values in fields escaped during call.
-    assert(an->escape_state() >= PointsToNode::ArgEscape, "sanity");
-    offs = Type::OffsetBot;
-  }
-  for (uint fe = 0; fe < an->edge_count(); fe++) {
-    assert(an->edge_type(fe) == PointsToNode::FieldEdge, "expecting a field edge");
-    int fi = an->edge_target(fe);
-    if (escaped) {
-      set_escape_state(fi, PointsToNode::GlobalEscape);
-    }
-    PointsToNode* pf = ptnode_adr(fi);
-    int po = pf->offset();
-    if (po == offs || po == Type::OffsetBot || offs == Type::OffsetBot) {
-      if (deferred)
-        add_deferred_edge(fi, to_i);
-      else
-        add_pointsto_edge(fi, to_i);
-    }
-  }
-}
-
-// Add a deferred  edge from node given by "from_i" to any field of adr_i
-// whose offset matches "offset".
-void ConnectionGraph::add_deferred_edge_to_fields(uint from_i, uint adr_i, int offs) {
-  // No fields for NULL pointer.
-  if (is_null_ptr(adr_i)) {
-    return;
-  }
-  if (adr_i == _phantom_object) {
-    // Add only one edge for unknown object.
-    add_pointsto_edge(from_i, _phantom_object);
-    return;
-  }
-  PointsToNode* an = ptnode_adr(adr_i);
-  bool is_alloc = an->_node->is_Allocate();
-  for (uint fe = 0; fe < an->edge_count(); fe++) {
-    assert(an->edge_type(fe) == PointsToNode::FieldEdge, "expecting a field edge");
-    int fi = an->edge_target(fe);
-    PointsToNode* pf = ptnode_adr(fi);
-    int offset = pf->offset();
-    if (!is_alloc) {
-      // Assume the field was set outside this method if it is not Allocation
-      add_pointsto_edge(fi, _phantom_object);
-    }
-    if (offset == offs || offset == Type::OffsetBot || offs == Type::OffsetBot) {
-      add_deferred_edge(from_i, fi);
-    }
-  }
-  // Some fields references (AddP) may still be missing
-  // until Connection Graph construction is complete.
-  // For example, loads from RAW pointers with offset 0
-  // which don't have AddP.
-  // A reference to phantom_object will be added if
-  // a field reference is still missing after completing
-  // Connection Graph (see remove_deferred()).
-}
-
-// Helper functions
-
-static Node* get_addp_base(Node *addp) {
+Node* ConnectionGraph::get_addp_base(Node *addp) {
   assert(addp->is_AddP(), "must be AddP");
   //
   // AddP cases for Base and Address inputs:
@@ -513,30 +2045,30 @@
   //       | |
   //       AddP  ( base == address )
   //
-  Node *base = addp->in(AddPNode::Base)->uncast();
-  if (base->is_top()) { // The AddP case #3 and #6.
-    base = addp->in(AddPNode::Address)->uncast();
+  Node *base = addp->in(AddPNode::Base);
+  if (base->uncast()->is_top()) { // The AddP case #3 and #6.
+    base = addp->in(AddPNode::Address);
     while (base->is_AddP()) {
       // Case #6 (unsafe access) may have several chained AddP nodes.
-      assert(base->in(AddPNode::Base)->is_top(), "expected unsafe access address only");
-      base = base->in(AddPNode::Address)->uncast();
+      assert(base->in(AddPNode::Base)->uncast()->is_top(), "expected unsafe access address only");
+      base = base->in(AddPNode::Address);
     }
-    assert(base->Opcode() == Op_ConP || base->Opcode() == Op_ThreadLocal ||
-           base->Opcode() == Op_CastX2P || base->is_DecodeN() ||
-           (base->is_Mem() && base->bottom_type() == TypeRawPtr::NOTNULL) ||
-           (base->is_Proj() && base->in(0)->is_Allocate()), "sanity");
+    Node* uncast_base = base->uncast();
+    int opcode = uncast_base->Opcode();
+    assert(opcode == Op_ConP || opcode == Op_ThreadLocal ||
+           opcode == Op_CastX2P || uncast_base->is_DecodeN() ||
+           (uncast_base->is_Mem() && uncast_base->bottom_type() == TypeRawPtr::NOTNULL) ||
+           (uncast_base->is_Proj() && uncast_base->in(0)->is_Allocate()), "sanity");
   }
   return base;
 }
 
-static Node* find_second_addp(Node* addp, Node* n) {
+Node* ConnectionGraph::find_second_addp(Node* addp, Node* n) {
   assert(addp->is_AddP() && addp->outcnt() > 0, "Don't process dead nodes");
-
   Node* addp2 = addp->raw_out(0);
   if (addp->outcnt() == 1 && addp2->is_AddP() &&
       addp2->in(AddPNode::Base) == n &&
       addp2->in(AddPNode::Address) == addp) {
-
     assert(addp->in(AddPNode::Base) == n, "expecting the same base");
     //
     // Find array's offset to push it on worklist first and
@@ -575,7 +2107,8 @@
 // Adjust the type and inputs of an AddP which computes the
 // address of a field of an instance
 //
-bool ConnectionGraph::split_AddP(Node *addp, Node *base,  PhaseGVN  *igvn) {
+bool ConnectionGraph::split_AddP(Node *addp, Node *base) {
+  PhaseGVN* igvn = _igvn;
   const TypeOopPtr *base_t = igvn->type(base)->isa_oopptr();
   assert(base_t != NULL && base_t->is_known_instance(), "expecting instance oopptr");
   const TypeOopPtr *t = igvn->type(addp)->isa_oopptr();
@@ -612,7 +2145,6 @@
       !base_t->klass()->is_subtype_of(t->klass())) {
      return false; // bail out
   }
-
   const TypeOopPtr *tinst = base_t->add_offset(t->offset())->is_oopptr();
   // Do NOT remove the next line: ensure a new alias index is allocated
   // for the instance type. Note: C++ will not remove it since the call
@@ -620,9 +2152,7 @@
   int alias_idx = _compile->get_alias_index(tinst);
   igvn->set_type(addp, tinst);
   // record the allocation in the node map
-  assert(ptnode_adr(addp->_idx)->_node != NULL, "should be registered");
-  set_map(addp->_idx, get_map(base->_idx));
-
+  set_map(addp, get_map(base->_idx));
   // Set addp's Base and Address to 'base'.
   Node *abase = addp->in(AddPNode::Base);
   Node *adr   = addp->in(AddPNode::Address);
@@ -657,8 +2187,9 @@
 // created phi or an existing phi.  Sets create_new to indicate whether a new
 // phi was created.  Cache the last newly created phi in the node map.
 //
-PhiNode *ConnectionGraph::create_split_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *>  &orig_phi_worklist, PhaseGVN  *igvn, bool &new_created) {
+PhiNode *ConnectionGraph::create_split_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *>  &orig_phi_worklist, bool &new_created) {
   Compile *C = _compile;
+  PhaseGVN* igvn = _igvn;
   new_created = false;
   int phi_alias_idx = C->get_alias_index(orig_phi->adr_type());
   // nothing to do if orig_phi is bottom memory or matches alias_idx
@@ -698,12 +2229,7 @@
   C->copy_node_notes_to(result, orig_phi);
   igvn->set_type(result, result->bottom_type());
   record_for_optimizer(result);
-
-  debug_only(Node* pn = ptnode_adr(orig_phi->_idx)->_node;)
-  assert(pn == NULL || pn == orig_phi, "wrong node");
-  set_map(orig_phi->_idx, result);
-  ptnode_adr(orig_phi->_idx)->_node = orig_phi;
-
+  set_map(orig_phi, result);
   new_created = true;
   return result;
 }
@@ -712,27 +2238,25 @@
 // Return a new version of Memory Phi "orig_phi" with the inputs having the
 // specified alias index.
 //
-PhiNode *ConnectionGraph::split_memory_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *>  &orig_phi_worklist, PhaseGVN  *igvn) {
-
+PhiNode *ConnectionGraph::split_memory_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *>  &orig_phi_worklist) {
   assert(alias_idx != Compile::AliasIdxBot, "can't split out bottom memory");
   Compile *C = _compile;
+  PhaseGVN* igvn = _igvn;
   bool new_phi_created;
-  PhiNode *result = create_split_phi(orig_phi, alias_idx, orig_phi_worklist, igvn, new_phi_created);
+  PhiNode *result = create_split_phi(orig_phi, alias_idx, orig_phi_worklist, new_phi_created);
   if (!new_phi_created) {
     return result;
   }
-
   GrowableArray<PhiNode *>  phi_list;
   GrowableArray<uint>  cur_input;
-
   PhiNode *phi = orig_phi;
   uint idx = 1;
   bool finished = false;
   while(!finished) {
     while (idx < phi->req()) {
-      Node *mem = find_inst_mem(phi->in(idx), alias_idx, orig_phi_worklist, igvn);
+      Node *mem = find_inst_mem(phi->in(idx), alias_idx, orig_phi_worklist);
       if (mem != NULL && mem->is_Phi()) {
-        PhiNode *newphi = create_split_phi(mem->as_Phi(), alias_idx, orig_phi_worklist, igvn, new_phi_created);
+        PhiNode *newphi = create_split_phi(mem->as_Phi(), alias_idx, orig_phi_worklist, new_phi_created);
         if (new_phi_created) {
           // found an phi for which we created a new split, push current one on worklist and begin
           // processing new one
@@ -775,19 +2299,18 @@
   return result;
 }
 
-
 //
 // The next methods are derived from methods in MemNode.
 //
-static Node *step_through_mergemem(MergeMemNode *mmem, int alias_idx, const TypeOopPtr *toop) {
+Node* ConnectionGraph::step_through_mergemem(MergeMemNode *mmem, int alias_idx, const TypeOopPtr *toop) {
   Node *mem = mmem;
   // TypeOopPtr::NOTNULL+any is an OOP with unknown offset - generally
   // means an array I have not precisely typed yet.  Do not do any
   // alias stuff with it any time soon.
-  if( toop->base() != Type::AnyPtr &&
+  if (toop->base() != Type::AnyPtr &&
       !(toop->klass() != NULL &&
         toop->klass()->is_java_lang_Object() &&
-        toop->offset() == Type::OffsetBot) ) {
+        toop->offset() == Type::OffsetBot)) {
     mem = mmem->memory_at(alias_idx);
     // Update input if it is progress over what we have now
   }
@@ -797,9 +2320,9 @@
 //
 // Move memory users to their memory slices.
 //
-void ConnectionGraph::move_inst_mem(Node* n, GrowableArray<PhiNode *>  &orig_phis, PhaseGVN *igvn) {
+void ConnectionGraph::move_inst_mem(Node* n, GrowableArray<PhiNode *>  &orig_phis) {
   Compile* C = _compile;
-
+  PhaseGVN* igvn = _igvn;
   const TypePtr* tp = igvn->type(n->in(MemNode::Address))->isa_ptr();
   assert(tp != NULL, "ptr type");
   int alias_idx = C->get_alias_index(tp);
@@ -816,7 +2339,7 @@
       }
       // Replace previous general reference to mem node.
       uint orig_uniq = C->unique();
-      Node* m = find_inst_mem(n, general_idx, orig_phis, igvn);
+      Node* m = find_inst_mem(n, general_idx, orig_phis);
       assert(orig_uniq == C->unique(), "no new nodes");
       mmem->set_memory_at(general_idx, m);
       --imax;
@@ -836,7 +2359,7 @@
       }
       // Move to general memory slice.
       uint orig_uniq = C->unique();
-      Node* m = find_inst_mem(n, general_idx, orig_phis, igvn);
+      Node* m = find_inst_mem(n, general_idx, orig_phis);
       assert(orig_uniq == C->unique(), "no new nodes");
       igvn->hash_delete(use);
       imax -= use->replace_edge(n, m);
@@ -873,10 +2396,11 @@
 // Search memory chain of "mem" to find a MemNode whose address
 // is the specified alias index.
 //
-Node* ConnectionGraph::find_inst_mem(Node *orig_mem, int alias_idx, GrowableArray<PhiNode *>  &orig_phis, PhaseGVN *phase) {
+Node* ConnectionGraph::find_inst_mem(Node *orig_mem, int alias_idx, GrowableArray<PhiNode *>  &orig_phis) {
   if (orig_mem == NULL)
     return orig_mem;
-  Compile* C = phase->C;
+  Compile* C = _compile;
+  PhaseGVN* igvn = _igvn;
   const TypeOopPtr *toop = C->get_adr_type(alias_idx)->isa_oopptr();
   bool is_instance = (toop != NULL) && toop->is_known_instance();
   Node *start_mem = C->start()->proj_out(TypeFunc::Memory);
@@ -887,7 +2411,7 @@
     if (result == start_mem)
       break;  // hit one of our sentinels
     if (result->is_Mem()) {
-      const Type *at = phase->type(result->in(MemNode::Address));
+      const Type *at = igvn->type(result->in(MemNode::Address));
       if (at == Type::TOP)
         break; // Dead
       assert (at->isa_ptr() != NULL, "pointer type required.");
@@ -909,7 +2433,7 @@
         break;  // hit one of our sentinels
       } else if (proj_in->is_Call()) {
         CallNode *call = proj_in->as_Call();
-        if (!call->may_modify(toop, phase)) {
+        if (!call->may_modify(toop, igvn)) {
           result = call->in(TypeFunc::Memory);
         }
       } else if (proj_in->is_Initialize()) {
@@ -928,7 +2452,7 @@
       if (result == mmem->base_memory()) {
         // Didn't find instance memory, search through general slice recursively.
         result = mmem->memory_at(C->get_general_index(alias_idx));
-        result = find_inst_mem(result, alias_idx, orig_phis, phase);
+        result = find_inst_mem(result, alias_idx, orig_phis);
         if (C->failing()) {
           return NULL;
         }
@@ -936,7 +2460,7 @@
       }
     } else if (result->is_Phi() &&
                C->get_alias_index(result->as_Phi()->adr_type()) != alias_idx) {
-      Node *un = result->as_Phi()->unique_input(phase);
+      Node *un = result->as_Phi()->unique_input(igvn);
       if (un != NULL) {
         orig_phis.append_if_missing(result->as_Phi());
         result = un;
@@ -944,7 +2468,7 @@
         break;
       }
     } else if (result->is_ClearArray()) {
-      if (!ClearArrayNode::step_through(&result, (uint)toop->instance_id(), phase)) {
+      if (!ClearArrayNode::step_through(&result, (uint)toop->instance_id(), igvn)) {
         // Can not bypass initialization of the instance
         // we are looking for.
         break;
@@ -952,7 +2476,7 @@
       // Otherwise skip it (the call updated 'result' value).
     } else if (result->Opcode() == Op_SCMemProj) {
       assert(result->in(0)->is_LoadStore(), "sanity");
-      const Type *at = phase->type(result->in(0)->in(MemNode::Address));
+      const Type *at = igvn->type(result->in(0)->in(MemNode::Address));
       if (at != Type::TOP) {
         assert (at->isa_ptr() != NULL, "pointer type required.");
         int idx = C->get_alias_index(at->is_ptr());
@@ -972,7 +2496,7 @@
       orig_phis.append_if_missing(mphi);
     } else if (C->get_alias_index(t) != alias_idx) {
       // Create a new Phi with the specified alias index type.
-      result = split_memory_phi(mphi, alias_idx, orig_phis, phase);
+      result = split_memory_phi(mphi, alias_idx, orig_phis);
     }
   }
   // the result is either MemNode, PhiNode, InitializeNode.
@@ -1071,12 +2595,12 @@
 void ConnectionGraph::split_unique_types(GrowableArray<Node *>  &alloc_worklist) {
   GrowableArray<Node *>  memnode_worklist;
   GrowableArray<PhiNode *>  orig_phis;
-
   PhaseIterGVN  *igvn = _igvn;
   uint new_index_start = (uint) _compile->num_alias_types();
   Arena* arena = Thread::current()->resource_area();
   VectorSet visited(arena);
-
+  ideal_nodes.clear(); // Reset for use with set_map/get_map.
+  uint unique_old = _compile->unique();
 
   //  Phase 1:  Process possible allocations from alloc_worklist.
   //  Create instance types for the CheckCastPP for allocations where possible.
@@ -1088,17 +2612,15 @@
   while (alloc_worklist.length() != 0) {
     Node *n = alloc_worklist.pop();
     uint ni = n->_idx;
-    const TypeOopPtr* tinst = NULL;
     if (n->is_Call()) {
       CallNode *alloc = n->as_Call();
       // copy escape information to call node
       PointsToNode* ptn = ptnode_adr(alloc->_idx);
-      PointsToNode::EscapeState es = escape_state(alloc);
+      PointsToNode::EscapeState es = ptn->escape_state();
       // We have an allocation or call which returns a Java object,
       // see if it is unescaped.
       if (es != PointsToNode::NoEscape || !ptn->scalar_replaceable())
         continue;
-
       // Find CheckCastPP for the allocate or for the return value of a call
       n = alloc->result_cast();
       if (n == NULL) {            // No uses except Initialize node
@@ -1145,20 +2667,18 @@
         // so it could be eliminated.
         alloc->as_Allocate()->_is_scalar_replaceable = true;
       }
-      set_escape_state(n->_idx, es); // CheckCastPP escape state
+      set_escape_state(ptnode_adr(n->_idx), es); // CheckCastPP escape state
       // in order for an object to be scalar-replaceable, it must be:
       //   - a direct allocation (not a call returning an object)
       //   - non-escaping
       //   - eligible to be a unique type
       //   - not determined to be ineligible by escape analysis
-      assert(ptnode_adr(alloc->_idx)->_node != NULL &&
-             ptnode_adr(n->_idx)->_node != NULL, "should be registered");
-      set_map(alloc->_idx, n);
-      set_map(n->_idx, alloc);
+      set_map(alloc, n);
+      set_map(n, alloc);
       const TypeOopPtr *t = igvn->type(n)->isa_oopptr();
       if (t == NULL)
         continue;  // not a TypeOopPtr
-      tinst = t->cast_to_exactness(true)->is_oopptr()->cast_to_instance_id(ni);
+      const TypeOopPtr* tinst = t->cast_to_exactness(true)->is_oopptr()->cast_to_instance_id(ni);
       igvn->hash_delete(n);
       igvn->set_type(n,  tinst);
       n->raise_bottom_type(tinst);
@@ -1168,9 +2688,10 @@
 
         // First, put on the worklist all Field edges from Connection Graph
         // which is more accurate then putting immediate users from Ideal Graph.
-        for (uint e = 0; e < ptn->edge_count(); e++) {
-          Node *use = ptnode_adr(ptn->edge_target(e))->_node;
-          assert(ptn->edge_type(e) == PointsToNode::FieldEdge && use->is_AddP(),
+        for (EdgeIterator e(ptn); e.has_next(); e.next()) {
+          PointsToNode* tgt = e.get();
+          Node* use = tgt->ideal_node();
+          assert(tgt->is_Field() && use->is_AddP(),
                  "only AddP nodes are Field edges in CG");
           if (use->outcnt() > 0) { // Don't process dead nodes
             Node* addp2 = find_second_addp(use, use->in(AddPNode::Base));
@@ -1202,16 +2723,18 @@
         }
       }
     } else if (n->is_AddP()) {
-      VectorSet* ptset = PointsTo(get_addp_base(n));
-      assert(ptset->Size() == 1, "AddP address is unique");
-      uint elem = ptset->getelem(); // Allocation node's index
-      if (elem == _phantom_object) {
-        assert(false, "escaped allocation");
-        continue; // Assume the value was set outside this method.
+      JavaObjectNode* jobj = unique_java_object(get_addp_base(n));
+      if (jobj == NULL || jobj == phantom_obj) {
+#ifdef ASSERT
+        ptnode_adr(get_addp_base(n)->_idx)->dump();
+        ptnode_adr(n->_idx)->dump();
+        assert(jobj != NULL && jobj != phantom_obj, "escaped allocation");
+#endif
+        _compile->record_failure(C2Compiler::retry_no_escape_analysis());
+        return;
       }
-      Node *base = get_map(elem);  // CheckCastPP node
-      if (!split_AddP(n, base, igvn)) continue; // wrong type from dead path
-      tinst = igvn->type(base)->isa_oopptr();
+      Node *base = get_map(jobj->idx());  // CheckCastPP node
+      if (!split_AddP(n, base)) continue; // wrong type from dead path
     } else if (n->is_Phi() ||
                n->is_CheckCastPP() ||
                n->is_EncodeP() ||
@@ -1221,18 +2744,20 @@
         assert(n->is_Phi(), "loops only through Phi's");
         continue;  // already processed
       }
-      VectorSet* ptset = PointsTo(n);
-      if (ptset->Size() == 1) {
-        uint elem = ptset->getelem(); // Allocation node's index
-        if (elem == _phantom_object) {
-          assert(false, "escaped allocation");
-          continue; // Assume the value was set outside this method.
-        }
-        Node *val = get_map(elem);   // CheckCastPP node
+      JavaObjectNode* jobj = unique_java_object(n);
+      if (jobj == NULL || jobj == phantom_obj) {
+#ifdef ASSERT
+        ptnode_adr(n->_idx)->dump();
+        assert(jobj != NULL && jobj != phantom_obj, "escaped allocation");
+#endif
+        _compile->record_failure(C2Compiler::retry_no_escape_analysis());
+        return;
+      } else {
+        Node *val = get_map(jobj->idx());   // CheckCastPP node
         TypeNode *tn = n->as_Type();
-        tinst = igvn->type(val)->isa_oopptr();
+        const TypeOopPtr* tinst = igvn->type(val)->isa_oopptr();
         assert(tinst != NULL && tinst->is_known_instance() &&
-               (uint)tinst->instance_id() == elem , "instance type expected.");
+               tinst->instance_id() == jobj->idx() , "instance type expected.");
 
         const Type *tn_type = igvn->type(tn);
         const TypeOopPtr *tn_t;
@@ -1241,7 +2766,6 @@
         } else {
           tn_t = tn_type->isa_oopptr();
         }
-
         if (tn_t != NULL && tinst->klass()->is_subtype_of(tn_t->klass())) {
           if (tn_type->isa_narrowoop()) {
             tn_type = tinst->make_narrowoop();
@@ -1314,13 +2838,13 @@
   }
   // New alias types were created in split_AddP().
   uint new_index_end = (uint) _compile->num_alias_types();
+  assert(unique_old == _compile->unique(), "there should be no new ideal nodes after Phase 1");
 
   //  Phase 2:  Process MemNode's from memnode_worklist. compute new address type and
   //            compute new values for Memory inputs  (the Memory inputs are not
   //            actually updated until phase 4.)
   if (memnode_worklist.length() == 0)
     return;  // nothing to do
-
   while (memnode_worklist.length() != 0) {
     Node *n = memnode_worklist.pop();
     if (visited.test_set(n->_idx))
@@ -1341,17 +2865,14 @@
       assert (addr_t->isa_ptr() != NULL, "pointer type required.");
       int alias_idx = _compile->get_alias_index(addr_t->is_ptr());
       assert ((uint)alias_idx < new_index_end, "wrong alias index");
-      Node *mem = find_inst_mem(n->in(MemNode::Memory), alias_idx, orig_phis, igvn);
+      Node *mem = find_inst_mem(n->in(MemNode::Memory), alias_idx, orig_phis);
       if (_compile->failing()) {
         return;
       }
       if (mem != n->in(MemNode::Memory)) {
         // We delay the memory edge update since we need old one in
         // MergeMem code below when instances memory slices are separated.
-        debug_only(Node* pn = ptnode_adr(n->_idx)->_node;)
-        assert(pn == NULL || pn == n, "wrong node");
-        set_map(n->_idx, mem);
-        ptnode_adr(n->_idx)->_node = n;
+        set_map(n, mem);
       }
       if (n->is_Load()) {
         continue;  // don't push users
@@ -1442,7 +2963,7 @@
         if((uint)_compile->get_general_index(ni) == i) {
           Node *m = (ni >= nmm->req()) ? nmm->empty_memory() : nmm->in(ni);
           if (nmm->is_empty_memory(m)) {
-            Node* result = find_inst_mem(mem, ni, orig_phis, igvn);
+            Node* result = find_inst_mem(mem, ni, orig_phis);
             if (_compile->failing()) {
               return;
             }
@@ -1458,7 +2979,7 @@
       if (result == nmm->base_memory()) {
         // Didn't find instance memory, search through general slice recursively.
         result = nmm->memory_at(_compile->get_general_index(ni));
-        result = find_inst_mem(result, ni, orig_phis, igvn);
+        result = find_inst_mem(result, ni, orig_phis);
         if (_compile->failing()) {
           return;
         }
@@ -1482,7 +3003,7 @@
     igvn->hash_delete(phi);
     for (uint i = 1; i < phi->req(); i++) {
       Node *mem = phi->in(i);
-      Node *new_mem = find_inst_mem(mem, alias_idx, orig_phis, igvn);
+      Node *new_mem = find_inst_mem(mem, alias_idx, orig_phis);
       if (_compile->failing()) {
         return;
       }
@@ -1496,39 +3017,36 @@
 
   // Update the memory inputs of MemNodes with the value we computed
   // in Phase 2 and move stores memory users to corresponding memory slices.
-
   // Disable memory split verification code until the fix for 6984348.
   // Currently it produces false negative results since it does not cover all cases.
 #if 0 // ifdef ASSERT
   visited.Reset();
   Node_Stack old_mems(arena, _compile->unique() >> 2);
 #endif
-  for (uint i = 0; i < nodes_size(); i++) {
-    Node *nmem = get_map(i);
-    if (nmem != NULL) {
-      Node *n = ptnode_adr(i)->_node;
-      assert(n != NULL, "sanity");
-      if (n->is_Mem()) {
+  for (uint i = 0; i < ideal_nodes.size(); i++) {
+    Node*    n = ideal_nodes.at(i);
+    Node* nmem = get_map(n->_idx);
+    assert(nmem != NULL, "sanity");
+    if (n->is_Mem()) {
 #if 0 // ifdef ASSERT
-        Node* old_mem = n->in(MemNode::Memory);
-        if (!visited.test_set(old_mem->_idx)) {
-          old_mems.push(old_mem, old_mem->outcnt());
-        }
+      Node* old_mem = n->in(MemNode::Memory);
+      if (!visited.test_set(old_mem->_idx)) {
+        old_mems.push(old_mem, old_mem->outcnt());
+      }
 #endif
-        assert(n->in(MemNode::Memory) != nmem, "sanity");
-        if (!n->is_Load()) {
-          // Move memory users of a store first.
-          move_inst_mem(n, orig_phis, igvn);
-        }
-        // Now update memory input
-        igvn->hash_delete(n);
-        n->set_req(MemNode::Memory, nmem);
-        igvn->hash_insert(n);
-        record_for_optimizer(n);
-      } else {
-        assert(n->is_Allocate() || n->is_CheckCastPP() ||
-               n->is_AddP() || n->is_Phi(), "unknown node used for set_map()");
+      assert(n->in(MemNode::Memory) != nmem, "sanity");
+      if (!n->is_Load()) {
+        // Move memory users of a store first.
+        move_inst_mem(n, orig_phis);
       }
+      // Now update memory input
+      igvn->hash_delete(n);
+      n->set_req(MemNode::Memory, nmem);
+      igvn->hash_insert(n);
+      record_for_optimizer(n);
+    } else {
+      assert(n->is_Allocate() || n->is_CheckCastPP() ||
+             n->is_AddP() || n->is_Phi(), "unknown node used for set_map()");
     }
   }
 #if 0 // ifdef ASSERT
@@ -1542,1571 +3060,72 @@
 #endif
 }
 
-bool ConnectionGraph::has_candidates(Compile *C) {
-  // EA brings benefits only when the code has allocations and/or locks which
-  // are represented by ideal Macro nodes.
-  int cnt = C->macro_count();
-  for( int i=0; i < cnt; i++ ) {
-    Node *n = C->macro_node(i);
-    if ( n->is_Allocate() )
-      return true;
-    if( n->is_Lock() ) {
-      Node* obj = n->as_Lock()->obj_node()->uncast();
-      if( !(obj->is_Parm() || obj->is_Con()) )
-        return true;
-    }
-  }
-  return false;
-}
-
-void ConnectionGraph::do_analysis(Compile *C, PhaseIterGVN *igvn) {
-  // Add ConP#NULL and ConN#NULL nodes before ConnectionGraph construction
-  // to create space for them in ConnectionGraph::_nodes[].
-  Node* oop_null = igvn->zerocon(T_OBJECT);
-  Node* noop_null = igvn->zerocon(T_NARROWOOP);
-
-  ConnectionGraph* congraph = new(C->comp_arena()) ConnectionGraph(C, igvn);
-  // Perform escape analysis
-  if (congraph->compute_escape()) {
-    // There are non escaping objects.
-    C->set_congraph(congraph);
-  }
-
-  // Cleanup.
-  if (oop_null->outcnt() == 0)
-    igvn->hash_delete(oop_null);
-  if (noop_null->outcnt() == 0)
-    igvn->hash_delete(noop_null);
-}
-
-bool ConnectionGraph::compute_escape() {
-  Compile* C = _compile;
-
-  // 1. Populate Connection Graph (CG) with Ideal nodes.
-
-  Unique_Node_List worklist_init;
-  worklist_init.map(C->unique(), NULL);  // preallocate space
-
-  // Initialize worklist
-  if (C->root() != NULL) {
-    worklist_init.push(C->root());
-  }
-
-  GrowableArray<Node*> alloc_worklist;
-  GrowableArray<Node*> addp_worklist;
-  GrowableArray<Node*> ptr_cmp_worklist;
-  GrowableArray<Node*> storestore_worklist;
-  PhaseGVN* igvn = _igvn;
-
-  // Push all useful nodes onto CG list and set their type.
-  for( uint next = 0; next < worklist_init.size(); ++next ) {
-    Node* n = worklist_init.at(next);
-    record_for_escape_analysis(n, igvn);
-    // Only allocations and java static calls results are checked
-    // for an escape status. See process_call_result() below.
-    if (n->is_Allocate() || n->is_CallStaticJava() &&
-        ptnode_adr(n->_idx)->node_type() == PointsToNode::JavaObject) {
-      alloc_worklist.append(n);
-    } else if(n->is_AddP()) {
-      // Collect address nodes. Use them during stage 3 below
-      // to build initial connection graph field edges.
-      addp_worklist.append(n);
-    } else if (n->is_MergeMem()) {
-      // Collect all MergeMem nodes to add memory slices for
-      // scalar replaceable objects in split_unique_types().
-      _mergemem_worklist.append(n->as_MergeMem());
-    } else if (OptimizePtrCompare && n->is_Cmp() &&
-               (n->Opcode() == Op_CmpP || n->Opcode() == Op_CmpN)) {
-      // Compare pointers nodes
-      ptr_cmp_worklist.append(n);
-    } else if (n->is_MemBarStoreStore()) {
-      // Collect all MemBarStoreStore nodes so that depending on the
-      // escape status of the associated Allocate node some of them
-      // may be eliminated.
-      storestore_worklist.append(n);
-    }
-    for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
-      Node* m = n->fast_out(i);   // Get user
-      worklist_init.push(m);
-    }
-  }
-
-  if (alloc_worklist.length() == 0) {
-    _collecting = false;
-    return false; // Nothing to do.
-  }
-
-  // 2. First pass to create simple CG edges (doesn't require to walk CG).
-  uint delayed_size = _delayed_worklist.size();
-  for( uint next = 0; next < delayed_size; ++next ) {
-    Node* n = _delayed_worklist.at(next);
-    build_connection_graph(n, igvn);
-  }
-
-  // 3. Pass to create initial fields edges (JavaObject -F-> AddP)
-  //    to reduce number of iterations during stage 4 below.
-  uint addp_length = addp_worklist.length();
-  for( uint next = 0; next < addp_length; ++next ) {
-    Node* n = addp_worklist.at(next);
-    Node* base = get_addp_base(n);
-    if (base->is_Proj() && base->in(0)->is_Call())
-      base = base->in(0);
-    PointsToNode::NodeType nt = ptnode_adr(base->_idx)->node_type();
-    if (nt == PointsToNode::JavaObject) {
-      build_connection_graph(n, igvn);
-    }
-  }
-
-  GrowableArray<int> cg_worklist;
-  cg_worklist.append(_phantom_object);
-  GrowableArray<uint>  worklist;
-
-  // 4. Build Connection Graph which need
-  //    to walk the connection graph.
-  _progress = false;
-  for (uint ni = 0; ni < nodes_size(); ni++) {
-    PointsToNode* ptn = ptnode_adr(ni);
-    Node *n = ptn->_node;
-    if (n != NULL) { // Call, AddP, LoadP, StoreP
-      build_connection_graph(n, igvn);
-      if (ptn->node_type() != PointsToNode::UnknownType)
-        cg_worklist.append(n->_idx); // Collect CG nodes
-      if (!_processed.test(n->_idx))
-        worklist.append(n->_idx); // Collect C/A/L/S nodes
-    }
-  }
-
-  // After IGVN user nodes may have smaller _idx than
-  // their inputs so they will be processed first in
-  // previous loop. Because of that not all Graph
-  // edges will be created. Walk over interesting
-  // nodes again until no new edges are created.
-  //
-  // Normally only 1-3 passes needed to build
-  // Connection Graph depending on graph complexity.
-  // Observed 8 passes in jvm2008 compiler.compiler.
-  // Set limit to 20 to catch situation when something
-  // did go wrong and recompile the method without EA.
-  // Also limit build time to 30 sec (60 in debug VM).
-
-#define CG_BUILD_ITER_LIMIT 20
-
-#ifdef ASSERT
-#define CG_BUILD_TIME_LIMIT 60.0
-#else
-#define CG_BUILD_TIME_LIMIT 30.0
-#endif
+#ifndef PRODUCT
+static const char *node_type_names[] = {
+  "UnknownType",
+  "JavaObject",
+  "LocalVar",
+  "Field",
+  "Arraycopy"
+};
 
-  uint length = worklist.length();
-  int iterations = 0;
-  elapsedTimer time;
-  while(_progress &&
-        (iterations++   < CG_BUILD_ITER_LIMIT) &&
-        (time.seconds() < CG_BUILD_TIME_LIMIT)) {
-    time.start();
-    _progress = false;
-    for( uint next = 0; next < length; ++next ) {
-      int ni = worklist.at(next);
-      PointsToNode* ptn = ptnode_adr(ni);
-      Node* n = ptn->_node;
-      assert(n != NULL, "should be known node");
-      build_connection_graph(n, igvn);
-    }
-    time.stop();
-  }
-  if ((iterations     >= CG_BUILD_ITER_LIMIT) ||
-      (time.seconds() >= CG_BUILD_TIME_LIMIT)) {
-    assert(false, err_msg("infinite EA connection graph build (%f sec, %d iterations) with %d nodes and worklist size %d",
-           time.seconds(), iterations, nodes_size(), length));
-    // Possible infinite build_connection_graph loop,
-    // bailout (no changes to ideal graph were made).
-    _collecting = false;
-    return false;
-  }
-#undef CG_BUILD_ITER_LIMIT
-#undef CG_BUILD_TIME_LIMIT
-
-  // 5. Propagate escaped states.
-  worklist.clear();
-
-  // mark all nodes reachable from GlobalEscape nodes
-  (void)propagate_escape_state(&cg_worklist, &worklist, PointsToNode::GlobalEscape);
-
-  // mark all nodes reachable from ArgEscape nodes
-  bool has_non_escaping_obj = propagate_escape_state(&cg_worklist, &worklist, PointsToNode::ArgEscape);
-
-  Arena* arena = Thread::current()->resource_area();
-  VectorSet visited(arena);
-
-  // 6. Find fields initializing values for not escaped allocations
-  uint alloc_length = alloc_worklist.length();
-  for (uint next = 0; next < alloc_length; ++next) {
-    Node* n = alloc_worklist.at(next);
-    PointsToNode::EscapeState es = ptnode_adr(n->_idx)->escape_state();
-    if (es == PointsToNode::NoEscape) {
-      has_non_escaping_obj = true;
-      if (n->is_Allocate()) {
-        find_init_values(n, &visited, igvn);
-        // The object allocated by this Allocate node will never be
-        // seen by an other thread. Mark it so that when it is
-        // expanded no MemBarStoreStore is added.
-        n->as_Allocate()->initialization()->set_does_not_escape();
-      }
-    } else if ((es == PointsToNode::ArgEscape) && n->is_Allocate()) {
-      // Same as above. Mark this Allocate node so that when it is
-      // expanded no MemBarStoreStore is added.
-      n->as_Allocate()->initialization()->set_does_not_escape();
-    }
-  }
-
-  uint cg_length = cg_worklist.length();
-
-  // Skip the rest of code if all objects escaped.
-  if (!has_non_escaping_obj) {
-    cg_length = 0;
-    addp_length = 0;
-  }
-
-  for (uint next = 0; next < cg_length; ++next) {
-    int ni = cg_worklist.at(next);
-    PointsToNode* ptn = ptnode_adr(ni);
-    PointsToNode::NodeType nt = ptn->node_type();
-    if (nt == PointsToNode::LocalVar || nt == PointsToNode::Field) {
-      if (ptn->edge_count() == 0) {
-        // No values were found. Assume the value was set
-        // outside this method - add edge to phantom object.
-        add_pointsto_edge(ni, _phantom_object);
-      }
-    }
-  }
-
-  // 7. Remove deferred edges from the graph.
-  for (uint next = 0; next < cg_length; ++next) {
-    int ni = cg_worklist.at(next);
-    PointsToNode* ptn = ptnode_adr(ni);
-    PointsToNode::NodeType nt = ptn->node_type();
-    if (nt == PointsToNode::LocalVar || nt == PointsToNode::Field) {
-      remove_deferred(ni, &worklist, &visited);
-    }
-  }
-
-  // 8. Adjust escape state of nonescaping objects.
-  for (uint next = 0; next < addp_length; ++next) {
-    Node* n = addp_worklist.at(next);
-    adjust_escape_state(n);
-  }
+static const char *esc_names[] = {
+  "UnknownEscape",
+  "NoEscape",
+  "ArgEscape",
+  "GlobalEscape"
+};
 
-  // push all NoEscape nodes on the worklist
-  worklist.clear();
-  for( uint next = 0; next < cg_length; ++next ) {
-    int nk = cg_worklist.at(next);
-    if (ptnode_adr(nk)->escape_state() == PointsToNode::NoEscape &&
-        !is_null_ptr(nk))
-      worklist.push(nk);
-  }
-
-  alloc_worklist.clear();
-  // Propagate scalar_replaceable value.
-  while(worklist.length() > 0) {
-    uint nk = worklist.pop();
-    PointsToNode* ptn = ptnode_adr(nk);
-    Node* n = ptn->_node;
-    bool scalar_replaceable = ptn->scalar_replaceable();
-    if (n->is_Allocate() && scalar_replaceable) {
-      // Push scalar replaceable allocations on alloc_worklist
-      // for processing in split_unique_types(). Note,
-      // following code may change scalar_replaceable value.
-      alloc_worklist.append(n);
-    }
-    uint e_cnt = ptn->edge_count();
-    for (uint ei = 0; ei < e_cnt; ei++) {
-      uint npi = ptn->edge_target(ei);
-      if (is_null_ptr(npi))
-        continue;
-      PointsToNode *np = ptnode_adr(npi);
-      if (np->escape_state() < PointsToNode::NoEscape) {
-        set_escape_state(npi, PointsToNode::NoEscape);
-        if (!scalar_replaceable) {
-          np->set_scalar_replaceable(false);
-        }
-        worklist.push(npi);
-      } else if (np->scalar_replaceable() && !scalar_replaceable) {
-        np->set_scalar_replaceable(false);
-        worklist.push(npi);
-      }
-    }
-  }
-
-  _collecting = false;
-  assert(C->unique() == nodes_size(), "there should be no new ideal nodes during ConnectionGraph build");
-
-  assert(ptnode_adr(_oop_null)->escape_state() == PointsToNode::NoEscape &&
-         ptnode_adr(_oop_null)->edge_count() == 0, "sanity");
-  if (UseCompressedOops) {
-    assert(ptnode_adr(_noop_null)->escape_state() == PointsToNode::NoEscape &&
-           ptnode_adr(_noop_null)->edge_count() == 0, "sanity");
-  }
-
-  if (EliminateLocks && has_non_escaping_obj) {
-    // Mark locks before changing ideal graph.
-    int cnt = C->macro_count();
-    for( int i=0; i < cnt; i++ ) {
-      Node *n = C->macro_node(i);
-      if (n->is_AbstractLock()) { // Lock and Unlock nodes
-        AbstractLockNode* alock = n->as_AbstractLock();
-        if (!alock->is_non_esc_obj()) {
-          PointsToNode::EscapeState es = escape_state(alock->obj_node());
-          assert(es != PointsToNode::UnknownEscape, "should know");
-          if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) {
-            assert(!alock->is_eliminated() || alock->is_coarsened(), "sanity");
-            // The lock could be marked eliminated by lock coarsening
-            // code during first IGVN before EA. Replace coarsened flag
-            // to eliminate all associated locks/unlocks.
-            alock->set_non_esc_obj();
-          }
-        }
-      }
-    }
-  }
-
-  if (OptimizePtrCompare && has_non_escaping_obj) {
-    // Add ConI(#CC_GT) and ConI(#CC_EQ).
-    _pcmp_neq = igvn->makecon(TypeInt::CC_GT);
-    _pcmp_eq = igvn->makecon(TypeInt::CC_EQ);
-    // Optimize objects compare.
-    while (ptr_cmp_worklist.length() != 0) {
-      Node *n = ptr_cmp_worklist.pop();
-      Node *res = optimize_ptr_compare(n);
-      if (res != NULL) {
-#ifndef PRODUCT
-        if (PrintOptimizePtrCompare) {
-          tty->print_cr("++++ Replaced: %d %s(%d,%d) --> %s", n->_idx, (n->Opcode() == Op_CmpP ? "CmpP" : "CmpN"), n->in(1)->_idx, n->in(2)->_idx, (res == _pcmp_eq ? "EQ" : "NotEQ"));
-          if (Verbose) {
-            n->dump(1);
-          }
-        }
-#endif
-        _igvn->replace_node(n, res);
-      }
-    }
-    // cleanup
-    if (_pcmp_neq->outcnt() == 0)
-      igvn->hash_delete(_pcmp_neq);
-    if (_pcmp_eq->outcnt()  == 0)
-      igvn->hash_delete(_pcmp_eq);
+void PointsToNode::dump(bool print_state) const {
+  NodeType nt = node_type();
+  tty->print("%s ", node_type_names[(int) nt]);
+  if (print_state) {
+    EscapeState es = escape_state();
+    EscapeState fields_es = fields_escape_state();
+    tty->print("%s(%s) ", esc_names[(int)es], esc_names[(int)fields_es]);
+    if (nt == PointsToNode::JavaObject && !this->scalar_replaceable())
+      tty->print("NSR");
   }
-
-  // For MemBarStoreStore nodes added in library_call.cpp, check
-  // escape status of associated AllocateNode and optimize out
-  // MemBarStoreStore node if the allocated object never escapes.
-  while (storestore_worklist.length() != 0) {
-    Node *n = storestore_worklist.pop();
-    MemBarStoreStoreNode *storestore = n ->as_MemBarStoreStore();
-    Node *alloc = storestore->in(MemBarNode::Precedent)->in(0);
-    assert (alloc->is_Allocate(), "storestore should point to AllocateNode");
-    PointsToNode::EscapeState es = ptnode_adr(alloc->_idx)->escape_state();
-    if (es == PointsToNode::NoEscape || es == PointsToNode::ArgEscape) {
-      MemBarNode* mb = MemBarNode::make(C, Op_MemBarCPUOrder, Compile::AliasIdxBot);
-      mb->init_req(TypeFunc::Memory, storestore->in(TypeFunc::Memory));
-      mb->init_req(TypeFunc::Control, storestore->in(TypeFunc::Control));
-
-      _igvn->register_new_node_with_optimizer(mb);
-      _igvn->replace_node(storestore, mb);
+  if (is_Field()) {
+    FieldNode* f = (FieldNode*)this;
+    tty->print("(");
+    for (BaseIterator i(f); i.has_next(); i.next()) {
+      PointsToNode* b = i.get();
+      tty->print(" %d%s", b->idx(),(b->is_JavaObject() ? "P" : ""));
     }
-  }
-
-#ifndef PRODUCT
-  if (PrintEscapeAnalysis) {
-    dump(); // Dump ConnectionGraph
-  }
-#endif
-
-  bool has_scalar_replaceable_candidates = false;
-  alloc_length = alloc_worklist.length();
-  for (uint next = 0; next < alloc_length; ++next) {
-    Node* n = alloc_worklist.at(next);
-    PointsToNode* ptn = ptnode_adr(n->_idx);
-    assert(ptn->escape_state() == PointsToNode::NoEscape, "sanity");
-    if (ptn->scalar_replaceable()) {
-      has_scalar_replaceable_candidates = true;
-      break;
-    }
-  }
-
-  if ( has_scalar_replaceable_candidates &&
-       C->AliasLevel() >= 3 && EliminateAllocations ) {
-
-    // Now use the escape information to create unique types for
-    // scalar replaceable objects.
-    split_unique_types(alloc_worklist);
-
-    if (C->failing())  return false;
-
-    C->print_method("After Escape Analysis", 2);
-
-#ifdef ASSERT
-  } else if (Verbose && (PrintEscapeAnalysis || PrintEliminateAllocations)) {
-    tty->print("=== No allocations eliminated for ");
-    C->method()->print_short_name();
-    if(!EliminateAllocations) {
-      tty->print(" since EliminateAllocations is off ===");
-    } else if(!has_scalar_replaceable_candidates) {
-      tty->print(" since there are no scalar replaceable candidates ===");
-    } else if(C->AliasLevel() < 3) {
-      tty->print(" since AliasLevel < 3 ===");
-    }
-    tty->cr();
-#endif
+    tty->print(" )");
   }
-  return has_non_escaping_obj;
-}
-
-// Find fields initializing values for allocations.
-void ConnectionGraph::find_init_values(Node* alloc, VectorSet* visited, PhaseTransform* phase) {
-  assert(alloc->is_Allocate(), "Should be called for Allocate nodes only");
-  PointsToNode* pta = ptnode_adr(alloc->_idx);
-  assert(pta->escape_state() == PointsToNode::NoEscape, "Not escaped Allocate nodes only");
-  InitializeNode* ini = alloc->as_Allocate()->initialization();
-
-  Compile* C = _compile;
-  visited->Reset();
-  // Check if a oop field's initializing value is recorded and add
-  // a corresponding NULL field's value if it is not recorded.
-  // Connection Graph does not record a default initialization by NULL
-  // captured by Initialize node.
-  //
-  uint null_idx = UseCompressedOops ? _noop_null : _oop_null;
-  uint ae_cnt = pta->edge_count();
-  bool visited_bottom_offset = false;
-  for (uint ei = 0; ei < ae_cnt; ei++) {
-    uint nidx = pta->edge_target(ei); // Field (AddP)
-    PointsToNode* ptn = ptnode_adr(nidx);
-    assert(ptn->_node->is_AddP(), "Should be AddP nodes only");
-    int offset = ptn->offset();
-    if (offset == Type::OffsetBot) {
-      if (!visited_bottom_offset) {
-        visited_bottom_offset = true;
-        // Check only oop fields.
-        const Type* adr_type = ptn->_node->as_AddP()->bottom_type();
-        if (!adr_type->isa_aryptr() ||
-            (adr_type->isa_aryptr()->klass() == NULL) ||
-             adr_type->isa_aryptr()->klass()->is_obj_array_klass()) {
-          // OffsetBot is used to reference array's element,
-          // always add reference to NULL since we don't
-          // known which element is referenced.
-          add_edge_from_fields(alloc->_idx, null_idx, offset);
-        }
-      }
-    } else if (offset != oopDesc::klass_offset_in_bytes() &&
-               !visited->test_set(offset)) {
-
-      // Check only oop fields.
-      const Type* adr_type = ptn->_node->as_AddP()->bottom_type();
-      BasicType basic_field_type = T_INT;
-      if (adr_type->isa_instptr()) {
-        ciField* field = C->alias_type(adr_type->isa_instptr())->field();
-        if (field != NULL) {
-          basic_field_type = field->layout_type();
-        } else {
-          // Ignore non field load (for example, klass load)
-        }
-      } else if (adr_type->isa_aryptr()) {
-        if (offset != arrayOopDesc::length_offset_in_bytes()) {
-          const Type* elemtype = adr_type->isa_aryptr()->elem();
-          basic_field_type = elemtype->array_element_basic_type();
-        } else {
-          // Ignore array length load
-        }
-#ifdef ASSERT
-      } else {
-        // Raw pointers are used for initializing stores so skip it
-        // since it should be recorded already
-        Node* base = get_addp_base(ptn->_node);
-        assert(adr_type->isa_rawptr() && base->is_Proj() &&
-               (base->in(0) == alloc),"unexpected pointer type");
-#endif
-      }
-      if (basic_field_type == T_OBJECT ||
-          basic_field_type == T_NARROWOOP ||
-          basic_field_type == T_ARRAY) {
-        Node* value = NULL;
-        if (ini != NULL) {
-          BasicType ft = UseCompressedOops ? T_NARROWOOP : T_OBJECT;
-          Node* store = ini->find_captured_store(offset, type2aelembytes(ft), phase);
-          if (store != NULL && store->is_Store()) {
-            value = store->in(MemNode::ValueIn);
-          } else {
-            // There could be initializing stores which follow allocation.
-            // For example, a volatile field store is not collected
-            // by Initialize node.
-            //
-            // Need to check for dependent loads to separate such stores from
-            // stores which follow loads. For now, add initial value NULL so
-            // that compare pointers optimization works correctly.
-          }
-        }
-        if (value == NULL || value != ptnode_adr(value->_idx)->_node) {
-          // A field's initializing value was not recorded. Add NULL.
-          add_edge_from_fields(alloc->_idx, null_idx, offset);
-        }
-      }
-    }
+  tty->print("[");
+  for (EdgeIterator i(this); i.has_next(); i.next()) {
+    PointsToNode* e = i.get();
+    tty->print(" %d%s%s", e->idx(),(e->is_JavaObject() ? "P" : (e->is_Field() ? "F" : "")), e->is_Arraycopy() ? "cp" : "");
   }
-}
-
-// Adjust escape state after Connection Graph is built.
-void ConnectionGraph::adjust_escape_state(Node* n) {
-  PointsToNode* ptn = ptnode_adr(n->_idx);
-  assert(n->is_AddP(), "Should be called for AddP nodes only");
-  // Search for objects which are not scalar replaceable
-  // and mark them to propagate the state to referenced objects.
-  //
-
-  int offset = ptn->offset();
-  Node* base = get_addp_base(n);
-  VectorSet* ptset = PointsTo(base);
-  int ptset_size = ptset->Size();
-
-  // An object is not scalar replaceable if the field which may point
-  // to it has unknown offset (unknown element of an array of objects).
-  //
-
-  if (offset == Type::OffsetBot) {
-    uint e_cnt = ptn->edge_count();
-    for (uint ei = 0; ei < e_cnt; ei++) {
-      uint npi = ptn->edge_target(ei);
-      ptnode_adr(npi)->set_scalar_replaceable(false);
-    }
-  }
-
-  // Currently an object is not scalar replaceable if a LoadStore node
-  // access its field since the field value is unknown after it.
-  //
-  bool has_LoadStore = false;
-  for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
-    Node *use = n->fast_out(i);
-    if (use->is_LoadStore()) {
-      has_LoadStore = true;
-      break;
-    }
-  }
-  // An object is not scalar replaceable if the address points
-  // to unknown field (unknown element for arrays, offset is OffsetBot).
-  //
-  // Or the address may point to more then one object. This may produce
-  // the false positive result (set not scalar replaceable)
-  // since the flow-insensitive escape analysis can't separate
-  // the case when stores overwrite the field's value from the case
-  // when stores happened on different control branches.
-  //
-  // Note: it will disable scalar replacement in some cases:
-  //
-  //    Point p[] = new Point[1];
-  //    p[0] = new Point(); // Will be not scalar replaced
-  //
-  // but it will save us from incorrect optimizations in next cases:
-  //
-  //    Point p[] = new Point[1];
-  //    if ( x ) p[0] = new Point(); // Will be not scalar replaced
-  //
-  if (ptset_size > 1 || ptset_size != 0 &&
-      (has_LoadStore || offset == Type::OffsetBot)) {
-    for( VectorSetI j(ptset); j.test(); ++j ) {
-      ptnode_adr(j.elem)->set_scalar_replaceable(false);
-    }
-  }
-}
-
-// Propagate escape states to referenced nodes.
-bool ConnectionGraph::propagate_escape_state(GrowableArray<int>* cg_worklist,
-                                             GrowableArray<uint>* worklist,
-                                             PointsToNode::EscapeState esc_state) {
-  bool has_java_obj = false;
-
-  // push all nodes with the same escape state on the worklist
-  uint cg_length = cg_worklist->length();
-  for (uint next = 0; next < cg_length; ++next) {
-    int nk = cg_worklist->at(next);
-    if (ptnode_adr(nk)->escape_state() == esc_state)
-      worklist->push(nk);
-  }
-  // mark all reachable nodes
-  while (worklist->length() > 0) {
-    int pt = worklist->pop();
-    PointsToNode* ptn = ptnode_adr(pt);
-    if (ptn->node_type() == PointsToNode::JavaObject &&
-        !is_null_ptr(pt)) {
-      has_java_obj = true;
-      if (esc_state > PointsToNode::NoEscape) {
-        // fields values are unknown if object escapes
-        add_edge_from_fields(pt, _phantom_object, Type::OffsetBot);
-      }
+  tty->print(" [");
+  for (UseIterator i(this); i.has_next(); i.next()) {
+    PointsToNode* u = i.get();
+    bool is_base = false;
+    if (PointsToNode::is_base_use(u)) {
+      is_base = true;
+      u = PointsToNode::get_use_node(u)->as_Field();
     }
-    uint e_cnt = ptn->edge_count();
-    for (uint ei = 0; ei < e_cnt; ei++) {
-      uint npi = ptn->edge_target(ei);
-      if (is_null_ptr(npi))
-        continue;
-      PointsToNode *np = ptnode_adr(npi);
-      if (np->escape_state() < esc_state) {
-        set_escape_state(npi, esc_state);
-        worklist->push(npi);
-      }
-    }
-  }
-  // Has not escaping java objects
-  return has_java_obj && (esc_state < PointsToNode::GlobalEscape);
-}
-
-// Optimize objects compare.
-Node* ConnectionGraph::optimize_ptr_compare(Node* n) {
-  assert(OptimizePtrCompare, "sanity");
-  // Clone returned Set since PointsTo() returns pointer
-  // to the same structure ConnectionGraph.pt_ptset.
-  VectorSet ptset1 = *PointsTo(n->in(1));
-  VectorSet ptset2 = *PointsTo(n->in(2));
-
-  // Check simple cases first.
-  if (ptset1.Size() == 1) {
-    uint pt1 = ptset1.getelem();
-    PointsToNode* ptn1 = ptnode_adr(pt1);
-    if (ptn1->escape_state() == PointsToNode::NoEscape) {
-      if (ptset2.Size() == 1 && ptset2.getelem() == pt1) {
-        // Comparing the same not escaping object.
-        return _pcmp_eq;
-      }
-      Node* obj = ptn1->_node;
-      // Comparing not escaping allocation.
-      if ((obj->is_Allocate() || obj->is_CallStaticJava()) &&
-          !ptset2.test(pt1)) {
-        return _pcmp_neq; // This includes nullness check.
-      }
-    }
-  } else if (ptset2.Size() == 1) {
-    uint pt2 = ptset2.getelem();
-    PointsToNode* ptn2 = ptnode_adr(pt2);
-    if (ptn2->escape_state() == PointsToNode::NoEscape) {
-      Node* obj = ptn2->_node;
-      // Comparing not escaping allocation.
-      if ((obj->is_Allocate() || obj->is_CallStaticJava()) &&
-          !ptset1.test(pt2)) {
-        return _pcmp_neq; // This includes nullness check.
-      }
-    }
+    tty->print(" %d%s%s", u->idx(), is_base ? "b" : "", u->is_Arraycopy() ? "cp" : "");
   }
-
-  if (!ptset1.disjoint(ptset2)) {
-    return NULL; // Sets are not disjoint
-  }
-
-  // Sets are disjoint.
-  bool set1_has_unknown_ptr = ptset1.test(_phantom_object) != 0;
-  bool set2_has_unknown_ptr = ptset2.test(_phantom_object) != 0;
-  bool set1_has_null_ptr   = (ptset1.test(_oop_null) | ptset1.test(_noop_null)) != 0;
-  bool set2_has_null_ptr   = (ptset2.test(_oop_null) | ptset2.test(_noop_null)) != 0;
-
-  if (set1_has_unknown_ptr && set2_has_null_ptr ||
-      set2_has_unknown_ptr && set1_has_null_ptr) {
-    // Check nullness of unknown object.
-    return NULL;
-  }
-
-  // Disjointness by itself is not sufficient since
-  // alias analysis is not complete for escaped objects.
-  // Disjoint sets are definitely unrelated only when
-  // at least one set has only not escaping objects.
-  if (!set1_has_unknown_ptr && !set1_has_null_ptr) {
-    bool has_only_non_escaping_alloc = true;
-    for (VectorSetI i(&ptset1); i.test(); ++i) {
-      uint pt = i.elem;
-      PointsToNode* ptn = ptnode_adr(pt);
-      Node* obj = ptn->_node;
-      if (ptn->escape_state() != PointsToNode::NoEscape ||
-          !(obj->is_Allocate() || obj->is_CallStaticJava())) {
-        has_only_non_escaping_alloc = false;
-        break;
-      }
-    }
-    if (has_only_non_escaping_alloc) {
-      return _pcmp_neq;
-    }
-  }
-  if (!set2_has_unknown_ptr && !set2_has_null_ptr) {
-    bool has_only_non_escaping_alloc = true;
-    for (VectorSetI i(&ptset2); i.test(); ++i) {
-      uint pt = i.elem;
-      PointsToNode* ptn = ptnode_adr(pt);
-      Node* obj = ptn->_node;
-      if (ptn->escape_state() != PointsToNode::NoEscape ||
-          !(obj->is_Allocate() || obj->is_CallStaticJava())) {
-        has_only_non_escaping_alloc = false;
-        break;
-      }
-    }
-    if (has_only_non_escaping_alloc) {
-      return _pcmp_neq;
-    }
-  }
-  return NULL;
+  tty->print(" ]]  ");
+  if (_node == NULL)
+    tty->print_cr("<null>");
+  else
+    _node->dump();
 }
 
-void ConnectionGraph::process_call_arguments(CallNode *call, PhaseTransform *phase) {
-    bool is_arraycopy = false;
-    switch (call->Opcode()) {
-#ifdef ASSERT
-    case Op_Allocate:
-    case Op_AllocateArray:
-    case Op_Lock:
-    case Op_Unlock:
-      assert(false, "should be done already");
-      break;
-#endif
-    case Op_CallLeafNoFP:
-      is_arraycopy = (call->as_CallLeaf()->_name != NULL &&
-                      strstr(call->as_CallLeaf()->_name, "arraycopy") != 0);
-      // fall through
-    case Op_CallLeaf:
-    {
-      // Stub calls, objects do not escape but they are not scale replaceable.
-      // Adjust escape state for outgoing arguments.
-      const TypeTuple * d = call->tf()->domain();
-      bool src_has_oops = false;
-      for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
-        const Type* at = d->field_at(i);
-        Node *arg = call->in(i)->uncast();
-        const Type *aat = phase->type(arg);
-        PointsToNode::EscapeState arg_esc = ptnode_adr(arg->_idx)->escape_state();
-        if (!arg->is_top() && at->isa_ptr() && aat->isa_ptr() &&
-            (is_arraycopy || arg_esc < PointsToNode::ArgEscape)) {
-#ifdef ASSERT
-          assert(aat == Type::TOP || aat == TypePtr::NULL_PTR ||
-                 aat->isa_ptr() != NULL, "expecting an Ptr");
-          if (!(is_arraycopy ||
-                call->as_CallLeaf()->_name != NULL &&
-                (strcmp(call->as_CallLeaf()->_name, "g1_wb_pre")  == 0 ||
-                 strcmp(call->as_CallLeaf()->_name, "g1_wb_post") == 0 ))
-          ) {
-            call->dump();
-            assert(false, "EA: unexpected CallLeaf");
-          }
-#endif
-          if (arg_esc < PointsToNode::ArgEscape) {
-            set_escape_state(arg->_idx, PointsToNode::ArgEscape);
-            Node* arg_base = arg;
-            if (arg->is_AddP()) {
-              //
-              // The inline_native_clone() case when the arraycopy stub is called
-              // after the allocation before Initialize and CheckCastPP nodes.
-              // Or normal arraycopy for object arrays case.
-              //
-              // Set AddP's base (Allocate) as not scalar replaceable since
-              // pointer to the base (with offset) is passed as argument.
-              //
-              arg_base = get_addp_base(arg);
-              set_escape_state(arg_base->_idx, PointsToNode::ArgEscape);
-            }
-          }
-
-          bool arg_has_oops = aat->isa_oopptr() &&
-                              (aat->isa_oopptr()->klass() == NULL || aat->isa_instptr() ||
-                               (aat->isa_aryptr() && aat->isa_aryptr()->klass()->is_obj_array_klass()));
-          if (i == TypeFunc::Parms) {
-            src_has_oops = arg_has_oops;
-          }
-          //
-          // src or dst could be j.l.Object when other is basic type array:
-          //
-          //   arraycopy(char[],0,Object*,0,size);
-          //   arraycopy(Object*,0,char[],0,size);
-          //
-          // Do nothing special in such cases.
-          //
-          if (is_arraycopy && (i > TypeFunc::Parms) &&
-              src_has_oops && arg_has_oops) {
-            // Destination object's fields reference an unknown object.
-            Node* arg_base = arg;
-            if (arg->is_AddP()) {
-              arg_base = get_addp_base(arg);
-            }
-            for (VectorSetI s(PointsTo(arg_base)); s.test(); ++s) {
-              uint ps = s.elem;
-              set_escape_state(ps, PointsToNode::ArgEscape);
-              add_edge_from_fields(ps, _phantom_object, Type::OffsetBot);
-            }
-            // Conservatively all values in source object fields globally escape
-            // since we don't know if values in destination object fields
-            // escape (it could be traced but it is too expensive).
-            Node* src = call->in(TypeFunc::Parms)->uncast();
-            Node* src_base = src;
-            if (src->is_AddP()) {
-              src_base  = get_addp_base(src);
-            }
-            for (VectorSetI s(PointsTo(src_base)); s.test(); ++s) {
-              uint ps = s.elem;
-              set_escape_state(ps, PointsToNode::ArgEscape);
-              // Use OffsetTop to indicate fields global escape.
-              add_edge_from_fields(ps, _phantom_object, Type::OffsetTop);
-            }
-          }
-        }
-      }
-      break;
-    }
-
-    case Op_CallStaticJava:
-    // For a static call, we know exactly what method is being called.
-    // Use bytecode estimator to record the call's escape affects
-    {
-      ciMethod *meth = call->as_CallJava()->method();
-      BCEscapeAnalyzer *call_analyzer = (meth !=NULL) ? meth->get_bcea() : NULL;
-      // fall-through if not a Java method or no analyzer information
-      if (call_analyzer != NULL) {
-        const TypeTuple * d = call->tf()->domain();
-        bool copy_dependencies = false;
-        for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
-          const Type* at = d->field_at(i);
-          int k = i - TypeFunc::Parms;
-          Node *arg = call->in(i)->uncast();
-
-          if (at->isa_oopptr() != NULL &&
-              ptnode_adr(arg->_idx)->escape_state() < PointsToNode::GlobalEscape) {
-
-            bool global_escapes = false;
-            bool fields_escapes = false;
-            if (!call_analyzer->is_arg_stack(k)) {
-              // The argument global escapes, mark everything it could point to
-              set_escape_state(arg->_idx, PointsToNode::GlobalEscape);
-              global_escapes = true;
-            } else {
-              if (!call_analyzer->is_arg_local(k)) {
-                // The argument itself doesn't escape, but any fields might
-                fields_escapes = true;
-              }
-              set_escape_state(arg->_idx, PointsToNode::ArgEscape);
-              copy_dependencies = true;
-            }
-
-            for( VectorSetI j(PointsTo(arg)); j.test(); ++j ) {
-              uint pt = j.elem;
-              if (global_escapes) {
-                // The argument global escapes, mark everything it could point to
-                set_escape_state(pt, PointsToNode::GlobalEscape);
-                add_edge_from_fields(pt, _phantom_object, Type::OffsetBot);
-              } else {
-                set_escape_state(pt, PointsToNode::ArgEscape);
-                if (fields_escapes) {
-                  // The argument itself doesn't escape, but any fields might.
-                  // Use OffsetTop to indicate such case.
-                  add_edge_from_fields(pt, _phantom_object, Type::OffsetTop);
-                }
-              }
-            }
-          }
-        }
-        if (copy_dependencies)
-          call_analyzer->copy_dependencies(_compile->dependencies());
-        break;
-      }
-    }
-
-    default:
-    // Fall-through here if not a Java method or no analyzer information
-    // or some other type of call, assume the worst case: all arguments
-    // globally escape.
-    {
-      // adjust escape state for  outgoing arguments
-      const TypeTuple * d = call->tf()->domain();
-      for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
-        const Type* at = d->field_at(i);
-        if (at->isa_oopptr() != NULL) {
-          Node *arg = call->in(i)->uncast();
-          set_escape_state(arg->_idx, PointsToNode::GlobalEscape);
-          for( VectorSetI j(PointsTo(arg)); j.test(); ++j ) {
-            uint pt = j.elem;
-            set_escape_state(pt, PointsToNode::GlobalEscape);
-            add_edge_from_fields(pt, _phantom_object, Type::OffsetBot);
-          }
-        }
-      }
-    }
-  }
-}
-void ConnectionGraph::process_call_result(ProjNode *resproj, PhaseTransform *phase) {
-  CallNode   *call = resproj->in(0)->as_Call();
-  uint    call_idx = call->_idx;
-  uint resproj_idx = resproj->_idx;
-
-  switch (call->Opcode()) {
-    case Op_Allocate:
-    {
-      Node *k = call->in(AllocateNode::KlassNode);
-      const TypeKlassPtr *kt = k->bottom_type()->isa_klassptr();
-      assert(kt != NULL, "TypeKlassPtr  required.");
-      ciKlass* cik = kt->klass();
-
-      PointsToNode::EscapeState es;
-      uint edge_to;
-      if (cik->is_subclass_of(_compile->env()->Thread_klass()) ||
-         !cik->is_instance_klass() || // StressReflectiveCode
-          cik->as_instance_klass()->has_finalizer()) {
-        es = PointsToNode::GlobalEscape;
-        edge_to = _phantom_object; // Could not be worse
-      } else {
-        es = PointsToNode::NoEscape;
-        edge_to = call_idx;
-        assert(ptnode_adr(call_idx)->scalar_replaceable(), "sanity");
-      }
-      set_escape_state(call_idx, es);
-      add_pointsto_edge(resproj_idx, edge_to);
-      _processed.set(resproj_idx);
-      break;
-    }
-
-    case Op_AllocateArray:
-    {
-
-      Node *k = call->in(AllocateNode::KlassNode);
-      const TypeKlassPtr *kt = k->bottom_type()->isa_klassptr();
-      assert(kt != NULL, "TypeKlassPtr  required.");
-      ciKlass* cik = kt->klass();
-
-      PointsToNode::EscapeState es;
-      uint edge_to;
-      if (!cik->is_array_klass()) { // StressReflectiveCode
-        es = PointsToNode::GlobalEscape;
-        edge_to = _phantom_object;
-      } else {
-        es = PointsToNode::NoEscape;
-        edge_to = call_idx;
-        assert(ptnode_adr(call_idx)->scalar_replaceable(), "sanity");
-        int length = call->in(AllocateNode::ALength)->find_int_con(-1);
-        if (length < 0 || length > EliminateAllocationArraySizeLimit) {
-          // Not scalar replaceable if the length is not constant or too big.
-          ptnode_adr(call_idx)->set_scalar_replaceable(false);
-        }
-      }
-      set_escape_state(call_idx, es);
-      add_pointsto_edge(resproj_idx, edge_to);
-      _processed.set(resproj_idx);
-      break;
-    }
-
-    case Op_CallStaticJava:
-    // For a static call, we know exactly what method is being called.
-    // Use bytecode estimator to record whether the call's return value escapes
-    {
-      bool done = true;
-      const TypeTuple *r = call->tf()->range();
-      const Type* ret_type = NULL;
-
-      if (r->cnt() > TypeFunc::Parms)
-        ret_type = r->field_at(TypeFunc::Parms);
-
-      // Note:  we use isa_ptr() instead of isa_oopptr()  here because the
-      //        _multianewarray functions return a TypeRawPtr.
-      if (ret_type == NULL || ret_type->isa_ptr() == NULL) {
-        _processed.set(resproj_idx);
-        break;  // doesn't return a pointer type
-      }
-      ciMethod *meth = call->as_CallJava()->method();
-      const TypeTuple * d = call->tf()->domain();
-      if (meth == NULL) {
-        // not a Java method, assume global escape
-        set_escape_state(call_idx, PointsToNode::GlobalEscape);
-        add_pointsto_edge(resproj_idx, _phantom_object);
-      } else {
-        BCEscapeAnalyzer *call_analyzer = meth->get_bcea();
-        bool copy_dependencies = false;
-
-        if (call_analyzer->is_return_allocated()) {
-          // Returns a newly allocated unescaped object, simply
-          // update dependency information.
-          // Mark it as NoEscape so that objects referenced by
-          // it's fields will be marked as NoEscape at least.
-          set_escape_state(call_idx, PointsToNode::NoEscape);
-          ptnode_adr(call_idx)->set_scalar_replaceable(false);
-          // Fields values are unknown
-          add_edge_from_fields(call_idx, _phantom_object, Type::OffsetBot);
-          add_pointsto_edge(resproj_idx, call_idx);
-          copy_dependencies = true;
-        } else {
-          // determine whether any arguments are returned
-          set_escape_state(call_idx, PointsToNode::ArgEscape);
-          bool ret_arg = false;
-          for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
-            const Type* at = d->field_at(i);
-            if (at->isa_oopptr() != NULL) {
-              Node *arg = call->in(i)->uncast();
-
-              if (call_analyzer->is_arg_returned(i - TypeFunc::Parms)) {
-                ret_arg = true;
-                PointsToNode *arg_esp = ptnode_adr(arg->_idx);
-                if (arg_esp->node_type() == PointsToNode::UnknownType)
-                  done = false;
-                else if (arg_esp->node_type() == PointsToNode::JavaObject)
-                  add_pointsto_edge(resproj_idx, arg->_idx);
-                else
-                  add_deferred_edge(resproj_idx, arg->_idx);
-              }
-            }
-          }
-          if (done) {
-            copy_dependencies = true;
-            // is_return_local() is true when only arguments are returned.
-            if (!ret_arg || !call_analyzer->is_return_local()) {
-              // Returns unknown object.
-              add_pointsto_edge(resproj_idx, _phantom_object);
-            }
-          }
-        }
-        if (copy_dependencies)
-          call_analyzer->copy_dependencies(_compile->dependencies());
-      }
-      if (done)
-        _processed.set(resproj_idx);
-      break;
-    }
-
-    default:
-    // Some other type of call, assume the worst case that the
-    // returned value, if any, globally escapes.
-    {
-      const TypeTuple *r = call->tf()->range();
-      if (r->cnt() > TypeFunc::Parms) {
-        const Type* ret_type = r->field_at(TypeFunc::Parms);
-
-        // Note:  we use isa_ptr() instead of isa_oopptr()  here because the
-        //        _multianewarray functions return a TypeRawPtr.
-        if (ret_type->isa_ptr() != NULL) {
-          set_escape_state(call_idx, PointsToNode::GlobalEscape);
-          add_pointsto_edge(resproj_idx, _phantom_object);
-        }
-      }
-      _processed.set(resproj_idx);
-    }
-  }
-}
-
-// Populate Connection Graph with Ideal nodes and create simple
-// connection graph edges (do not need to check the node_type of inputs
-// or to call PointsTo() to walk the connection graph).
-void ConnectionGraph::record_for_escape_analysis(Node *n, PhaseTransform *phase) {
-  if (_processed.test(n->_idx))
-    return; // No need to redefine node's state.
-
-  if (n->is_Call()) {
-    // Arguments to allocation and locking don't escape.
-    if (n->is_Allocate()) {
-      add_node(n, PointsToNode::JavaObject, PointsToNode::UnknownEscape, true);
-      record_for_optimizer(n);
-    } else if (n->is_Lock() || n->is_Unlock()) {
-      // Put Lock and Unlock nodes on IGVN worklist to process them during
-      // the first IGVN optimization when escape information is still available.
-      record_for_optimizer(n);
-      _processed.set(n->_idx);
-    } else {
-      // Don't mark as processed since call's arguments have to be processed.
-      PointsToNode::NodeType nt = PointsToNode::UnknownType;
-      PointsToNode::EscapeState es = PointsToNode::UnknownEscape;
-
-      // Check if a call returns an object.
-      const TypeTuple *r = n->as_Call()->tf()->range();
-      if (r->cnt() > TypeFunc::Parms &&
-          r->field_at(TypeFunc::Parms)->isa_ptr() &&
-          n->as_Call()->proj_out(TypeFunc::Parms) != NULL) {
-        nt = PointsToNode::JavaObject;
-        if (!n->is_CallStaticJava()) {
-          // Since the called mathod is statically unknown assume
-          // the worst case that the returned value globally escapes.
-          es = PointsToNode::GlobalEscape;
-        }
-      }
-      add_node(n, nt, es, false);
-    }
-    return;
-  }
-
-  // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
-  // ThreadLocal has RawPrt type.
-  switch (n->Opcode()) {
-    case Op_AddP:
-    {
-      add_node(n, PointsToNode::Field, PointsToNode::UnknownEscape, false);
-      break;
-    }
-    case Op_CastX2P:
-    { // "Unsafe" memory access.
-      add_node(n, PointsToNode::JavaObject, PointsToNode::GlobalEscape, true);
-      break;
-    }
-    case Op_CastPP:
-    case Op_CheckCastPP:
-    case Op_EncodeP:
-    case Op_DecodeN:
-    {
-      add_node(n, PointsToNode::LocalVar, PointsToNode::UnknownEscape, false);
-      int ti = n->in(1)->_idx;
-      PointsToNode::NodeType nt = ptnode_adr(ti)->node_type();
-      if (nt == PointsToNode::UnknownType) {
-        _delayed_worklist.push(n); // Process it later.
-        break;
-      } else if (nt == PointsToNode::JavaObject) {
-        add_pointsto_edge(n->_idx, ti);
-      } else {
-        add_deferred_edge(n->_idx, ti);
-      }
-      _processed.set(n->_idx);
-      break;
-    }
-    case Op_ConP:
-    {
-      // assume all pointer constants globally escape except for null
-      PointsToNode::EscapeState es;
-      if (phase->type(n) == TypePtr::NULL_PTR)
-        es = PointsToNode::NoEscape;
-      else
-        es = PointsToNode::GlobalEscape;
-
-      add_node(n, PointsToNode::JavaObject, es, true);
-      break;
-    }
-    case Op_ConN:
-    {
-      // assume all narrow oop constants globally escape except for null
-      PointsToNode::EscapeState es;
-      if (phase->type(n) == TypeNarrowOop::NULL_PTR)
-        es = PointsToNode::NoEscape;
-      else
-        es = PointsToNode::GlobalEscape;
-
-      add_node(n, PointsToNode::JavaObject, es, true);
-      break;
-    }
-    case Op_CreateEx:
-    {
-      // assume that all exception objects globally escape
-      add_node(n, PointsToNode::JavaObject, PointsToNode::GlobalEscape, true);
-      break;
-    }
-    case Op_LoadKlass:
-    case Op_LoadNKlass:
-    {
-      add_node(n, PointsToNode::JavaObject, PointsToNode::GlobalEscape, true);
-      break;
-    }
-    case Op_LoadP:
-    case Op_LoadN:
-    {
-      const Type *t = phase->type(n);
-      if (t->make_ptr() == NULL) {
-        _processed.set(n->_idx);
-        return;
-      }
-      add_node(n, PointsToNode::LocalVar, PointsToNode::UnknownEscape, false);
-      break;
-    }
-    case Op_Parm:
-    {
-      _processed.set(n->_idx); // No need to redefine it state.
-      uint con = n->as_Proj()->_con;
-      if (con < TypeFunc::Parms)
-        return;
-      const Type *t = n->in(0)->as_Start()->_domain->field_at(con);
-      if (t->isa_ptr() == NULL)
-        return;
-      // We have to assume all input parameters globally escape
-      // (Note: passing 'false' since _processed is already set).
-      add_node(n, PointsToNode::JavaObject, PointsToNode::GlobalEscape, false);
-      break;
-    }
-    case Op_PartialSubtypeCheck:
-    { // Produces Null or notNull and is used in CmpP.
-      add_node(n, PointsToNode::JavaObject, PointsToNode::ArgEscape, true);
-      break;
-    }
-    case Op_Phi:
-    {
-      const Type *t = n->as_Phi()->type();
-      if (t->make_ptr() == NULL) {
-        // nothing to do if not an oop or narrow oop
-        _processed.set(n->_idx);
-        return;
-      }
-      add_node(n, PointsToNode::LocalVar, PointsToNode::UnknownEscape, false);
-      uint i;
-      for (i = 1; i < n->req() ; i++) {
-        Node* in = n->in(i);
-        if (in == NULL)
-          continue;  // ignore NULL
-        in = in->uncast();
-        if (in->is_top() || in == n)
-          continue;  // ignore top or inputs which go back this node
-        int ti = in->_idx;
-        PointsToNode::NodeType nt = ptnode_adr(ti)->node_type();
-        if (nt == PointsToNode::UnknownType) {
-          break;
-        } else if (nt == PointsToNode::JavaObject) {
-          add_pointsto_edge(n->_idx, ti);
-        } else {
-          add_deferred_edge(n->_idx, ti);
-        }
-      }
-      if (i >= n->req())
-        _processed.set(n->_idx);
-      else
-        _delayed_worklist.push(n);
-      break;
-    }
-    case Op_Proj:
-    {
-      // we are only interested in the oop result projection from a call
-      if (n->as_Proj()->_con == TypeFunc::Parms && n->in(0)->is_Call() ) {
-        const TypeTuple *r = n->in(0)->as_Call()->tf()->range();
-        assert(r->cnt() > TypeFunc::Parms, "sanity");
-        if (r->field_at(TypeFunc::Parms)->isa_ptr() != NULL) {
-          add_node(n, PointsToNode::LocalVar, PointsToNode::UnknownEscape, false);
-          int ti = n->in(0)->_idx;
-          // The call may not be registered yet (since not all its inputs are registered)
-          // if this is the projection from backbranch edge of Phi.
-          if (ptnode_adr(ti)->node_type() != PointsToNode::UnknownType) {
-            process_call_result(n->as_Proj(), phase);
-          }
-          if (!_processed.test(n->_idx)) {
-            // The call's result may need to be processed later if the call
-            // returns it's argument and the argument is not processed yet.
-            _delayed_worklist.push(n);
-          }
-          break;
-        }
-      }
-      _processed.set(n->_idx);
-      break;
-    }
-    case Op_Return:
-    {
-      if( n->req() > TypeFunc::Parms &&
-          phase->type(n->in(TypeFunc::Parms))->isa_oopptr() ) {
-        // Treat Return value as LocalVar with GlobalEscape escape state.
-        add_node(n, PointsToNode::LocalVar, PointsToNode::GlobalEscape, false);
-        int ti = n->in(TypeFunc::Parms)->_idx;
-        PointsToNode::NodeType nt = ptnode_adr(ti)->node_type();
-        if (nt == PointsToNode::UnknownType) {
-          _delayed_worklist.push(n); // Process it later.
-          break;
-        } else if (nt == PointsToNode::JavaObject) {
-          add_pointsto_edge(n->_idx, ti);
-        } else {
-          add_deferred_edge(n->_idx, ti);
-        }
-      }
-      _processed.set(n->_idx);
-      break;
-    }
-    case Op_StoreP:
-    case Op_StoreN:
-    {
-      const Type *adr_type = phase->type(n->in(MemNode::Address));
-      adr_type = adr_type->make_ptr();
-      if (adr_type->isa_oopptr()) {
-        add_node(n, PointsToNode::UnknownType, PointsToNode::UnknownEscape, false);
-      } else {
-        Node* adr = n->in(MemNode::Address);
-        if (adr->is_AddP() && phase->type(adr) == TypeRawPtr::NOTNULL &&
-            adr->in(AddPNode::Address)->is_Proj() &&
-            adr->in(AddPNode::Address)->in(0)->is_Allocate()) {
-          add_node(n, PointsToNode::UnknownType, PointsToNode::UnknownEscape, false);
-          // We are computing a raw address for a store captured
-          // by an Initialize compute an appropriate address type.
-          int offs = (int)phase->find_intptr_t_con(adr->in(AddPNode::Offset), Type::OffsetBot);
-          assert(offs != Type::OffsetBot, "offset must be a constant");
-        } else {
-          _processed.set(n->_idx);
-          return;
-        }
-      }
-      break;
-    }
-    case Op_StorePConditional:
-    case Op_CompareAndSwapP:
-    case Op_CompareAndSwapN:
-    {
-      const Type *adr_type = phase->type(n->in(MemNode::Address));
-      adr_type = adr_type->make_ptr();
-      if (adr_type->isa_oopptr()) {
-        add_node(n, PointsToNode::UnknownType, PointsToNode::UnknownEscape, false);
-      } else {
-        _processed.set(n->_idx);
-        return;
-      }
-      break;
-    }
-    case Op_AryEq:
-    case Op_StrComp:
-    case Op_StrEquals:
-    case Op_StrIndexOf:
-    {
-      // char[] arrays passed to string intrinsics are not scalar replaceable.
-      add_node(n, PointsToNode::UnknownType, PointsToNode::UnknownEscape, false);
-      break;
-    }
-    case Op_ThreadLocal:
-    {
-      add_node(n, PointsToNode::JavaObject, PointsToNode::ArgEscape, true);
-      break;
-    }
-    default:
-      ;
-      // nothing to do
-  }
-  return;
-}
-
-void ConnectionGraph::build_connection_graph(Node *n, PhaseTransform *phase) {
-  uint n_idx = n->_idx;
-  assert(ptnode_adr(n_idx)->_node != NULL, "node should be registered");
-
-  // Don't set processed bit for AddP, LoadP, StoreP since
-  // they may need more then one pass to process.
-  // Also don't mark as processed Call nodes since their
-  // arguments may need more then one pass to process.
-  if (_processed.test(n_idx))
-    return; // No need to redefine node's state.
-
-  if (n->is_Call()) {
-    CallNode *call = n->as_Call();
-    process_call_arguments(call, phase);
-    return;
-  }
-
-  switch (n->Opcode()) {
-    case Op_AddP:
-    {
-      Node *base = get_addp_base(n);
-      int offset = address_offset(n, phase);
-      // Create a field edge to this node from everything base could point to.
-      for( VectorSetI i(PointsTo(base)); i.test(); ++i ) {
-        uint pt = i.elem;
-        add_field_edge(pt, n_idx, offset);
-      }
-      break;
-    }
-    case Op_CastX2P:
-    {
-      assert(false, "Op_CastX2P");
-      break;
-    }
-    case Op_CastPP:
-    case Op_CheckCastPP:
-    case Op_EncodeP:
-    case Op_DecodeN:
-    {
-      int ti = n->in(1)->_idx;
-      assert(ptnode_adr(ti)->node_type() != PointsToNode::UnknownType, "all nodes should be registered");
-      if (ptnode_adr(ti)->node_type() == PointsToNode::JavaObject) {
-        add_pointsto_edge(n_idx, ti);
-      } else {
-        add_deferred_edge(n_idx, ti);
-      }
-      _processed.set(n_idx);
-      break;
-    }
-    case Op_ConP:
-    {
-      assert(false, "Op_ConP");
-      break;
-    }
-    case Op_ConN:
-    {
-      assert(false, "Op_ConN");
-      break;
-    }
-    case Op_CreateEx:
-    {
-      assert(false, "Op_CreateEx");
-      break;
-    }
-    case Op_LoadKlass:
-    case Op_LoadNKlass:
-    {
-      assert(false, "Op_LoadKlass");
-      break;
-    }
-    case Op_LoadP:
-    case Op_LoadN:
-    {
-      const Type *t = phase->type(n);
-#ifdef ASSERT
-      if (t->make_ptr() == NULL)
-        assert(false, "Op_LoadP");
-#endif
-
-      Node* adr = n->in(MemNode::Address)->uncast();
-      Node* adr_base;
-      if (adr->is_AddP()) {
-        adr_base = get_addp_base(adr);
-      } else {
-        adr_base = adr;
-      }
-
-      // For everything "adr_base" could point to, create a deferred edge from
-      // this node to each field with the same offset.
-      int offset = address_offset(adr, phase);
-      for( VectorSetI i(PointsTo(adr_base)); i.test(); ++i ) {
-        uint pt = i.elem;
-        if (adr->is_AddP()) {
-          // Add field edge if it is missing.
-          add_field_edge(pt, adr->_idx, offset);
-        }
-        add_deferred_edge_to_fields(n_idx, pt, offset);
-      }
-      break;
-    }
-    case Op_Parm:
-    {
-      assert(false, "Op_Parm");
-      break;
-    }
-    case Op_PartialSubtypeCheck:
-    {
-      assert(false, "Op_PartialSubtypeCheck");
-      break;
-    }
-    case Op_Phi:
-    {
-#ifdef ASSERT
-      const Type *t = n->as_Phi()->type();
-      if (t->make_ptr() == NULL)
-        assert(false, "Op_Phi");
-#endif
-      for (uint i = 1; i < n->req() ; i++) {
-        Node* in = n->in(i);
-        if (in == NULL)
-          continue;  // ignore NULL
-        in = in->uncast();
-        if (in->is_top() || in == n)
-          continue;  // ignore top or inputs which go back this node
-        int ti = in->_idx;
-        PointsToNode::NodeType nt = ptnode_adr(ti)->node_type();
-        assert(nt != PointsToNode::UnknownType, "all nodes should be known");
-        if (nt == PointsToNode::JavaObject) {
-          add_pointsto_edge(n_idx, ti);
-        } else {
-          add_deferred_edge(n_idx, ti);
-        }
-      }
-      _processed.set(n_idx);
-      break;
-    }
-    case Op_Proj:
-    {
-      // we are only interested in the oop result projection from a call
-      if (n->as_Proj()->_con == TypeFunc::Parms && n->in(0)->is_Call() ) {
-        assert(ptnode_adr(n->in(0)->_idx)->node_type() != PointsToNode::UnknownType,
-               "all nodes should be registered");
-        const TypeTuple *r = n->in(0)->as_Call()->tf()->range();
-        assert(r->cnt() > TypeFunc::Parms, "sanity");
-        if (r->field_at(TypeFunc::Parms)->isa_ptr() != NULL) {
-          process_call_result(n->as_Proj(), phase);
-          assert(_processed.test(n_idx), "all call results should be processed");
-          break;
-        }
-      }
-      assert(false, "Op_Proj");
-      break;
-    }
-    case Op_Return:
-    {
-#ifdef ASSERT
-      if( n->req() <= TypeFunc::Parms ||
-          !phase->type(n->in(TypeFunc::Parms))->isa_oopptr() ) {
-        assert(false, "Op_Return");
-      }
-#endif
-      int ti = n->in(TypeFunc::Parms)->_idx;
-      assert(ptnode_adr(ti)->node_type() != PointsToNode::UnknownType, "node should be registered");
-      if (ptnode_adr(ti)->node_type() == PointsToNode::JavaObject) {
-        add_pointsto_edge(n_idx, ti);
-      } else {
-        add_deferred_edge(n_idx, ti);
-      }
-      _processed.set(n_idx);
-      break;
-    }
-    case Op_StoreP:
-    case Op_StoreN:
-    case Op_StorePConditional:
-    case Op_CompareAndSwapP:
-    case Op_CompareAndSwapN:
-    {
-      Node *adr = n->in(MemNode::Address);
-      const Type *adr_type = phase->type(adr)->make_ptr();
-#ifdef ASSERT
-      if (!adr_type->isa_oopptr())
-        assert(phase->type(adr) == TypeRawPtr::NOTNULL, "Op_StoreP");
-#endif
-
-      assert(adr->is_AddP(), "expecting an AddP");
-      Node *adr_base = get_addp_base(adr);
-      Node *val = n->in(MemNode::ValueIn)->uncast();
-      int offset = address_offset(adr, phase);
-      // For everything "adr_base" could point to, create a deferred edge
-      // to "val" from each field with the same offset.
-      for( VectorSetI i(PointsTo(adr_base)); i.test(); ++i ) {
-        uint pt = i.elem;
-        // Add field edge if it is missing.
-        add_field_edge(pt, adr->_idx, offset);
-        add_edge_from_fields(pt, val->_idx, offset);
-      }
-      break;
-    }
-    case Op_AryEq:
-    case Op_StrComp:
-    case Op_StrEquals:
-    case Op_StrIndexOf:
-    {
-      // char[] arrays passed to string intrinsic do not escape but
-      // they are not scalar replaceable. Adjust escape state for them.
-      // Start from in(2) edge since in(1) is memory edge.
-      for (uint i = 2; i < n->req(); i++) {
-        Node* adr = n->in(i)->uncast();
-        const Type *at = phase->type(adr);
-        if (!adr->is_top() && at->isa_ptr()) {
-          assert(at == Type::TOP || at == TypePtr::NULL_PTR ||
-                 at->isa_ptr() != NULL, "expecting an Ptr");
-          if (adr->is_AddP()) {
-            adr = get_addp_base(adr);
-          }
-          // Mark as ArgEscape everything "adr" could point to.
-          set_escape_state(adr->_idx, PointsToNode::ArgEscape);
-        }
-      }
-      _processed.set(n_idx);
-      break;
-    }
-    case Op_ThreadLocal:
-    {
-      assert(false, "Op_ThreadLocal");
-      break;
-    }
-    default:
-      // This method should be called only for EA specific nodes.
-      ShouldNotReachHere();
-  }
-}
-
-#ifndef PRODUCT
-void ConnectionGraph::dump() {
+void ConnectionGraph::dump(GrowableArray<PointsToNode*>& ptnodes_worklist) {
   bool first = true;
-
-  uint size = nodes_size();
-  for (uint ni = 0; ni < size; ni++) {
-    PointsToNode *ptn = ptnode_adr(ni);
-    PointsToNode::NodeType ptn_type = ptn->node_type();
-
-    if (ptn_type != PointsToNode::JavaObject || ptn->_node == NULL)
+  int ptnodes_length = ptnodes_worklist.length();
+  for (int i = 0; i < ptnodes_length; i++) {
+    PointsToNode *ptn = ptnodes_worklist.at(i);
+    if (ptn == NULL || !ptn->is_JavaObject())
       continue;
-    PointsToNode::EscapeState es = escape_state(ptn->_node);
-    if (ptn->_node->is_Allocate() && (es == PointsToNode::NoEscape || Verbose)) {
+    PointsToNode::EscapeState es = ptn->escape_state();
+    if (ptn->ideal_node()->is_Allocate() && (es == PointsToNode::NoEscape || Verbose)) {
       if (first) {
         tty->cr();
         tty->print("======== Connection graph for ");
@@ -3114,22 +3133,14 @@
         tty->cr();
         first = false;
       }
-      tty->print("%6d ", ni);
       ptn->dump();
-      // Print all locals which reference this allocation
-      for (uint li = ni; li < size; li++) {
-        PointsToNode *ptn_loc = ptnode_adr(li);
-        PointsToNode::NodeType ptn_loc_type = ptn_loc->node_type();
-        if ( ptn_loc_type == PointsToNode::LocalVar && ptn_loc->_node != NULL &&
-             ptn_loc->edge_count() == 1 && ptn_loc->edge_target(0) == ni ) {
-          ptnode_adr(li)->dump(false);
-        }
-      }
-      if (Verbose) {
-        // Print all fields which reference this allocation
-        for (uint i = 0; i < ptn->edge_count(); i++) {
-          uint ei = ptn->edge_target(i);
-          ptnode_adr(ei)->dump(false);
+      // Print all locals and fields which reference this allocation
+      for (UseIterator j(ptn); j.has_next(); j.next()) {
+        PointsToNode* use = j.get();
+        if (use->is_LocalVar()) {
+          use->dump(Verbose);
+        } else if (Verbose) {
+          use->dump();
         }
       }
       tty->cr();
--- a/hotspot/src/share/vm/opto/escape.hpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/opto/escape.hpp	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -115,18 +115,36 @@
 class  CallNode;
 class  PhiNode;
 class  PhaseTransform;
+class  PointsToNode;
 class  Type;
 class  TypePtr;
 class  VectorSet;
 
-class PointsToNode {
-friend class ConnectionGraph;
+class JavaObjectNode;
+class LocalVarNode;
+class FieldNode;
+class ArraycopyNode;
+
+// ConnectionGraph nodes
+class PointsToNode : public ResourceObj {
+  GrowableArray<PointsToNode*> _edges; // List of nodes this node points to
+  GrowableArray<PointsToNode*> _uses;  // List of nodes which point to this node
+
+  const u1           _type;  // NodeType
+  u1                _flags;  // NodeFlags
+  u1               _escape;  // EscapeState of object
+  u1        _fields_escape;  // EscapeState of object's fields
+
+  Node* const        _node;  // Ideal node corresponding to this PointsTo node.
+  const int           _idx;  // Cached ideal node's _idx
+
 public:
   typedef enum {
     UnknownType = 0,
     JavaObject  = 1,
     LocalVar    = 2,
-    Field       = 3
+    Field       = 3,
+    Arraycopy   = 4
   } NodeType;
 
   typedef enum {
@@ -140,178 +158,387 @@
   } EscapeState;
 
   typedef enum {
-    UnknownEdge   = 0,
-    PointsToEdge  = 1,
-    DeferredEdge  = 2,
-    FieldEdge     = 3
-  } EdgeType;
-
-private:
-  enum {
-    EdgeMask = 3,
-    EdgeShift = 2,
-
-    INITIAL_EDGE_COUNT = 4
-  };
-
-  NodeType             _type;
-  EscapeState          _escape;
-  GrowableArray<uint>* _edges; // outgoing edges
-  Node* _node;                 // Ideal node corresponding to this PointsTo node.
-  int   _offset;               // Object fields offsets.
-  bool  _scalar_replaceable;   // Not escaped object could be replaced with scalar
-  bool  _has_unknown_ptr;      // Has edge to phantom_object
-
-public:
-  PointsToNode():
-    _type(UnknownType),
-    _escape(UnknownEscape),
-    _edges(NULL),
-    _node(NULL),
-    _offset(-1),
-    _has_unknown_ptr(false),
-    _scalar_replaceable(true) {}
+    ScalarReplaceable = 1,  // Not escaped object could be replaced with scalar
+    PointsToUnknown   = 2,  // Has edge to phantom_object
+    ArraycopySrc      = 4,  // Has edge from Arraycopy node
+    ArraycopyDst      = 8   // Has edge to Arraycopy node
+  } NodeFlags;
 
 
-  EscapeState escape_state() const { return _escape; }
-  NodeType node_type() const { return _type;}
-  int offset() { return _offset;}
-  bool scalar_replaceable() { return _scalar_replaceable;}
-  bool has_unknown_ptr()    { return _has_unknown_ptr;}
-
-  void set_offset(int offs) { _offset = offs;}
-  void set_escape_state(EscapeState state) { _escape = state; }
-  void set_node_type(NodeType ntype) {
-    assert(_type == UnknownType || _type == ntype, "Can't change node type");
-    _type = ntype;
-  }
-  void set_scalar_replaceable(bool v) { _scalar_replaceable = v; }
-  void set_has_unknown_ptr()          { _has_unknown_ptr = true; }
-
-  // count of outgoing edges
-  uint edge_count() const { return (_edges == NULL) ? 0 : _edges->length(); }
-
-  // node index of target of outgoing edge "e"
-  uint edge_target(uint e) const {
-    assert(_edges != NULL, "valid edge index");
-    return (_edges->at(e) >> EdgeShift);
-  }
-  // type of outgoing edge "e"
-  EdgeType edge_type(uint e) const {
-    assert(_edges != NULL, "valid edge index");
-    return (EdgeType) (_edges->at(e) & EdgeMask);
+  PointsToNode(Compile *C, Node* n, EscapeState es, NodeType type):
+    _edges(C->comp_arena(), 2, 0, NULL),
+    _uses (C->comp_arena(), 2, 0, NULL),
+    _node(n),
+    _idx(n->_idx),
+    _type((u1)type),
+    _escape((u1)es),
+    _fields_escape((u1)es),
+    _flags(ScalarReplaceable) {
+    assert(n != NULL && es != UnknownEscape, "sanity");
   }
 
-  // add a edge of the specified type pointing to the specified target
-  void add_edge(uint targIdx, EdgeType et);
+  Node* ideal_node()   const { return _node; }
+  int          idx()   const { return _idx; }
+
+  bool is_JavaObject() const { return _type == (u1)JavaObject; }
+  bool is_LocalVar()   const { return _type == (u1)LocalVar; }
+  bool is_Field()      const { return _type == (u1)Field; }
+  bool is_Arraycopy()  const { return _type == (u1)Arraycopy; }
+
+  JavaObjectNode* as_JavaObject() { assert(is_JavaObject(),""); return (JavaObjectNode*)this; }
+  LocalVarNode*   as_LocalVar()   { assert(is_LocalVar(),"");   return (LocalVarNode*)this; }
+  FieldNode*      as_Field()      { assert(is_Field(),"");      return (FieldNode*)this; }
+  ArraycopyNode*  as_Arraycopy()  { assert(is_Arraycopy(),"");  return (ArraycopyNode*)this; }
+
+  EscapeState escape_state() const { return (EscapeState)_escape; }
+  void    set_escape_state(EscapeState state) { _escape = (u1)state; }
+
+  EscapeState fields_escape_state() const { return (EscapeState)_fields_escape; }
+  void    set_fields_escape_state(EscapeState state) { _fields_escape = (u1)state; }
+
+  bool     has_unknown_ptr() const { return (_flags & PointsToUnknown) != 0; }
+  void set_has_unknown_ptr()       { _flags |= PointsToUnknown; }
+
+  bool     arraycopy_src() const { return (_flags & ArraycopySrc) != 0; }
+  void set_arraycopy_src()       { _flags |= ArraycopySrc; }
+  bool     arraycopy_dst() const { return (_flags & ArraycopyDst) != 0; }
+  void set_arraycopy_dst()       { _flags |= ArraycopyDst; }
 
-  // remove an edge of the specified type pointing to the specified target
-  void remove_edge(uint targIdx, EdgeType et);
+  bool     scalar_replaceable() const { return (_flags & ScalarReplaceable) != 0;}
+  void set_scalar_replaceable(bool v) {
+    if (v)
+      _flags |= ScalarReplaceable;
+    else
+      _flags &= ~ScalarReplaceable;
+  }
+
+  int edge_count()              const { return _edges.length(); }
+  PointsToNode* edge(int e)     const { return _edges.at(e); }
+  bool add_edge(PointsToNode* edge)    { return _edges.append_if_missing(edge); }
+
+  int use_count()             const { return _uses.length(); }
+  PointsToNode* use(int e)    const { return _uses.at(e); }
+  bool add_use(PointsToNode* use)    { return _uses.append_if_missing(use); }
+
+  // Mark base edge use to distinguish from stored value edge.
+  bool add_base_use(FieldNode* use) { return _uses.append_if_missing((PointsToNode*)((intptr_t)use + 1)); }
+  static bool is_base_use(PointsToNode* use) { return (((intptr_t)use) & 1); }
+  static PointsToNode* get_use_node(PointsToNode* use) { return (PointsToNode*)(((intptr_t)use) & ~1); }
+
+  // Return true if this node points to specified node or nodes it points to.
+  bool points_to(JavaObjectNode* ptn) const;
+
+  // Return true if this node points only to non-escaping allocations.
+  bool non_escaping_allocation();
+
+  // Return true if one node points to an other.
+  bool meet(PointsToNode* ptn);
 
 #ifndef PRODUCT
+  NodeType node_type() const { return (NodeType)_type;}
   void dump(bool print_state=true) const;
 #endif
 
 };
 
+class LocalVarNode: public PointsToNode {
+public:
+  LocalVarNode(Compile *C, Node* n, EscapeState es):
+    PointsToNode(C, n, es, LocalVar) {}
+};
+
+class JavaObjectNode: public PointsToNode {
+public:
+  JavaObjectNode(Compile *C, Node* n, EscapeState es):
+    PointsToNode(C, n, es, JavaObject) {
+      if (es > NoEscape)
+        set_scalar_replaceable(false);
+    }
+};
+
+class FieldNode: public PointsToNode {
+  GrowableArray<PointsToNode*> _bases; // List of JavaObject nodes which point to this node
+  const int   _offset; // Field's offset.
+  const bool  _is_oop; // Field points to object
+        bool  _has_unknown_base; // Has phantom_object base
+public:
+  FieldNode(Compile *C, Node* n, EscapeState es, int offs, bool is_oop):
+    PointsToNode(C, n, es, Field),
+    _offset(offs), _is_oop(is_oop),
+    _has_unknown_base(false) {}
+
+  int      offset()              const { return _offset;}
+  bool     is_oop()              const { return _is_oop;}
+  bool     has_unknown_base()    const { return _has_unknown_base; }
+  void set_has_unknown_base()          { _has_unknown_base = true; }
+
+  int base_count()              const { return _bases.length(); }
+  PointsToNode* base(int e)     const { return _bases.at(e); }
+  bool add_base(PointsToNode* base)    { return _bases.append_if_missing(base); }
+#ifdef ASSERT
+  // Return true if bases points to this java object.
+  bool has_base(JavaObjectNode* ptn) const;
+#endif
+
+};
+
+class ArraycopyNode: public PointsToNode {
+public:
+  ArraycopyNode(Compile *C, Node* n, EscapeState es):
+    PointsToNode(C, n, es, Arraycopy) {}
+};
+
+// Iterators for PointsTo node's edges:
+//   for (EdgeIterator i(n); i.has_next(); i.next()) {
+//     PointsToNode* u = i.get();
+class PointsToIterator: public StackObj {
+protected:
+  const PointsToNode* node;
+  const int cnt;
+  int i;
+public:
+  inline PointsToIterator(const PointsToNode* n, int cnt) : node(n), cnt(cnt), i(0) { }
+  inline bool has_next() const { return i < cnt; }
+  inline void next() { i++; }
+  PointsToNode* get() const { ShouldNotCallThis(); return NULL; }
+};
+
+class EdgeIterator: public PointsToIterator {
+public:
+  inline EdgeIterator(const PointsToNode* n) : PointsToIterator(n, n->edge_count()) { }
+  inline PointsToNode* get() const { return node->edge(i); }
+};
+
+class UseIterator: public PointsToIterator {
+public:
+  inline UseIterator(const PointsToNode* n) : PointsToIterator(n, n->use_count()) { }
+  inline PointsToNode* get() const { return node->use(i); }
+};
+
+class BaseIterator: public PointsToIterator {
+public:
+  inline BaseIterator(const FieldNode* n) : PointsToIterator(n, n->base_count()) { }
+  inline PointsToNode* get() const { return ((PointsToNode*)node)->as_Field()->base(i); }
+};
+
+
 class ConnectionGraph: public ResourceObj {
 private:
-  GrowableArray<PointsToNode>  _nodes; // Connection graph nodes indexed
-                                       // by ideal node index.
-
-  Unique_Node_List  _delayed_worklist; // Nodes to be processed before
-                                       // the call build_connection_graph().
+  GrowableArray<PointsToNode*>  _nodes; // Map from ideal nodes to
+                                        // ConnectionGraph nodes.
 
-  GrowableArray<MergeMemNode *>  _mergemem_worklist; // List of all MergeMem nodes
+  GrowableArray<PointsToNode*>  _worklist; // Nodes to be processed
 
-  VectorSet                _processed; // Records which nodes have been
-                                       // processed.
-
-  bool                    _collecting; // Indicates whether escape information
-                                       // is still being collected. If false,
-                                       // no new nodes will be processed.
+  bool            _collecting; // Indicates whether escape information
+                               // is still being collected. If false,
+                               // no new nodes will be processed.
 
-  bool                    _progress;   // Indicates whether new Graph's edges
-                                       // were created.
+  bool               _verify;  // verify graph
 
-  uint                _phantom_object; // Index of globally escaping object
-                                       // that pointer values loaded from
-                                       // a field which has not been set
-                                       // are assumed to point to.
-  uint                      _oop_null; // ConP(#NULL)->_idx
-  uint                     _noop_null; // ConN(#NULL)->_idx
-  Node*                     _pcmp_neq; // ConI(#CC_GT)
-  Node*                      _pcmp_eq; // ConI(#CC_EQ)
+  JavaObjectNode* phantom_obj; // Unknown object
+  JavaObjectNode*    null_obj;
+  Node*             _pcmp_neq; // ConI(#CC_GT)
+  Node*              _pcmp_eq; // ConI(#CC_EQ)
 
-  Compile *                  _compile; // Compile object for current compilation
-  PhaseIterGVN *                _igvn; // Value numbering
+  Compile*           _compile; // Compile object for current compilation
+  PhaseIterGVN*         _igvn; // Value numbering
+
+  Unique_Node_List ideal_nodes; // Used by CG construction and types splitting.
 
   // Address of an element in _nodes.  Used when the element is to be modified
-  PointsToNode *ptnode_adr(uint idx) const {
+  PointsToNode* ptnode_adr(int idx) const {
     // There should be no new ideal nodes during ConnectionGraph build,
-    // growableArray::adr_at() will throw assert otherwise.
-    return _nodes.adr_at(idx);
+    // growableArray::at() will throw assert otherwise.
+    return _nodes.at(idx);
   }
   uint nodes_size() const { return _nodes.length(); }
 
-  bool is_null_ptr(uint idx) const { return (idx == _noop_null || idx == _oop_null); }
+  // Add nodes to ConnectionGraph.
+  void add_local_var(Node* n, PointsToNode::EscapeState es);
+  void add_java_object(Node* n, PointsToNode::EscapeState es);
+  void add_field(Node* n, PointsToNode::EscapeState es, int offset);
+  void add_arraycopy(Node* n, PointsToNode::EscapeState es, PointsToNode* src, PointsToNode* dst);
+
+  // Compute the escape state for arguments to a call.
+  void process_call_arguments(CallNode *call);
+
+  // Add PointsToNode node corresponding to a call
+  void add_call_node(CallNode* call);
+
+  // Map ideal node to existing PointsTo node (usually phantom_object).
+  void map_ideal_node(Node *n, PointsToNode* ptn) {
+    assert(ptn != NULL, "only existing PointsTo node");
+    _nodes.at_put(n->_idx, ptn);
+  }
+
+  // Create PointsToNode node and add it to Connection Graph.
+  void add_node_to_connection_graph(Node *n, Unique_Node_List *delayed_worklist);
+
+  // Add final simple edges to graph.
+  void add_final_edges(Node *n);
+
+  // Finish Graph construction.
+  bool complete_connection_graph(GrowableArray<PointsToNode*>&   ptnodes_worklist,
+                                 GrowableArray<JavaObjectNode*>& non_escaped_worklist,
+                                 GrowableArray<JavaObjectNode*>& java_objects_worklist,
+                                 GrowableArray<FieldNode*>&      oop_fields_worklist);
+
+#ifdef ASSERT
+  void verify_connection_graph(GrowableArray<PointsToNode*>&   ptnodes_worklist,
+                               GrowableArray<JavaObjectNode*>& non_escaped_worklist,
+                               GrowableArray<JavaObjectNode*>& java_objects_worklist,
+                               GrowableArray<Node*>& addp_worklist);
+#endif
+
+  // Add all references to this JavaObject node.
+  int add_java_object_edges(JavaObjectNode* jobj, bool populate_worklist);
+
+  // Put node on worklist if it is (or was) not there.
+  void add_to_worklist(PointsToNode* pt) {
+    _worklist.push(pt);
+    return;
+  }
+
+  // Put on worklist all uses of this node.
+  void add_uses_to_worklist(PointsToNode* pt) {
+    for (UseIterator i(pt); i.has_next(); i.next())
+      _worklist.push(i.get());
+  }
+
+  // Put on worklist all field's uses and related field nodes.
+  void add_field_uses_to_worklist(FieldNode* field);
+
+  // Put on worklist all related field nodes.
+  void add_fields_to_worklist(FieldNode* field, PointsToNode* base);
+
+  // Find fields which have unknown value.
+  int find_field_value(FieldNode* field);
+
+  // Find fields initializing values for allocations.
+  int find_init_values(JavaObjectNode* ptn, PointsToNode* init_val, PhaseTransform* phase);
+
+  // Set the escape state of an object and its fields.
+  void set_escape_state(PointsToNode* ptn, PointsToNode::EscapeState esc) {
+    // Don't change non-escaping state of NULL pointer.
+    if (ptn != null_obj) {
+      if (ptn->escape_state() < esc)
+        ptn->set_escape_state(esc);
+      if (ptn->fields_escape_state() < esc)
+        ptn->set_fields_escape_state(esc);
+    }
+  }
+  void set_fields_escape_state(PointsToNode* ptn, PointsToNode::EscapeState esc) {
+    // Don't change non-escaping state of NULL pointer.
+    if (ptn != null_obj) {
+      if (ptn->fields_escape_state() < esc)
+        ptn->set_fields_escape_state(esc);
+    }
+  }
 
-  // Add node to ConnectionGraph.
-  void add_node(Node *n, PointsToNode::NodeType nt, PointsToNode::EscapeState es, bool done);
+  // Propagate GlobalEscape and ArgEscape escape states to all nodes
+  // and check that we still have non-escaping java objects.
+  bool find_non_escaped_objects(GrowableArray<PointsToNode*>& ptnodes_worklist,
+                                GrowableArray<JavaObjectNode*>& non_escaped_worklist);
+
+  // Adjust scalar_replaceable state after Connection Graph is built.
+  void adjust_scalar_replaceable_state(JavaObjectNode* jobj);
+
+  // Optimize ideal graph.
+  void optimize_ideal_graph(GrowableArray<Node*>& ptr_cmp_worklist,
+                            GrowableArray<Node*>& storestore_worklist);
+  // Optimize objects compare.
+  Node* optimize_ptr_compare(Node* n);
+
+  // Returns unique corresponding java object or NULL.
+  JavaObjectNode* unique_java_object(Node *n);
+
+  // Add an edge of the specified type pointing to the specified target.
+  bool add_edge(PointsToNode* from, PointsToNode* to) {
+    assert(!from->is_Field() || from->as_Field()->is_oop(), "sanity");
+
+    if (to == phantom_obj) {
+      if (from->has_unknown_ptr()) {
+        return false; // already points to phantom_obj
+      }
+      from->set_has_unknown_ptr();
+    }
+
+    bool is_new = from->add_edge(to);
+    assert(to != phantom_obj || is_new, "sanity");
+    if (is_new) { // New edge?
+      assert(!_verify, "graph is incomplete");
+      is_new = to->add_use(from);
+      assert(is_new, "use should be also new");
+    }
+    return is_new;
+  }
+
+  // Add an edge from Field node to its base and back.
+  bool add_base(FieldNode* from, PointsToNode* to) {
+    assert(!to->is_Arraycopy(), "sanity");
+    if (to == phantom_obj) {
+      if (from->has_unknown_base()) {
+        return false; // already has phantom_obj base
+      }
+      from->set_has_unknown_base();
+    }
+    bool is_new = from->add_base(to);
+    assert(to != phantom_obj || is_new, "sanity");
+    if (is_new) {      // New edge?
+      assert(!_verify, "graph is incomplete");
+      if (to == null_obj)
+        return is_new; // Don't add fields to NULL pointer.
+      if (to->is_JavaObject()) {
+        is_new = to->add_edge(from);
+      } else {
+        is_new = to->add_base_use(from);
+      }
+      assert(is_new, "use should be also new");
+    }
+    return is_new;
+  }
+
+  // Add LocalVar node and edge if possible
+  void add_local_var_and_edge(Node* n, PointsToNode::EscapeState es, Node* to,
+                              Unique_Node_List *delayed_worklist) {
+    PointsToNode* ptn = ptnode_adr(to->_idx);
+    if (delayed_worklist != NULL) { // First iteration of CG construction
+      add_local_var(n, es);
+      if (ptn == NULL) {
+        delayed_worklist->push(n);
+        return; // Process it later.
+      }
+    } else {
+      assert(ptn != NULL, "node should be registered");
+    }
+    add_edge(ptnode_adr(n->_idx), ptn);
+  }
+
+  // Helper functions
+  bool   is_oop_field(Node* n, int offset);
+  static Node* get_addp_base(Node *addp);
+  static Node* find_second_addp(Node* addp, Node* n);
 
   // offset of a field reference
   int address_offset(Node* adr, PhaseTransform *phase);
 
-  // compute the escape state for arguments to a call
-  void process_call_arguments(CallNode *call, PhaseTransform *phase);
 
-  // compute the escape state for the return value of a call
-  void process_call_result(ProjNode *resproj, PhaseTransform *phase);
-
-  // Populate Connection Graph with Ideal nodes.
-  void record_for_escape_analysis(Node *n, PhaseTransform *phase);
-
-  // Build Connection Graph and set nodes escape state.
-  void build_connection_graph(Node *n, PhaseTransform *phase);
-
-  // walk the connection graph starting at the node corresponding to "n" and
-  // add the index of everything it could point to, to "ptset".  This may cause
-  // Phi's encountered to get (re)processed  (which requires "phase".)
-  VectorSet* PointsTo(Node * n);
-
-  // Reused structures for PointsTo().
-  VectorSet            pt_ptset;
-  VectorSet            pt_visited;
-  GrowableArray<uint>  pt_worklist;
+  // Propagate unique types created for unescaped allocated objects
+  // through the graph
+  void split_unique_types(GrowableArray<Node *>  &alloc_worklist);
 
-  //  Edge manipulation.  The "from_i" and "to_i" arguments are the
-  //  node indices of the source and destination of the edge
-  void add_pointsto_edge(uint from_i, uint to_i);
-  void add_deferred_edge(uint from_i, uint to_i);
-  void add_field_edge(uint from_i, uint to_i, int offs);
+  // Helper methods for unique types split.
+  bool split_AddP(Node *addp, Node *base);
 
-  // Add an edge of the specified type pointing to the specified target.
-  // Set _progress if new edge is added.
-  void add_edge(PointsToNode *f, uint to_i, PointsToNode::EdgeType et) {
-    uint e_cnt = f->edge_count();
-    f->add_edge(to_i, et);
-    _progress |= (f->edge_count() != e_cnt);
-  }
+  PhiNode *create_split_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *>  &orig_phi_worklist, bool &new_created);
+  PhiNode *split_memory_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *>  &orig_phi_worklist);
 
-  // Add an edge to node given by "to_i" from any field of adr_i whose offset
-  // matches "offset"  A deferred edge is added if to_i is a LocalVar, and
-  // a pointsto edge is added if it is a JavaObject
-  void add_edge_from_fields(uint adr, uint to_i, int offs);
-
-  // Add a deferred  edge from node given by "from_i" to any field
-  // of adr_i whose offset matches "offset"
-  void add_deferred_edge_to_fields(uint from_i, uint adr, int offs);
+  void  move_inst_mem(Node* n, GrowableArray<PhiNode *>  &orig_phis);
+  Node* find_inst_mem(Node* mem, int alias_idx,GrowableArray<PhiNode *>  &orig_phi_worklist);
+  Node* step_through_mergemem(MergeMemNode *mmem, int alias_idx, const TypeOopPtr *toop);
 
 
-  // Remove outgoing deferred edges from the node referenced by "ni".
-  // Any outgoing edges from the target of the deferred edge are copied
-  // to "ni".
-  void remove_deferred(uint ni, GrowableArray<uint>* deferred_edges, VectorSet* visited);
+  GrowableArray<MergeMemNode*>  _mergemem_worklist; // List of all MergeMem nodes
 
   Node_Array _node_map; // used for bookeeping during type splitting
                         // Used for the following purposes:
@@ -320,21 +547,18 @@
                         // MemNode       - new memory input for this node
                         // ChecCastPP    - allocation that this is a cast of
                         // allocation    - CheckCastPP of the allocation
-  bool split_AddP(Node *addp, Node *base,  PhaseGVN  *igvn);
-  PhiNode *create_split_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *>  &orig_phi_worklist, PhaseGVN  *igvn, bool &new_created);
-  PhiNode *split_memory_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *>  &orig_phi_worklist, PhaseGVN  *igvn);
-  void  move_inst_mem(Node* n, GrowableArray<PhiNode *>  &orig_phis, PhaseGVN *igvn);
-  Node *find_inst_mem(Node *mem, int alias_idx,GrowableArray<PhiNode *>  &orig_phi_worklist,  PhaseGVN  *igvn);
-
-  // Propagate unique types created for unescaped allocated objects
-  // through the graph
-  void split_unique_types(GrowableArray<Node *>  &alloc_worklist);
 
   // manage entries in _node_map
-  void  set_map(int idx, Node *n)        { _node_map.map(idx, n); }
-  Node *get_map(int idx)                 { return _node_map[idx]; }
-  PhiNode *get_map_phi(int idx) {
-    Node *phi = _node_map[idx];
+
+  void  set_map(Node* from, Node* to)  {
+    ideal_nodes.push(from);
+    _node_map.map(from->_idx, to);
+  }
+
+  Node* get_map(int idx) { return _node_map[idx]; }
+
+  PhiNode* get_map_phi(int idx) {
+    Node* phi = _node_map[idx];
     return (phi == NULL) ? NULL : phi->as_Phi();
   }
 
@@ -344,23 +568,6 @@
     _igvn->add_users_to_worklist(n);
   }
 
-  // Set the escape state of a node
-  void set_escape_state(uint ni, PointsToNode::EscapeState es);
-
-  // Find fields initializing values for allocations.
-  void find_init_values(Node* n, VectorSet* visited, PhaseTransform* phase);
-
-  // Adjust escape state after Connection Graph is built.
-  void adjust_escape_state(Node* n);
-
-  // Propagate escape states to referenced nodes.
-  bool propagate_escape_state(GrowableArray<int>* cg_worklist,
-                              GrowableArray<uint>* worklist,
-                              PointsToNode::EscapeState esc_state);
-
-  // Optimize objects compare.
-  Node* optimize_ptr_compare(Node* n);
-
   // Compute the escape information
   bool compute_escape();
 
@@ -373,11 +580,10 @@
   // Perform escape analysis
   static void do_analysis(Compile *C, PhaseIterGVN *igvn);
 
-  // escape state of a node
-  PointsToNode::EscapeState escape_state(Node *n);
+  bool not_global_escape(Node *n);
 
 #ifndef PRODUCT
-  void dump();
+  void dump(GrowableArray<PointsToNode*>& ptnodes_worklist);
 #endif
 };
 
--- a/hotspot/src/share/vm/opto/library_call.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/opto/library_call.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -338,8 +338,27 @@
     break;
 
   case vmIntrinsics::_bitCount_i:
+    if (!Matcher::match_rule_supported(Op_PopCountI)) return NULL;
+    break;
+
   case vmIntrinsics::_bitCount_l:
-    if (!UsePopCountInstruction)  return NULL;
+    if (!Matcher::match_rule_supported(Op_PopCountL)) return NULL;
+    break;
+
+  case vmIntrinsics::_numberOfLeadingZeros_i:
+    if (!Matcher::match_rule_supported(Op_CountLeadingZerosI)) return NULL;
+    break;
+
+  case vmIntrinsics::_numberOfLeadingZeros_l:
+    if (!Matcher::match_rule_supported(Op_CountLeadingZerosL)) return NULL;
+    break;
+
+  case vmIntrinsics::_numberOfTrailingZeros_i:
+    if (!Matcher::match_rule_supported(Op_CountTrailingZerosI)) return NULL;
+    break;
+
+  case vmIntrinsics::_numberOfTrailingZeros_l:
+    if (!Matcher::match_rule_supported(Op_CountTrailingZerosL)) return NULL;
     break;
 
   case vmIntrinsics::_Reference_get:
@@ -416,14 +435,12 @@
     return kit.transfer_exceptions_into_jvms();
   }
 
-  if (PrintIntrinsics) {
+  // The intrinsic bailed out
+  if (PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) {
     if (jvms->has_method()) {
       // Not a root compile.
-      tty->print("Did not inline intrinsic %s%s at bci:%d in",
-                 vmIntrinsics::name_at(intrinsic_id()),
-                 (is_virtual() ? " (virtual)" : ""), kit.bci());
-      kit.caller()->print_short_name(tty);
-      tty->print_cr(" (%d bytes)", kit.caller()->code_size());
+      const char* msg = is_virtual() ? "failed to inline (intrinsic, virtual)" : "failed to inline (intrinsic)";
+      CompileTask::print_inlining(kit.callee(), jvms->depth() - 1, kit.bci(), msg);
     } else {
       // Root compile
       tty->print("Did not generate intrinsic %s%s at bci:%d in",
@@ -5453,4 +5470,3 @@
   push(result);
   return true;
 }
-
--- a/hotspot/src/share/vm/opto/phase.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/opto/phase.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,8 +39,9 @@
 
 // The next timers used for LogCompilation
 elapsedTimer Phase::_t_parser;
-elapsedTimer Phase::_t_escapeAnalysis;
 elapsedTimer Phase::_t_optimizer;
+elapsedTimer   Phase::_t_escapeAnalysis;
+elapsedTimer     Phase::_t_connectionGraph;
 elapsedTimer   Phase::_t_idealLoop;
 elapsedTimer   Phase::_t_ccp;
 elapsedTimer Phase::_t_matcher;
@@ -51,6 +52,7 @@
 elapsedTimer Phase::_t_graphReshaping;
 elapsedTimer Phase::_t_scheduler;
 elapsedTimer Phase::_t_blockOrdering;
+elapsedTimer Phase::_t_macroEliminate;
 elapsedTimer Phase::_t_macroExpand;
 elapsedTimer Phase::_t_peephole;
 elapsedTimer Phase::_t_codeGeneration;
@@ -104,6 +106,8 @@
     if (DoEscapeAnalysis) {
       // EA is part of Optimizer.
       tty->print_cr ("      escape analysis: %3.3f sec", Phase::_t_escapeAnalysis.seconds());
+      tty->print_cr ("        connection graph: %3.3f sec", Phase::_t_connectionGraph.seconds());
+      tty->print_cr ("      macroEliminate : %3.3f sec", Phase::_t_macroEliminate.seconds());
     }
     tty->print_cr ("      iterGVN        : %3.3f sec", Phase::_t_iterGVN.seconds());
     tty->print_cr ("      idealLoop      : %3.3f sec", Phase::_t_idealLoop.seconds());
@@ -112,9 +116,10 @@
     tty->print_cr ("      iterGVN2       : %3.3f sec", Phase::_t_iterGVN2.seconds());
     tty->print_cr ("      macroExpand    : %3.3f sec", Phase::_t_macroExpand.seconds());
     tty->print_cr ("      graphReshape   : %3.3f sec", Phase::_t_graphReshaping.seconds());
-    double optimizer_subtotal = Phase::_t_iterGVN.seconds() +
+    double optimizer_subtotal = Phase::_t_iterGVN.seconds() + Phase::_t_iterGVN2.seconds() +
+      Phase::_t_escapeAnalysis.seconds() + Phase::_t_macroEliminate.seconds() +
       Phase::_t_idealLoop.seconds() + Phase::_t_ccp.seconds() +
-      Phase::_t_graphReshaping.seconds();
+      Phase::_t_macroExpand.seconds() + Phase::_t_graphReshaping.seconds();
     double percent_of_optimizer = ((optimizer_subtotal == 0.0) ? 0.0 : (optimizer_subtotal / Phase::_t_optimizer.seconds() * 100.0));
     tty->print_cr ("      subtotal       : %3.3f sec,  %3.2f %%", optimizer_subtotal, percent_of_optimizer);
   }
--- a/hotspot/src/share/vm/opto/phase.hpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/opto/phase.hpp	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -72,8 +72,12 @@
 
 // The next timers used for LogCompilation
   static elapsedTimer _t_parser;
-  static elapsedTimer _t_escapeAnalysis;
   static elapsedTimer _t_optimizer;
+public:
+  // ConnectionGraph can't be Phase since it is used after EA done.
+  static elapsedTimer   _t_escapeAnalysis;
+  static elapsedTimer     _t_connectionGraph;
+protected:
   static elapsedTimer   _t_idealLoop;
   static elapsedTimer   _t_ccp;
   static elapsedTimer _t_matcher;
@@ -84,6 +88,7 @@
   static elapsedTimer _t_graphReshaping;
   static elapsedTimer _t_scheduler;
   static elapsedTimer _t_blockOrdering;
+  static elapsedTimer _t_macroEliminate;
   static elapsedTimer _t_macroExpand;
   static elapsedTimer _t_peephole;
   static elapsedTimer _t_codeGeneration;
--- a/hotspot/src/share/vm/prims/jvm.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/prims/jvm.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -1301,9 +1301,6 @@
 // Inner class reflection ///////////////////////////////////////////////////////////////////////////////
 
 JVM_ENTRY(jobjectArray, JVM_GetDeclaredClasses(JNIEnv *env, jclass ofClass))
-  const int inner_class_info_index = 0;
-  const int outer_class_info_index = 1;
-
   JvmtiVMObjectAllocEventCollector oam;
   // ofClass is a reference to a java_lang_Class object. The mirror object
   // of an instanceKlass
@@ -1315,26 +1312,26 @@
   }
 
   instanceKlassHandle k(thread, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(ofClass)));
-
-  if (k->inner_classes()->length() == 0) {
+  InnerClassesIterator iter(k);
+
+  if (iter.length() == 0) {
     // Neither an inner nor outer class
     oop result = oopFactory::new_objArray(SystemDictionary::Class_klass(), 0, CHECK_NULL);
     return (jobjectArray)JNIHandles::make_local(env, result);
   }
 
   // find inner class info
-  typeArrayHandle    icls(thread, k->inner_classes());
   constantPoolHandle cp(thread, k->constants());
-  int length = icls->length();
+  int length = iter.length();
 
   // Allocate temp. result array
   objArrayOop r = oopFactory::new_objArray(SystemDictionary::Class_klass(), length/4, CHECK_NULL);
   objArrayHandle result (THREAD, r);
   int members = 0;
 
-  for(int i = 0; i < length; i += 4) {
-    int ioff = icls->ushort_at(i + inner_class_info_index);
-    int ooff = icls->ushort_at(i + outer_class_info_index);
+  for (; !iter.done(); iter.next()) {
+    int ioff = iter.inner_class_info_index();
+    int ooff = iter.outer_class_info_index();
 
     if (ioff != 0 && ooff != 0) {
       // Check to see if the name matches the class we're looking for
@@ -1392,17 +1389,13 @@
                                                      bool* inner_is_member,
                                                      TRAPS) {
   Thread* thread = THREAD;
-  const int inner_class_info_index = inner_class_inner_class_info_offset;
-  const int outer_class_info_index = inner_class_outer_class_info_offset;
-
-  if (k->inner_classes()->length() == 0) {
+  InnerClassesIterator iter(k);
+  if (iter.length() == 0) {
     // No inner class info => no declaring class
     return NULL;
   }
 
-  typeArrayHandle i_icls(thread, k->inner_classes());
   constantPoolHandle i_cp(thread, k->constants());
-  int i_length = i_icls->length();
 
   bool found = false;
   klassOop ok;
@@ -1410,10 +1403,10 @@
   *inner_is_member = false;
 
   // Find inner_klass attribute
-  for (int i = 0; i < i_length && !found; i += inner_class_next_offset) {
-    int ioff = i_icls->ushort_at(i + inner_class_info_index);
-    int ooff = i_icls->ushort_at(i + outer_class_info_index);
-    int noff = i_icls->ushort_at(i + inner_class_inner_name_offset);
+  for (; !iter.done() && !found; iter.next()) {
+    int ioff = iter.inner_class_info_index();
+    int ooff = iter.outer_class_info_index();
+    int noff = iter.inner_name_index();
     if (ioff != 0) {
       // Check to see if the name matches the class we're looking for
       // before attempting to find the class.
--- a/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -292,8 +292,8 @@
 
 // Compute the number of entries in the InnerClasses attribute
 u2 JvmtiClassFileReconstituter::inner_classes_attribute_length() {
-  typeArrayOop inner_class_list = ikh()->inner_classes();
-  return (inner_class_list == NULL) ? 0 : inner_class_list->length();
+  InnerClassesIterator iter(ikh());
+  return iter.length();
 }
 
 // Write an annotation attribute.  The VM stores them in raw form, so all we need
@@ -324,26 +324,20 @@
 // JVMSpec|     } classes[number_of_classes];
 // JVMSpec|   }
 void JvmtiClassFileReconstituter::write_inner_classes_attribute(int length) {
-  typeArrayOop inner_class_list = ikh()->inner_classes();
-  guarantee(inner_class_list != NULL && inner_class_list->length() == length,
+  InnerClassesIterator iter(ikh());
+  guarantee(iter.length() != 0 && iter.length() == length,
             "caller must check");
-  typeArrayHandle inner_class_list_h(thread(), inner_class_list);
-  assert (length % instanceKlass::inner_class_next_offset == 0, "just checking");
   u2 entry_count = length / instanceKlass::inner_class_next_offset;
   u4 size = 2 + entry_count * (2+2+2+2);
 
   write_attribute_name_index("InnerClasses");
   write_u4(size);
   write_u2(entry_count);
-  for (int i = 0; i < length; i += instanceKlass::inner_class_next_offset) {
-    write_u2(inner_class_list_h->ushort_at(
-                      i + instanceKlass::inner_class_inner_class_info_offset));
-    write_u2(inner_class_list_h->ushort_at(
-                      i + instanceKlass::inner_class_outer_class_info_offset));
-    write_u2(inner_class_list_h->ushort_at(
-                      i + instanceKlass::inner_class_inner_name_offset));
-    write_u2(inner_class_list_h->ushort_at(
-                      i + instanceKlass::inner_class_access_flags_offset));
+  for (; !iter.done(); iter.next()) {
+    write_u2(iter.inner_class_info_index());
+    write_u2(iter.outer_class_info_index());
+    write_u2(iter.inner_name_index());
+    write_u2(iter.inner_access_flags());
   }
 }
 
@@ -727,8 +721,11 @@
       case Bytecodes::_invokestatic    :  // fall through
       case Bytecodes::_invokedynamic   :  // fall through
       case Bytecodes::_invokeinterface :
-        assert(len == 3 || (code == Bytecodes::_invokeinterface && len ==5),
+        assert(len == 3 ||
+               (code == Bytecodes::_invokeinterface && len == 5) ||
+               (code == Bytecodes::_invokedynamic   && len == 5),
                "sanity check");
+
         int cpci = Bytes::get_native_u2(bcp+1);
         bool is_invokedynamic = (EnableInvokeDynamic && code == Bytecodes::_invokedynamic);
         if (is_invokedynamic)
--- a/hotspot/src/share/vm/prims/jvmtiExport.hpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiExport.hpp	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -324,6 +324,12 @@
       record_vm_internal_object_allocation(object);
     }
   }
+  inline static void post_array_size_exhausted() {
+    if (should_post_resource_exhausted()) {
+      post_resource_exhausted(JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR,
+                              "Requested array size exceeds VM limit");
+    }
+  }
 
   static void cleanup_thread             (JavaThread* thread) KERNEL_RETURN;
 
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -2400,44 +2400,33 @@
   // new constant indices as needed. The inner classes info is a
   // quadruple:
   // (inner_class_info, outer_class_info, inner_name, inner_access_flags)
-  typeArrayOop inner_class_list = scratch_class->inner_classes();
-  int icl_length = (inner_class_list == NULL) ? 0 : inner_class_list->length();
-  if (icl_length > 0) {
-    typeArrayHandle inner_class_list_h(THREAD, inner_class_list);
-    for (int i = 0; i < icl_length;
-         i += instanceKlass::inner_class_next_offset) {
-      int cur_index = inner_class_list_h->ushort_at(i
-                        + instanceKlass::inner_class_inner_class_info_offset);
-      if (cur_index == 0) {
-        continue;  // JVM spec. allows null inner class refs so skip it
-      }
-      int new_index = find_new_index(cur_index);
-      if (new_index != 0) {
-        RC_TRACE_WITH_THREAD(0x00080000, THREAD,
-          ("inner_class_info change: %d to %d", cur_index, new_index));
-        inner_class_list_h->ushort_at_put(i
-          + instanceKlass::inner_class_inner_class_info_offset, new_index);
-      }
-      cur_index = inner_class_list_h->ushort_at(i
-                    + instanceKlass::inner_class_outer_class_info_offset);
-      new_index = find_new_index(cur_index);
-      if (new_index != 0) {
-        RC_TRACE_WITH_THREAD(0x00080000, THREAD,
-          ("outer_class_info change: %d to %d", cur_index, new_index));
-        inner_class_list_h->ushort_at_put(i
-          + instanceKlass::inner_class_outer_class_info_offset, new_index);
-      }
-      cur_index = inner_class_list_h->ushort_at(i
-                    + instanceKlass::inner_class_inner_name_offset);
-      new_index = find_new_index(cur_index);
-      if (new_index != 0) {
-        RC_TRACE_WITH_THREAD(0x00080000, THREAD,
-          ("inner_name change: %d to %d", cur_index, new_index));
-        inner_class_list_h->ushort_at_put(i
-          + instanceKlass::inner_class_inner_name_offset, new_index);
-      }
-    } // end for each inner class
-  } // end if we have inner classes
+  InnerClassesIterator iter(scratch_class);
+  for (; !iter.done(); iter.next()) {
+    int cur_index = iter.inner_class_info_index();
+    if (cur_index == 0) {
+      continue;  // JVM spec. allows null inner class refs so skip it
+    }
+    int new_index = find_new_index(cur_index);
+    if (new_index != 0) {
+      RC_TRACE_WITH_THREAD(0x00080000, THREAD,
+        ("inner_class_info change: %d to %d", cur_index, new_index));
+      iter.set_inner_class_info_index(new_index);
+    }
+    cur_index = iter.outer_class_info_index();
+    new_index = find_new_index(cur_index);
+    if (new_index != 0) {
+      RC_TRACE_WITH_THREAD(0x00080000, THREAD,
+        ("outer_class_info change: %d to %d", cur_index, new_index));
+      iter.set_outer_class_info_index(new_index);
+    }
+    cur_index = iter.inner_name_index();
+    new_index = find_new_index(cur_index);
+    if (new_index != 0) {
+      RC_TRACE_WITH_THREAD(0x00080000, THREAD,
+        ("inner_name change: %d to %d", cur_index, new_index));
+      iter.set_inner_name_index(new_index);
+    }
+  } // end for each inner class
 
   // Attach each method in klass to the new constant pool and update
   // to use new constant pool indices as needed:
--- a/hotspot/src/share/vm/prims/nativeLookup.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/prims/nativeLookup.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -121,6 +121,7 @@
   void JNICALL JVM_RegisterUnsafeMethods(JNIEnv *env, jclass unsafecls);
   void JNICALL JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass unsafecls);
   void JNICALL JVM_RegisterPerfMethods(JNIEnv *env, jclass perfclass);
+  void JNICALL JVM_RegisterWhiteBoxMethods(JNIEnv *env, jclass wbclass);
 }
 
 #define CC (char*)  /* cast a literal from (const char*) */
@@ -133,7 +134,8 @@
 
   { CC"Java_sun_misc_Unsafe_registerNatives",                      NULL, FN_PTR(JVM_RegisterUnsafeMethods)       },
   { CC"Java_java_lang_invoke_MethodHandleNatives_registerNatives", NULL, FN_PTR(JVM_RegisterMethodHandleMethods) },
-  { CC"Java_sun_misc_Perf_registerNatives",                        NULL, FN_PTR(JVM_RegisterPerfMethods)         }
+  { CC"Java_sun_misc_Perf_registerNatives",                        NULL, FN_PTR(JVM_RegisterPerfMethods)         },
+  { CC"Java_sun_hotspot_WhiteBox_registerNatives",                 NULL, FN_PTR(JVM_RegisterWhiteBoxMethods)     },
 };
 
 static address lookup_special_native(char* jni_name) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/prims/whitebox.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+
+#include "jni.h"
+
+#include "memory/universe.hpp"
+#include "oops/oop.inline.hpp"
+#include "prims/whitebox.hpp"
+#include "runtime/interfaceSupport.hpp"
+#include "runtime/os.hpp"
+#include "utilities/debug.hpp"
+
+#ifndef SERIALGC
+#include "gc_implementation/g1/concurrentMark.hpp"
+#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
+#include "gc_implementation/g1/heapRegionRemSet.hpp"
+#endif // !SERIALGC
+
+bool WhiteBox::_used = false;
+
+// Entry macro to transition from JNI to VM state.
+
+#define WB_ENTRY(result_type, header) JNI_ENTRY(result_type, header)
+#define WB_END JNI_END
+
+// Definitions of functions exposed via Whitebox API
+
+WB_ENTRY(jlong, WB_GetObjectAddress(JNIEnv* env, jobject o, jobject obj))
+  return (jlong)(void*)JNIHandles::resolve(obj);
+WB_END
+
+WB_ENTRY(jint, WB_GetHeapOopSize(JNIEnv* env, jobject o))
+  return heapOopSize;
+WB_END
+
+#ifndef SERIALGC
+WB_ENTRY(jboolean, WB_G1IsHumongous(JNIEnv* env, jobject o, jobject obj))
+  G1CollectedHeap* g1 = G1CollectedHeap::heap();
+  oop result = JNIHandles::resolve(obj);
+  const HeapRegion* hr = g1->heap_region_containing(result);
+  return hr->isHumongous();
+WB_END
+
+WB_ENTRY(jlong, WB_G1NumFreeRegions(JNIEnv* env, jobject o))
+  G1CollectedHeap* g1 = G1CollectedHeap::heap();
+  size_t nr = g1->free_regions();
+  return (jlong)nr;
+WB_END
+
+WB_ENTRY(jboolean, WB_G1InConcurrentMark(JNIEnv* env, jobject o))
+  G1CollectedHeap* g1 = G1CollectedHeap::heap();
+  ConcurrentMark* cm = g1->concurrent_mark();
+  return cm->concurrent_marking_in_progress();
+WB_END
+
+WB_ENTRY(jint, WB_G1RegionSize(JNIEnv* env, jobject o))
+  return (jint)HeapRegion::GrainBytes;
+WB_END
+#endif // !SERIALGC
+
+#define CC (char*)
+
+static JNINativeMethod methods[] = {
+  {CC"getObjectAddress",   CC"(Ljava/lang/Object;)J", (void*)&WB_GetObjectAddress  },
+  {CC"getHeapOopSize",     CC"()I",                   (void*)&WB_GetHeapOopSize    },
+#ifndef SERIALGC
+  {CC"g1InConcurrentMark", CC"()Z",                   (void*)&WB_G1InConcurrentMark},
+  {CC"g1IsHumongous",      CC"(Ljava/lang/Object;)Z", (void*)&WB_G1IsHumongous     },
+  {CC"g1NumFreeRegions",   CC"()J",                   (void*)&WB_G1NumFreeRegions  },
+  {CC"g1RegionSize",       CC"()I",                   (void*)&WB_G1RegionSize      },
+#endif // !SERIALGC
+};
+
+#undef CC
+
+JVM_ENTRY(void, JVM_RegisterWhiteBoxMethods(JNIEnv* env, jclass wbclass))
+  {
+    if (WhiteBoxAPI) {
+      // Make sure that wbclass is loaded by the null classloader
+      instanceKlassHandle ikh = instanceKlassHandle(JNIHandles::resolve(wbclass)->klass());
+      Handle loader(ikh->class_loader());
+      if (loader.is_null()) {
+        ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
+        jint result = env->RegisterNatives(wbclass, methods, sizeof(methods)/sizeof(methods[0]));
+        if (result == 0) {
+          WhiteBox::set_used();
+        }
+      }
+    }
+  }
+JVM_END
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/prims/whitebox.hpp	Fri Mar 30 16:57:50 2012 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_PRIMS_WHITEBOX_HPP
+#define SHARE_VM_PRIMS_WHITEBOX_HPP
+
+class WhiteBox : public AllStatic {
+ private:
+  static bool _used;
+ public:
+  static bool used()     { return _used; }
+  static void set_used() { _used = true; }
+};
+
+#endif // SHARE_VM_PRIMS_WHITEBOX_HPP
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -816,8 +816,21 @@
     return true;
   }
 
-  jio_fprintf(defaultStream::error_stream(),
-              "Unrecognized VM option '%s'\n", argname);
+  // For locked flags, report a custom error message if available.
+  // Otherwise, report the standard unrecognized VM option.
+
+  Flag* locked_flag = Flag::find_flag((char*)argname, strlen(argname), true);
+  if (locked_flag != NULL) {
+    char locked_message_buf[BUFLEN];
+    locked_flag->get_locked_message(locked_message_buf, BUFLEN);
+    if (strlen(locked_message_buf) == 0) {
+      jio_fprintf(defaultStream::error_stream(),
+        "Unrecognized VM option '%s'\n", argname);
+    } else {
+      jio_fprintf(defaultStream::error_stream(), "%s", locked_message_buf);
+    }
+  }
+
   // allow for commandline "commenting out" options like -XX:#+Verbose
   return arg[0] == '#';
 }
@@ -2050,6 +2063,19 @@
     FREE_C_HEAP_ARRAY(char, altclasses_path);
   }
 
+  if (WhiteBoxAPI) {
+    // Append wb.jar to bootclasspath if enabled
+    const char* wb_jar = "wb.jar";
+    size_t wb_path_len = strlen(get_meta_index_dir()) + 1 +
+                         strlen(wb_jar);
+    char* wb_path = NEW_C_HEAP_ARRAY(char, wb_path_len);
+    strcpy(wb_path, get_meta_index_dir());
+    strcat(wb_path, wb_jar);
+    scp.add_suffix(wb_path);
+    scp_assembly_required = true;
+    FREE_C_HEAP_ARRAY(char, wb_path);
+  }
+
   // Parse _JAVA_OPTIONS environment variable (if present) (mimics classic VM)
   result = parse_java_options_environment_variable(&scp, &scp_assembly_required);
   if (result != JNI_OK) {
@@ -2510,15 +2536,6 @@
       // was arrived at by experimenting with specjbb.
       FLAG_SET_CMDLINE(uintx, OldPLABSize, 8*K);  // Note: this is in words
 
-      // CompilationPolicyChoice=0 causes the server compiler to adopt
-      // a more conservative which-method-do-I-compile policy when one
-      // of the counters maintained by the interpreter trips.  The
-      // result is reduced startup time and improved specjbb and
-      // alacrity performance.  Zero is the default, but we set it
-      // explicitly here in case the default changes.
-      // See runtime/compilationPolicy.*.
-      FLAG_SET_CMDLINE(intx, CompilationPolicyChoice, 0);
-
       // Enable parallel GC and adaptive generation sizing
       FLAG_SET_CMDLINE(bool, UseParallelGC, true);
       FLAG_SET_DEFAULT(ParallelGCThreads,
--- a/hotspot/src/share/vm/runtime/globals.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/runtime/globals.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -81,6 +81,12 @@
   }
 }
 
+// Get custom message for this locked flag, or return NULL if
+// none is available.
+void Flag::get_locked_message(char* buf, int buflen) const {
+  get_locked_message_ext(buf, buflen);
+}
+
 bool Flag::is_writeable() const {
   return strcmp(kind, "{manageable}") == 0 ||
          strcmp(kind, "{product rw}") == 0 ||
@@ -260,17 +266,22 @@
   return strncmp(s, q, len) == 0;
 }
 
-Flag* Flag::find_flag(char* name, size_t length) {
-  for (Flag* current = &flagTable[0]; current->name; current++) {
+// Search the flag table for a named flag
+Flag* Flag::find_flag(char* name, size_t length, bool allow_locked) {
+  for (Flag* current = &flagTable[0]; current->name != NULL; current++) {
     if (str_equal(current->name, name, length)) {
+      // Found a matching entry.  Report locked flags only if allowed.
       if (!(current->is_unlocked() || current->is_unlocker())) {
-        // disable use of diagnostic or experimental flags until they
-        // are explicitly unlocked
-        return NULL;
+        if (!allow_locked) {
+          // disable use of locked flags, e.g. diagnostic, experimental,
+          // commercial... until they are explicitly unlocked
+          return NULL;
+        }
       }
       return current;
     }
   }
+  // Flag name is not in the flag table
   return NULL;
 }
 
--- a/hotspot/src/share/vm/runtime/globals.hpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/runtime/globals.hpp	Fri Mar 30 16:57:50 2012 -0700
@@ -222,7 +222,7 @@
   // number of flags
   static size_t numFlags;
 
-  static Flag* find_flag(char* name, size_t length);
+  static Flag* find_flag(char* name, size_t length, bool allow_locked = false);
 
   bool is_bool() const        { return strcmp(type, "bool") == 0; }
   bool get_bool() const       { return *((bool*) addr); }
@@ -259,6 +259,9 @@
   bool is_writeable_ext() const;
   bool is_external_ext() const;
 
+  void get_locked_message(char*, int) const;
+  void get_locked_message_ext(char*, int) const;
+
   void print_on(outputStream* st, bool withComments = false );
   void print_as_flag(outputStream* st);
 };
@@ -3896,7 +3899,10 @@
   product(bool, UseVMInterruptibleIO, false,                                \
           "(Unstable, Solaris-specific) Thread interrupt before or with "   \
           "EINTR for I/O operations results in OS_INTRPT. The default value"\
-          " of this flag is true for JDK 6 and earlier")
+          " of this flag is true for JDK 6 and earlier")                    \
+                                                                            \
+  diagnostic(bool, WhiteBoxAPI, false,                                      \
+          "Enable internal testing APIs")
 
 /*
  *  Macros for factoring of globals
--- a/hotspot/src/share/vm/runtime/globals_ext.hpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/runtime/globals_ext.hpp	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -61,4 +61,9 @@
   return false;
 }
 
+inline void Flag::get_locked_message_ext(char* buf, int buflen) const {
+  assert(buf != NULL, "Buffer cannot be NULL");
+  buf[0] = '\0';
+}
+
 #endif // SHARE_VM_RUNTIME_GLOBALS_EXT_HPP
--- a/hotspot/src/share/vm/runtime/reflection.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/runtime/reflection.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -591,14 +591,11 @@
 // Caller is responsible for figuring out in advance which case must be true.
 void Reflection::check_for_inner_class(instanceKlassHandle outer, instanceKlassHandle inner,
                                        bool inner_is_member, TRAPS) {
-  const int inner_class_info_index = 0;
-  const int outer_class_info_index = 1;
-
-  typeArrayHandle    icls (THREAD, outer->inner_classes());
+  InnerClassesIterator iter(outer);
   constantPoolHandle cp   (THREAD, outer->constants());
-  for(int i = 0; i < icls->length(); i += 4) {
-     int ioff = icls->ushort_at(i + inner_class_info_index);
-     int ooff = icls->ushort_at(i + outer_class_info_index);
+  for (; !iter.done(); iter.next()) {
+     int ioff = iter.inner_class_info_index();
+     int ooff = iter.outer_class_info_index();
 
      if (inner_is_member && ioff != 0 && ooff != 0) {
         klassOop o = cp->klass_at(ooff, CHECK);
--- a/hotspot/src/share/vm/runtime/safepoint.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/runtime/safepoint.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -219,6 +219,8 @@
 #ifdef ASSERT
   for (JavaThread *cur = Threads::first(); cur != NULL; cur = cur->next()) {
     assert(cur->safepoint_state()->is_running(), "Illegal initial state");
+    // Clear the visited flag to ensure that the critical counts are collected properly.
+    cur->set_visited_for_critical_count(false);
   }
 #endif // ASSERT
 
@@ -378,6 +380,13 @@
 
   OrderAccess::fence();
 
+#ifdef ASSERT
+  for (JavaThread *cur = Threads::first(); cur != NULL; cur = cur->next()) {
+    // make sure all the threads were visited
+    assert(cur->was_visited_for_critical_count(), "missed a thread");
+  }
+#endif // ASSERT
+
   // Update the count of active JNI critical regions
   GC_locker::set_jni_lock_count(_current_jni_active_count);
 
@@ -626,6 +635,7 @@
         _waiting_to_block--;
         thread->safepoint_state()->set_has_called_back(true);
 
+        DEBUG_ONLY(thread->set_visited_for_critical_count(true));
         if (thread->in_critical()) {
           // Notice that this thread is in a critical section
           increment_jni_active_count();
@@ -907,12 +917,8 @@
   // running, but are actually at a safepoint. We will happily
   // agree and update the safepoint state here.
   if (SafepointSynchronize::safepoint_safe(_thread, state)) {
+    SafepointSynchronize::check_for_lazy_critical_native(_thread, state);
     roll_forward(_at_safepoint);
-    SafepointSynchronize::check_for_lazy_critical_native(_thread, state);
-    if (_thread->in_critical()) {
-      // Notice that this thread is in a critical section
-      SafepointSynchronize::increment_jni_active_count();
-    }
     return;
   }
 
@@ -937,6 +943,11 @@
   switch(_type) {
     case _at_safepoint:
       SafepointSynchronize::signal_thread_at_safepoint();
+      DEBUG_ONLY(_thread->set_visited_for_critical_count(true));
+      if (_thread->in_critical()) {
+        // Notice that this thread is in a critical section
+        SafepointSynchronize::increment_jni_active_count();
+      }
       break;
 
     case _call_back:
--- a/hotspot/src/share/vm/runtime/thread.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/runtime/thread.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -247,6 +247,10 @@
   omInUseList = NULL ;
   omInUseCount = 0 ;
 
+#ifdef ASSERT
+  _visited_for_critical_count = false;
+#endif
+
   _SR_lock = new Monitor(Mutex::suspend_resume, "SR_lock", true);
   _suspend_flags = 0;
 
--- a/hotspot/src/share/vm/runtime/thread.hpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/runtime/thread.hpp	Fri Mar 30 16:57:50 2012 -0700
@@ -268,6 +268,15 @@
   ObjectMonitor* omInUseList;                   // SLL to track monitors in circulation
   int omInUseCount;                             // length of omInUseList
 
+#ifdef ASSERT
+ private:
+  bool _visited_for_critical_count;
+
+ public:
+  void set_visited_for_critical_count(bool z) { _visited_for_critical_count = z; }
+  bool was_visited_for_critical_count() const   { return _visited_for_critical_count; }
+#endif
+
  public:
   enum {
     is_definitely_current_thread = true
--- a/hotspot/src/share/vm/utilities/growableArray.hpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/utilities/growableArray.hpp	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -198,8 +198,11 @@
     return idx;
   }
 
-  void append_if_missing(const E& elem) {
-    if (!contains(elem)) append(elem);
+  bool append_if_missing(const E& elem) {
+    // Returns TRUE if elem is added.
+    bool missed = !contains(elem);
+    if (missed) append(elem);
+    return missed;
   }
 
   E at(int i) const {
@@ -292,12 +295,22 @@
     ShouldNotReachHere();
   }
 
+  // The order is preserved.
   void remove_at(int index) {
     assert(0 <= index && index < _len, "illegal index");
     for (int j = index + 1; j < _len; j++) _data[j-1] = _data[j];
     _len--;
   }
 
+  // The order is changed.
+  void delete_at(int index) {
+    assert(0 <= index && index < _len, "illegal index");
+    if (index < --_len) {
+      // Replace removed element with last one.
+      _data[index] = _data[_len];
+    }
+  }
+
   // inserts the given element before the element at index i
   void insert_before(const int idx, const E& elem) {
     check_nesting();
--- a/hotspot/src/share/vm/utilities/numberSeq.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/utilities/numberSeq.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -156,6 +156,10 @@
     _sequence[i] = 0.0;
 }
 
+TruncatedSeq::~TruncatedSeq() {
+  FREE_C_HEAP_ARRAY(double, _sequence);
+}
+
 void TruncatedSeq::add(double val) {
   AbsSeq::add(val);
 
--- a/hotspot/src/share/vm/utilities/numberSeq.hpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/utilities/numberSeq.hpp	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -118,6 +118,7 @@
   // accepts a value for L
   TruncatedSeq(int length = DefaultSeqLength,
                double alpha = DEFAULT_ALPHA_VALUE);
+  ~TruncatedSeq();
   virtual void add(double val);
   virtual double maximum() const;
   virtual double last() const; // the last value added to the sequence
--- a/hotspot/src/share/vm/utilities/vmError.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/src/share/vm/utilities/vmError.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -25,6 +25,7 @@
 #include "precompiled.hpp"
 #include "compiler/compileBroker.hpp"
 #include "gc_interface/collectedHeap.hpp"
+#include "prims/whitebox.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/frame.inline.hpp"
 #include "runtime/init.hpp"
@@ -717,6 +718,13 @@
        st->cr();
      }
 
+  STEP(215, "(printing warning if internal testing API used)" )
+
+     if (WhiteBox::used()) {
+       st->print_cr("Unsupported internal testing APIs have been used.");
+       st->cr();
+     }
+
   STEP(220, "(printing environment variables)" )
 
      if (_verbose) {
--- a/hotspot/test/Makefile	Fri Mar 30 15:43:13 2012 -0700
+++ b/hotspot/test/Makefile	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1995, 2012, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,8 @@
 # Makefile to run various jdk tests
 #
 
+GETMIXEDPATH=echo
+
 # Get OS/ARCH specifics
 OSNAME = $(shell uname -s)
 ifeq ($(OSNAME), SunOS)
@@ -60,7 +62,14 @@
     ARCH = i586
   endif
 endif
-ifeq ($(OSNAME), Windows_NT)
+ifeq ($(PLATFORM),)
+  # detect wether we're running in MKS or cygwin
+  ifeq ($(OSNAME), Windows_NT) # MKS
+    GETMIXEDPATH=dosname -s
+  endif
+  ifeq ($(findstring CYGWIN,$(OSNAME)), CYGWIN)
+    GETMIXEDPATH=cygpath -m -s
+  endif
   PLATFORM = windows
   SLASH_JAVA = J:
   ifeq ($(word 1, $(PROCESSOR_IDENTIFIER)),ia64)
@@ -228,6 +237,24 @@
 
 ################################################################
 
+# wbapitest (make sure the whitebox testing api classes work
+
+wbapitest: prep $(JT_HOME) $(PRODUCT_HOME) $(JTREG)
+	$(JTREG) -a -v:fail,error               \
+          $(JTREG_KEY_OPTION)                   \
+          $(EXTRA_JTREG_OPTIONS)                \
+          -r:$(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)")/JTreport    \
+          -w:$(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)")/JTwork      \
+          -jdk:$(shell $(GETMIXEDPATH) "$(PRODUCT_HOME)")                  \
+          $(JAVA_OPTIONS:%=-vmoption:%)         \
+          $(shell $(GETMIXEDPATH) "$(TEST_ROOT)")/sanity                   \
+	  || $(BUNDLE_UP_FAILED)
+	$(BUNDLE_UP)
+
+PHONY_LIST += wbapitest
+
+################################################################
+
 # packtest
 
 # Expect JPRT to set JPRT_PACKTEST_HOME.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/sanity/WBApi.java	Fri Mar 30 16:57:50 2012 -0700
@@ -0,0 +1,13 @@
+/*
+ * @test WBApi
+ * @summary verify that whitebox functions can be linked and executed
+ * @run compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI WBApi.java
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI WBApi
+ */
+
+import sun.hotspot.WhiteBox;
+public class WBApi {
+    public static void main(String... args) {
+        System.out.printf("args at: %x\n",WhiteBox.getWhiteBox().getObjectAddress(args));
+    }
+}
--- a/jaxp/.hgtags	Fri Mar 30 15:43:13 2012 -0700
+++ b/jaxp/.hgtags	Fri Mar 30 16:57:50 2012 -0700
@@ -150,3 +150,7 @@
 dbb7283c197b27da1fc12ae8a83785c851b68c12 jdk8-b26
 80c47eb83d24fdd64bbb48f288bd6d4f03e0ec88 jdk8-b27
 f3244c1f04864d35c41fa8d13669faf4f65b81e2 jdk8-b28
+25099a745e1a43579b6af86b3e052b2e50958753 jdk8-b29
+3be30c25a8255803652b5c466336055d36e2ba21 jdk8-b30
+94aabe098916440ae7911866311c9617d8481a36 jdk8-b31
+60960fbc75df8be4c1a2504aa69fc1428cc94f93 jdk8-b32
--- a/jaxws/.hgignore	Fri Mar 30 15:43:13 2012 -0700
+++ b/jaxws/.hgignore	Fri Mar 30 16:57:50 2012 -0700
@@ -5,3 +5,4 @@
 ^webrev/
 /nbproject/private/
 ^.hgtip
+.DS_Store
--- a/jaxws/.hgtags	Fri Mar 30 15:43:13 2012 -0700
+++ b/jaxws/.hgtags	Fri Mar 30 16:57:50 2012 -0700
@@ -150,3 +150,7 @@
 3518639eab6ce5c7b482bdb0a60342c392ab97a8 jdk8-b26
 38c037af4127289de12efc67f45d19bb67abff69 jdk8-b27
 88b85470e72ce48515c802d2158f61cad198b935 jdk8-b28
+4897d9d2d04838e3479745efa238a99bacd939c9 jdk8-b29
+6882b10e85d6f6ba110dbb50926d6fe2222cc7ad jdk8-b30
+4c41c6d0e15de3b56919a5ba0a0f248a2d07f2b2 jdk8-b31
+017a7dbfaa92f5a8b144e6c890d1cebdaecaf681 jdk8-b32
--- a/jaxws/make/jprt.properties	Fri Mar 30 15:43:13 2012 -0700
+++ b/jaxws/make/jprt.properties	Fri Mar 30 16:57:50 2012 -0700
@@ -39,6 +39,7 @@
     solaris_x64_5.10-{product|fastdebug},                       \
     linux_i586_2.6-{product|fastdebug},                         \
     linux_x64_2.6-{product|fastdebug},                          \
+    macosx_x64_10.7-{product|fastdebug},                        \
     windows_i586_5.1-{product|fastdebug},                       \
     windows_x64_5.2-{product|fastdebug}
 
--- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/ws/EnvelopeStyle.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/ws/EnvelopeStyle.java	Fri Mar 30 16:57:50 2012 -0700
@@ -1,41 +1,26 @@
 /*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
- * The contents of this file are subject to the terms of either the GNU
- * General Public License Version 2 only ("GPL") or the Common Development
- * and Distribution License("CDDL") (collectively, the "License").  You
- * may not use this file except in compliance with the License.  You can
- * obtain a copy of the License at
- * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
- * or packager/legal/LICENSE.txt.  See the License for the specific
- * language governing permissions and limitations under the License.
- *
- * When distributing the software, include this License Header Notice in each
- * file and include the License file at packager/legal/LICENSE.txt.
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
  *
- * GPL Classpath Exception:
- * Oracle designates this particular file as subject to the "Classpath"
- * exception as provided by Oracle in the GPL Version 2 section of the License
- * file that accompanied this code.
- *
- * Modifications:
- * If applicable, add the following below the License Header, with the fields
- * enclosed by brackets [] replaced by your own identifying information:
- * "Portions Copyright [year] [name of copyright owner]"
+ * 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).
  *
- * Contributor(s):
- * If you wish your version of this file to be governed by only the CDDL or
- * only the GPL Version 2, indicate your decision by adding "[Contributor]
- * elects to include this software in this distribution under the [CDDL or GPL
- * Version 2] license."  If you don't indicate a single choice of license, a
- * recipient has the option to distribute your version of this file under
- * either the CDDL, the GPL Version 2 or to extend the choice of license to
- * its licensees as provided above.  However, if you add GPL Version 2 code
- * and therefore, elected the GPL Version 2 license, then the option applies
- * only if the new code is made subject to such option by the copyright
- * holder.
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
  */
 
 package com.sun.xml.internal.org.jvnet.ws;
--- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/ws/EnvelopeStyleFeature.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/ws/EnvelopeStyleFeature.java	Fri Mar 30 16:57:50 2012 -0700
@@ -1,41 +1,26 @@
 /*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
- * The contents of this file are subject to the terms of either the GNU
- * General Public License Version 2 only ("GPL") or the Common Development
- * and Distribution License("CDDL") (collectively, the "License").  You
- * may not use this file except in compliance with the License.  You can
- * obtain a copy of the License at
- * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
- * or packager/legal/LICENSE.txt.  See the License for the specific
- * language governing permissions and limitations under the License.
- *
- * When distributing the software, include this License Header Notice in each
- * file and include the License file at packager/legal/LICENSE.txt.
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
  *
- * GPL Classpath Exception:
- * Oracle designates this particular file as subject to the "Classpath"
- * exception as provided by Oracle in the GPL Version 2 section of the License
- * file that accompanied this code.
- *
- * Modifications:
- * If applicable, add the following below the License Header, with the fields
- * enclosed by brackets [] replaced by your own identifying information:
- * "Portions Copyright [year] [name of copyright owner]"
+ * 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).
  *
- * Contributor(s):
- * If you wish your version of this file to be governed by only the CDDL or
- * only the GPL Version 2, indicate your decision by adding "[Contributor]
- * elects to include this software in this distribution under the [CDDL or GPL
- * Version 2] license."  If you don't indicate a single choice of license, a
- * recipient has the option to distribute your version of this file under
- * either the CDDL, the GPL Version 2 or to extend the choice of license to
- * its licensees as provided above.  However, if you add GPL Version 2 code
- * and therefore, elected the GPL Version 2 license, then the option applies
- * only if the new code is made subject to such option by the copyright
- * holder.
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
  */
 
 package com.sun.xml.internal.org.jvnet.ws;
--- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/ws/databinding/Databinding.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/ws/databinding/Databinding.java	Fri Mar 30 16:57:50 2012 -0700
@@ -1,41 +1,26 @@
 /*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
- * The contents of this file are subject to the terms of either the GNU
- * General Public License Version 2 only ("GPL") or the Common Development
- * and Distribution License("CDDL") (collectively, the "License").  You
- * may not use this file except in compliance with the License.  You can
- * obtain a copy of the License at
- * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
- * or packager/legal/LICENSE.txt.  See the License for the specific
- * language governing permissions and limitations under the License.
- *
- * When distributing the software, include this License Header Notice in each
- * file and include the License file at packager/legal/LICENSE.txt.
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
  *
- * GPL Classpath Exception:
- * Oracle designates this particular file as subject to the "Classpath"
- * exception as provided by Oracle in the GPL Version 2 section of the License
- * file that accompanied this code.
- *
- * Modifications:
- * If applicable, add the following below the License Header, with the fields
- * enclosed by brackets [] replaced by your own identifying information:
- * "Portions Copyright [year] [name of copyright owner]"
+ * 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).
  *
- * Contributor(s):
- * If you wish your version of this file to be governed by only the CDDL or
- * only the GPL Version 2, indicate your decision by adding "[Contributor]
- * elects to include this software in this distribution under the [CDDL or GPL
- * Version 2] license."  If you don't indicate a single choice of license, a
- * recipient has the option to distribute your version of this file under
- * either the CDDL, the GPL Version 2 or to extend the choice of license to
- * its licensees as provided above.  However, if you add GPL Version 2 code
- * and therefore, elected the GPL Version 2 license, then the option applies
- * only if the new code is made subject to such option by the copyright
- * holder.
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
  */
 
 package com.sun.xml.internal.org.jvnet.ws.databinding;
--- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/ws/databinding/DatabindingFactory.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/ws/databinding/DatabindingFactory.java	Fri Mar 30 16:57:50 2012 -0700
@@ -1,41 +1,26 @@
 /*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
- * The contents of this file are subject to the terms of either the GNU
- * General Public License Version 2 only ("GPL") or the Common Development
- * and Distribution License("CDDL") (collectively, the "License").  You
- * may not use this file except in compliance with the License.  You can
- * obtain a copy of the License at
- * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
- * or packager/legal/LICENSE.txt.  See the License for the specific
- * language governing permissions and limitations under the License.
- *
- * When distributing the software, include this License Header Notice in each
- * file and include the License file at packager/legal/LICENSE.txt.
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
  *
- * GPL Classpath Exception:
- * Oracle designates this particular file as subject to the "Classpath"
- * exception as provided by Oracle in the GPL Version 2 section of the License
- * file that accompanied this code.
- *
- * Modifications:
- * If applicable, add the following below the License Header, with the fields
- * enclosed by brackets [] replaced by your own identifying information:
- * "Portions Copyright [year] [name of copyright owner]"
+ * 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).
  *
- * Contributor(s):
- * If you wish your version of this file to be governed by only the CDDL or
- * only the GPL Version 2, indicate your decision by adding "[Contributor]
- * elects to include this software in this distribution under the [CDDL or GPL
- * Version 2] license."  If you don't indicate a single choice of license, a
- * recipient has the option to distribute your version of this file under
- * either the CDDL, the GPL Version 2 or to extend the choice of license to
- * its licensees as provided above.  However, if you add GPL Version 2 code
- * and therefore, elected the GPL Version 2 license, then the option applies
- * only if the new code is made subject to such option by the copyright
- * holder.
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
  */
 
 package com.sun.xml.internal.org.jvnet.ws.databinding;
--- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/ws/databinding/DatabindingMode.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/ws/databinding/DatabindingMode.java	Fri Mar 30 16:57:50 2012 -0700
@@ -1,42 +1,28 @@
 /*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
- * The contents of this file are subject to the terms of either the GNU
- * General Public License Version 2 only ("GPL") or the Common Development
- * and Distribution License("CDDL") (collectively, the "License").  You
- * may not use this file except in compliance with the License.  You can
- * obtain a copy of the License at
- * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
- * or packager/legal/LICENSE.txt.  See the License for the specific
- * language governing permissions and limitations under the License.
- *
- * When distributing the software, include this License Header Notice in each
- * file and include the License file at packager/legal/LICENSE.txt.
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
  *
- * GPL Classpath Exception:
- * Oracle designates this particular file as subject to the "Classpath"
- * exception as provided by Oracle in the GPL Version 2 section of the License
- * file that accompanied this code.
- *
- * Modifications:
- * If applicable, add the following below the License Header, with the fields
- * enclosed by brackets [] replaced by your own identifying information:
- * "Portions Copyright [year] [name of copyright owner]"
+ * 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).
  *
- * Contributor(s):
- * If you wish your version of this file to be governed by only the CDDL or
- * only the GPL Version 2, indicate your decision by adding "[Contributor]
- * elects to include this software in this distribution under the [CDDL or GPL
- * Version 2] license."  If you don't indicate a single choice of license, a
- * recipient has the option to distribute your version of this file under
- * either the CDDL, the GPL Version 2 or to extend the choice of license to
- * its licensees as provided above.  However, if you add GPL Version 2 code
- * and therefore, elected the GPL Version 2 license, then the option applies
- * only if the new code is made subject to such option by the copyright
- * holder.
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
  */
+
 package com.sun.xml.internal.org.jvnet.ws.databinding;
 
 import java.lang.annotation.Retention;
--- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/ws/databinding/DatabindingModeFeature.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/ws/databinding/DatabindingModeFeature.java	Fri Mar 30 16:57:50 2012 -0700
@@ -1,41 +1,26 @@
 /*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
- * The contents of this file are subject to the terms of either the GNU
- * General Public License Version 2 only ("GPL") or the Common Development
- * and Distribution License("CDDL") (collectively, the "License").  You
- * may not use this file except in compliance with the License.  You can
- * obtain a copy of the License at
- * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
- * or packager/legal/LICENSE.txt.  See the License for the specific
- * language governing permissions and limitations under the License.
- *
- * When distributing the software, include this License Header Notice in each
- * file and include the License file at packager/legal/LICENSE.txt.
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
  *
- * GPL Classpath Exception:
- * Oracle designates this particular file as subject to the "Classpath"
- * exception as provided by Oracle in the GPL Version 2 section of the License
- * file that accompanied this code.
- *
- * Modifications:
- * If applicable, add the following below the License Header, with the fields
- * enclosed by brackets [] replaced by your own identifying information:
- * "Portions Copyright [year] [name of copyright owner]"
+ * 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).
  *
- * Contributor(s):
- * If you wish your version of this file to be governed by only the CDDL or
- * only the GPL Version 2, indicate your decision by adding "[Contributor]
- * elects to include this software in this distribution under the [CDDL or GPL
- * Version 2] license."  If you don't indicate a single choice of license, a
- * recipient has the option to distribute your version of this file under
- * either the CDDL, the GPL Version 2 or to extend the choice of license to
- * its licensees as provided above.  However, if you add GPL Version 2 code
- * and therefore, elected the GPL Version 2 license, then the option applies
- * only if the new code is made subject to such option by the copyright
- * holder.
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
  */
 
 package com.sun.xml.internal.org.jvnet.ws.databinding;
--- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/ws/databinding/JavaCallInfo.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/ws/databinding/JavaCallInfo.java	Fri Mar 30 16:57:50 2012 -0700
@@ -1,41 +1,26 @@
 /*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
- * The contents of this file are subject to the terms of either the GNU
- * General Public License Version 2 only ("GPL") or the Common Development
- * and Distribution License("CDDL") (collectively, the "License").  You
- * may not use this file except in compliance with the License.  You can
- * obtain a copy of the License at
- * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
- * or packager/legal/LICENSE.txt.  See the License for the specific
- * language governing permissions and limitations under the License.
- *
- * When distributing the software, include this License Header Notice in each
- * file and include the License file at packager/legal/LICENSE.txt.
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
  *
- * GPL Classpath Exception:
- * Oracle designates this particular file as subject to the "Classpath"
- * exception as provided by Oracle in the GPL Version 2 section of the License
- * file that accompanied this code.
- *
- * Modifications:
- * If applicable, add the following below the License Header, with the fields
- * enclosed by brackets [] replaced by your own identifying information:
- * "Portions Copyright [year] [name of copyright owner]"
+ * 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).
  *
- * Contributor(s):
- * If you wish your version of this file to be governed by only the CDDL or
- * only the GPL Version 2, indicate your decision by adding "[Contributor]
- * elects to include this software in this distribution under the [CDDL or GPL
- * Version 2] license."  If you don't indicate a single choice of license, a
- * recipient has the option to distribute your version of this file under
- * either the CDDL, the GPL Version 2 or to extend the choice of license to
- * its licensees as provided above.  However, if you add GPL Version 2 code
- * and therefore, elected the GPL Version 2 license, then the option applies
- * only if the new code is made subject to such option by the copyright
- * holder.
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
  */
 
 package com.sun.xml.internal.org.jvnet.ws.databinding;
--- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/ws/message/ContentType.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/ws/message/ContentType.java	Fri Mar 30 16:57:50 2012 -0700
@@ -1,41 +1,26 @@
 /*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
- * The contents of this file are subject to the terms of either the GNU
- * General Public License Version 2 only ("GPL") or the Common Development
- * and Distribution License("CDDL") (collectively, the "License").  You
- * may not use this file except in compliance with the License.  You can
- * obtain a copy of the License at
- * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
- * or packager/legal/LICENSE.txt.  See the License for the specific
- * language governing permissions and limitations under the License.
- *
- * When distributing the software, include this License Header Notice in each
- * file and include the License file at packager/legal/LICENSE.txt.
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
  *
- * GPL Classpath Exception:
- * Oracle designates this particular file as subject to the "Classpath"
- * exception as provided by Oracle in the GPL Version 2 section of the License
- * file that accompanied this code.
- *
- * Modifications:
- * If applicable, add the following below the License Header, with the fields
- * enclosed by brackets [] replaced by your own identifying information:
- * "Portions Copyright [year] [name of copyright owner]"
+ * 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).
  *
- * Contributor(s):
- * If you wish your version of this file to be governed by only the CDDL or
- * only the GPL Version 2, indicate your decision by adding "[Contributor]
- * elects to include this software in this distribution under the [CDDL or GPL
- * Version 2] license."  If you don't indicate a single choice of license, a
- * recipient has the option to distribute your version of this file under
- * either the CDDL, the GPL Version 2 or to extend the choice of license to
- * its licensees as provided above.  However, if you add GPL Version 2 code
- * and therefore, elected the GPL Version 2 license, then the option applies
- * only if the new code is made subject to such option by the copyright
- * holder.
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
  */
 
 package com.sun.xml.internal.org.jvnet.ws.message;
--- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/ws/message/DistributedPropertySet.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/ws/message/DistributedPropertySet.java	Fri Mar 30 16:57:50 2012 -0700
@@ -1,41 +1,26 @@
 /*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
- * The contents of this file are subject to the terms of either the GNU
- * General Public License Version 2 only ("GPL") or the Common Development
- * and Distribution License("CDDL") (collectively, the "License").  You
- * may not use this file except in compliance with the License.  You can
- * obtain a copy of the License at
- * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
- * or packager/legal/LICENSE.txt.  See the License for the specific
- * language governing permissions and limitations under the License.
- *
- * When distributing the software, include this License Header Notice in each
- * file and include the License file at packager/legal/LICENSE.txt.
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
  *
- * GPL Classpath Exception:
- * Oracle designates this particular file as subject to the "Classpath"
- * exception as provided by Oracle in the GPL Version 2 section of the License
- * file that accompanied this code.
- *
- * Modifications:
- * If applicable, add the following below the License Header, with the fields
- * enclosed by brackets [] replaced by your own identifying information:
- * "Portions Copyright [year] [name of copyright owner]"
+ * 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).
  *
- * Contributor(s):
- * If you wish your version of this file to be governed by only the CDDL or
- * only the GPL Version 2, indicate your decision by adding "[Contributor]
- * elects to include this software in this distribution under the [CDDL or GPL
- * Version 2] license."  If you don't indicate a single choice of license, a
- * recipient has the option to distribute your version of this file under
- * either the CDDL, the GPL Version 2 or to extend the choice of license to
- * its licensees as provided above.  However, if you add GPL Version 2 code
- * and therefore, elected the GPL Version 2 license, then the option applies
- * only if the new code is made subject to such option by the copyright
- * holder.
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
  */
 
 package com.sun.xml.internal.org.jvnet.ws.message;
--- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/ws/message/MessageContext.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/ws/message/MessageContext.java	Fri Mar 30 16:57:50 2012 -0700
@@ -1,41 +1,26 @@
 /*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
- * The contents of this file are subject to the terms of either the GNU
- * General Public License Version 2 only ("GPL") or the Common Development
- * and Distribution License("CDDL") (collectively, the "License").  You
- * may not use this file except in compliance with the License.  You can
- * obtain a copy of the License at
- * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
- * or packager/legal/LICENSE.txt.  See the License for the specific
- * language governing permissions and limitations under the License.
- *
- * When distributing the software, include this License Header Notice in each
- * file and include the License file at packager/legal/LICENSE.txt.
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
  *
- * GPL Classpath Exception:
- * Oracle designates this particular file as subject to the "Classpath"
- * exception as provided by Oracle in the GPL Version 2 section of the License
- * file that accompanied this code.
- *
- * Modifications:
- * If applicable, add the following below the License Header, with the fields
- * enclosed by brackets [] replaced by your own identifying information:
- * "Portions Copyright [year] [name of copyright owner]"
+ * 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).
  *
- * Contributor(s):
- * If you wish your version of this file to be governed by only the CDDL or
- * only the GPL Version 2, indicate your decision by adding "[Contributor]
- * elects to include this software in this distribution under the [CDDL or GPL
- * Version 2] license."  If you don't indicate a single choice of license, a
- * recipient has the option to distribute your version of this file under
- * either the CDDL, the GPL Version 2 or to extend the choice of license to
- * its licensees as provided above.  However, if you add GPL Version 2 code
- * and therefore, elected the GPL Version 2 license, then the option applies
- * only if the new code is made subject to such option by the copyright
- * holder.
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
  */
 
 package com.sun.xml.internal.org.jvnet.ws.message;
--- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/ws/message/MessageContextFactory.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/ws/message/MessageContextFactory.java	Fri Mar 30 16:57:50 2012 -0700
@@ -1,3 +1,28 @@
+/*
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
 package com.sun.xml.internal.org.jvnet.ws.message;
 
 import java.io.IOException;
--- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/ws/message/PropertySet.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/ws/message/PropertySet.java	Fri Mar 30 16:57:50 2012 -0700
@@ -1,41 +1,26 @@
 /*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
- * The contents of this file are subject to the terms of either the GNU
- * General Public License Version 2 only ("GPL") or the Common Development
- * and Distribution License("CDDL") (collectively, the "License").  You
- * may not use this file except in compliance with the License.  You can
- * obtain a copy of the License at
- * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
- * or packager/legal/LICENSE.txt.  See the License for the specific
- * language governing permissions and limitations under the License.
- *
- * When distributing the software, include this License Header Notice in each
- * file and include the License file at packager/legal/LICENSE.txt.
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
  *
- * GPL Classpath Exception:
- * Oracle designates this particular file as subject to the "Classpath"
- * exception as provided by Oracle in the GPL Version 2 section of the License
- * file that accompanied this code.
- *
- * Modifications:
- * If applicable, add the following below the License Header, with the fields
- * enclosed by brackets [] replaced by your own identifying information:
- * "Portions Copyright [year] [name of copyright owner]"
+ * 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).
  *
- * Contributor(s):
- * If you wish your version of this file to be governed by only the CDDL or
- * only the GPL Version 2, indicate your decision by adding "[Contributor]
- * elects to include this software in this distribution under the [CDDL or GPL
- * Version 2] license."  If you don't indicate a single choice of license, a
- * recipient has the option to distribute your version of this file under
- * either the CDDL, the GPL Version 2 or to extend the choice of license to
- * its licensees as provided above.  However, if you add GPL Version 2 code
- * and therefore, elected the GPL Version 2 license, then the option applies
- * only if the new code is made subject to such option by the copyright
- * holder.
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
  */
 
 package com.sun.xml.internal.org.jvnet.ws.message;
--- a/jdk/.hgtags	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/.hgtags	Fri Mar 30 16:57:50 2012 -0700
@@ -151,3 +151,6 @@
 c68342532e2e7deb3a25fc04ed3e4c142278f747 jdk8-b27
 1e1d41daaded291ab3a370ca6a27f7325701978e jdk8-b28
 c5b882dce0fe27e05dc64debc92b1fb9ebf880ec jdk8-b29
+cdbb33303ea344d5e9013e2dd642e7a6e7768db6 jdk8-b30
+27f0c08c427c65fcab6917edf646f59058e59524 jdk8-b31
+ddfe5562f61f54ed2121ac0c73b688b94f3e66b5 jdk8-b32
--- a/jdk/make/common/shared/Compiler-gcc.gmk	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/make/common/shared/Compiler-gcc.gmk	Fri Mar 30 16:57:50 2012 -0700
@@ -67,7 +67,7 @@
     CXX            = $(COMPILER_PATH)g++
   endif
   # Option used to create a shared library
-  SHARED_LIBRARY_FLAG = -shared -mimpure-text
+  SHARED_LIBRARY_FLAG = -shared
   SUN_COMP_VER := $(shell $(CC) --verbose 2>&1 )
 
 endif
--- a/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java	Fri Mar 30 16:57:50 2012 -0700
@@ -522,11 +522,6 @@
         postEvent(targetToAppContext(event.getSource()), event);
     }
 
-    /*
-     * Returns true if the application (one of its windows) owns keyboard focus.
-     */
-    public abstract boolean isApplicationActive();
-
     // use peer's back buffer to implement non-opaque windows.
     @Override
     public boolean needUpdateWindow() {
--- a/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java	Fri Mar 30 16:57:50 2012 -0700
@@ -1067,11 +1067,7 @@
             return false;
         }
 
-        // Cross-app activation requests are not allowed.
-        if (cause != CausedFocusEvent.Cause.MOUSE_EVENT &&
-            !((LWToolkit)Toolkit.getDefaultToolkit()).isApplicationActive())
-        {
-            focusLog.fine("the app is inactive, so the request is rejected");
+        if (platformWindow.rejectFocusRequest(cause)) {
             return false;
         }
 
--- a/jdk/src/macosx/classes/sun/lwawt/PlatformWindow.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/src/macosx/classes/sun/lwawt/PlatformWindow.java	Fri Mar 30 16:57:50 2012 -0700
@@ -27,6 +27,7 @@
 
 import java.awt.*;
 
+import sun.awt.CausedFocusEvent;
 import sun.java2d.SurfaceData;
 
 // TODO Is it worth to generify this interface, like that:
@@ -117,6 +118,8 @@
 
     public void updateFocusableWindowState();
 
+    public boolean rejectFocusRequest(CausedFocusEvent.Cause cause);
+
     public boolean requestWindowFocus();
 
     /*
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java	Fri Mar 30 16:57:50 2012 -0700
@@ -38,6 +38,8 @@
 public class CEmbeddedFrame extends EmbeddedFrame {
 
     private CPlatformResponder responder;
+    private boolean focused = true;
+    private boolean parentWindowActive = true;
 
     public CEmbeddedFrame() {
         show();
@@ -94,4 +96,31 @@
     public void handleInputEvent(String text) {
         new RuntimeException("Not implemented");
     }
+
+    public void handleFocusEvent(boolean focused) {
+        this.focused = focused;
+        updateOverlayWindowActiveState();
+    }
+
+    public void handleWindowFocusEvent(boolean parentWindowActive) {
+        this.parentWindowActive = parentWindowActive;
+        updateOverlayWindowActiveState();
+    }
+
+    public boolean isParentWindowActive() {
+        return parentWindowActive;
+    }
+
+    /*
+     * May change appearance of contents of window, and generate a
+     * WINDOW_ACTIVATED event.
+     */
+    private void updateOverlayWindowActiveState() {
+        final boolean showAsFocused = parentWindowActive && focused;
+        dispatchEvent(
+            new FocusEvent(this, showAsFocused ?
+                                 FocusEvent.FOCUS_GAINED :
+                                 FocusEvent.FOCUS_LOST));
+     }
+
 }
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java	Fri Mar 30 16:57:50 2012 -0700
@@ -33,17 +33,23 @@
 
 import sun.awt.CGraphicsConfig;
 import sun.awt.CGraphicsDevice;
+import sun.awt.CausedFocusEvent;
 
 import java.awt.*;
 import java.awt.BufferCapabilities.FlipContents;
 
+import sun.util.logging.PlatformLogger;
+
 /*
  * Provides a lightweight implementation of the EmbeddedFrame.
  */
 public class CPlatformEmbeddedFrame implements PlatformWindow {
 
+    private static final PlatformLogger focusLogger = PlatformLogger.getLogger("sun.lwawt.macosx.focus.CPlatformEmbeddedFrame");
+
     private CGLLayer windowLayer;
     private LWWindowPeer peer;
+    private CEmbeddedFrame target;
 
     private volatile int screenX = 0;
     private volatile int screenY = 0;
@@ -52,6 +58,7 @@
     public void initialize(Window target, final LWWindowPeer peer, PlatformWindow owner) {
         this.peer = peer;
         this.windowLayer = new CGLLayer(peer);
+        this.target = (CEmbeddedFrame)target;
     }
 
     @Override
@@ -149,6 +156,18 @@
     public void updateFocusableWindowState() {}
 
     @Override
+    public boolean rejectFocusRequest(CausedFocusEvent.Cause cause) {
+        // Cross-app activation requests are not allowed.
+        if (cause != CausedFocusEvent.Cause.MOUSE_EVENT &&
+            !target.isParentWindowActive())
+        {
+            focusLogger.fine("the embedder is inactive, so the request is rejected");
+            return true;
+        }
+        return false;
+    }
+
+    @Override
     public boolean requestWindowFocus() {
         return true;
     }
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Fri Mar 30 16:57:50 2012 -0700
@@ -65,6 +65,7 @@
 
     // Loger to report issues happened during execution but that do not affect functionality
     private static final PlatformLogger logger = PlatformLogger.getLogger("sun.lwawt.macosx.CPlatformWindow");
+    private static final PlatformLogger focusLogger = PlatformLogger.getLogger("sun.lwawt.macosx.focus.CPlatformWindow");
 
     // for client properties
     public static final String WINDOW_BRUSH_METAL_LOOK = "apple.awt.brushMetalLook";
@@ -112,6 +113,7 @@
     static final int MINIMIZABLE = 1 << 8;
 
     static final int RESIZABLE = 1 << 9; // both a style bit and prop bit
+    static final int NONACTIVATING = 1 << 24;
 
     static final int _STYLE_PROP_BITMASK = DECORATED | TEXTURED | UNIFIED | UTILITY | HUD | SHEET | CLOSEABLE | MINIMIZABLE | RESIZABLE;
 
@@ -127,9 +129,6 @@
 
     static final int _METHOD_PROP_BITMASK = RESIZABLE | HAS_SHADOW | ZOOMABLE | ALWAYS_ON_TOP | HIDES_ON_DEACTIVATE | DRAGGABLE_BACKGROUND | DOCUMENT_MODIFIED | FULLSCREENABLE;
 
-    // not sure
-    static final int POPUP = 1 << 14;
-
     // corresponds to callback-based properties
     static final int SHOULD_BECOME_KEY = 1 << 12;
     static final int SHOULD_BECOME_MAIN = 1 << 13;
@@ -264,10 +263,6 @@
         // defaults style bits
         int styleBits = DECORATED | HAS_SHADOW | CLOSEABLE | MINIMIZABLE | ZOOMABLE | RESIZABLE;
 
-        if (target.getName() == "###overrideRedirect###") {
-            styleBits = SET(styleBits, POPUP, true);
-        }
-
         if (isNativelyFocusableWindow()) {
             styleBits = SET(styleBits, SHOULD_BECOME_KEY, true);
             styleBits = SET(styleBits, SHOULD_BECOME_MAIN, true);
@@ -275,6 +270,7 @@
 
         final boolean isFrame = (target instanceof Frame);
         final boolean isDialog = (target instanceof Dialog);
+        final boolean isPopup = (target.getType() == Window.Type.POPUP);
         if (isDialog) {
             styleBits = SET(styleBits, MINIMIZABLE, false);
         }
@@ -304,8 +300,10 @@
         }
 
         // If the target is a dialog, popup or tooltip we want it to ignore the brushed metal look.
-        if (!isDialog && IS(styleBits, POPUP)) {
+        if (isPopup) {
             styleBits = SET(styleBits, TEXTURED, true);
+            // Popups in applets don't activate applet's process
+            styleBits = SET(styleBits, NONACTIVATING, true);
         }
 
         if (target instanceof javax.swing.RootPaneContainer) {
@@ -498,11 +496,18 @@
             // If it ain't blocked, or is being hidden, go regular way
             if (visible) {
                 CWrapper.NSWindow.makeFirstResponder(nsWindowPtr, contentView.getAWTView());
+
+                boolean isPopup = (target.getType() == Window.Type.POPUP);
+                if (isPopup) {
+                    // Popups in applets don't activate applet's process
+                    CWrapper.NSWindow.orderFrontRegardless(nsWindowPtr);
+                } else {
+                    CWrapper.NSWindow.orderFront(nsWindowPtr);
+                }
+
                 boolean isKeyWindow = CWrapper.NSWindow.isKeyWindow(nsWindowPtr);
                 if (!isKeyWindow) {
-                    CWrapper.NSWindow.makeKeyAndOrderFront(nsWindowPtr);
-                } else {
-                    CWrapper.NSWindow.orderFront(nsWindowPtr);
+                    CWrapper.NSWindow.makeKeyWindow(nsWindowPtr);
                 }
             } else {
                 CWrapper.NSWindow.orderOut(nsWindowPtr);
@@ -600,7 +605,20 @@
     }
 
     @Override
+    public boolean rejectFocusRequest(CausedFocusEvent.Cause cause) {
+        // Cross-app activation requests are not allowed.
+        if (cause != CausedFocusEvent.Cause.MOUSE_EVENT &&
+            !((LWCToolkit)Toolkit.getDefaultToolkit()).isApplicationActive())
+        {
+            focusLogger.fine("the app is inactive, so the request is rejected");
+            return true;
+        }
+        return false;
+    }
+
+    @Override
     public boolean requestWindowFocus() {
+
         long ptr = getNSWindowPtr();
         if (CWrapper.NSWindow.canBecomeMainWindow(ptr)) {
             CWrapper.NSWindow.makeMainWindow(ptr);
@@ -751,6 +769,11 @@
      * Callbacks from the AWTWindow and AWTView objc classes.
      *************************************************************/
     private void deliverWindowFocusEvent(boolean gained){
+        // Fix for 7150349: ingore "gained" notifications when the app is inactive.
+        if (gained && !((LWCToolkit)Toolkit.getDefaultToolkit()).isApplicationActive()) {
+            focusLogger.fine("the app is inactive, so the notification is ignored");
+            return;
+        }
         peer.notifyActivation(gained);
     }
 
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CWrapper.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CWrapper.java	Fri Mar 30 16:57:50 2012 -0700
@@ -47,6 +47,7 @@
         public static native void setLevel(long window, int level);
 
         public static native void makeKeyAndOrderFront(long window);
+        public static native void makeKeyWindow(long window);
         public static native void makeMainWindow(long window);
         public static native boolean canBecomeMainWindow(long window);
         public static native boolean isKeyWindow(long window);
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java	Fri Mar 30 16:57:50 2012 -0700
@@ -686,7 +686,10 @@
         return sunAwtDisableCALayers.booleanValue();
     }
 
-    @Override
+
+    /*
+     * Returns true if the application (one of its windows) owns keyboard focus.
+     */
     public native boolean isApplicationActive();
 
     /************************
--- a/jdk/src/macosx/native/sun/awt/AWTView.m	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/src/macosx/native/sun/awt/AWTView.m	Fri Mar 30 16:57:50 2012 -0700
@@ -812,7 +812,7 @@
     // Unicode value.
     NSUInteger utf8Length = [aString lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
 
-    if ([self hasMarkedText] || !fProcessingKeystroke || (utf8Length > 2)) {
+    if ([self hasMarkedText] || !fProcessingKeystroke || (utf8Length > 1)) {
         JNIEnv *env = [ThreadUtilities getJNIEnv];
 
         static JNF_MEMBER_CACHE(jm_selectPreviousGlyph, jc_CInputMethod, "selectPreviousGlyph", "()V");
--- a/jdk/src/macosx/native/sun/awt/AWTWindow.m	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/src/macosx/native/sun/awt/AWTWindow.m	Fri Mar 30 16:57:50 2012 -0700
@@ -102,11 +102,12 @@
         type |= NSBorderlessWindowMask;
     }
 
-    if (IS(styleBits, TEXTURED))    type |= NSTexturedBackgroundWindowMask;
-    if (IS(styleBits, UNIFIED))     type |= NSUnifiedTitleAndToolbarWindowMask;
-    if (IS(styleBits, UTILITY))     type |= NSUtilityWindowMask;
-    if (IS(styleBits, HUD))         type |= NSHUDWindowMask;
-    if (IS(styleBits, SHEET))       type |= NSDocModalWindowMask;
+    if (IS(styleBits, TEXTURED))      type |= NSTexturedBackgroundWindowMask;
+    if (IS(styleBits, UNIFIED))       type |= NSUnifiedTitleAndToolbarWindowMask;
+    if (IS(styleBits, UTILITY))       type |= NSUtilityWindowMask;
+    if (IS(styleBits, HUD))           type |= NSHUDWindowMask;
+    if (IS(styleBits, SHEET))         type |= NSDocModalWindowMask;
+    if (IS(styleBits, NONACTIVATING)) type |= NSNonactivatingPanelMask;
 
     return type;
 }
--- a/jdk/src/macosx/native/sun/awt/CWrapper.m	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/src/macosx/native/sun/awt/CWrapper.m	Fri Mar 30 16:57:50 2012 -0700
@@ -76,6 +76,26 @@
 
 /*
  * Class:     sun_lwawt_macosx_CWrapper$NSWindow
+ * Method:    makeKeyWindow
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL
+Java_sun_lwawt_macosx_CWrapper_00024NSWindow_makeKeyWindow
+(JNIEnv *env, jclass cls, jlong windowPtr)
+{
+JNF_COCOA_ENTER(env);
+
+    NSWindow *window = (NSWindow *)jlong_to_ptr(windowPtr);
+    [JNFRunLoop performOnMainThread:@selector(makeKeyWindow)
+                                 on:window
+                         withObject:nil
+                      waitUntilDone:NO];
+
+JNF_COCOA_EXIT(env);
+}
+
+/*
+ * Class:     sun_lwawt_macosx_CWrapper$NSWindow
  * Method:    makeMainWindow
  * Signature: (J)V
  */
--- a/jdk/src/macosx/native/sun/awt/LWCToolkit.m	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/src/macosx/native/sun/awt/LWCToolkit.m	Fri Mar 30 16:57:50 2012 -0700
@@ -401,18 +401,21 @@
 JNIEXPORT jboolean JNICALL Java_sun_lwawt_macosx_LWCToolkit_isApplicationActive
 (JNIEnv *env, jclass clazz)
 {
-        __block jboolean active = JNI_FALSE;
+    __block jboolean active = JNI_FALSE;
 
-AWT_ASSERT_NOT_APPKIT_THREAD;
 JNF_COCOA_ENTER(env);
 
+    if ([NSThread isMainThread]) {
+        active = (jboolean)[NSRunningApplication currentApplication].active;
+    } else {
         [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^() {
-                active = (jboolean)[NSRunningApplication currentApplication].active;
+            active = (jboolean)[NSRunningApplication currentApplication].active;
         }];
+    }
 
 JNF_COCOA_EXIT(env);
 
-        return active;
+    return active;
 }
 
 
--- a/jdk/src/macosx/native/sun/awt/OSVersion.m	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/src/macosx/native/sun/awt/OSVersion.m	Fri Mar 30 16:57:50 2012 -0700
@@ -31,33 +31,31 @@
 #import <JavaRuntimeSupport/JavaRuntimeSupport.h>
 
 
-// returns 10.7 for Lion, 10.6 for SnowLeopard etc.
-double getOSXMajorVersion() {
-    char *version = JRSCopyOSVersion();
-
-    if (version == NULL) return 0.0;
-
-    char temp[32];
-    strlcpy(temp, version, sizeof(temp));
-    free(version);
-
-    if (strlen(temp) < 3) {
-        return 0.0;
+// returns 107 for Lion, 106 for SnowLeopard etc.
+int getOSXMajorVersion() {
+    char *ver = JRSCopyOSVersion();
+    if (ver == NULL) { 
+        return 0;
     }
 
-    if (temp[2] != '.')  { // Third char must be a '.'
-        return 0.0;
+    int len = strlen(ver);
+    int v = 0;
+    
+    // Third char must be a '.'    
+    if (len >= 3 && ver[2] == '.') {
+        int i;
+        
+        v = (ver[0] - '0') * 10 + (ver[1] - '0');
+        for (i = 3; i < len && isdigit(ver[i]); ++i) {
+            v = v * 10 + (ver[i] - '0');
+        }
     }
 
-    char *ptr = strchr(temp+3, '.'); // remove the second . if one exists.
-    if (ptr != NULL) {
-        *ptr = 0;
-    }
-
-    return atof(temp);
+    free(ver);
+    
+    return v;
 }
 
-
 BOOL isSnowLeopardOrLower() {
-    return (getOSXMajorVersion() < 10.7);
+    return (getOSXMajorVersion() < 107);
 }
--- a/jdk/src/share/classes/java/util/CurrencyData.properties	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/src/share/classes/java/util/CurrencyData.properties	Fri Mar 30 16:57:50 2012 -0700
@@ -26,8 +26,7 @@
 formatVersion=1
 
 # Version of the currency code information in this class.
-# It is a serial number that accompanies with each amendment, such as 
-# 'MAxxx.doc'
+# It is a serial number that accompanies with each amendment.
 
 dataVersion=153
 
@@ -49,7 +48,7 @@
     NIO558-NLG528-NOK578-NPR524-NZD554-OMR512-PAB590-PEN604-PGK598-PHP608-\
     PKR586-PLN985-PTE620-PYG600-QAR634-ROL946-RON946-RSD941-RUB643-RUR810-RWF646-SAR682-\
     SBD090-SCR690-SDD736-SDG938-SEK752-SGD702-SHP654-SIT705-SKK703-SLL694-SOS706-\
-    SRD968-SRG740-STD678-SVC222-SYP760-SZL748-THB764-TJS972-TMM795-TMT934-TND788-TOP776-\
+    SRD968-SRG740-SSP728-STD678-SVC222-SYP760-SZL748-THB764-TJS972-TMM795-TMT934-TND788-TOP776-\
     TPE626-TRL792-TRY949-TTD780-TWD901-TZS834-UAH980-UGX800-USD840-USN997-USS998-\
     UYU858-UZS860-VEB862-VEF937-VND704-VUV548-WST882-XAF950-XAG961-XAU959-XBA955-\
     XBB956-XBC957-XBD958-XCD951-XDR960-XFO000-XFU000-XOF952-XPD964-XPF953-\
@@ -463,6 +462,8 @@
 WS=WST
 # SAN MARINO
 SM=EUR
+# SOUTH SUDAN
+SS=SSP
 # SAO TOME AND PRINCIPE
 ST=STD
 # SAUDI ARABIA
--- a/jdk/src/share/classes/java/util/LocaleISOData.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/src/share/classes/java/util/LocaleISOData.java	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -433,6 +433,7 @@
         + "SN" + "SEN"  // Senegal, Republic of
         + "SO" + "SOM"  // Somalia, Somali Republic
         + "SR" + "SUR"  // Suriname, Republic of
+        + "SS" + "SSD"  // South Sudan
         + "ST" + "STP"  // Sao Tome and Principe, Democratic Republic of
         + "SV" + "SLV"  // El Salvador, Republic of
         + "SX" + "SXM"  // Sint Maarten (Dutch part)
--- a/jdk/src/share/classes/javax/swing/DefaultListSelectionModel.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/src/share/classes/javax/swing/DefaultListSelectionModel.java	Fri Mar 30 16:57:50 2012 -0700
@@ -252,6 +252,10 @@
 
     // Updates first and last change indices
     private void markAsDirty(int r) {
+        if (r == -1) {
+            return;
+        }
+
         firstAdjustedIndex = Math.min(firstAdjustedIndex, r);
         lastAdjustedIndex =  Math.max(lastAdjustedIndex, r);
     }
@@ -358,16 +362,12 @@
     private void updateLeadAnchorIndices(int anchorIndex, int leadIndex) {
         if (leadAnchorNotificationEnabled) {
             if (this.anchorIndex != anchorIndex) {
-                if (this.anchorIndex != -1) { // The unassigned state.
-                    markAsDirty(this.anchorIndex);
-                }
+                markAsDirty(this.anchorIndex);
                 markAsDirty(anchorIndex);
             }
 
             if (this.leadIndex != leadIndex) {
-                if (this.leadIndex != -1) { // The unassigned state.
-                    markAsDirty(this.leadIndex);
-                }
+                markAsDirty(this.leadIndex);
                 markAsDirty(leadIndex);
             }
         }
--- a/jdk/src/share/classes/sun/util/resources/CurrencyNames.properties	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/src/share/classes/sun/util/resources/CurrencyNames.properties	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,7 @@
 #
 # COPYRIGHT AND PERMISSION NOTICE
 #
-# Copyright (C) 1991-2011 Unicode, Inc. All rights reserved.
+# Copyright (C) 1991-2012 Unicode, Inc. All rights reserved.
 # Distributed under the Terms of Use in http://www.unicode.org/copyright.html.
 #
 # Permission is hereby granted, free of charge, to any person obtaining
@@ -226,6 +226,7 @@
 SOS=SOS
 SRD=SRD
 SRG=SRG
+SSP=SSP
 STD=STD
 SVC=SVC
 SYP=SYP
@@ -443,6 +444,7 @@
 sos=Somali Shilling
 srd=Surinamese Dollar
 srg=Surinamese Guilder
+ssp=South Sudanese Pound
 std=S\u00e3o Tom\u00e9 and Pr\u00edncipe Dobra
 svc=Salvadoran Col\u00f3n
 syp=Syrian Pound
@@ -486,7 +488,9 @@
 xpd=Palladium
 xpf=CFP Franc
 xpt=Platinum
+xsu=Sucre
 xts=Testing Currency Code
+xua=ADB Unit of Account
 xxx=Unknown Currency
 yer=Yemeni Rial
 yum=Yugoslavian New Dinar (1994-2002)
--- a/jdk/src/share/classes/sun/util/resources/LocaleNames.properties	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/src/share/classes/sun/util/resources/LocaleNames.properties	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -1077,6 +1077,7 @@
 SN=Senegal
 SO=Somalia
 SR=Suriname
+SS=South Sudan
 ST=Sao Tome And Principe
 SV=El Salvador
 SX=Sint Maarten (Dutch part)
--- a/jdk/src/share/demo/jvmti/compiledMethodLoad/sample.makefile.txt	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/src/share/demo/jvmti/compiledMethodLoad/sample.makefile.txt	Fri Mar 30 16:57:50 2012 -0700
@@ -90,7 +90,7 @@
     OBJECTS=$(SOURCES:%.c=%.o)
     # Library name and options needed to build it
     LIBRARY=lib$(LIBNAME).so
-    LDFLAGS=-Wl,-soname=$(LIBRARY) -static-libgcc -mimpure-text
+    LDFLAGS=-Wl,-soname=$(LIBRARY) -static-libgcc
     # Libraries we are dependent on
     LIBRARIES=-lc
     # Building a shared library
--- a/jdk/src/share/demo/jvmti/gctest/sample.makefile.txt	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/src/share/demo/jvmti/gctest/sample.makefile.txt	Fri Mar 30 16:57:50 2012 -0700
@@ -90,7 +90,7 @@
     OBJECTS=$(SOURCES:%.c=%.o)
     # Library name and options needed to build it
     LIBRARY=lib$(LIBNAME).so
-    LDFLAGS=-Wl,-soname=$(LIBRARY) -static-libgcc -mimpure-text
+    LDFLAGS=-Wl,-soname=$(LIBRARY) -static-libgcc
     # Libraries we are dependent on
     LIBRARIES=-lc
     # Building a shared library
--- a/jdk/src/share/demo/jvmti/heapTracker/sample.makefile.txt	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/src/share/demo/jvmti/heapTracker/sample.makefile.txt	Fri Mar 30 16:57:50 2012 -0700
@@ -94,7 +94,7 @@
     OBJECTS=$(SOURCES:%.c=%.o)
     # Library name and options needed to build it
     LIBRARY=lib$(LIBNAME).so
-    LDFLAGS=-Wl,-soname=$(LIBRARY) -static-libgcc -mimpure-text
+    LDFLAGS=-Wl,-soname=$(LIBRARY) -static-libgcc
     # Libraries we are dependent on
     LIBRARIES=-L $(JDK)/jre/lib/$(LIBARCH) -ljava_crw_demo -lc
     # Building a shared library
--- a/jdk/src/share/demo/jvmti/heapViewer/sample.makefile.txt	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/src/share/demo/jvmti/heapViewer/sample.makefile.txt	Fri Mar 30 16:57:50 2012 -0700
@@ -90,7 +90,7 @@
     OBJECTS=$(SOURCES:%.c=%.o)
     # Library name and options needed to build it
     LIBRARY=lib$(LIBNAME).so
-    LDFLAGS=-Wl,-soname=$(LIBRARY) -static-libgcc -mimpure-text
+    LDFLAGS=-Wl,-soname=$(LIBRARY) -static-libgcc
     # Libraries we are dependent on
     LIBRARIES=-lc
     # Building a shared library
--- a/jdk/src/share/demo/jvmti/hprof/sample.makefile.txt	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/src/share/demo/jvmti/hprof/sample.makefile.txt	Fri Mar 30 16:57:50 2012 -0700
@@ -130,7 +130,7 @@
     OBJECTS=$(SOURCES:%.c=%.o)
     # Library name and options needed to build it
     LIBRARY=lib$(LIBNAME).so
-    LDFLAGS=-Wl,-soname=$(LIBRARY) -static-libgcc -mimpure-text
+    LDFLAGS=-Wl,-soname=$(LIBRARY) -static-libgcc
     # Libraries we are dependent on
     LIBRARIES= -ldl -lc
     # Building a shared library
--- a/jdk/src/share/demo/jvmti/index.html	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/src/share/demo/jvmti/index.html	Fri Mar 30 16:57:50 2012 -0700
@@ -308,7 +308,7 @@
 <code><ul>
 gcc -O2 -fPIC -pthread -DLINUX -c <i>*.c</i>
 <br>
-gcc -z defs -static-libgcc -shared -mimpure-text -o <i>libXXX.so *.o</i> -lc
+gcc -z defs -static-libgcc -shared -o <i>libXXX.so *.o</i> -lc
 </code></ul>
 <br>
 For AMD64:
@@ -316,7 +316,7 @@
 <code><ul>
 gcc -O2 -fPIC -pthread -DLINUX -D_LP64=1 -c <i>*.c</i>
 <br>
-gcc -z defs -static-libgcc -shared -mimpure-text -o <i>libXXX.so *.o</i> -lc
+gcc -z defs -static-libgcc -shared -o <i>libXXX.so *.o</i> -lc
 </code></ul>
 <br>
 </li>
@@ -339,7 +339,7 @@
 </li>
 
 <li>
-Library: Use -static-libgcc -mimpure-text.
+Library: Use -static-libgcc.
 <br>
 When building the shared library (-shared option), this option
 allows for maximum portability of the library between different
--- a/jdk/src/share/demo/jvmti/java_crw_demo/sample.makefile.txt	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/src/share/demo/jvmti/java_crw_demo/sample.makefile.txt	Fri Mar 30 16:57:50 2012 -0700
@@ -90,7 +90,7 @@
     OBJECTS=$(SOURCES:%.c=%.o)
     # Library name and options needed to build it
     LIBRARY=lib$(LIBNAME).so
-    LDFLAGS=-Wl,-soname=$(LIBRARY) -static-libgcc -mimpure-text
+    LDFLAGS=-Wl,-soname=$(LIBRARY) -static-libgcc
     # Libraries we are dependent on
     LIBRARIES=-lc
     # Building a shared library
--- a/jdk/src/share/demo/jvmti/minst/sample.makefile.txt	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/src/share/demo/jvmti/minst/sample.makefile.txt	Fri Mar 30 16:57:50 2012 -0700
@@ -94,7 +94,7 @@
     OBJECTS=$(SOURCES:%.c=%.o)
     # Library name and options needed to build it
     LIBRARY=lib$(LIBNAME).so
-    LDFLAGS=-Wl,-soname=$(LIBRARY) -static-libgcc -mimpure-text
+    LDFLAGS=-Wl,-soname=$(LIBRARY) -static-libgcc
     # Libraries we are dependent on
     LIBRARIES=-L $(JDK)/jre/lib/$(LIBARCH) -ljava_crw_demo -lc
     # Building a shared library
--- a/jdk/src/share/demo/jvmti/mtrace/sample.makefile.txt	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/src/share/demo/jvmti/mtrace/sample.makefile.txt	Fri Mar 30 16:57:50 2012 -0700
@@ -94,7 +94,7 @@
     OBJECTS=$(SOURCES:%.c=%.o)
     # Library name and options needed to build it
     LIBRARY=lib$(LIBNAME).so
-    LDFLAGS=-Wl,-soname=$(LIBRARY) -static-libgcc -mimpure-text
+    LDFLAGS=-Wl,-soname=$(LIBRARY) -static-libgcc
     # Libraries we are dependent on
     LIBRARIES=-L $(JDK)/jre/lib/$(LIBARCH) -ljava_crw_demo -lc
     # Building a shared library
--- a/jdk/src/share/demo/jvmti/versionCheck/sample.makefile.txt	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/src/share/demo/jvmti/versionCheck/sample.makefile.txt	Fri Mar 30 16:57:50 2012 -0700
@@ -90,7 +90,7 @@
     OBJECTS=$(SOURCES:%.c=%.o)
     # Library name and options needed to build it
     LIBRARY=lib$(LIBNAME).so
-    LDFLAGS=-Wl,-soname=$(LIBRARY) -static-libgcc -mimpure-text
+    LDFLAGS=-Wl,-soname=$(LIBRARY) -static-libgcc
     # Libraries we are dependent on
     LIBRARIES=-lc
     # Building a shared library
--- a/jdk/src/share/demo/jvmti/waiters/sample.makefile.txt	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/src/share/demo/jvmti/waiters/sample.makefile.txt	Fri Mar 30 16:57:50 2012 -0700
@@ -91,7 +91,7 @@
     OBJECTS=$(SOURCES:%.cpp=%.o)
     # Library name and options needed to build it
     LIBRARY=lib$(LIBNAME).so
-    LDFLAGS=-Wl,-soname=$(LIBRARY) -static-libgcc -mimpure-text
+    LDFLAGS=-Wl,-soname=$(LIBRARY) -static-libgcc
     # Libraries we are dependent on
     LIBRARIES=
     # Building a shared library
--- a/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c	Fri Mar 30 16:57:50 2012 -0700
@@ -541,6 +541,8 @@
         J2dRlsTraceLn1(J2D_TRACE_ERROR,
                        "X11SD_SetupSharedSegment shmget has failed: %s",
                        strerror(errno));
+        free((void *)shminfo);
+        XDestroyImage(img);
         return NULL;
     }
 
@@ -550,6 +552,8 @@
         J2dRlsTraceLn1(J2D_TRACE_ERROR,
                        "X11SD_SetupSharedSegment shmat has failed: %s",
                        strerror(errno));
+        free((void *)shminfo);
+        XDestroyImage(img);
         return NULL;
     }
 
@@ -570,6 +574,9 @@
         J2dRlsTraceLn1(J2D_TRACE_ERROR,
                        "X11SD_SetupSharedSegment XShmAttach has failed: %s",
                        strerror(errno));
+        shmdt(shminfo->shmaddr);
+        free((void *)shminfo);
+        XDestroyImage(img);
         return NULL;
     }
 
@@ -1345,13 +1352,10 @@
 #ifdef MITSHM
         if (image->obdata != NULL) {
             X11SD_DropSharedSegment((XShmSegmentInfo*)image->obdata);
-        } else {
-            free(image->data);
+            image->obdata = NULL;
         }
-#else
-        free(image->data);
 #endif /* MITSHM */
-        XFree(image);
+        XDestroyImage(image);
     }
 }
 
--- a/jdk/src/windows/native/sun/windows/awt_Component.cpp	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp	Fri Mar 30 16:57:50 2012 -0700
@@ -302,6 +302,7 @@
         delete m_childList;
 
     DestroyDropTarget();
+    ReleaseDragCapture(0);
 
     if (m_myControlID != 0) {
         AwtComponent* parent = GetParent();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Frame/WindowDragTest/WindowDragTest.java	Fri Mar 30 16:57:50 2012 -0700
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+  @test
+  @bug 7128738
+  @summary dragged dialog freezes system on dispose
+  @author Oleg Pekhovskiy: area=awt.toplevel
+  @library ../../regtesthelpers
+  @run main WindowDragTest
+*/
+
+import java.awt.Frame;
+import java.awt.event.InputEvent;
+import java.awt.AWTException;
+import test.java.awt.regtesthelpers.Util;
+import java.awt.Robot;
+import java.awt.Point;
+import java.awt.Dimension;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+
+public class WindowDragTest {
+
+    static boolean passed = false;
+
+    public static void main(String[] args) {
+        try {
+            Robot robot = new Robot();
+            robot.setAutoDelay(1000);
+
+            Frame frame1 = new Frame();
+            frame1.setBounds(50, 50, 300, 200);
+            frame1.setVisible(true);
+            frame1.toFront();
+            frame1.addMouseListener(new MouseAdapter() {
+                @Override
+                public void mouseClicked(MouseEvent e) {
+                    // Clicking frame1 succeeded - mouse is not captured
+                    passed = true;
+                }
+            });
+            robot.delay(1000);
+
+            Frame frame2 = new Frame();
+            frame2.setBounds(100, 100, 300, 200);
+            frame2.setVisible(true);
+            frame2.toFront();
+            robot.delay(1000);
+
+            Point p = frame2.getLocationOnScreen();
+            Dimension d = frame2.getSize();
+
+            // Move cursor to frame2 title bar to drag
+            robot.mouseMove(p.x + (int)(d.getWidth() / 2), p.y + (int)frame2.getInsets().top / 2);
+            Util.waitForIdle(robot);
+
+            // Start window dragging
+            robot.mousePress(InputEvent.BUTTON1_MASK);
+            Util.waitForIdle(robot);
+
+            // Dispose window being dragged
+            frame2.dispose();
+            Util.waitForIdle(robot);
+
+            // Release mouse button to be able to get MOUSE_CLICKED event on Util.clickOnComp()
+            robot.mouseRelease(InputEvent.BUTTON1_MASK);
+            Util.waitForIdle(robot);
+
+            // Click frame1 to check whether mouse is not captured by frame2
+            Util.clickOnComp(frame1, robot);
+            Util.waitForIdle(robot);
+
+            frame1.dispose();
+            if (passed) {
+                System.out.println("Test passed.");
+            }
+            else {
+                System.out.println("Test failed.");
+                throw new RuntimeException("Test failed.");
+            }
+        }
+        catch (AWTException e) {
+            throw new RuntimeException("AWTException occurred - problem creating robot!");
+        }
+    }
+}
--- a/jdk/test/java/util/Currency/tablea1.txt	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/test/java/util/Currency/tablea1.txt	Fri Mar 30 16:57:50 2012 -0700
@@ -1,6 +1,6 @@
 #
 #
-# Based on BSi's ISO4217 data - "TABLE A1.doc" + amendments up until MA153.doc
+# Amendments up until ISO 4217 AMENDMENT NUMBER 153
 #   (As of 12 January 2012)
 #
 
@@ -227,6 +227,7 @@
 SB	SBD	90	2
 SO	SOS	706	2
 ZA	ZAR	710	2
+SS	SSP	728	2
 ES	EUR	978	2
 LK	LKR	144	2
 SD	SDG	938	2
--- a/jdk/test/java/util/Locale/LocaleTest.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/test/java/util/Locale/LocaleTest.java	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
  * @bug 4052404 4052440 4084688 4092475 4101316 4105828 4107014 4107953 4110613
  * 4118587 4118595 4122371 4126371 4126880 4135316 4135752 4139504 4139940 4143951
  * 4147315 4147317 4147552 4335196 4778440 4940539 5010672 6475525 6544471 6627549
- * 6786276 7066203
+ * 6786276 7066203 7085757
  * @summary test Locales
  */
 /*
@@ -400,7 +400,7 @@
     }
 
     /**
-     * @bug 4106155 4118587 7066203
+     * @bug 4106155 4118587 7066203 7085757
      */
     public void TestGetLangsAndCountries() {
         // It didn't seem right to just do an exhaustive test of everything here, so I check
@@ -440,8 +440,8 @@
         String[] spotCheck2 = { "US", "CA", "GB", "FR", "DE", "IT", "JP", "KR", "CN", "TW", "TH" };
 
 
-        if (test.length != 249)
-            errln("Expected getISOCountries to return 249 countries; it returned " + test.length);
+        if (test.length != 250)
+            errln("Expected getISOCountries to return 250 countries; it returned " + test.length);
         else {
             for (int i = 0; i < spotCheck2.length; i++) {
                 int j;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JTable/7027139/bug7027139.java	Fri Mar 30 16:57:50 2012 -0700
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+   @bug 7027139
+   @summary getFirstIndex() does not return the first index that has changed
+   @author Pavel Porvatov
+*/
+
+import javax.swing.*;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+
+public class bug7027139 {
+    public static void main(String[] args) throws Exception {
+        SwingUtilities.invokeAndWait(new Runnable() {
+            public void run() {
+                JTable orderTable = new JTable(new String[][]{
+                        {"Item 1 1", "Item 1 2"},
+                        {"Item 2 1", "Item 2 2"},
+                        {"Item 3 1", "Item 3 2"},
+                        {"Item 4 1", "Item 4 2"},
+                },
+                        new String[]{"Col 1", "Col 2"});
+
+                ListSelectionModel selectionModel = orderTable.getSelectionModel();
+                selectionModel.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+                selectionModel.addListSelectionListener(new ListSelectionListener() {
+                    public void valueChanged(ListSelectionEvent e) {
+                        if (e.getValueIsAdjusting()) {
+                            return;
+                        }
+
+                        if (e.getFirstIndex() < 0) {
+                            throw new RuntimeException("Test bug7027139 failed");
+                        }
+                    }
+                });
+
+                orderTable.selectAll();
+            }
+        });
+
+        System.out.println("Test bug7027139 passed");
+    }
+}
--- a/jdk/test/sun/text/resources/LocaleData	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/test/sun/text/resources/LocaleData	Fri Mar 30 16:57:50 2012 -0700
@@ -7019,3 +7019,11 @@
 FormatData/bg/DateTimePatterns/5=dd MMMM y
 FormatData/bg/DateTimePatterns/6=dd.MM.yyyy
 FormatData/bg/DateTimePatterns/7=dd.MM.yy
+
+# bug 7085757
+CurrencyNames//SSP=SSP
+CurrencyNames//ssp=South Sudanese Pound
+CurrencyNames//xsu=Sucre
+CurrencyNames//xua=ADB Unit of Account
+LocaleNames//SS=South Sudan
+LocaleNames/en/SS=South Sudan
\ No newline at end of file
--- a/jdk/test/sun/text/resources/LocaleDataTest.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/jdk/test/sun/text/resources/LocaleDataTest.java	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,7 +34,7 @@
  *      6509039 6609737 6610748 6645271 6507067 6873931 6450945 6645268 6646611
  *      6645405 6650730 6910489 6573250 6870908 6585666 6716626 6914413 6916787
  *      6919624 6998391 7019267 7020960 7025837 7020583 7036905 7066203 7101495
- *      7003124
+ *      7003124 7085757
  * @summary Verify locale data
  *
  */
--- a/langtools/.hgignore	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/.hgignore	Fri Mar 30 16:57:50 2012 -0700
@@ -2,3 +2,4 @@
 ^dist/
 /nbproject/private/
 ^.hgtip
+.DS_Store
--- a/langtools/.hgtags	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/.hgtags	Fri Mar 30 16:57:50 2012 -0700
@@ -150,3 +150,7 @@
 b556aa8a99c358469861770aebdce884e06fa178 jdk8-b26
 be456f9c64e818161c789252145d4ddc292ae863 jdk8-b27
 5bed623b0c773aa8a8d5f8d4004ce9d3974143cc jdk8-b28
+e974e82abe51ef66dc32bb6ab5d0733753d3c7d7 jdk8-b29
+08a3425f39f829502ca0ddbfb2d051c31710cb19 jdk8-b30
+b28cfbe7e8b196da954bed9a22bfd790e55333aa jdk8-b31
+be069d72dde2bfe6f996c46325a320961ca854c2 jdk8-b32
--- a/langtools/make/build.xml	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/make/build.xml	Fri Mar 30 16:57:50 2012 -0700
@@ -862,7 +862,8 @@
                source="${boot.javac.source}"
                target="${boot.javac.target}"
                executable="${boot.java.home}/bin/javac"
-               srcdir="${make.tools.dir}/CompileProperties"
+               srcdir="${make.tools.dir}"
+               includes="compileproperties/* anttasks/CompileProperties*"
                destdir="${build.toolclasses.dir}/"
                classpath="${ant.core.lib}"
                bootclasspath="${boot.java.home}/jre/lib/rt.jar"
@@ -870,7 +871,7 @@
             <compilerarg line="${javac.lint.opts}"/>
         </javac>
         <taskdef name="pcompile"
-                 classname="CompilePropertiesTask"
+                 classname="anttasks.CompilePropertiesTask"
                  classpath="${build.toolclasses.dir}/"/>
     </target>
 
@@ -880,7 +881,8 @@
                source="${boot.javac.source}"
                target="${boot.javac.target}"
                executable="${boot.java.home}/bin/javac"
-               srcdir="${make.tools.dir}/GenStubs"
+               srcdir="${make.tools.dir}"
+               includes="genstubs/* anttasks/GenStubs*"
                destdir="${build.toolclasses.dir}/"
                classpath="${ant.core.lib}"
                includeantruntime="false">
@@ -888,7 +890,7 @@
             <compilerarg line="${javac.lint.opts}"/>
         </javac>
         <taskdef name="genstubs"
-                 classname="GenStubs$$Ant"
+                 classname="anttasks.GenStubsTask"
                  classpath="${build.toolclasses.dir}/"/>
     </target>
 
--- a/langtools/make/jprt.properties	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/make/jprt.properties	Fri Mar 30 16:57:50 2012 -0700
@@ -39,6 +39,7 @@
     solaris_x64_5.10-{product|fastdebug},                       \
     linux_i586_2.6-{product|fastdebug},                         \
     linux_x64_2.6-{product|fastdebug},                          \
+    macosx_x64_10.7-{product|fastdebug},                        \
     windows_i586_5.1-{product|fastdebug},                       \
     windows_x64_5.2-{product|fastdebug}
 
@@ -50,6 +51,7 @@
     solaris_x64_5.10-product-c2-TESTNAME,                       \
     linux_i586_2.6-product-{c1|c2}-TESTNAME,                    \
     linux_x64_2.6-product-c2-TESTNAME,                          \
+    macosx_x64_10.7-product-c2-TESTNAME,                        \
     windows_i586_5.1-product-c1-TESTNAME,                       \
     windows_x64_5.2-product-c2-TESTNAME
 
@@ -60,3 +62,18 @@
 # Directories to be excluded from the source bundles
 jprt.bundle.exclude.src.dirs=build dist webrev
 
+# Test target list (no fastdebug & limited c2 testing)
+jprt.my.test.target.set= 					\
+    solaris_sparc_5.10-product-c1-TESTNAME,                     \
+    solaris_sparcv9_5.10-product-c2-TESTNAME,                   \
+    solaris_i586_5.10-product-c1-TESTNAME,                      \
+    solaris_x64_5.10-product-c2-TESTNAME,                       \
+    linux_i586_2.6-product-{c1|c2}-TESTNAME,                    \
+    linux_x64_2.6-product-c2-TESTNAME,                          \
+    macosx_x64_10.7-product-c2-TESTNAME,                        \
+    windows_i586_5.1-product-c1-TESTNAME,                       \
+    windows_x64_5.2-product-c2-TESTNAME
+
+# Default test targets
+jprt.make.rule.test.targets=					\
+    ${jprt.my.test.target.set:TESTNAME=jtreg}
--- a/langtools/make/netbeans/langtools/build.xml	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/make/netbeans/langtools/build.xml	Fri Mar 30 16:57:50 2012 -0700
@@ -261,7 +261,8 @@
 
     <target name="-def-select-tool">
         <mkdir dir="${build.toolclasses.dir}"/>
-        <javac srcdir="${make.tools.dir}/SelectTool"
+        <javac srcdir="${make.tools.dir}"
+               includes="anttasks/SelectTool*"
                destdir="${build.toolclasses.dir}/"
                classpath="${ant.core.lib}"
                includeantruntime="false"
@@ -270,7 +271,7 @@
                    <compilerarg line="-Xlint"/>
         </javac>
         <taskdef name="select-tool"
-                 classname="SelectToolTask"
+                 classname="anttasks.SelectToolTask"
                  classpath="${build.toolclasses.dir}/"/>
     </target>
 
--- a/langtools/make/tools/CompileProperties/CompileProperties.java	Fri Mar 30 15:43:13 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,402 +0,0 @@
-/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Properties;
-
-/** Translates a .properties file into a .java file containing the
- *  definition of a java.util.Properties subclass which can then be
- *  compiled with javac. <P>
- *
- *  Usage: java CompileProperties [path to .properties file] [path to .java file to be output] [super class]
- *
- *  Infers the package by looking at the common suffix of the two
- *  inputs, eliminating "classes" from it.
- *
- * @author Scott Violet
- * @author Kenneth Russell
- */
-
-public class CompileProperties {
-
-    public static void main(String[] args) {
-        CompileProperties cp = new CompileProperties();
-        boolean ok = cp.run(args);
-        if ( !ok ) {
-            System.exit(1);
-        }
-    }
-
-    static interface Log {
-        void info(String msg);
-        void verbose(String msg);
-        void error(String msg, Exception e);
-    }
-
-    private String propfiles[];
-    private String outfiles[] ;
-    private String supers[]   ;
-    private int compileCount = 0;
-    private boolean quiet = false;
-    private Log log;
-
-    public void setLog(Log log) {
-        this.log = log;
-    }
-
-    public boolean run(String[] args) {
-        if (log == null) {
-            log = new Log() {
-                public void error(String msg, Exception e) {
-                    System.err.println("ERROR: CompileProperties: " + msg);
-                    if ( e != null ) {
-                        System.err.println("EXCEPTION: " + e.toString());
-                        e.printStackTrace();
-                    }
-                }
-                public void info(String msg) {
-                    System.out.println(msg);
-                }
-                public void verbose(String msg) {
-                    if (!quiet)
-                        System.out.println(msg);
-                }
-            };
-        }
-
-        boolean ok = true;
-        /* Original usage */
-        if (args.length == 2 && args[0].charAt(0) != '-' ) {
-            ok = createFile(args[0], args[1], "java.util.ListResourceBundle");
-        } else if (args.length == 3) {
-            ok = createFile(args[0], args[1], args[2]);
-        } else if (args.length == 0) {
-            usage(log);
-            ok = false;
-        } else {
-            /* New batch usage */
-            ok = parseOptions(args);
-            if ( ok && compileCount == 0 ) {
-                log.error("options parsed but no files to compile", null);
-                ok = false;
-            }
-            /* Need at least one file. */
-            if ( !ok ) {
-                usage(log);
-            } else {
-                /* Process files */
-                for ( int i = 0; i < compileCount && ok ; i++ ) {
-                    ok = createFile(propfiles[i], outfiles[i], supers[i]);
-                }
-            }
-        }
-        return ok;
-    }
-
-    private boolean parseOptions(String args[]) {
-        boolean ok = true;
-        if ( compileCount > 0 ) {
-            String new_propfiles[] = new String[compileCount + args.length];
-            String new_outfiles[]  = new String[compileCount + args.length];
-            String new_supers[]    = new String[compileCount + args.length];
-            System.arraycopy(propfiles, 0, new_propfiles, 0, compileCount);
-            System.arraycopy(outfiles, 0, new_outfiles, 0, compileCount);
-            System.arraycopy(supers, 0, new_supers, 0, compileCount);
-            propfiles = new_propfiles;
-            outfiles  = new_outfiles;
-            supers    = new_supers;
-        } else {
-            propfiles = new String[args.length];
-            outfiles  = new String[args.length];
-            supers    = new String[args.length];
-        }
-
-        for ( int i = 0; i < args.length ; i++ ) {
-            if ( "-compile".equals(args[i]) && i+3 < args.length ) {
-                propfiles[compileCount] = args[++i];
-                outfiles[compileCount]  = args[++i];
-                supers[compileCount]    = args[++i];
-                compileCount++;
-            } else if ( "-optionsfile".equals(args[i]) && i+1 < args.length ) {
-                String filename = args[++i];
-                FileInputStream finput = null;
-                byte contents[] = null;
-                try {
-                    finput = new FileInputStream(filename);
-                    int byteCount = finput.available();
-                    if ( byteCount <= 0 ) {
-                        log.error("The -optionsfile file is empty", null);
-                        ok = false;
-                    } else {
-                        contents = new byte[byteCount];
-                        int bytesRead = finput.read(contents);
-                        if ( byteCount != bytesRead ) {
-                            log.error("Cannot read all of -optionsfile file", null);
-                            ok = false;
-                        }
-                    }
-                } catch ( IOException e ) {
-                    log.error("cannot open " + filename, e);
-                    ok = false;
-                }
-                if ( finput != null ) {
-                    try {
-                        finput.close();
-                    } catch ( IOException e ) {
-                        ok = false;
-                        log.error("cannot close " + filename, e);
-                    }
-                }
-                if ( ok = true && contents != null ) {
-                    String tokens[] = (new String(contents)).split("\\s+");
-                    if ( tokens.length > 0 ) {
-                        ok = parseOptions(tokens);
-                    }
-                }
-                if ( !ok ) {
-                    break;
-                }
-            } else if ( "-quiet".equals(args[i]) ) {
-                quiet = true;
-            } else {
-                log.error("argument error", null);
-                ok = false;
-            }
-        }
-        return ok;
-    }
-
-    private boolean createFile(String propertiesPath, String outputPath,
-            String superClass) {
-        boolean ok = true;
-        log.verbose("parsing: " + propertiesPath);
-        Properties p = new Properties();
-        try {
-            p.load(new FileInputStream(propertiesPath));
-        } catch ( FileNotFoundException e ) {
-            ok = false;
-            log.error("Cannot find file " + propertiesPath, e);
-        } catch ( IOException e ) {
-            ok = false;
-            log.error("IO error on file " + propertiesPath, e);
-        }
-        if ( ok ) {
-            String packageName = inferPackageName(propertiesPath, outputPath);
-            log.verbose("inferred package name: " + packageName);
-            List<String> sortedKeys = new ArrayList<String>();
-            for ( Object key : p.keySet() ) {
-                sortedKeys.add((String)key);
-            }
-            Collections.sort(sortedKeys);
-            Iterator<String> keys = sortedKeys.iterator();
-
-            StringBuffer data = new StringBuffer();
-
-            while (keys.hasNext()) {
-                String key = keys.next();
-                data.append("            { \"" + escape(key) + "\", \"" +
-                        escape((String)p.get(key)) + "\" },\n");
-            }
-
-            // Get class name from java filename, not the properties filename.
-            //   (zh_TW properties might be used to create zh_HK files)
-            File file = new File(outputPath);
-            String name = file.getName();
-            int dotIndex = name.lastIndexOf('.');
-            String className;
-            if (dotIndex == -1) {
-                className = name;
-            } else {
-                className = name.substring(0, dotIndex);
-            }
-
-            String packageString = "";
-            if (packageName != null && !packageName.equals("")) {
-                packageString = "package " + packageName + ";\n\n";
-            }
-
-            Writer writer = null;
-            try {
-                writer = new BufferedWriter(
-                        new OutputStreamWriter(new FileOutputStream(outputPath), "8859_1"));
-                MessageFormat format = new MessageFormat(FORMAT);
-                writer.write(format.format(new Object[] { packageString, className, superClass, data }));
-            } catch ( IOException e ) {
-                ok = false;
-                log.error("IO error writing to file " + outputPath, e);
-            }
-            if ( writer != null ) {
-                try {
-                    writer.flush();
-                } catch ( IOException e ) {
-                    ok = false;
-                    log.error("IO error flush " + outputPath, e);
-                }
-                try {
-                    writer.close();
-                } catch ( IOException e ) {
-                    ok = false;
-                    log.error("IO error close " + outputPath, e);
-                }
-            }
-            log.verbose("wrote: " + outputPath);
-        }
-        return ok;
-    }
-
-    private static void usage(Log log) {
-        log.info("usage:");
-        log.info("    java CompileProperties path_to_properties_file path_to_java_output_file [super_class]");
-        log.info("      -OR-");
-        log.info("    java CompileProperties {-compile path_to_properties_file path_to_java_output_file super_class} -or- -optionsfile filename");
-        log.info("");
-        log.info("Example:");
-        log.info("    java CompileProperties -compile test.properties test.java java.util.ListResourceBundle");
-        log.info("    java CompileProperties -optionsfile option_file");
-        log.info("option_file contains: -compile test.properties test.java java.util.ListResourceBundle");
-    }
-
-    private static String escape(String theString) {
-        // This is taken from Properties.saveConvert with changes for Java strings
-        int len = theString.length();
-        StringBuffer outBuffer = new StringBuffer(len*2);
-
-        for(int x=0; x<len; x++) {
-            char aChar = theString.charAt(x);
-            switch(aChar) {
-                case '\\':outBuffer.append('\\'); outBuffer.append('\\');
-                break;
-                case '\t':outBuffer.append('\\'); outBuffer.append('t');
-                break;
-                case '\n':outBuffer.append('\\'); outBuffer.append('n');
-                break;
-                case '\r':outBuffer.append('\\'); outBuffer.append('r');
-                break;
-                case '\f':outBuffer.append('\\'); outBuffer.append('f');
-                break;
-                default:
-                    if ((aChar < 0x0020) || (aChar > 0x007e)) {
-                        outBuffer.append('\\');
-                        outBuffer.append('u');
-                        outBuffer.append(toHex((aChar >> 12) & 0xF));
-                        outBuffer.append(toHex((aChar >>  8) & 0xF));
-                        outBuffer.append(toHex((aChar >>  4) & 0xF));
-                        outBuffer.append(toHex( aChar        & 0xF));
-                    } else {
-                        if (specialSaveChars.indexOf(aChar) != -1) {
-                            outBuffer.append('\\');
-                        }
-                        outBuffer.append(aChar);
-                    }
-            }
-        }
-        return outBuffer.toString();
-    }
-
-    private static String inferPackageName(String inputPath, String outputPath) {
-        // Normalize file names
-        inputPath  = new File(inputPath).getPath();
-        outputPath = new File(outputPath).getPath();
-        // Split into components
-        String sep;
-        if (File.separatorChar == '\\') {
-            sep = "\\\\";
-        } else {
-            sep = File.separator;
-        }
-        String[] inputs  = inputPath.split(sep);
-        String[] outputs = outputPath.split(sep);
-        // Match common names, eliminating first "classes" entry from
-        // each if present
-        int inStart  = 0;
-        int inEnd    = inputs.length - 2;
-        int outEnd   = outputs.length - 2;
-        int i = inEnd;
-        int j = outEnd;
-        while (i >= 0 && j >= 0) {
-            if (!inputs[i].equals(outputs[j]) ||
-                    (inputs[i].equals("gensrc") && inputs[j].equals("gensrc"))) {
-                ++i;
-                ++j;
-                break;
-            }
-            --i;
-            --j;
-        }
-        String result;
-        if (i < 0 || j < 0 || i >= inEnd || j >= outEnd) {
-            result = "";
-        } else {
-            if (inputs[i].equals("classes") && outputs[j].equals("classes")) {
-                ++i;
-            }
-            inStart = i;
-            StringBuffer buf = new StringBuffer();
-            for (i = inStart; i <= inEnd; i++) {
-                buf.append(inputs[i]);
-                if (i < inEnd) {
-                    buf.append('.');
-                }
-            }
-            result = buf.toString();
-        }
-        return result;
-    }
-
-    private static final String FORMAT =
-            "{0}" +
-            "public final class {1} extends {2} '{'\n" +
-            "    protected final Object[][] getContents() '{'\n" +
-            "        return new Object[][] '{'\n" +
-            "{3}" +
-            "        };\n" +
-            "    }\n" +
-            "}\n";
-
-    // This comes from Properties
-    private static char toHex(int nibble) {
-        return hexDigit[(nibble & 0xF)];
-    }
-
-    // This comes from Properties
-    private static final char[] hexDigit = {
-        '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
-    };
-
-    // Note: different from that in Properties
-    private static final String specialSaveChars = "\"";
-}
--- a/langtools/make/tools/CompileProperties/CompilePropertiesTask.java	Fri Mar 30 15:43:13 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.DirectoryScanner;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.taskdefs.MatchingTask;
-
-public class CompilePropertiesTask extends MatchingTask {
-    public void setSrcDir(File srcDir) {
-        this.srcDir = srcDir;
-    }
-
-    public void setDestDir(File destDir) {
-        this.destDir = destDir;
-    }
-
-    public void setSuperclass(String superclass) {
-        this.superclass = superclass;
-    }
-
-    @Override
-    public void execute() {
-        CompileProperties.Log log = new CompileProperties.Log() {
-            public void error(String msg, Exception e) {
-                log(msg, Project.MSG_ERR);
-            }
-            public void info(String msg) {
-                log(msg, Project.MSG_INFO);
-            }
-            public void verbose(String msg) {
-                log(msg, Project.MSG_VERBOSE);
-            }
-        };
-        List<String> mainOpts = new ArrayList<String>();
-        int count = 0;
-        DirectoryScanner s = getDirectoryScanner(srcDir);
-        for (String path: s.getIncludedFiles()) {
-            if (path.endsWith(".properties")) {
-                String destPath =
-                        path.substring(0, path.length() - ".properties".length()) +
-                        ".java";
-                File srcFile = new File(srcDir, path);
-                File destFile = new File(destDir, destPath);
-                // Arguably, the comparison in the next line should be ">", not ">="
-                // but that assumes the resolution of the last modified time is fine
-                // grained enough; in practice, it is better to use ">=".
-                if (destFile.exists() && destFile.lastModified() >= srcFile.lastModified())
-                    continue;
-                destFile.getParentFile().mkdirs();
-                mainOpts.add("-compile");
-                mainOpts.add(srcFile.getPath());
-                mainOpts.add(destFile.getPath());
-                mainOpts.add(superclass);
-                count++;
-            }
-        }
-        if (mainOpts.size() > 0) {
-            log("Generating " + count + " resource files to " + destDir, Project.MSG_INFO);
-            CompileProperties cp = new CompileProperties();
-            cp.setLog(log);
-            boolean ok = cp.run(mainOpts.toArray(new String[mainOpts.size()]));
-            if (!ok)
-                throw new BuildException("CompileProperties failed.");
-        }
-    }
-
-    private File srcDir;
-    private File destDir;
-    private String superclass = "java.util.ListResourceBundle";
-}
--- a/langtools/make/tools/GenStubs/GenStubs.java	Fri Mar 30 15:43:13 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,448 +0,0 @@
-/*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.io.*;
-import java.util.*;
-import javax.tools.JavaFileObject;
-import javax.tools.StandardJavaFileManager;
-import javax.tools.StandardLocation;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.DirectoryScanner;
-import org.apache.tools.ant.taskdefs.MatchingTask;
-import org.apache.tools.ant.types.Path;
-import org.apache.tools.ant.types.Reference;
-
-
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.util.JavacTask;
-import com.sun.tools.javac.api.JavacTool;
-import com.sun.tools.javac.code.Flags;
-import com.sun.tools.javac.code.TypeTags;
-import com.sun.tools.javac.tree.JCTree;
-import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
-import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
-import com.sun.tools.javac.tree.JCTree.JCIdent;
-import com.sun.tools.javac.tree.JCTree.JCImport;
-import com.sun.tools.javac.tree.JCTree.JCLiteral;
-import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
-import com.sun.tools.javac.tree.JCTree.JCModifiers;
-import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
-import com.sun.tools.javac.tree.Pretty;
-import com.sun.tools.javac.tree.TreeMaker;
-import com.sun.tools.javac.tree.TreeScanner;
-import com.sun.tools.javac.tree.TreeTranslator;
-import com.sun.tools.javac.util.Context;
-import com.sun.tools.javac.util.ListBuffer;
-import com.sun.tools.javac.util.Name;
-import javax.tools.JavaFileManager;
-
-/**
- * Generate stub source files by removing implementation details from input files.
- *
- * This is a special purpose stub generator, specific to the needs of generating
- * stub files for JDK 7 API that are needed to compile langtools files that depend
- * on that API. The stub generator works by removing as much of the API source code
- * as possible without affecting the public signature, in order to reduce the
- * transitive closure of the API being referenced. The resulting stubs can be
- * put on the langtools sourcepath with -implicit:none to compile the langtools
- * files that depend on the JDK 7 API.
- *
- * Usage:
- *  genstubs -s <outdir> -sourcepath <path> <classnames>
- *
- * The specified class names are looked up on the sourcepath, and corresponding
- * stubs are written to the source output directory.
- *
- * Classes are parsed into javac ASTs, then processed with a javac TreeTranslator
- * to remove implementation details, and written out in the source output directory.
- * Documentation comments and annotations are removed. Method bodies are removed
- * and methods are marked native. Private and package-private field definitions
- * have their initializers replace with 0, 0.0, false, null as appropriate.
- *
- * An Ant task, Main$Ant is also provided. Files are specified with an implicit
- * fileset, using srcdir as a base directory. The set of files to be included
- * is specified with an includes attribute or nested <includes> set. However,
- * unlike a normal fileset, an empty includes attribute means "no files" instead
- * of "all files".  The Ant task also accepts "fork=true" and classpath attribute
- * or nested <classpath> element to run GenStubs in a separate VM with the specified
- * path. This is likely necessary if a JDK 7 parser is required to read the
- * JDK 7 input files.
- */
-
-public class GenStubs {
-    static class Fault extends Exception {
-        private static final long serialVersionUID = 0;
-        Fault(String message) {
-            super(message);
-        }
-        Fault(String message, Throwable cause) {
-            super(message);
-            initCause(cause);
-        }
-    }
-
-    public static void main(String[] args) {
-        boolean ok = new GenStubs().run(args);
-        if (!ok)
-            System.exit(1);
-    }
-
-    boolean run(String... args) {
-        File outdir = null;
-        String sourcepath = null;
-        List<String> classes = new ArrayList<String>();
-        for (ListIterator<String> iter = Arrays.asList(args).listIterator(); iter.hasNext(); ) {
-            String arg = iter.next();
-            if (arg.equals("-s") && iter.hasNext())
-                outdir = new File(iter.next());
-            else if (arg.equals("-sourcepath") && iter.hasNext())
-                sourcepath = iter.next();
-            else if (arg.startsWith("-"))
-                throw new IllegalArgumentException(arg);
-            else {
-                classes.add(arg);
-                while (iter.hasNext())
-                    classes.add(iter.next());
-            }
-        }
-
-        return run(sourcepath, outdir, classes);
-    }
-
-    boolean run(String sourcepath, File outdir, List<String> classes) {
-        //System.err.println("run: sourcepath:" + sourcepath + " outdir:" + outdir + " classes:" + classes);
-        if (sourcepath == null)
-            throw new IllegalArgumentException("sourcepath not set");
-        if (outdir == null)
-            throw new IllegalArgumentException("source output dir not set");
-
-        JavacTool tool = JavacTool.create();
-        StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
-
-        try {
-            fm.setLocation(StandardLocation.SOURCE_OUTPUT, Collections.singleton(outdir));
-            fm.setLocation(StandardLocation.SOURCE_PATH, splitPath(sourcepath));
-            List<JavaFileObject> files = new ArrayList<JavaFileObject>();
-            for (String c: classes) {
-                JavaFileObject fo = fm.getJavaFileForInput(
-                        StandardLocation.SOURCE_PATH, c, JavaFileObject.Kind.SOURCE);
-                if (fo == null)
-                    error("class not found: " + c);
-                else
-                    files.add(fo);
-            }
-
-            JavacTask t = tool.getTask(null, fm, null, null, null, files);
-            Iterable<? extends CompilationUnitTree> trees = t.parse();
-            for (CompilationUnitTree tree: trees) {
-                makeStub(fm, tree);
-            }
-        } catch (IOException e) {
-            error("IO error " + e, e);
-        }
-
-        return (errors == 0);
-    }
-
-    void makeStub(StandardJavaFileManager fm, CompilationUnitTree tree) throws IOException {
-        CompilationUnitTree tree2 = new StubMaker().translate(tree);
-        CompilationUnitTree tree3 = new ImportCleaner(fm).removeRedundantImports(tree2);
-
-        String className = fm.inferBinaryName(StandardLocation.SOURCE_PATH, tree.getSourceFile());
-        JavaFileObject fo = fm.getJavaFileForOutput(StandardLocation.SOURCE_OUTPUT,
-                className, JavaFileObject.Kind.SOURCE, null);
-        // System.err.println("Writing " + className + " to " + fo.getName());
-        Writer out = fo.openWriter();
-        try {
-            new Pretty(out, true).printExpr((JCTree) tree3);
-        } finally {
-            out.close();
-        }
-    }
-
-    List<File> splitPath(String path) {
-        List<File> list = new ArrayList<File>();
-        for (String p: path.split(File.pathSeparator)) {
-            if (p.length() > 0)
-                list.add(new File(p));
-        }
-        return list;
-    }
-
-    void error(String message) {
-        System.err.println(message);
-        errors++;
-    }
-
-    void error(String message, Throwable cause) {
-        error(message);
-    }
-
-    int errors;
-
-    class StubMaker extends TreeTranslator {
-        CompilationUnitTree translate(CompilationUnitTree tree) {
-            return super.translate((JCCompilationUnit) tree);
-        }
-
-        /**
-         * compilation units: remove javadoc comments
-         * -- required, in order to remove @deprecated tags, since we
-         * (separately) remove all annotations, including @Deprecated
-         */
-        public void visitTopLevel(JCCompilationUnit tree) {
-            super.visitTopLevel(tree);
-            tree.docComments = Collections.emptyMap();
-        }
-
-        /**
-         * methods: remove method bodies, make methods native
-         */
-        @Override
-        public void visitMethodDef(JCMethodDecl tree) {
-            tree.mods = translate(tree.mods);
-            tree.restype = translate(tree.restype);
-            tree.typarams = translateTypeParams(tree.typarams);
-            tree.params = translateVarDefs(tree.params);
-            tree.thrown = translate(tree.thrown);
-            if (tree.restype != null && tree.body != null) {
-                tree.mods.flags |= Flags.NATIVE;
-                tree.body = null;
-            }
-            result = tree;
-        }
-
-        /**
-         * modifiers: remove annotations
-         */
-        @Override
-        public void visitModifiers(JCModifiers tree) {
-            tree.annotations = com.sun.tools.javac.util.List.nil();
-            result = tree;
-        }
-
-        /**
-         * field definitions: replace initializers with 0, 0.0, false etc
-         * when possible -- i.e. leave public, protected initializers alone
-         */
-        @Override
-        public void visitVarDef(JCVariableDecl tree) {
-            tree.mods = translate(tree.mods);
-            tree.vartype = translate(tree.vartype);
-            if (tree.init != null) {
-                if ((tree.mods.flags & (Flags.PUBLIC | Flags.PROTECTED)) != 0)
-                    tree.init = translate(tree.init);
-                else {
-                    String t = tree.vartype.toString();
-                    if (t.equals("boolean"))
-                        tree.init = new JCLiteral(TypeTags.BOOLEAN, 0) { };
-                    else if (t.equals("byte"))
-                        tree.init = new JCLiteral(TypeTags.BYTE, 0) { };
-                    else if (t.equals("char"))
-                        tree.init = new JCLiteral(TypeTags.CHAR, 0) { };
-                    else if (t.equals("double"))
-                        tree.init = new JCLiteral(TypeTags.DOUBLE, 0.d) { };
-                    else if (t.equals("float"))
-                        tree.init = new JCLiteral(TypeTags.FLOAT, 0.f) { };
-                    else if (t.equals("int"))
-                        tree.init = new JCLiteral(TypeTags.INT, 0) { };
-                    else if (t.equals("long"))
-                        tree.init = new JCLiteral(TypeTags.LONG, 0) { };
-                    else if (t.equals("short"))
-                        tree.init = new JCLiteral(TypeTags.SHORT, 0) { };
-                    else
-                        tree.init = new JCLiteral(TypeTags.BOT, null) { };
-                }
-            }
-            result = tree;
-        }
-    }
-
-    class ImportCleaner extends TreeScanner {
-        private Set<Name> names = new HashSet<Name>();
-        private TreeMaker m;
-
-        ImportCleaner(JavaFileManager fm) {
-            // ImportCleaner itself doesn't require a filemanager, but instantiating
-            // a TreeMaker does, indirectly (via ClassReader, sigh)
-            Context c = new Context();
-            c.put(JavaFileManager.class, fm);
-            m = TreeMaker.instance(c);
-        }
-
-        CompilationUnitTree removeRedundantImports(CompilationUnitTree t) {
-            JCCompilationUnit tree = (JCCompilationUnit) t;
-            tree.accept(this);
-            ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
-            for (JCTree def: tree.defs) {
-                if (def.getTag() == JCTree.IMPORT) {
-                    JCImport imp = (JCImport) def;
-                    if (imp.qualid.getTag() == JCTree.SELECT) {
-                        JCFieldAccess qualid = (JCFieldAccess) imp.qualid;
-                        if (!qualid.name.toString().equals("*")
-                                && !names.contains(qualid.name)) {
-                            continue;
-                        }
-                    }
-                }
-                defs.add(def);
-            }
-            return m.TopLevel(tree.packageAnnotations, tree.pid, defs.toList());
-        }
-
-        @Override
-        public void visitImport(JCImport tree) { } // ignore names found in imports
-
-        @Override
-        public void visitIdent(JCIdent tree) {
-            names.add(tree.name);
-        }
-
-        @Override
-        public void visitSelect(JCFieldAccess tree) {
-            super.visitSelect(tree);
-            names.add(tree.name);
-        }
-    }
-
-    //---------- Ant Invocation ------------------------------------------------
-
-    public static class Ant extends MatchingTask {
-        private File srcDir;
-        private File destDir;
-        private boolean fork;
-        private Path classpath;
-        private String includes;
-
-        public void setSrcDir(File dir) {
-            this.srcDir = dir;
-        }
-
-        public void setDestDir(File dir) {
-            this.destDir = dir;
-        }
-
-        public void setFork(boolean v) {
-            this.fork = v;
-        }
-
-        public void setClasspath(Path cp) {
-            if (classpath == null)
-                classpath = cp;
-            else
-                classpath.append(cp);
-        }
-
-        public Path createClasspath() {
-            if (classpath == null) {
-                classpath = new Path(getProject());
-            }
-            return classpath.createPath();
-        }
-
-        public void setClasspathRef(Reference r) {
-            createClasspath().setRefid(r);
-        }
-
-        public void setIncludes(String includes) {
-            super.setIncludes(includes);
-            this.includes = includes;
-        }
-
-        @Override
-        public void execute() {
-            if (includes != null && includes.trim().isEmpty())
-                return;
-
-            DirectoryScanner s = getDirectoryScanner(srcDir);
-            String[] files = s.getIncludedFiles();
-//            System.err.println("Ant.execute: srcDir " + srcDir);
-//            System.err.println("Ant.execute: destDir " + destDir);
-//            System.err.println("Ant.execute: files " + Arrays.asList(files));
-
-            files = filter(srcDir, destDir, files);
-            if (files.length == 0)
-                return;
-            System.out.println("Generating " + files.length + " stub files to " + destDir);
-
-            List<String> classNames = new ArrayList<String>();
-            for (String file: files) {
-                classNames.add(file.replaceAll(".java$", "").replace('/', '.'));
-            }
-
-            if (!fork) {
-                GenStubs m = new GenStubs();
-                boolean ok = m.run(srcDir.getPath(), destDir, classNames);
-                if (!ok)
-                    throw new BuildException("genstubs failed");
-            } else {
-                List<String> cmd = new ArrayList<String>();
-                String java_home = System.getProperty("java.home");
-                cmd.add(new File(new File(java_home, "bin"), "java").getPath());
-                if (classpath != null)
-                    cmd.add("-Xbootclasspath/p:" + classpath);
-                cmd.add(GenStubs.class.getName());
-                cmd.add("-sourcepath");
-                cmd.add(srcDir.getPath());
-                cmd.add("-s");
-                cmd.add(destDir.getPath());
-                cmd.addAll(classNames);
-                //System.err.println("GenStubs exec " + cmd);
-                ProcessBuilder pb = new ProcessBuilder(cmd);
-                pb.redirectErrorStream(true);
-                try {
-                    Process p = pb.start();
-                    BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
-                    try {
-                        String line;
-                        while ((line = in.readLine()) != null)
-                            System.out.println(line);
-                    } finally {
-                        in.close();
-                    }
-                    int rc = p.waitFor();
-                    if (rc != 0)
-                        throw new BuildException("genstubs failed");
-                } catch (IOException e) {
-                    throw new BuildException("genstubs failed", e);
-                } catch (InterruptedException e) {
-                    throw new BuildException("genstubs failed", e);
-                }
-            }
-        }
-
-        String[] filter(File srcDir, File destDir, String[] files) {
-            List<String> results = new ArrayList<String>();
-            for (String f: files) {
-                long srcTime = new File(srcDir, f).lastModified();
-                long destTime = new File(destDir, f).lastModified();
-                if (srcTime > destTime)
-                    results.add(f);
-            }
-            return results.toArray(new String[results.size()]);
-        }
-    }
-}
--- a/langtools/make/tools/SelectTool/SelectToolTask.java	Fri Mar 30 15:43:13 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,284 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.awt.GridBagConstraints;
-import java.awt.GridBagLayout;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.FocusEvent;
-import java.awt.event.FocusListener;
-import java.awt.event.ItemEvent;
-import java.awt.event.ItemListener;
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Properties;
-import javax.swing.JButton;
-import javax.swing.JCheckBox;
-import javax.swing.JComboBox;
-import javax.swing.JDialog;
-import javax.swing.JLabel;
-import javax.swing.JOptionPane;
-import javax.swing.JPanel;
-import javax.swing.JTextField;
-
-import javax.swing.SwingUtilities;
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.Task;
-
-/**
- * Task to allow the user to control langtools tools built when using NetBeans.
- *
- * There are two primary modes.
- * 1) Property mode. In this mode, property names are provided to get values
- * that may be specified by the user, either directly in a GUI dialog, or
- * read from a properties file. If the GUI dialog is invoked, values may
- * optionally be set for future use.
- * 2) Setup mode. In this mode, no property names are provided, and the GUI
- * is invoked to allow the user to set or reset values for use in property mode.
- */
-public class SelectToolTask extends Task {
-    /**
-     * Set the location of the private properties file used to keep the retain
-     * user preferences for this repository.
-     */
-    public void setPropertyFile(File propertyFile) {
-        this.propertyFile = propertyFile;
-    }
-
-    /**
-     * Set the name of the property which will be set to the name of the
-     * selected tool, if any. If no tool is selected, the property will
-     * remain unset.
-     */
-    public void setToolProperty(String toolProperty) {
-        this.toolProperty = toolProperty;
-    }
-
-    /**
-     * Set the name of the property which will be set to the execution args of the
-     * selected tool, if any. The args default to an empty string.
-     */
-    public void setArgsProperty(String argsProperty) {
-        this.argsProperty = argsProperty;
-    }
-
-    /**
-     * Specify whether or not to pop up a dialog if the user has not specified
-     * a default value for a property.
-     */
-    public void setAskIfUnset(boolean askIfUnset) {
-        this.askIfUnset = askIfUnset;
-    }
-
-    @Override
-    public void execute() {
-        Project p = getProject();
-
-        Properties props = readProperties(propertyFile);
-        toolName = props.getProperty("tool.name");
-        if (toolName != null) {
-            toolArgs = props.getProperty(toolName + ".args", "");
-        }
-
-        if (toolProperty == null ||
-            askIfUnset && (toolName == null
-                || (argsProperty != null && toolArgs == null))) {
-            showGUI(props);
-        }
-
-        // finally, return required values, if any
-        if (toolProperty != null && !(toolName == null || toolName.equals(""))) {
-            p.setProperty(toolProperty, toolName);
-
-            if (argsProperty != null && toolArgs != null)
-                p.setProperty(argsProperty, toolArgs);
-        }
-    }
-
-    void showGUI(Properties fileProps) {
-        Properties guiProps = new Properties(fileProps);
-        JOptionPane p = createPane(guiProps);
-        p.createDialog("Select Tool").setVisible(true);
-
-        toolName = (String) toolChoice.getSelectedItem();
-        toolArgs = argsField.getText();
-
-        if (defaultCheck.isSelected()) {
-            if (toolName.equals("")) {
-                fileProps.remove("tool.name");
-            } else {
-                fileProps.put("tool.name", toolName);
-                fileProps.put(toolName + ".args", toolArgs);
-            }
-            writeProperties(propertyFile, fileProps);
-        }
-    }
-
-    JOptionPane createPane(final Properties props) {
-        JPanel body = new JPanel(new GridBagLayout());
-        GridBagConstraints lc = new GridBagConstraints();
-        lc.insets.right = 10;
-        lc.insets.bottom = 3;
-        GridBagConstraints fc = new GridBagConstraints();
-        fc.anchor = GridBagConstraints.WEST;
-        fc.gridx = 1;
-        fc.gridwidth = GridBagConstraints.REMAINDER;
-        fc.insets.bottom = 3;
-
-        JLabel toolLabel = new JLabel("Tool:");
-        body.add(toolLabel, lc);
-        String[] toolChoices = { "apt", "javac", "javadoc", "javah", "javap" };
-        if (true || toolProperty == null) {
-            // include empty value in setup mode
-            List<String> l = new ArrayList<String>(Arrays.asList(toolChoices));
-            l.add(0, "");
-            toolChoices = l.toArray(new String[l.size()]);
-        }
-        toolChoice = new JComboBox(toolChoices);
-        if (toolName != null)
-            toolChoice.setSelectedItem(toolName);
-        toolChoice.addItemListener(new ItemListener() {
-            public void itemStateChanged(ItemEvent e) {
-                String tn = (String) e.getItem();
-                argsField.setText(getDefaultArgsForTool(props, tn));
-                if (toolProperty != null)
-                    okButton.setEnabled(!tn.equals(""));
-            }
-        });
-        body.add(toolChoice, fc);
-
-        argsField = new JTextField(getDefaultArgsForTool(props, toolName), 40);
-        if (toolProperty == null || argsProperty != null) {
-            JLabel argsLabel = new JLabel("Args:");
-            body.add(argsLabel, lc);
-            body.add(argsField, fc);
-            argsField.addFocusListener(new FocusListener() {
-                public void focusGained(FocusEvent e) {
-                }
-                public void focusLost(FocusEvent e) {
-                    String toolName = (String) toolChoice.getSelectedItem();
-                    if (toolName.length() > 0)
-                        props.put(toolName + ".args", argsField.getText());
-                }
-            });
-        }
-
-        defaultCheck = new JCheckBox("Set as default");
-        if (toolProperty == null)
-            defaultCheck.setSelected(true);
-        else
-            body.add(defaultCheck, fc);
-
-        final JOptionPane p = new JOptionPane(body);
-        okButton = new JButton("OK");
-        okButton.setEnabled(toolProperty == null || (toolName != null && !toolName.equals("")));
-        okButton.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent e) {
-                JDialog d = (JDialog) SwingUtilities.getAncestorOfClass(JDialog.class, p);
-                d.setVisible(false);
-            }
-        });
-        p.setOptions(new Object[] { okButton });
-
-        return p;
-    }
-
-    Properties readProperties(File file) {
-        Properties p = new Properties();
-        if (file != null && file.exists()) {
-            Reader in = null;
-            try {
-                in = new BufferedReader(new FileReader(file));
-                p.load(in);
-                in.close();
-            } catch (IOException e) {
-                throw new BuildException("error reading property file", e);
-            } finally {
-                if (in != null) {
-                    try {
-                        in.close();
-                    } catch (IOException e) {
-                        throw new BuildException("cannot close property file", e);
-                    }
-                }
-            }
-        }
-        return p;
-    }
-
-    void writeProperties(File file, Properties p) {
-        if (file != null) {
-            Writer out = null;
-            try {
-                File dir = file.getParentFile();
-                if (dir != null && !dir.exists())
-                    dir.mkdirs();
-                out = new BufferedWriter(new FileWriter(file));
-                p.store(out, "langtools properties");
-                out.close();
-            } catch (IOException e) {
-                throw new BuildException("error writing property file", e);
-            } finally {
-                if (out != null) {
-                    try {
-                        out.close();
-                    } catch (IOException e) {
-                        throw new BuildException("cannot close property file", e);
-                    }
-                }
-            }
-        }
-    }
-
-    String getDefaultArgsForTool(Properties props, String tn) {
-        return (tn == null || tn.equals("")) ? "" : props.getProperty(tn + ".args", "");
-    }
-
-    // Ant task parameters
-    private boolean askIfUnset;
-    private String toolProperty;
-    private String argsProperty;
-    private File propertyFile;
-
-    // GUI components
-    private JComboBox toolChoice;
-    private JTextField argsField;
-    private JCheckBox defaultCheck;
-    private JButton okButton;
-
-    // Result values for the client
-    private String toolName;
-    private String toolArgs;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/make/tools/anttasks/CompilePropertiesTask.java	Fri Mar 30 16:57:50 2012 -0700
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package anttasks;
+
+import compileproperties.CompileProperties;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.MatchingTask;
+
+public class CompilePropertiesTask extends MatchingTask {
+    public void setSrcDir(File srcDir) {
+        this.srcDir = srcDir;
+    }
+
+    public void setDestDir(File destDir) {
+        this.destDir = destDir;
+    }
+
+    public void setSuperclass(String superclass) {
+        this.superclass = superclass;
+    }
+
+    @Override
+    public void execute() {
+        CompileProperties.Log log = new CompileProperties.Log() {
+            public void error(String msg, Exception e) {
+                log(msg, Project.MSG_ERR);
+            }
+            public void info(String msg) {
+                log(msg, Project.MSG_INFO);
+            }
+            public void verbose(String msg) {
+                log(msg, Project.MSG_VERBOSE);
+            }
+        };
+        List<String> mainOpts = new ArrayList<String>();
+        int count = 0;
+        DirectoryScanner s = getDirectoryScanner(srcDir);
+        for (String path: s.getIncludedFiles()) {
+            if (path.endsWith(".properties")) {
+                String destPath =
+                        path.substring(0, path.length() - ".properties".length()) +
+                        ".java";
+                File srcFile = new File(srcDir, path);
+                File destFile = new File(destDir, destPath);
+                // Arguably, the comparison in the next line should be ">", not ">="
+                // but that assumes the resolution of the last modified time is fine
+                // grained enough; in practice, it is better to use ">=".
+                if (destFile.exists() && destFile.lastModified() >= srcFile.lastModified())
+                    continue;
+                destFile.getParentFile().mkdirs();
+                mainOpts.add("-compile");
+                mainOpts.add(srcFile.getPath());
+                mainOpts.add(destFile.getPath());
+                mainOpts.add(superclass);
+                count++;
+            }
+        }
+        if (mainOpts.size() > 0) {
+            log("Generating " + count + " resource files to " + destDir, Project.MSG_INFO);
+            CompileProperties cp = new CompileProperties();
+            cp.setLog(log);
+            boolean ok = cp.run(mainOpts.toArray(new String[mainOpts.size()]));
+            if (!ok)
+                throw new BuildException("CompileProperties failed.");
+        }
+    }
+
+    private File srcDir;
+    private File destDir;
+    private String superclass = "java.util.ListResourceBundle";
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/make/tools/anttasks/GenStubsTask.java	Fri Mar 30 16:57:50 2012 -0700
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package anttasks;
+
+import genstubs.GenStubs;
+
+import java.io.*;
+import java.util.*;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.taskdefs.MatchingTask;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Reference;
+
+/**
+ * Files are specified with an implicit fileset, using srcdir as a base directory.
+ * The set of files to be included is specified with an includes attribute or
+ * nested <includes> set. However, unlike a normal fileset, an empty includes attribute
+ * means "no files" instead of "all files".  The Ant task also accepts "fork=true" and
+ * classpath attribute or nested <classpath> element to run GenStubs in a separate VM
+ * with the specified path. This is likely necessary if a JDK 7 parser is required to read the
+ * JDK 7 input files.
+ */
+public class GenStubsTask extends MatchingTask {
+    private File srcDir;
+    private File destDir;
+    private boolean fork;
+    private Path classpath;
+    private String includes;
+
+    public void setSrcDir(File dir) {
+        this.srcDir = dir;
+    }
+
+    public void setDestDir(File dir) {
+        this.destDir = dir;
+    }
+
+    public void setFork(boolean v) {
+        this.fork = v;
+    }
+
+    public void setClasspath(Path cp) {
+        if (classpath == null)
+            classpath = cp;
+        else
+            classpath.append(cp);
+    }
+
+    public Path createClasspath() {
+        if (classpath == null) {
+            classpath = new Path(getProject());
+        }
+        return classpath.createPath();
+    }
+
+    public void setClasspathRef(Reference r) {
+        createClasspath().setRefid(r);
+    }
+
+    public void setIncludes(String includes) {
+        super.setIncludes(includes);
+        this.includes = includes;
+    }
+
+    @Override
+    public void execute() {
+        if (includes != null && includes.trim().isEmpty())
+            return;
+
+        DirectoryScanner s = getDirectoryScanner(srcDir);
+        String[] files = s.getIncludedFiles();
+//            System.err.println("Ant.execute: srcDir " + srcDir);
+//            System.err.println("Ant.execute: destDir " + destDir);
+//            System.err.println("Ant.execute: files " + Arrays.asList(files));
+
+        files = filter(srcDir, destDir, files);
+        if (files.length == 0)
+            return;
+        System.out.println("Generating " + files.length + " stub files to " + destDir);
+
+        List<String> classNames = new ArrayList<String>();
+        for (String file: files) {
+            classNames.add(file.replaceAll(".java$", "").replace('/', '.'));
+        }
+
+        if (!fork) {
+            GenStubs m = new GenStubs();
+            boolean ok = m.run(srcDir.getPath(), destDir, classNames);
+            if (!ok)
+                throw new BuildException("genstubs failed");
+        } else {
+            List<String> cmd = new ArrayList<String>();
+            String java_home = System.getProperty("java.home");
+            cmd.add(new File(new File(java_home, "bin"), "java").getPath());
+            if (classpath != null)
+                cmd.add("-Xbootclasspath/p:" + classpath);
+            cmd.add(GenStubs.class.getName());
+            cmd.add("-sourcepath");
+            cmd.add(srcDir.getPath());
+            cmd.add("-s");
+            cmd.add(destDir.getPath());
+            cmd.addAll(classNames);
+            //System.err.println("GenStubs exec " + cmd);
+            ProcessBuilder pb = new ProcessBuilder(cmd);
+            pb.redirectErrorStream(true);
+            try {
+                Process p = pb.start();
+                BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
+                try {
+                    String line;
+                    while ((line = in.readLine()) != null)
+                        System.out.println(line);
+                } finally {
+                    in.close();
+                }
+                int rc = p.waitFor();
+                if (rc != 0)
+                    throw new BuildException("genstubs failed");
+            } catch (IOException e) {
+                throw new BuildException("genstubs failed", e);
+            } catch (InterruptedException e) {
+                throw new BuildException("genstubs failed", e);
+            }
+        }
+    }
+
+    String[] filter(File srcDir, File destDir, String[] files) {
+        List<String> results = new ArrayList<String>();
+        for (String f: files) {
+            long srcTime = new File(srcDir, f).lastModified();
+            long destTime = new File(destDir, f).lastModified();
+            if (srcTime > destTime)
+                results.add(f);
+        }
+        return results.toArray(new String[results.size()]);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/make/tools/anttasks/SelectToolTask.java	Fri Mar 30 16:57:50 2012 -0700
@@ -0,0 +1,286 @@
+/*
+ * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package anttasks;
+
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Properties;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+
+import javax.swing.SwingUtilities;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+
+/**
+ * Task to allow the user to control langtools tools built when using NetBeans.
+ *
+ * There are two primary modes.
+ * 1) Property mode. In this mode, property names are provided to get values
+ * that may be specified by the user, either directly in a GUI dialog, or
+ * read from a properties file. If the GUI dialog is invoked, values may
+ * optionally be set for future use.
+ * 2) Setup mode. In this mode, no property names are provided, and the GUI
+ * is invoked to allow the user to set or reset values for use in property mode.
+ */
+public class SelectToolTask extends Task {
+    /**
+     * Set the location of the private properties file used to keep the retain
+     * user preferences for this repository.
+     */
+    public void setPropertyFile(File propertyFile) {
+        this.propertyFile = propertyFile;
+    }
+
+    /**
+     * Set the name of the property which will be set to the name of the
+     * selected tool, if any. If no tool is selected, the property will
+     * remain unset.
+     */
+    public void setToolProperty(String toolProperty) {
+        this.toolProperty = toolProperty;
+    }
+
+    /**
+     * Set the name of the property which will be set to the execution args of the
+     * selected tool, if any. The args default to an empty string.
+     */
+    public void setArgsProperty(String argsProperty) {
+        this.argsProperty = argsProperty;
+    }
+
+    /**
+     * Specify whether or not to pop up a dialog if the user has not specified
+     * a default value for a property.
+     */
+    public void setAskIfUnset(boolean askIfUnset) {
+        this.askIfUnset = askIfUnset;
+    }
+
+    @Override
+    public void execute() {
+        Project p = getProject();
+
+        Properties props = readProperties(propertyFile);
+        toolName = props.getProperty("tool.name");
+        if (toolName != null) {
+            toolArgs = props.getProperty(toolName + ".args", "");
+        }
+
+        if (toolProperty == null ||
+            askIfUnset && (toolName == null
+                || (argsProperty != null && toolArgs == null))) {
+            showGUI(props);
+        }
+
+        // finally, return required values, if any
+        if (toolProperty != null && !(toolName == null || toolName.equals(""))) {
+            p.setProperty(toolProperty, toolName);
+
+            if (argsProperty != null && toolArgs != null)
+                p.setProperty(argsProperty, toolArgs);
+        }
+    }
+
+    void showGUI(Properties fileProps) {
+        Properties guiProps = new Properties(fileProps);
+        JOptionPane p = createPane(guiProps);
+        p.createDialog("Select Tool").setVisible(true);
+
+        toolName = (String) toolChoice.getSelectedItem();
+        toolArgs = argsField.getText();
+
+        if (defaultCheck.isSelected()) {
+            if (toolName.equals("")) {
+                fileProps.remove("tool.name");
+            } else {
+                fileProps.put("tool.name", toolName);
+                fileProps.put(toolName + ".args", toolArgs);
+            }
+            writeProperties(propertyFile, fileProps);
+        }
+    }
+
+    JOptionPane createPane(final Properties props) {
+        JPanel body = new JPanel(new GridBagLayout());
+        GridBagConstraints lc = new GridBagConstraints();
+        lc.insets.right = 10;
+        lc.insets.bottom = 3;
+        GridBagConstraints fc = new GridBagConstraints();
+        fc.anchor = GridBagConstraints.WEST;
+        fc.gridx = 1;
+        fc.gridwidth = GridBagConstraints.REMAINDER;
+        fc.insets.bottom = 3;
+
+        JLabel toolLabel = new JLabel("Tool:");
+        body.add(toolLabel, lc);
+        String[] toolChoices = { "apt", "javac", "javadoc", "javah", "javap" };
+        if (true || toolProperty == null) {
+            // include empty value in setup mode
+            List<String> l = new ArrayList<String>(Arrays.asList(toolChoices));
+            l.add(0, "");
+            toolChoices = l.toArray(new String[l.size()]);
+        }
+        toolChoice = new JComboBox(toolChoices);
+        if (toolName != null)
+            toolChoice.setSelectedItem(toolName);
+        toolChoice.addItemListener(new ItemListener() {
+            public void itemStateChanged(ItemEvent e) {
+                String tn = (String) e.getItem();
+                argsField.setText(getDefaultArgsForTool(props, tn));
+                if (toolProperty != null)
+                    okButton.setEnabled(!tn.equals(""));
+            }
+        });
+        body.add(toolChoice, fc);
+
+        argsField = new JTextField(getDefaultArgsForTool(props, toolName), 40);
+        if (toolProperty == null || argsProperty != null) {
+            JLabel argsLabel = new JLabel("Args:");
+            body.add(argsLabel, lc);
+            body.add(argsField, fc);
+            argsField.addFocusListener(new FocusListener() {
+                public void focusGained(FocusEvent e) {
+                }
+                public void focusLost(FocusEvent e) {
+                    String toolName = (String) toolChoice.getSelectedItem();
+                    if (toolName.length() > 0)
+                        props.put(toolName + ".args", argsField.getText());
+                }
+            });
+        }
+
+        defaultCheck = new JCheckBox("Set as default");
+        if (toolProperty == null)
+            defaultCheck.setSelected(true);
+        else
+            body.add(defaultCheck, fc);
+
+        final JOptionPane p = new JOptionPane(body);
+        okButton = new JButton("OK");
+        okButton.setEnabled(toolProperty == null || (toolName != null && !toolName.equals("")));
+        okButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                JDialog d = (JDialog) SwingUtilities.getAncestorOfClass(JDialog.class, p);
+                d.setVisible(false);
+            }
+        });
+        p.setOptions(new Object[] { okButton });
+
+        return p;
+    }
+
+    Properties readProperties(File file) {
+        Properties p = new Properties();
+        if (file != null && file.exists()) {
+            Reader in = null;
+            try {
+                in = new BufferedReader(new FileReader(file));
+                p.load(in);
+                in.close();
+            } catch (IOException e) {
+                throw new BuildException("error reading property file", e);
+            } finally {
+                if (in != null) {
+                    try {
+                        in.close();
+                    } catch (IOException e) {
+                        throw new BuildException("cannot close property file", e);
+                    }
+                }
+            }
+        }
+        return p;
+    }
+
+    void writeProperties(File file, Properties p) {
+        if (file != null) {
+            Writer out = null;
+            try {
+                File dir = file.getParentFile();
+                if (dir != null && !dir.exists())
+                    dir.mkdirs();
+                out = new BufferedWriter(new FileWriter(file));
+                p.store(out, "langtools properties");
+                out.close();
+            } catch (IOException e) {
+                throw new BuildException("error writing property file", e);
+            } finally {
+                if (out != null) {
+                    try {
+                        out.close();
+                    } catch (IOException e) {
+                        throw new BuildException("cannot close property file", e);
+                    }
+                }
+            }
+        }
+    }
+
+    String getDefaultArgsForTool(Properties props, String tn) {
+        return (tn == null || tn.equals("")) ? "" : props.getProperty(tn + ".args", "");
+    }
+
+    // Ant task parameters
+    private boolean askIfUnset;
+    private String toolProperty;
+    private String argsProperty;
+    private File propertyFile;
+
+    // GUI components
+    private JComboBox toolChoice;
+    private JTextField argsField;
+    private JCheckBox defaultCheck;
+    private JButton okButton;
+
+    // Result values for the client
+    private String toolName;
+    private String toolArgs;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/make/tools/compileproperties/CompileProperties.java	Fri Mar 30 16:57:50 2012 -0700
@@ -0,0 +1,404 @@
+/*
+ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package compileproperties;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+
+/** Translates a .properties file into a .java file containing the
+ *  definition of a java.util.Properties subclass which can then be
+ *  compiled with javac. <P>
+ *
+ *  Usage: java CompileProperties [path to .properties file] [path to .java file to be output] [super class]
+ *
+ *  Infers the package by looking at the common suffix of the two
+ *  inputs, eliminating "classes" from it.
+ *
+ * @author Scott Violet
+ * @author Kenneth Russell
+ */
+
+public class CompileProperties {
+
+    public static void main(String[] args) {
+        CompileProperties cp = new CompileProperties();
+        boolean ok = cp.run(args);
+        if ( !ok ) {
+            System.exit(1);
+        }
+    }
+
+    public static interface Log {
+        void info(String msg);
+        void verbose(String msg);
+        void error(String msg, Exception e);
+    }
+
+    private String propfiles[];
+    private String outfiles[] ;
+    private String supers[]   ;
+    private int compileCount = 0;
+    private boolean quiet = false;
+    public Log log;
+
+    public void setLog(Log log) {
+        this.log = log;
+    }
+
+    public boolean run(String[] args) {
+        if (log == null) {
+            log = new Log() {
+                public void error(String msg, Exception e) {
+                    System.err.println("ERROR: CompileProperties: " + msg);
+                    if ( e != null ) {
+                        System.err.println("EXCEPTION: " + e.toString());
+                        e.printStackTrace();
+                    }
+                }
+                public void info(String msg) {
+                    System.out.println(msg);
+                }
+                public void verbose(String msg) {
+                    if (!quiet)
+                        System.out.println(msg);
+                }
+            };
+        }
+
+        boolean ok = true;
+        /* Original usage */
+        if (args.length == 2 && args[0].charAt(0) != '-' ) {
+            ok = createFile(args[0], args[1], "java.util.ListResourceBundle");
+        } else if (args.length == 3) {
+            ok = createFile(args[0], args[1], args[2]);
+        } else if (args.length == 0) {
+            usage(log);
+            ok = false;
+        } else {
+            /* New batch usage */
+            ok = parseOptions(args);
+            if ( ok && compileCount == 0 ) {
+                log.error("options parsed but no files to compile", null);
+                ok = false;
+            }
+            /* Need at least one file. */
+            if ( !ok ) {
+                usage(log);
+            } else {
+                /* Process files */
+                for ( int i = 0; i < compileCount && ok ; i++ ) {
+                    ok = createFile(propfiles[i], outfiles[i], supers[i]);
+                }
+            }
+        }
+        return ok;
+    }
+
+    private boolean parseOptions(String args[]) {
+        boolean ok = true;
+        if ( compileCount > 0 ) {
+            String new_propfiles[] = new String[compileCount + args.length];
+            String new_outfiles[]  = new String[compileCount + args.length];
+            String new_supers[]    = new String[compileCount + args.length];
+            System.arraycopy(propfiles, 0, new_propfiles, 0, compileCount);
+            System.arraycopy(outfiles, 0, new_outfiles, 0, compileCount);
+            System.arraycopy(supers, 0, new_supers, 0, compileCount);
+            propfiles = new_propfiles;
+            outfiles  = new_outfiles;
+            supers    = new_supers;
+        } else {
+            propfiles = new String[args.length];
+            outfiles  = new String[args.length];
+            supers    = new String[args.length];
+        }
+
+        for ( int i = 0; i < args.length ; i++ ) {
+            if ( "-compile".equals(args[i]) && i+3 < args.length ) {
+                propfiles[compileCount] = args[++i];
+                outfiles[compileCount]  = args[++i];
+                supers[compileCount]    = args[++i];
+                compileCount++;
+            } else if ( "-optionsfile".equals(args[i]) && i+1 < args.length ) {
+                String filename = args[++i];
+                FileInputStream finput = null;
+                byte contents[] = null;
+                try {
+                    finput = new FileInputStream(filename);
+                    int byteCount = finput.available();
+                    if ( byteCount <= 0 ) {
+                        log.error("The -optionsfile file is empty", null);
+                        ok = false;
+                    } else {
+                        contents = new byte[byteCount];
+                        int bytesRead = finput.read(contents);
+                        if ( byteCount != bytesRead ) {
+                            log.error("Cannot read all of -optionsfile file", null);
+                            ok = false;
+                        }
+                    }
+                } catch ( IOException e ) {
+                    log.error("cannot open " + filename, e);
+                    ok = false;
+                }
+                if ( finput != null ) {
+                    try {
+                        finput.close();
+                    } catch ( IOException e ) {
+                        ok = false;
+                        log.error("cannot close " + filename, e);
+                    }
+                }
+                if ( ok = true && contents != null ) {
+                    String tokens[] = (new String(contents)).split("\\s+");
+                    if ( tokens.length > 0 ) {
+                        ok = parseOptions(tokens);
+                    }
+                }
+                if ( !ok ) {
+                    break;
+                }
+            } else if ( "-quiet".equals(args[i]) ) {
+                quiet = true;
+            } else {
+                log.error("argument error", null);
+                ok = false;
+            }
+        }
+        return ok;
+    }
+
+    private boolean createFile(String propertiesPath, String outputPath,
+            String superClass) {
+        boolean ok = true;
+        log.verbose("parsing: " + propertiesPath);
+        Properties p = new Properties();
+        try {
+            p.load(new FileInputStream(propertiesPath));
+        } catch ( FileNotFoundException e ) {
+            ok = false;
+            log.error("Cannot find file " + propertiesPath, e);
+        } catch ( IOException e ) {
+            ok = false;
+            log.error("IO error on file " + propertiesPath, e);
+        }
+        if ( ok ) {
+            String packageName = inferPackageName(propertiesPath, outputPath);
+            log.verbose("inferred package name: " + packageName);
+            List<String> sortedKeys = new ArrayList<String>();
+            for ( Object key : p.keySet() ) {
+                sortedKeys.add((String)key);
+            }
+            Collections.sort(sortedKeys);
+            Iterator<String> keys = sortedKeys.iterator();
+
+            StringBuffer data = new StringBuffer();
+
+            while (keys.hasNext()) {
+                String key = keys.next();
+                data.append("            { \"" + escape(key) + "\", \"" +
+                        escape((String)p.get(key)) + "\" },\n");
+            }
+
+            // Get class name from java filename, not the properties filename.
+            //   (zh_TW properties might be used to create zh_HK files)
+            File file = new File(outputPath);
+            String name = file.getName();
+            int dotIndex = name.lastIndexOf('.');
+            String className;
+            if (dotIndex == -1) {
+                className = name;
+            } else {
+                className = name.substring(0, dotIndex);
+            }
+
+            String packageString = "";
+            if (packageName != null && !packageName.equals("")) {
+                packageString = "package " + packageName + ";\n\n";
+            }
+
+            Writer writer = null;
+            try {
+                writer = new BufferedWriter(
+                        new OutputStreamWriter(new FileOutputStream(outputPath), "8859_1"));
+                MessageFormat format = new MessageFormat(FORMAT);
+                writer.write(format.format(new Object[] { packageString, className, superClass, data }));
+            } catch ( IOException e ) {
+                ok = false;
+                log.error("IO error writing to file " + outputPath, e);
+            }
+            if ( writer != null ) {
+                try {
+                    writer.flush();
+                } catch ( IOException e ) {
+                    ok = false;
+                    log.error("IO error flush " + outputPath, e);
+                }
+                try {
+                    writer.close();
+                } catch ( IOException e ) {
+                    ok = false;
+                    log.error("IO error close " + outputPath, e);
+                }
+            }
+            log.verbose("wrote: " + outputPath);
+        }
+        return ok;
+    }
+
+    private static void usage(Log log) {
+        log.info("usage:");
+        log.info("    java CompileProperties path_to_properties_file path_to_java_output_file [super_class]");
+        log.info("      -OR-");
+        log.info("    java CompileProperties {-compile path_to_properties_file path_to_java_output_file super_class} -or- -optionsfile filename");
+        log.info("");
+        log.info("Example:");
+        log.info("    java CompileProperties -compile test.properties test.java java.util.ListResourceBundle");
+        log.info("    java CompileProperties -optionsfile option_file");
+        log.info("option_file contains: -compile test.properties test.java java.util.ListResourceBundle");
+    }
+
+    private static String escape(String theString) {
+        // This is taken from Properties.saveConvert with changes for Java strings
+        int len = theString.length();
+        StringBuffer outBuffer = new StringBuffer(len*2);
+
+        for(int x=0; x<len; x++) {
+            char aChar = theString.charAt(x);
+            switch(aChar) {
+                case '\\':outBuffer.append('\\'); outBuffer.append('\\');
+                break;
+                case '\t':outBuffer.append('\\'); outBuffer.append('t');
+                break;
+                case '\n':outBuffer.append('\\'); outBuffer.append('n');
+                break;
+                case '\r':outBuffer.append('\\'); outBuffer.append('r');
+                break;
+                case '\f':outBuffer.append('\\'); outBuffer.append('f');
+                break;
+                default:
+                    if ((aChar < 0x0020) || (aChar > 0x007e)) {
+                        outBuffer.append('\\');
+                        outBuffer.append('u');
+                        outBuffer.append(toHex((aChar >> 12) & 0xF));
+                        outBuffer.append(toHex((aChar >>  8) & 0xF));
+                        outBuffer.append(toHex((aChar >>  4) & 0xF));
+                        outBuffer.append(toHex( aChar        & 0xF));
+                    } else {
+                        if (specialSaveChars.indexOf(aChar) != -1) {
+                            outBuffer.append('\\');
+                        }
+                        outBuffer.append(aChar);
+                    }
+            }
+        }
+        return outBuffer.toString();
+    }
+
+    private static String inferPackageName(String inputPath, String outputPath) {
+        // Normalize file names
+        inputPath  = new File(inputPath).getPath();
+        outputPath = new File(outputPath).getPath();
+        // Split into components
+        String sep;
+        if (File.separatorChar == '\\') {
+            sep = "\\\\";
+        } else {
+            sep = File.separator;
+        }
+        String[] inputs  = inputPath.split(sep);
+        String[] outputs = outputPath.split(sep);
+        // Match common names, eliminating first "classes" entry from
+        // each if present
+        int inStart  = 0;
+        int inEnd    = inputs.length - 2;
+        int outEnd   = outputs.length - 2;
+        int i = inEnd;
+        int j = outEnd;
+        while (i >= 0 && j >= 0) {
+            if (!inputs[i].equals(outputs[j]) ||
+                    (inputs[i].equals("gensrc") && inputs[j].equals("gensrc"))) {
+                ++i;
+                ++j;
+                break;
+            }
+            --i;
+            --j;
+        }
+        String result;
+        if (i < 0 || j < 0 || i >= inEnd || j >= outEnd) {
+            result = "";
+        } else {
+            if (inputs[i].equals("classes") && outputs[j].equals("classes")) {
+                ++i;
+            }
+            inStart = i;
+            StringBuffer buf = new StringBuffer();
+            for (i = inStart; i <= inEnd; i++) {
+                buf.append(inputs[i]);
+                if (i < inEnd) {
+                    buf.append('.');
+                }
+            }
+            result = buf.toString();
+        }
+        return result;
+    }
+
+    private static final String FORMAT =
+            "{0}" +
+            "public final class {1} extends {2} '{'\n" +
+            "    protected final Object[][] getContents() '{'\n" +
+            "        return new Object[][] '{'\n" +
+            "{3}" +
+            "        };\n" +
+            "    }\n" +
+            "}\n";
+
+    // This comes from Properties
+    private static char toHex(int nibble) {
+        return hexDigit[(nibble & 0xF)];
+    }
+
+    // This comes from Properties
+    private static final char[] hexDigit = {
+        '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
+    };
+
+    // Note: different from that in Properties
+    private static final String specialSaveChars = "\"";
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/make/tools/genstubs/GenStubs.java	Fri Mar 30 16:57:50 2012 -0700
@@ -0,0 +1,316 @@
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package genstubs;
+
+import java.io.*;
+import java.util.*;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.util.JavacTask;
+import com.sun.tools.javac.api.JavacTool;
+import com.sun.tools.javac.code.Flags;
+import com.sun.tools.javac.code.TypeTags;
+import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
+import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
+import com.sun.tools.javac.tree.JCTree.JCIdent;
+import com.sun.tools.javac.tree.JCTree.JCImport;
+import com.sun.tools.javac.tree.JCTree.JCLiteral;
+import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
+import com.sun.tools.javac.tree.JCTree.JCModifiers;
+import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
+import com.sun.tools.javac.tree.Pretty;
+import com.sun.tools.javac.tree.TreeMaker;
+import com.sun.tools.javac.tree.TreeScanner;
+import com.sun.tools.javac.tree.TreeTranslator;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.ListBuffer;
+import com.sun.tools.javac.util.Name;
+import javax.tools.JavaFileManager;
+
+/**
+ * Generate stub source files by removing implementation details from input files.
+ *
+ * This is a special purpose stub generator, specific to the needs of generating
+ * stub files for JDK 7 API that are needed to compile langtools files that depend
+ * on that API. The stub generator works by removing as much of the API source code
+ * as possible without affecting the public signature, in order to reduce the
+ * transitive closure of the API being referenced. The resulting stubs can be
+ * put on the langtools sourcepath with -implicit:none to compile the langtools
+ * files that depend on the JDK 7 API.
+ *
+ * Usage:
+ *  genstubs -s <outdir> -sourcepath <path> <classnames>
+ *
+ * The specified class names are looked up on the sourcepath, and corresponding
+ * stubs are written to the source output directory.
+ *
+ * Classes are parsed into javac ASTs, then processed with a javac TreeTranslator
+ * to remove implementation details, and written out in the source output directory.
+ * Documentation comments and annotations are removed. Method bodies are removed
+ * and methods are marked native. Private and package-private field definitions
+ * have their initializers replace with 0, 0.0, false, null as appropriate.
+ */
+
+public class GenStubs {
+    static class Fault extends Exception {
+        private static final long serialVersionUID = 0;
+        Fault(String message) {
+            super(message);
+        }
+        Fault(String message, Throwable cause) {
+            super(message);
+            initCause(cause);
+        }
+    }
+
+    public static void main(String[] args) {
+        boolean ok = new GenStubs().run(args);
+        if (!ok)
+            System.exit(1);
+    }
+
+    public boolean run(String... args) {
+        File outdir = null;
+        String sourcepath = null;
+        List<String> classes = new ArrayList<String>();
+        for (ListIterator<String> iter = Arrays.asList(args).listIterator(); iter.hasNext(); ) {
+            String arg = iter.next();
+            if (arg.equals("-s") && iter.hasNext())
+                outdir = new File(iter.next());
+            else if (arg.equals("-sourcepath") && iter.hasNext())
+                sourcepath = iter.next();
+            else if (arg.startsWith("-"))
+                throw new IllegalArgumentException(arg);
+            else {
+                classes.add(arg);
+                while (iter.hasNext())
+                    classes.add(iter.next());
+            }
+        }
+
+        return run(sourcepath, outdir, classes);
+    }
+
+    public boolean run(String sourcepath, File outdir, List<String> classes) {
+        //System.err.println("run: sourcepath:" + sourcepath + " outdir:" + outdir + " classes:" + classes);
+        if (sourcepath == null)
+            throw new IllegalArgumentException("sourcepath not set");
+        if (outdir == null)
+            throw new IllegalArgumentException("source output dir not set");
+
+        JavacTool tool = JavacTool.create();
+        StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
+
+        try {
+            fm.setLocation(StandardLocation.SOURCE_OUTPUT, Collections.singleton(outdir));
+            fm.setLocation(StandardLocation.SOURCE_PATH, splitPath(sourcepath));
+            List<JavaFileObject> files = new ArrayList<JavaFileObject>();
+            for (String c: classes) {
+                JavaFileObject fo = fm.getJavaFileForInput(
+                        StandardLocation.SOURCE_PATH, c, JavaFileObject.Kind.SOURCE);
+                if (fo == null)
+                    error("class not found: " + c);
+                else
+                    files.add(fo);
+            }
+
+            JavacTask t = tool.getTask(null, fm, null, null, null, files);
+            Iterable<? extends CompilationUnitTree> trees = t.parse();
+            for (CompilationUnitTree tree: trees) {
+                makeStub(fm, tree);
+            }
+        } catch (IOException e) {
+            error("IO error " + e, e);
+        }
+
+        return (errors == 0);
+    }
+
+    void makeStub(StandardJavaFileManager fm, CompilationUnitTree tree) throws IOException {
+        CompilationUnitTree tree2 = new StubMaker().translate(tree);
+        CompilationUnitTree tree3 = new ImportCleaner(fm).removeRedundantImports(tree2);
+
+        String className = fm.inferBinaryName(StandardLocation.SOURCE_PATH, tree.getSourceFile());
+        JavaFileObject fo = fm.getJavaFileForOutput(StandardLocation.SOURCE_OUTPUT,
+                className, JavaFileObject.Kind.SOURCE, null);
+        // System.err.println("Writing " + className + " to " + fo.getName());
+        Writer out = fo.openWriter();
+        try {
+            new Pretty(out, true).printExpr((JCTree) tree3);
+        } finally {
+            out.close();
+        }
+    }
+
+    List<File> splitPath(String path) {
+        List<File> list = new ArrayList<File>();
+        for (String p: path.split(File.pathSeparator)) {
+            if (p.length() > 0)
+                list.add(new File(p));
+        }
+        return list;
+    }
+
+    void error(String message) {
+        System.err.println(message);
+        errors++;
+    }
+
+    void error(String message, Throwable cause) {
+        error(message);
+    }
+
+    int errors;
+
+    class StubMaker extends TreeTranslator {
+        CompilationUnitTree translate(CompilationUnitTree tree) {
+            return super.translate((JCCompilationUnit) tree);
+        }
+
+        /**
+         * compilation units: remove javadoc comments
+         * -- required, in order to remove @deprecated tags, since we
+         * (separately) remove all annotations, including @Deprecated
+         */
+        public void visitTopLevel(JCCompilationUnit tree) {
+            super.visitTopLevel(tree);
+            tree.docComments = Collections.emptyMap();
+        }
+
+        /**
+         * methods: remove method bodies, make methods native
+         */
+        @Override
+        public void visitMethodDef(JCMethodDecl tree) {
+            tree.mods = translate(tree.mods);
+            tree.restype = translate(tree.restype);
+            tree.typarams = translateTypeParams(tree.typarams);
+            tree.params = translateVarDefs(tree.params);
+            tree.thrown = translate(tree.thrown);
+            if (tree.restype != null && tree.body != null) {
+                tree.mods.flags |= Flags.NATIVE;
+                tree.body = null;
+            }
+            result = tree;
+        }
+
+        /**
+         * modifiers: remove annotations
+         */
+        @Override
+        public void visitModifiers(JCModifiers tree) {
+            tree.annotations = com.sun.tools.javac.util.List.nil();
+            result = tree;
+        }
+
+        /**
+         * field definitions: replace initializers with 0, 0.0, false etc
+         * when possible -- i.e. leave public, protected initializers alone
+         */
+        @Override
+        public void visitVarDef(JCVariableDecl tree) {
+            tree.mods = translate(tree.mods);
+            tree.vartype = translate(tree.vartype);
+            if (tree.init != null) {
+                if ((tree.mods.flags & (Flags.PUBLIC | Flags.PROTECTED)) != 0)
+                    tree.init = translate(tree.init);
+                else {
+                    String t = tree.vartype.toString();
+                    if (t.equals("boolean"))
+                        tree.init = new JCLiteral(TypeTags.BOOLEAN, 0) { };
+                    else if (t.equals("byte"))
+                        tree.init = new JCLiteral(TypeTags.BYTE, 0) { };
+                    else if (t.equals("char"))
+                        tree.init = new JCLiteral(TypeTags.CHAR, 0) { };
+                    else if (t.equals("double"))
+                        tree.init = new JCLiteral(TypeTags.DOUBLE, 0.d) { };
+                    else if (t.equals("float"))
+                        tree.init = new JCLiteral(TypeTags.FLOAT, 0.f) { };
+                    else if (t.equals("int"))
+                        tree.init = new JCLiteral(TypeTags.INT, 0) { };
+                    else if (t.equals("long"))
+                        tree.init = new JCLiteral(TypeTags.LONG, 0) { };
+                    else if (t.equals("short"))
+                        tree.init = new JCLiteral(TypeTags.SHORT, 0) { };
+                    else
+                        tree.init = new JCLiteral(TypeTags.BOT, null) { };
+                }
+            }
+            result = tree;
+        }
+    }
+
+    class ImportCleaner extends TreeScanner {
+        private Set<Name> names = new HashSet<Name>();
+        private TreeMaker m;
+
+        ImportCleaner(JavaFileManager fm) {
+            // ImportCleaner itself doesn't require a filemanager, but instantiating
+            // a TreeMaker does, indirectly (via ClassReader, sigh)
+            Context c = new Context();
+            c.put(JavaFileManager.class, fm);
+            m = TreeMaker.instance(c);
+        }
+
+        CompilationUnitTree removeRedundantImports(CompilationUnitTree t) {
+            JCCompilationUnit tree = (JCCompilationUnit) t;
+            tree.accept(this);
+            ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
+            for (JCTree def: tree.defs) {
+                if (def.getTag() == JCTree.Tag.IMPORT) {
+                    JCImport imp = (JCImport) def;
+                    if (imp.qualid.getTag() == JCTree.Tag.SELECT) {
+                        JCFieldAccess qualid = (JCFieldAccess) imp.qualid;
+                        if (!qualid.name.toString().equals("*")
+                                && !names.contains(qualid.name)) {
+                            continue;
+                        }
+                    }
+                }
+                defs.add(def);
+            }
+            return m.TopLevel(tree.packageAnnotations, tree.pid, defs.toList());
+        }
+
+        @Override
+        public void visitImport(JCImport tree) { } // ignore names found in imports
+
+        @Override
+        public void visitIdent(JCIdent tree) {
+            names.add(tree.name);
+        }
+
+        @Override
+        public void visitSelect(JCFieldAccess tree) {
+            super.visitSelect(tree);
+            names.add(tree.name);
+        }
+    }
+}
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java	Fri Mar 30 16:57:50 2012 -0700
@@ -1235,7 +1235,7 @@
             // if origin is derived from a raw type, we might have missed
             // an implementation because we do not know enough about instantiations.
             // in this case continue with the supertype as origin.
-            if (types.isDerivedRaw(origin.type))
+            if (types.isDerivedRaw(origin.type) && !origin.isInterface())
                 return implementation(types.supertype(origin.type).tsym, types, checkResult);
             else
                 return null;
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -126,6 +126,7 @@
     public final Type cloneableType;
     public final Type serializableType;
     public final Type methodHandleType;
+    public final Type nativeHeaderType;
     public final Type polymorphicSignatureType;
     public final Type throwableType;
     public final Type errorType;
@@ -477,6 +478,7 @@
                                             List.of(exceptionType), methodClass),
                              autoCloseableType.tsym);
         trustMeType = enterClass("java.lang.SafeVarargs");
+        nativeHeaderType = enterClass("javax.tools.annotation.GenerateNativeHeader");
 
         synthesizeEmptyInterfaceIfMissing(autoCloseableType);
         synthesizeEmptyInterfaceIfMissing(cloneableType);
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -199,16 +199,15 @@
      *  @param tree     The tree whose kind and type is checked
      *  @param owntype  The computed type of the tree
      *  @param ownkind  The computed kind of the tree
-     *  @param pkind    The expected kind (or: protokind) of the tree
-     *  @param pt       The expected type (or: prototype) of the tree
+     *  @param resultInfo  The expected result of the tree
      */
-    Type check(JCTree tree, Type owntype, int ownkind, int pkind, Type pt) {
-        if (owntype.tag != ERROR && pt.tag != METHOD && pt.tag != FORALL) {
-            if ((ownkind & ~pkind) == 0) {
-                owntype = chk.checkType(tree.pos(), owntype, pt, errKey);
+    Type check(JCTree tree, Type owntype, int ownkind, ResultInfo resultInfo) {
+        if (owntype.tag != ERROR && resultInfo.pt.tag != METHOD && resultInfo.pt.tag != FORALL) {
+            if ((ownkind & ~resultInfo.pkind) == 0) {
+                owntype = chk.checkType(tree.pos(), owntype, resultInfo.pt, errKey);
             } else {
                 log.error(tree.pos(), "unexpected.type",
-                          kindNames(pkind),
+                          kindNames(resultInfo.pkind),
                           kindName(ownkind));
                 owntype = types.createErrorType(owntype);
             }
@@ -333,7 +332,16 @@
     public Type attribType(JCTree node, TypeSymbol sym) {
         Env<AttrContext> env = enter.typeEnvs.get(sym);
         Env<AttrContext> localEnv = env.dup(node, env.info.dup());
-        return attribTree(node, localEnv, Kinds.TYP, Type.noType);
+        return attribTree(node, localEnv, unknownTypeInfo);
+    }
+
+    public Type attribImportQualifier(JCImport tree, Env<AttrContext> env) {
+        // Attribute qualifying package or class.
+        JCFieldAccess s = (JCFieldAccess)tree.qualid;
+        return attribTree(s.selected,
+                       env,
+                       new ResultInfo(tree.staticImport ? TYP : (TYP | PCK),
+                       Type.noType));
     }
 
     public Env<AttrContext> attribExprToTree(JCTree expr, Env<AttrContext> env, JCTree tree) {
@@ -386,6 +394,28 @@
         }
     }
 
+    static class ResultInfo {
+        int pkind;
+        Type pt;
+
+        ResultInfo(int pkind, Type pt) {
+            this.pkind = pkind;
+            this.pt = pt;
+        }
+    }
+
+    private final ResultInfo statInfo = new ResultInfo(NIL, Type.noType);
+    private final ResultInfo varInfo = new ResultInfo(VAR, Type.noType);
+    private final ResultInfo unknownExprInfo = new ResultInfo(VAL, Type.noType);
+    private final ResultInfo unknownTypeInfo = new ResultInfo(TYP, Type.noType);
+
+    Type pt() {
+        return resultInfo.pt;
+    }
+
+    int pkind() {
+        return resultInfo.pkind;
+    }
 
 /* ************************************************************************
  * Visitor methods
@@ -395,13 +425,9 @@
      */
     Env<AttrContext> env;
 
-    /** Visitor argument: the currently expected proto-kind.
+    /** Visitor argument: the currently expected attribution result.
      */
-    int pkind;
-
-    /** Visitor argument: the currently expected proto-type.
-     */
-    Type pt;
+    ResultInfo resultInfo;
 
     /** Visitor argument: the error key to be generated when a type error occurs
      */
@@ -416,22 +442,19 @@
      *
      *  @param tree    The tree to be visited.
      *  @param env     The environment visitor argument.
-     *  @param pkind   The protokind visitor argument.
-     *  @param pt      The prototype visitor argument.
+     *  @param resultInfo   The result info visitor argument.
      */
-    Type attribTree(JCTree tree, Env<AttrContext> env, int pkind, Type pt) {
-        return attribTree(tree, env, pkind, pt, "incompatible.types");
+    private Type attribTree(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo) {
+        return attribTree(tree, env, resultInfo, "incompatible.types");
     }
 
-    Type attribTree(JCTree tree, Env<AttrContext> env, int pkind, Type pt, String errKey) {
+    private Type attribTree(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo, String errKey) {
         Env<AttrContext> prevEnv = this.env;
-        int prevPkind = this.pkind;
-        Type prevPt = this.pt;
+        ResultInfo prevResult = this.resultInfo;
         String prevErrKey = this.errKey;
         try {
             this.env = env;
-            this.pkind = pkind;
-            this.pt = pt;
+            this.resultInfo = resultInfo;
             this.errKey = errKey;
             tree.accept(this);
             if (tree == breakTree)
@@ -442,8 +465,7 @@
             return chk.completionError(tree.pos(), ex);
         } finally {
             this.env = prevEnv;
-            this.pkind = prevPkind;
-            this.pt = prevPt;
+            this.resultInfo = prevResult;
             this.errKey = prevErrKey;
         }
     }
@@ -451,18 +473,18 @@
     /** Derived visitor method: attribute an expression tree.
      */
     public Type attribExpr(JCTree tree, Env<AttrContext> env, Type pt) {
-        return attribTree(tree, env, VAL, pt.tag != ERROR ? pt : Type.noType);
+        return attribExpr(tree, env, pt, "incompatible.types");
     }
 
     public Type attribExpr(JCTree tree, Env<AttrContext> env, Type pt, String key) {
-        return attribTree(tree, env, VAL, pt.tag != ERROR ? pt : Type.noType, key);
+        return attribTree(tree, env, new ResultInfo(VAL, pt.tag != ERROR ? pt : Type.noType), key);
     }
 
     /** Derived visitor method: attribute an expression tree with
      *  no constraints on the computed type.
      */
     Type attribExpr(JCTree tree, Env<AttrContext> env) {
-        return attribTree(tree, env, VAL, Type.noType);
+        return attribTree(tree, env, unknownExprInfo);
     }
 
     /** Derived visitor method: attribute a type tree.
@@ -475,14 +497,14 @@
     /** Derived visitor method: attribute a type tree.
      */
     Type attribType(JCTree tree, Env<AttrContext> env, Type pt) {
-        Type result = attribTree(tree, env, TYP, pt);
+        Type result = attribTree(tree, env, new ResultInfo(TYP, pt));
         return result;
     }
 
     /** Derived visitor method: attribute a statement or definition tree.
      */
     public Type attribStat(JCTree tree, Env<AttrContext> env) {
-        return attribTree(tree, env, NIL, Type.noType);
+        return attribTree(tree, env, statInfo);
     }
 
     /** Attribute a list of expressions, returning a list of types.
@@ -507,7 +529,7 @@
         ListBuffer<Type> argtypes = new ListBuffer<Type>();
         for (List<JCExpression> l = trees; l.nonEmpty(); l = l.tail)
             argtypes.append(chk.checkNonVoid(
-                l.head.pos(), types.upperBound(attribTree(l.head, env, VAL, Infer.anyPoly))));
+                l.head.pos(), types.upperBound(attribExpr(l.head, env, Infer.anyPoly))));
         return argtypes.toList();
     }
 
@@ -1181,7 +1203,7 @@
         result = check(tree,
                        capture(condType(tree.pos(), tree.cond.type,
                                         tree.truepart.type, tree.falsepart.type)),
-                       VAL, pkind, pt);
+                       VAL, resultInfo);
     }
     //where
         /** Compute the type of a conditional expression, after
@@ -1500,8 +1522,8 @@
                     // ...and check that it is legal in the current context.
                     // (this will also set the tree's type)
                     Type mpt = newMethTemplate(argtypes, typeargtypes);
-                    checkId(tree.meth, site, sym, localEnv, MTH,
-                            mpt, tree.varargsElement != null);
+                    checkId(tree.meth, site, sym, localEnv, new ResultInfo(MTH, mpt),
+                            tree.varargsElement != null);
                 }
                 // Otherwise, `site' is an error type and we do nothing
             }
@@ -1518,8 +1540,6 @@
             Type mpt = newMethTemplate(argtypes, typeargtypes);
             localEnv.info.varArgs = false;
             Type mtype = attribExpr(tree.meth, localEnv, mpt);
-            if (localEnv.info.varArgs)
-                Assert.check(mtype.isErroneous() || tree.varargsElement != null);
 
             // Compute the result type.
             Type restype = mtype.getReturnType();
@@ -1552,7 +1572,10 @@
 
             // Check that value of resulting type is admissible in the
             // current context.  Also, capture the return type
-            result = check(tree, capture(restype), VAL, pkind, pt);
+            result = check(tree, capture(restype), VAL, resultInfo);
+
+            if (localEnv.info.varArgs)
+                Assert.check(result.isErroneous() || tree.varargsElement != null);
         }
         chk.validate(tree.typeargs, localEnv);
     }
@@ -1627,7 +1650,6 @@
         // Attribute clazz expression and store
         // symbol + type back into the attributed tree.
         Type clazztype = attribType(clazz, env);
-        Pair<Scope,Scope> mapping = getSyntheticScopeMapping(clazztype);
         clazztype = chk.checkDiamond(tree, clazztype);
         chk.validate(clazz, localEnv);
         if (tree.encl != null) {
@@ -1654,7 +1676,7 @@
         List<Type> typeargtypes = attribTypes(tree.typeargs, localEnv);
 
         if (TreeInfo.isDiamond(tree) && !clazztype.isErroneous()) {
-            clazztype = attribDiamond(localEnv, tree, clazztype, mapping, argtypes, typeargtypes);
+            clazztype = attribDiamond(localEnv, tree, clazztype, argtypes, typeargtypes);
             clazz.type = clazztype;
         } else if (allowDiamondFinder &&
                 tree.def == null &&
@@ -1671,7 +1693,6 @@
                 inferred = attribDiamond(localEnv,
                         tree,
                         clazztype,
-                        mapping,
                         argtypes,
                         typeargtypes);
             }
@@ -1682,7 +1703,7 @@
             if (inferred != null &&
                     !inferred.isErroneous() &&
                     inferred.tag == CLASS &&
-                    types.isAssignable(inferred, pt.tag == NONE ? clazztype : pt, Warner.noWarnings)) {
+                    types.isAssignable(inferred, pt().tag == NONE ? clazztype : pt(), Warner.noWarnings)) {
                 String key = types.isSameType(clazztype, inferred) ?
                     "diamond.redundant.args" :
                     "diamond.redundant.args.1";
@@ -1732,7 +1753,7 @@
                     tree.pos(), rsEnv, clazztype, argtypes, typeargtypes);
                 tree.constructorType = tree.constructor.type.isErroneous() ?
                     syms.errType :
-                    checkMethod(clazztype,
+                    checkConstructor(clazztype,
                         tree.constructor,
                         rsEnv,
                         tree.args,
@@ -1807,7 +1828,7 @@
                     tree.constructorType =  syms.errType;
                 }
                 else {
-                    tree.constructorType = checkMethod(clazztype,
+                    tree.constructorType = checkConstructor(clazztype,
                             tree.constructor,
                             localEnv,
                             tree.args,
@@ -1820,19 +1841,17 @@
             if (tree.constructor != null && tree.constructor.kind == MTH)
                 owntype = clazztype;
         }
-        result = check(tree, owntype, VAL, pkind, pt);
+        result = check(tree, owntype, VAL, resultInfo);
         chk.validate(tree.typeargs, localEnv);
     }
 
     Type attribDiamond(Env<AttrContext> env,
                         JCNewClass tree,
                         Type clazztype,
-                        Pair<Scope, Scope> mapping,
                         List<Type> argtypes,
                         List<Type> typeargtypes) {
         if (clazztype.isErroneous() ||
-                clazztype.isInterface() ||
-                mapping == erroneousMapping) {
+                clazztype.isInterface()) {
             //if the type of the instance creation expression is erroneous,
             //or if it's an interface, or if something prevented us to form a valid
             //mapping, return the (possibly erroneous) type unchanged
@@ -1841,27 +1860,22 @@
 
         //dup attribution environment and augment the set of inference variables
         Env<AttrContext> localEnv = env.dup(tree);
-        localEnv.info.tvars = clazztype.tsym.type.getTypeArguments();
+
+        ClassType site = new ClassType(clazztype.getEnclosingType(),
+                    clazztype.tsym.type.getTypeArguments(),
+                    clazztype.tsym);
 
         //if the type of the instance creation expression is a class type
         //apply method resolution inference (JLS 15.12.2.7). The return type
         //of the resolved constructor will be a partially instantiated type
-        ((ClassSymbol) clazztype.tsym).members_field = mapping.snd;
-        Symbol constructor;
-        try {
-            constructor = rs.resolveDiamond(tree.pos(),
+        Symbol constructor = rs.resolveDiamond(tree.pos(),
                     localEnv,
-                    clazztype,
+                    site,
                     argtypes,
                     typeargtypes);
-        } finally {
-            ((ClassSymbol) clazztype.tsym).members_field = mapping.fst;
-        }
+
         if (constructor.kind == MTH) {
-            ClassType ct = new ClassType(clazztype.getEnclosingType(),
-                    clazztype.tsym.type.getTypeArguments(),
-                    clazztype.tsym);
-            clazztype = checkMethod(ct,
+            clazztype = checkMethod(site,
                     constructor,
                     localEnv,
                     tree.args,
@@ -1872,13 +1886,13 @@
             clazztype = syms.errType;
         }
 
-        if (clazztype.tag == FORALL && !pt.isErroneous()) {
+        if (clazztype.tag == FORALL && !pt().isErroneous()) {
             //if the resolved constructor's return type has some uninferred
             //type-variables, infer them using the expected type and declared
             //bounds (JLS 15.12.2.8).
             try {
                 clazztype = infer.instantiateExpr((ForAll) clazztype,
-                        pt.tag == NONE ? syms.objectType : pt,
+                        pt().tag == NONE ? syms.objectType : pt(),
                         Warner.noWarnings);
             } catch (Infer.InferenceException ex) {
                 //an error occurred while inferring uninstantiated type-variables
@@ -1893,42 +1907,6 @@
                 true);
     }
 
-    /** Creates a synthetic scope containing fake generic constructors.
-     *  Assuming that the original scope contains a constructor of the kind:
-     *  Foo(X x, Y y), where X,Y are class type-variables declared in Foo,
-     *  the synthetic scope is added a generic constructor of the kind:
-     *  <X,Y>Foo<X,Y>(X x, Y y). This is crucial in order to enable diamond
-     *  inference. The inferred return type of the synthetic constructor IS
-     *  the inferred type for the diamond operator.
-     */
-    private Pair<Scope, Scope> getSyntheticScopeMapping(Type ctype) {
-        if (ctype.tag != CLASS) {
-            return erroneousMapping;
-        }
-
-        Pair<Scope, Scope> mapping =
-                new Pair<Scope, Scope>(ctype.tsym.members(), new Scope(ctype.tsym));
-
-        //for each constructor in the original scope, create a synthetic constructor
-        //whose return type is the type of the class in which the constructor is
-        //declared, and insert it into the new scope.
-        for (Scope.Entry e = mapping.fst.lookup(names.init);
-                e.scope != null;
-                e = e.next()) {
-            Type synthRestype = new ClassType(ctype.getEnclosingType(),
-                        ctype.tsym.type.getTypeArguments(),
-                        ctype.tsym);
-            MethodSymbol synhConstr = new MethodSymbol(e.sym.flags(),
-                    names.init,
-                    types.createMethodTypeWithReturn(e.sym.type, synthRestype),
-                    e.sym.owner);
-            mapping.snd.enter(synhConstr);
-        }
-        return mapping;
-    }
-
-    private final Pair<Scope,Scope> erroneousMapping = new Pair<Scope,Scope>(null, null);
-
     /** Make an attributed null check tree.
      */
     public JCExpression makeNullCheck(JCExpression arg) {
@@ -1957,14 +1935,14 @@
         } else {
             // we are seeing an untyped aggregate { ... }
             // this is allowed only if the prototype is an array
-            if (pt.tag == ARRAY) {
-                elemtype = types.elemtype(pt);
+            if (pt().tag == ARRAY) {
+                elemtype = types.elemtype(pt());
             } else {
-                if (pt.tag != ERROR) {
+                if (pt().tag != ERROR) {
                     log.error(tree.pos(), "illegal.initializer.for.type",
-                              pt);
+                              pt());
                 }
-                elemtype = types.createErrorType(pt);
+                elemtype = types.createErrorType(pt());
             }
         }
         if (tree.elems != null) {
@@ -1973,7 +1951,7 @@
         }
         if (!types.isReifiable(elemtype))
             log.error(tree.pos(), "generic.array.creation");
-        result = check(tree, owntype, VAL, pkind, pt);
+        result = check(tree, owntype, VAL, resultInfo);
     }
 
     @Override
@@ -1987,23 +1965,23 @@
     }
 
     public void visitParens(JCParens tree) {
-        Type owntype = attribTree(tree.expr, env, pkind, pt);
-        result = check(tree, owntype, pkind, pkind, pt);
+        Type owntype = attribTree(tree.expr, env, resultInfo);
+        result = check(tree, owntype, pkind(), resultInfo);
         Symbol sym = TreeInfo.symbol(tree);
         if (sym != null && (sym.kind&(TYP|PCK)) != 0)
             log.error(tree.pos(), "illegal.start.of.type");
     }
 
     public void visitAssign(JCAssign tree) {
-        Type owntype = attribTree(tree.lhs, env.dup(tree), VAR, Type.noType);
+        Type owntype = attribTree(tree.lhs, env.dup(tree), varInfo);
         Type capturedType = capture(owntype);
         attribExpr(tree.rhs, env, owntype);
-        result = check(tree, capturedType, VAL, pkind, pt);
+        result = check(tree, capturedType, VAL, resultInfo);
     }
 
     public void visitAssignop(JCAssignOp tree) {
         // Attribute arguments.
-        Type owntype = attribTree(tree.lhs, env, VAR, Type.noType);
+        Type owntype = attribTree(tree.lhs, env, varInfo);
         Type operand = attribExpr(tree.rhs, env);
         // Find operator.
         Symbol operator = tree.operator = rs.resolveBinaryOperator(
@@ -2023,13 +2001,13 @@
                               operator.type.getReturnType(),
                               owntype);
         }
-        result = check(tree, owntype, VAL, pkind, pt);
+        result = check(tree, owntype, VAL, resultInfo);
     }
 
     public void visitUnary(JCUnary tree) {
         // Attribute arguments.
         Type argtype = (tree.getTag().isIncOrDecUnaryOp())
-            ? attribTree(tree.arg, env, VAR, Type.noType)
+            ? attribTree(tree.arg, env, varInfo)
             : chk.checkNonVoid(tree.arg.pos(), attribExpr(tree.arg, env));
 
         // Find operator.
@@ -2061,7 +2039,7 @@
                 }
             }
         }
-        result = check(tree, owntype, VAL, pkind, pt);
+        result = check(tree, owntype, VAL, resultInfo);
     }
 
     public void visitBinary(JCBinary tree) {
@@ -2114,7 +2092,7 @@
 
             chk.checkDivZero(tree.rhs.pos(), operator, right);
         }
-        result = check(tree, owntype, VAL, pkind, pt);
+        result = check(tree, owntype, VAL, resultInfo);
     }
 
     public void visitTypeCast(JCTypeCast tree) {
@@ -2127,7 +2105,7 @@
         Type owntype = chk.checkCastable(tree.expr.pos(), exprtype, clazztype);
         if (exprtype.constValue() != null)
             owntype = cfolder.coerce(exprtype, owntype);
-        result = check(tree, capture(owntype), VAL, pkind, pt);
+        result = check(tree, capture(owntype), VAL, resultInfo);
     }
 
     public void visitTypeTest(JCInstanceOf tree) {
@@ -2137,7 +2115,7 @@
             tree.clazz.pos(), attribType(tree.clazz, env));
         chk.validate(tree.clazz, env, false);
         chk.checkCastable(tree.expr.pos(), exprtype, clazztype);
-        result = check(tree, syms.booleanType, VAL, pkind, pt);
+        result = check(tree, syms.booleanType, VAL, resultInfo);
     }
 
     public void visitIndexed(JCArrayAccess tree) {
@@ -2148,8 +2126,8 @@
             owntype = types.elemtype(atype);
         else if (atype.tag != ERROR)
             log.error(tree.pos(), "array.req.but.found", atype);
-        if ((pkind & VAR) == 0) owntype = capture(owntype);
-        result = check(tree, owntype, VAR, pkind, pt);
+        if ((pkind() & VAR) == 0) owntype = capture(owntype);
+        result = check(tree, owntype, VAR, resultInfo);
     }
 
     public void visitIdent(JCIdent tree) {
@@ -2157,16 +2135,16 @@
         boolean varArgs = false;
 
         // Find symbol
-        if (pt.tag == METHOD || pt.tag == FORALL) {
+        if (pt().tag == METHOD || pt().tag == FORALL) {
             // If we are looking for a method, the prototype `pt' will be a
             // method type with the type of the call's arguments as parameters.
             env.info.varArgs = false;
-            sym = rs.resolveMethod(tree.pos(), env, tree.name, pt.getParameterTypes(), pt.getTypeArguments());
+            sym = rs.resolveMethod(tree.pos(), env, tree.name, pt().getParameterTypes(), pt().getTypeArguments());
             varArgs = env.info.varArgs;
         } else if (tree.sym != null && tree.sym.kind != VAR) {
             sym = tree.sym;
         } else {
-            sym = rs.resolveIdent(tree.pos(), env, tree.name, pkind);
+            sym = rs.resolveIdent(tree.pos(), env, tree.name, pkind());
         }
         tree.sym = sym;
 
@@ -2213,7 +2191,7 @@
 
             // If we are expecting a variable (as opposed to a value), check
             // that the variable is assignable in the current environment.
-            if (pkind == VAR)
+            if (pkind() == VAR)
                 checkAssignable(tree.pos(), v, null, env);
         }
 
@@ -2234,7 +2212,7 @@
             while (env1.outer != null && !rs.isAccessible(env, env1.enclClass.sym.type, sym))
                 env1 = env1.outer;
         }
-        result = checkId(tree, env1.enclClass.sym.type, sym, env, pkind, pt, varArgs);
+        result = checkId(tree, env1.enclClass.sym.type, sym, env, resultInfo, varArgs);
     }
 
     public void visitSelect(JCFieldAccess tree) {
@@ -2245,14 +2223,14 @@
         {
             skind = TYP;
         } else {
-            if ((pkind & PCK) != 0) skind = skind | PCK;
-            if ((pkind & TYP) != 0) skind = skind | TYP | PCK;
-            if ((pkind & (VAL | MTH)) != 0) skind = skind | VAL | TYP;
+            if ((pkind() & PCK) != 0) skind = skind | PCK;
+            if ((pkind() & TYP) != 0) skind = skind | TYP | PCK;
+            if ((pkind() & (VAL | MTH)) != 0) skind = skind | VAL | TYP;
         }
 
         // Attribute the qualifier expression, and determine its symbol (if any).
-        Type site = attribTree(tree.selected, env, skind, Infer.anyPoly);
-        if ((pkind & (PCK | TYP)) == 0)
+        Type site = attribTree(tree.selected, env, new ResultInfo(skind, Infer.anyPoly));
+        if ((pkind() & (PCK | TYP)) == 0)
             site = capture(site); // Capture field access
 
         // don't allow T.class T[].class, etc
@@ -2287,10 +2265,10 @@
 
         // Determine the symbol represented by the selection.
         env.info.varArgs = false;
-        Symbol sym = selectSym(tree, sitesym, site, env, pt, pkind);
-        if (sym.exists() && !isType(sym) && (pkind & (PCK | TYP)) != 0) {
+        Symbol sym = selectSym(tree, sitesym, site, env, resultInfo);
+        if (sym.exists() && !isType(sym) && (pkind() & (PCK | TYP)) != 0) {
             site = capture(site);
-            sym = selectSym(tree, sitesym, site, env, pt, pkind);
+            sym = selectSym(tree, sitesym, site, env, resultInfo);
         }
         boolean varArgs = env.info.varArgs;
         tree.sym = sym;
@@ -2310,7 +2288,7 @@
 
             // If we are expecting a variable (as opposed to a value), check
             // that the variable is assignable in the current environment.
-            if (pkind == VAR)
+            if (pkind() == VAR)
                 checkAssignable(tree.pos(), v, tree.selected, env);
         }
 
@@ -2326,8 +2304,8 @@
 
         // Disallow selecting a type from an expression
         if (isType(sym) && (sitesym==null || (sitesym.kind&(TYP|PCK)) == 0)) {
-            tree.type = check(tree.selected, pt,
-                              sitesym == null ? VAL : sitesym.kind, TYP|PCK, pt);
+            tree.type = check(tree.selected, pt(),
+                              sitesym == null ? VAL : sitesym.kind, new ResultInfo(TYP|PCK, pt()));
         }
 
         if (isType(sitesym)) {
@@ -2367,7 +2345,7 @@
         }
 
         env.info.selectSuper = selectSuperPrev;
-        result = checkId(tree, site, sym, env, pkind, pt, varArgs);
+        result = checkId(tree, site, sym, env, resultInfo, varArgs);
         env.info.tvars = List.nil();
     }
     //where
@@ -2376,34 +2354,25 @@
          *  @param tree   The select tree.
          *  @param site   The type of the selected expression,
          *  @param env    The current environment.
-         *  @param pt     The current prototype.
-         *  @param pkind  The expected kind(s) of the Select expression.
+         *  @param resultInfo The current result.
          */
         private Symbol selectSym(JCFieldAccess tree,
-                                     Type site,
-                                     Env<AttrContext> env,
-                                     Type pt,
-                                     int pkind) {
-            return selectSym(tree, site.tsym, site, env, pt, pkind);
-        }
-        private Symbol selectSym(JCFieldAccess tree,
                                  Symbol location,
                                  Type site,
                                  Env<AttrContext> env,
-                                 Type pt,
-                                 int pkind) {
+                                 ResultInfo resultInfo) {
             DiagnosticPosition pos = tree.pos();
             Name name = tree.name;
             switch (site.tag) {
             case PACKAGE:
                 return rs.access(
-                    rs.findIdentInPackage(env, site.tsym, name, pkind),
+                    rs.findIdentInPackage(env, site.tsym, name, resultInfo.pkind),
                     pos, location, site, name, true);
             case ARRAY:
             case CLASS:
-                if (pt.tag == METHOD || pt.tag == FORALL) {
+                if (resultInfo.pt.tag == METHOD || resultInfo.pt.tag == FORALL) {
                     return rs.resolveQualifiedMethod(
-                        pos, env, location, site, name, pt.getParameterTypes(), pt.getTypeArguments());
+                        pos, env, location, site, name, resultInfo.pt.getParameterTypes(), resultInfo.pt.getTypeArguments());
                 } else if (name == names._this || name == names._super) {
                     return rs.resolveSelf(pos, env, site.tsym, name);
                 } else if (name == names._class) {
@@ -2418,8 +2387,8 @@
                         STATIC | PUBLIC | FINAL, names._class, t, site.tsym);
                 } else {
                     // We are seeing a plain identifier as selector.
-                    Symbol sym = rs.findIdentInType(env, site, name, pkind);
-                    if ((pkind & ERRONEOUS) == 0)
+                    Symbol sym = rs.findIdentInType(env, site, name, resultInfo.pkind);
+                    if ((resultInfo.pkind & ERRONEOUS) == 0)
                         sym = rs.access(sym, pos, location, site, name, true);
                     return sym;
                 }
@@ -2433,7 +2402,7 @@
                 // other words, we are seeing this illegal program:
                 // class B<T> extends A<T.foo> {}
                 Symbol sym = (site.getUpperBound() != null)
-                    ? selectSym(tree, location, capture(site.getUpperBound()), env, pt, pkind)
+                    ? selectSym(tree, location, capture(site.getUpperBound()), env, resultInfo)
                     : null;
                 if (sym == null) {
                     log.error(pos, "type.var.cant.be.deref");
@@ -2487,17 +2456,15 @@
          *                    expression, otherwise the type of the current class.
          *  @param sym        The symbol representing the identifier.
          *  @param env        The current environment.
-         *  @param pkind      The set of expected kinds.
-         *  @param pt         The expected type.
+         *  @param resultInfo    The expected result
          */
         Type checkId(JCTree tree,
                      Type site,
                      Symbol sym,
                      Env<AttrContext> env,
-                     int pkind,
-                     Type pt,
+                     ResultInfo resultInfo,
                      boolean useVarargs) {
-            if (pt.isErroneous()) return types.createErrorType(site);
+            if (resultInfo.pt.isErroneous()) return types.createErrorType(site);
             Type owntype; // The computed type of this identifier occurrence.
             switch (sym.kind) {
             case TYP:
@@ -2542,7 +2509,7 @@
                 // which is being assigned to, issue an unchecked warning if
                 // its type changes under erasure.
                 if (allowGenerics &&
-                    pkind == VAR &&
+                    resultInfo.pkind == VAR &&
                     v.owner.kind == TYP &&
                     (v.flags() & STATIC) == 0 &&
                     (site.tag == CLASS || site.tag == TYPEVAR)) {
@@ -2577,14 +2544,14 @@
                 if (v.getConstValue() != null && isStaticReference(tree))
                     owntype = owntype.constType(v.getConstValue());
 
-                if (pkind == VAL) {
+                if (resultInfo.pkind == VAL) {
                     owntype = capture(owntype); // capture "names as expressions"
                 }
                 break;
             case MTH: {
                 JCMethodInvocation app = (JCMethodInvocation)env.tree;
                 owntype = checkMethod(site, sym, env, app.args,
-                                      pt.getParameterTypes(), pt.getTypeArguments(),
+                                      resultInfo.pt.getParameterTypes(), resultInfo.pt.getTypeArguments(),
                                       env.info.varArgs);
                 break;
             }
@@ -2607,7 +2574,7 @@
 
             // Test (3): if symbol is a variable, check that its type and
             // kind are compatible with the prototype and protokind.
-            return check(tree, owntype, sym.kind, pkind, pt);
+            return check(tree, owntype, sym.kind, resultInfo);
         }
 
         /** Check that variable is initialized and evaluate the variable's
@@ -2720,7 +2687,7 @@
     Warner noteWarner = new Warner();
 
     /**
-     * Check that method arguments conform to its instantation.
+     * Check that method arguments conform to its instantiation.
      **/
     public Type checkMethod(Type site,
                             Symbol sym,
@@ -2757,112 +2724,44 @@
                                       true,
                                       useVarargs,
                                       noteWarner);
-        boolean warned = noteWarner.hasNonSilentLint(LintCategory.UNCHECKED);
+
+        boolean unchecked = noteWarner.hasNonSilentLint(LintCategory.UNCHECKED);
 
         // If this fails, something went wrong; we should not have
         // found the identifier in the first place.
         if (owntype == null) {
-            if (!pt.isErroneous())
+            if (!pt().isErroneous())
                 log.error(env.tree.pos(),
-                          "internal.error.cant.instantiate",
-                          sym, site,
-                          Type.toString(pt.getParameterTypes()));
+                           "internal.error.cant.instantiate",
+                           sym, site,
+                          Type.toString(pt().getParameterTypes()));
             owntype = types.createErrorType(site);
+            return types.createErrorType(site);
+        } else if (owntype.getReturnType().tag == FORALL && !unchecked) {
+            return owntype;
         } else {
-            // System.out.println("call   : " + env.tree);
-            // System.out.println("method : " + owntype);
-            // System.out.println("actuals: " + argtypes);
-            List<Type> formals = owntype.getParameterTypes();
-            Type last = useVarargs ? formals.last() : null;
-            if (sym.name==names.init &&
-                sym.owner == syms.enumSym)
-                formals = formals.tail.tail;
-            List<JCExpression> args = argtrees;
-            while (formals.head != last) {
-                JCTree arg = args.head;
-                Warner warn = chk.convertWarner(arg.pos(), arg.type, formals.head);
-                assertConvertible(arg, arg.type, formals.head, warn);
-                warned |= warn.hasNonSilentLint(LintCategory.UNCHECKED);
-                args = args.tail;
-                formals = formals.tail;
-            }
-            if (useVarargs) {
-                Type varArg = types.elemtype(last);
-                while (args.tail != null) {
-                    JCTree arg = args.head;
-                    Warner warn = chk.convertWarner(arg.pos(), arg.type, varArg);
-                    assertConvertible(arg, arg.type, varArg, warn);
-                    warned |= warn.hasNonSilentLint(LintCategory.UNCHECKED);
-                    args = args.tail;
-                }
-            } else if ((sym.flags() & VARARGS) != 0 && allowVarargs) {
-                // non-varargs call to varargs method
-                Type varParam = owntype.getParameterTypes().last();
-                Type lastArg = argtypes.last();
-                if (types.isSubtypeUnchecked(lastArg, types.elemtype(varParam)) &&
-                    !types.isSameType(types.erasure(varParam), types.erasure(lastArg)))
-                    log.warning(argtrees.last().pos(), "inexact.non-varargs.call",
-                                types.elemtype(varParam),
-                                varParam);
-            }
-
-            if (warned && sym.type.tag == FORALL) {
-                chk.warnUnchecked(env.tree.pos(),
-                                  "unchecked.meth.invocation.applied",
-                                  kindName(sym),
-                                  sym.name,
-                                  rs.methodArguments(sym.type.getParameterTypes()),
-                                  rs.methodArguments(argtypes),
-                                  kindName(sym.location()),
-                                  sym.location());
-                owntype = new MethodType(owntype.getParameterTypes(),
-                                         types.erasure(owntype.getReturnType()),
-                                         types.erasure(owntype.getThrownTypes()),
-                                         syms.methodClass);
-            }
-            if (useVarargs) {
-                JCTree tree = env.tree;
-                Type argtype = owntype.getParameterTypes().last();
-                if (owntype.getReturnType().tag != FORALL || warned) {
-                    chk.checkVararg(env.tree.pos(), owntype.getParameterTypes(), sym);
-                }
-                Type elemtype = types.elemtype(argtype);
-                switch (tree.getTag()) {
-                case APPLY:
-                    ((JCMethodInvocation) tree).varargsElement = elemtype;
-                    break;
-                case NEWCLASS:
-                    ((JCNewClass) tree).varargsElement = elemtype;
-                    break;
-                default:
-                    throw new AssertionError(""+tree);
-                }
-            }
+            return chk.checkMethod(owntype, sym, env, argtrees, argtypes, useVarargs, unchecked);
         }
+    }
+
+    /**
+     * Check that constructor arguments conform to its instantiation.
+     **/
+    public Type checkConstructor(Type site,
+                            Symbol sym,
+                            Env<AttrContext> env,
+                            final List<JCExpression> argtrees,
+                            List<Type> argtypes,
+                            List<Type> typeargtypes,
+                            boolean useVarargs) {
+        Type owntype = checkMethod(site, sym, env, argtrees, argtypes, typeargtypes, useVarargs);
+        chk.checkType(env.tree.pos(), owntype.getReturnType(), syms.voidType);
         return owntype;
     }
 
-    private void assertConvertible(JCTree tree, Type actual, Type formal, Warner warn) {
-        if (types.isConvertible(actual, formal, warn))
-            return;
-
-        if (formal.isCompound()
-            && types.isSubtype(actual, types.supertype(formal))
-            && types.isSubtypeUnchecked(actual, types.interfaces(formal), warn))
-            return;
-
-        if (false) {
-            // TODO: make assertConvertible work
-            chk.typeError(tree.pos(), diags.fragment("incompatible.types"), actual, formal);
-            throw new AssertionError("Tree: " + tree
-                                     + " actual:" + actual
-                                     + " formal: " + formal);
-        }
-    }
-
     public void visitLiteral(JCLiteral tree) {
         result = check(
-            tree, litType(tree.typetag).constType(tree.value), VAL, pkind, pt);
+            tree, litType(tree.typetag).constType(tree.value), VAL, resultInfo);
     }
     //where
     /** Return the type of a literal with given type tag.
@@ -2872,13 +2771,13 @@
     }
 
     public void visitTypeIdent(JCPrimitiveTypeTree tree) {
-        result = check(tree, syms.typeOfTag[tree.typetag], TYP, pkind, pt);
+        result = check(tree, syms.typeOfTag[tree.typetag], TYP, resultInfo);
     }
 
     public void visitTypeArray(JCArrayTypeTree tree) {
         Type etype = attribType(tree.elemtype, env);
         Type type = new ArrayType(etype, syms.arrayClass);
-        result = check(tree, type, TYP, pkind, pt);
+        result = check(tree, type, TYP, resultInfo);
     }
 
     /** Visitor method for parameterized types.
@@ -2936,7 +2835,7 @@
                 owntype = types.createErrorType(tree.type);
             }
         }
-        result = check(tree, owntype, TYP, pkind, pt);
+        result = check(tree, owntype, TYP, resultInfo);
     }
 
     public void visitTypeUnion(JCTypeUnion tree) {
@@ -2973,7 +2872,7 @@
                 all_multicatchTypes.append(ctype);
             }
         }
-        Type t = check(tree, types.lub(multicatchTypes.toList()), TYP, pkind, pt);
+        Type t = check(tree, types.lub(multicatchTypes.toList()), TYP, resultInfo);
         if (t.tag == CLASS) {
             List<Type> alternatives =
                 ((all_multicatchTypes == null) ? multicatchTypes : all_multicatchTypes).toList();
@@ -3059,18 +2958,18 @@
         result = check(tree, new WildcardType(chk.checkRefType(tree.pos(), type),
                                               tree.kind.kind,
                                               syms.boundClass),
-                       TYP, pkind, pt);
+                       TYP, resultInfo);
     }
 
     public void visitAnnotation(JCAnnotation tree) {
-        log.error(tree.pos(), "annotation.not.valid.for.type", pt);
+        log.error(tree.pos(), "annotation.not.valid.for.type", pt());
         result = tree.type = syms.errType;
     }
 
     public void visitErroneous(JCErroneous tree) {
         if (tree.errs != null)
             for (JCTree err : tree.errs)
-                attribTree(err, env, ERR, pt);
+                attribTree(err, env, new ResultInfo(ERR, pt()));
         result = tree.type = syms.errType;
     }
 
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java	Fri Mar 30 16:57:50 2012 -0700
@@ -63,6 +63,7 @@
 
     private final Names names;
     private final Log log;
+    private final Resolve rs;
     private final Symtab syms;
     private final Enter enter;
     private final Infer infer;
@@ -95,6 +96,7 @@
 
         names = Names.instance(context);
         log = Log.instance(context);
+        rs = Resolve.instance(context);
         syms = Symtab.instance(context);
         enter = Enter.instance(context);
         infer = Infer.instance(context);
@@ -106,6 +108,7 @@
 
         Source source = Source.instance(context);
         allowGenerics = source.allowGenerics();
+        allowVarargs = source.allowVarargs();
         allowAnnotations = source.allowAnnotations();
         allowCovariantReturns = source.allowCovariantReturns();
         allowSimplifiedVarargs = source.allowSimplifiedVarargs();
@@ -137,6 +140,10 @@
      */
     boolean allowGenerics;
 
+    /** Switch: varargs enabled?
+     */
+    boolean allowVarargs;
+
     /** Switch: annotations enabled?
      */
     boolean allowAnnotations;
@@ -525,16 +532,16 @@
      *  @param a             The type that should be bounded by bs.
      *  @param bs            The bound.
      */
-    private boolean checkExtends(Type a, TypeVar bs) {
+    private boolean checkExtends(Type a, Type bound) {
          if (a.isUnbound()) {
              return true;
          } else if (a.tag != WILDCARD) {
              a = types.upperBound(a);
-             return types.isSubtype(a, bs.bound);
+             return types.isSubtype(a, bound);
          } else if (a.isExtendsBound()) {
-             return types.isCastable(bs.getUpperBound(), types.upperBound(a), Warner.noWarnings);
+             return types.isCastable(bound, types.upperBound(a), Warner.noWarnings);
          } else if (a.isSuperBound()) {
-             return !types.notSoftSubtype(types.lowerBound(a), bs.getUpperBound());
+             return !types.notSoftSubtype(types.lowerBound(a), bound);
          }
          return true;
      }
@@ -743,22 +750,103 @@
                     (s.flags() & (STATIC | FINAL)) != 0);
         }
 
-    /**
-     * Check that vararg method call is sound
-     * @param pos Position to be used for error reporting.
-     * @param argtypes Actual arguments supplied to vararg method.
-     */
-    void checkVararg(DiagnosticPosition pos, List<Type> argtypes, Symbol msym) {
-        Type argtype = argtypes.last();
-        if (!types.isReifiable(argtype) &&
-                (!allowSimplifiedVarargs ||
-                msym.attribute(syms.trustMeType.tsym) == null ||
-                !isTrustMeAllowedOnMethod(msym))) {
-            warnUnchecked(pos,
-                              "unchecked.generic.array.creation",
-                              argtype);
+    Type checkMethod(Type owntype,
+                            Symbol sym,
+                            Env<AttrContext> env,
+                            final List<JCExpression> argtrees,
+                            List<Type> argtypes,
+                            boolean useVarargs,
+                            boolean unchecked) {
+        // System.out.println("call   : " + env.tree);
+        // System.out.println("method : " + owntype);
+        // System.out.println("actuals: " + argtypes);
+        List<Type> formals = owntype.getParameterTypes();
+        Type last = useVarargs ? formals.last() : null;
+        if (sym.name==names.init &&
+                sym.owner == syms.enumSym)
+                formals = formals.tail.tail;
+        List<JCExpression> args = argtrees;
+        while (formals.head != last) {
+            JCTree arg = args.head;
+            Warner warn = convertWarner(arg.pos(), arg.type, formals.head);
+            assertConvertible(arg, arg.type, formals.head, warn);
+            args = args.tail;
+            formals = formals.tail;
+        }
+        if (useVarargs) {
+            Type varArg = types.elemtype(last);
+            while (args.tail != null) {
+                JCTree arg = args.head;
+                Warner warn = convertWarner(arg.pos(), arg.type, varArg);
+                assertConvertible(arg, arg.type, varArg, warn);
+                args = args.tail;
+            }
+        } else if ((sym.flags() & VARARGS) != 0 && allowVarargs) {
+            // non-varargs call to varargs method
+            Type varParam = owntype.getParameterTypes().last();
+            Type lastArg = argtypes.last();
+            if (types.isSubtypeUnchecked(lastArg, types.elemtype(varParam)) &&
+                    !types.isSameType(types.erasure(varParam), types.erasure(lastArg)))
+                log.warning(argtrees.last().pos(), "inexact.non-varargs.call",
+                        types.elemtype(varParam), varParam);
         }
+        if (unchecked) {
+            warnUnchecked(env.tree.pos(),
+                    "unchecked.meth.invocation.applied",
+                    kindName(sym),
+                    sym.name,
+                    rs.methodArguments(sym.type.getParameterTypes()),
+                    rs.methodArguments(argtypes),
+                    kindName(sym.location()),
+                    sym.location());
+           owntype = new MethodType(owntype.getParameterTypes(),
+                   types.erasure(owntype.getReturnType()),
+                   types.erasure(owntype.getThrownTypes()),
+                   syms.methodClass);
+        }
+        if (useVarargs) {
+            JCTree tree = env.tree;
+            Type argtype = owntype.getParameterTypes().last();
+            if (!types.isReifiable(argtype) &&
+                    (!allowSimplifiedVarargs ||
+                    sym.attribute(syms.trustMeType.tsym) == null ||
+                    !isTrustMeAllowedOnMethod(sym))) {
+                warnUnchecked(env.tree.pos(),
+                                  "unchecked.generic.array.creation",
+                                  argtype);
+            }
+            Type elemtype = types.elemtype(argtype);
+            switch (tree.getTag()) {
+                case APPLY:
+                    ((JCMethodInvocation) tree).varargsElement = elemtype;
+                    break;
+                case NEWCLASS:
+                    ((JCNewClass) tree).varargsElement = elemtype;
+                    break;
+                default:
+                    throw new AssertionError(""+tree);
+            }
+         }
+         return owntype;
     }
+    //where
+        private void assertConvertible(JCTree tree, Type actual, Type formal, Warner warn) {
+            if (types.isConvertible(actual, formal, warn))
+                return;
+
+            if (formal.isCompound()
+                && types.isSubtype(actual, types.supertype(formal))
+                && types.isSubtypeUnchecked(actual, types.interfaces(formal), warn))
+                return;
+
+            if (false) {
+                // TODO: make assertConvertible work
+                typeError(tree.pos(), diags.fragment("incompatible.types"), actual, formal);
+                throw new AssertionError("Tree: " + tree
+                                         + " actual:" + actual
+                                         + " formal: " + formal);
+            }
+        }
 
     /**
      * Check that type 't' is a valid instantiation of a generic class
@@ -776,18 +864,16 @@
             List<Type> actuals = type.allparams();
             List<Type> args = type.getTypeArguments();
             List<Type> forms = type.tsym.type.getTypeArguments();
-            ListBuffer<Type> tvars_buf = new ListBuffer<Type>();
+            ListBuffer<Type> bounds_buf = new ListBuffer<Type>();
 
             // For matching pairs of actual argument types `a' and
             // formal type parameters with declared bound `b' ...
             while (args.nonEmpty() && forms.nonEmpty()) {
                 // exact type arguments needs to know their
                 // bounds (for upper and lower bound
-                // calculations).  So we create new TypeVars with
-                // bounds substed with actuals.
-                tvars_buf.append(types.substBound(((TypeVar)forms.head),
-                                                  formals,
-                                                  actuals));
+                // calculations).  So we create new bounds where
+                // type-parameters are replaced with actuals argument types.
+                bounds_buf.append(types.subst(forms.head.getUpperBound(), formals, actuals));
                 args = args.tail;
                 forms = forms.tail;
             }
@@ -804,32 +890,30 @@
             }
 
             args = type.getTypeArguments();
-            List<Type> tvars = tvars_buf.toList();
+            List<Type> bounds = bounds_buf.toList();
 
-            while (args.nonEmpty() && tvars.nonEmpty()) {
-                Type actual = types.subst(args.head,
-                    type.tsym.type.getTypeArguments(),
-                    tvars_buf.toList());
+            while (args.nonEmpty() && bounds.nonEmpty()) {
+                Type actual = args.head;
                 if (!isTypeArgErroneous(actual) &&
-                        !tvars.head.getUpperBound().isErroneous() &&
-                        !checkExtends(actual, (TypeVar)tvars.head)) {
+                        !bounds.head.isErroneous() &&
+                        !checkExtends(actual, bounds.head)) {
                     return args.head;
                 }
                 args = args.tail;
-                tvars = tvars.tail;
+                bounds = bounds.tail;
             }
 
             args = type.getTypeArguments();
-            tvars = tvars_buf.toList();
+            bounds = bounds_buf.toList();
 
             for (Type arg : types.capture(type).getTypeArguments()) {
                 if (arg.tag == TYPEVAR &&
                         arg.getUpperBound().isErroneous() &&
-                        !tvars.head.getUpperBound().isErroneous() &&
+                        !bounds.head.isErroneous() &&
                         !isTypeArgErroneous(args.head)) {
                     return args.head;
                 }
-                tvars = tvars.tail;
+                bounds = bounds.tail;
                 args = args.tail;
             }
 
@@ -2492,7 +2576,7 @@
                     if (enableSunApiLintControl)
                       warnSunApi(pos, "sun.proprietary", s);
                     else
-                      log.strictWarning(pos, "sun.proprietary", s);
+                      log.mandatoryWarning(pos, "sun.proprietary", s);
                 }
             });
         }
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java	Fri Mar 30 16:57:50 2012 -0700
@@ -385,7 +385,6 @@
                                   final Warner warn) throws InferenceException {
         //-System.err.println("instantiateMethod(" + tvars + ", " + mt + ", " + argtypes + ")"); //DEBUG
         List<Type> undetvars = Type.map(tvars, fromTypeVarFun);
-        //final List<Type> capturedArgs = types.capture(argtypes);
 
         final List<Type> capturedArgs =
                 rs.checkRawArgumentsAcceptable(env, undetvars, argtypes, mt.getParameterTypes(),
@@ -445,16 +444,20 @@
                     return List.nil();
                 }
                 @Override
-                void check(List<Type> inferred, Types types) throws NoInstanceException {
+                void instantiateReturnType(Type restype, List<Type> inferred, Types types) throws NoInstanceException {
+                    Type owntype = new MethodType(types.subst(getParameterTypes(), tvars, inferred),
+                                       restype,
+                                       types.subst(getThrownTypes(), tvars, inferred),
+                                       qtype.tsym);
                     // check that actuals conform to inferred formals
-                    checkArgumentsAcceptable(env, capturedArgs, getParameterTypes(), allowBoxing, useVarargs, warn);
+                    warn.clear();
+                    checkArgumentsAcceptable(env, capturedArgs, owntype.getParameterTypes(), allowBoxing, useVarargs, warn);
                     // check that inferred bounds conform to their bounds
                     checkWithinBounds(all_tvars,
                            types.subst(inferredTypes, tvars, inferred), warn);
-                    if (useVarargs) {
-                        chk.checkVararg(env.tree.pos(), getParameterTypes(), msym);
-                    }
-            }};
+                    qtype = chk.checkMethod(owntype, msym, env, TreeInfo.args(env.tree), capturedArgs, useVarargs, warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED));
+                }
+            };
         }
         else {
             // check that actuals conform to inferred formals
@@ -520,16 +523,7 @@
                 return qtype.map(f);
             }
 
-            void instantiateReturnType(Type restype, List<Type> inferred, Types types) throws NoInstanceException {
-                //update method type with newly inferred type-arguments
-                qtype = new MethodType(types.subst(getParameterTypes(), tvars, inferred),
-                                       restype,
-                                       types.subst(UninferredMethodType.this.getThrownTypes(), tvars, inferred),
-                                       UninferredMethodType.this.qtype.tsym);
-                check(inferred, types);
-            }
-
-            abstract void check(List<Type> inferred, Types types) throws NoInstanceException;
+            abstract void instantiateReturnType(Type restype, List<Type> inferred, Types types);
 
             abstract List<Type> getConstraints(TypeVar tv, ConstraintKind ck);
 
@@ -544,7 +538,7 @@
                     if (rs.verboseResolutionMode.contains(VerboseResolutionMode.DEFERRED_INST)) {
                         log.note(pos, "deferred.method.inst", msym, UninferredMethodType.this.qtype, newRestype);
                     }
-                    return newRestype;
+                    return UninferredMethodType.this.qtype.getReturnType();
                 }
                 @Override
                 public List<Type> getConstraints(TypeVar tv, ConstraintKind ck) {
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Fri Mar 30 16:57:50 2012 -0700
@@ -529,24 +529,17 @@
 
     // process the non-static imports and the static imports of types.
     public void visitImport(JCImport tree) {
-        JCTree imp = tree.qualid;
+        JCFieldAccess imp = (JCFieldAccess)tree.qualid;
         Name name = TreeInfo.name(imp);
-        TypeSymbol p;
 
         // Create a local environment pointing to this tree to disable
         // effects of other imports in Resolve.findGlobalType
         Env<AttrContext> localEnv = env.dup(tree);
 
-        // Attribute qualifying package or class.
-        JCFieldAccess s = (JCFieldAccess) imp;
-        p = attr.
-            attribTree(s.selected,
-                       localEnv,
-                       tree.staticImport ? TYP : (TYP | PCK),
-                       Type.noType).tsym;
+        TypeSymbol p = attr.attribImportQualifier(tree, localEnv).tsym;
         if (name == names.asterisk) {
             // Import on demand.
-            chk.checkCanonical(s.selected);
+            chk.checkCanonical(imp.selected);
             if (tree.staticImport)
                 importStaticAll(tree.pos, p, env);
             else
@@ -555,7 +548,7 @@
             // Named type import.
             if (tree.staticImport) {
                 importNamedStatic(tree.pos(), p, name, localEnv);
-                chk.checkCanonical(s.selected);
+                chk.checkCanonical(imp.selected);
             } else {
                 TypeSymbol c = attribImportType(imp, localEnv).tsym;
                 chk.checkCanonical(imp);
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Fri Mar 30 16:57:50 2012 -0700
@@ -29,6 +29,7 @@
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.code.Type.*;
 import com.sun.tools.javac.code.Symbol.*;
+import com.sun.tools.javac.comp.Resolve.MethodResolutionContext.Candidate;
 import com.sun.tools.javac.jvm.*;
 import com.sun.tools.javac.tree.*;
 import com.sun.tools.javac.tree.JCTree.*;
@@ -39,10 +40,9 @@
 
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.EnumMap;
 import java.util.EnumSet;
-import java.util.HashMap;
 import java.util.HashSet;
-import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Set;
 
@@ -84,6 +84,58 @@
 
     Scope polymorphicSignatureScope;
 
+    protected Resolve(Context context) {
+        context.put(resolveKey, this);
+        syms = Symtab.instance(context);
+
+        varNotFound = new
+            SymbolNotFoundError(ABSENT_VAR);
+        wrongMethod = new
+            InapplicableSymbolError();
+        wrongMethods = new
+            InapplicableSymbolsError();
+        methodNotFound = new
+            SymbolNotFoundError(ABSENT_MTH);
+        typeNotFound = new
+            SymbolNotFoundError(ABSENT_TYP);
+
+        names = Names.instance(context);
+        log = Log.instance(context);
+        chk = Check.instance(context);
+        infer = Infer.instance(context);
+        reader = ClassReader.instance(context);
+        treeinfo = TreeInfo.instance(context);
+        types = Types.instance(context);
+        diags = JCDiagnostic.Factory.instance(context);
+        Source source = Source.instance(context);
+        boxingEnabled = source.allowBoxing();
+        varargsEnabled = source.allowVarargs();
+        Options options = Options.instance(context);
+        debugResolve = options.isSet("debugresolve");
+        verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options);
+        Target target = Target.instance(context);
+        allowMethodHandles = target.hasMethodHandles();
+        polymorphicSignatureScope = new Scope(syms.noSymbol);
+
+        inapplicableMethodException = new InapplicableMethodException(diags);
+    }
+
+    /** error symbols, which are returned when resolution fails
+     */
+    private final SymbolNotFoundError varNotFound;
+    private final InapplicableSymbolError wrongMethod;
+    private final InapplicableSymbolsError wrongMethods;
+    private final SymbolNotFoundError methodNotFound;
+    private final SymbolNotFoundError typeNotFound;
+
+    public static Resolve instance(Context context) {
+        Resolve instance = context.get(resolveKey);
+        if (instance == null)
+            instance = new Resolve(context);
+        return instance;
+    }
+
+    // <editor-fold defaultstate="collapsed" desc="Verbose resolution diagnostics support">
     enum VerboseResolutionMode {
         SUCCESS("success"),
         FAILURE("failure"),
@@ -119,56 +171,74 @@
         }
     }
 
-    public static Resolve instance(Context context) {
-        Resolve instance = context.get(resolveKey);
-        if (instance == null)
-            instance = new Resolve(context);
-        return instance;
+    void reportVerboseResolutionDiagnostic(DiagnosticPosition dpos, Name name, Type site,
+            List<Type> argtypes, List<Type> typeargtypes, Symbol bestSoFar) {
+        boolean success = bestSoFar.kind < ERRONEOUS;
+
+        if (success && !verboseResolutionMode.contains(VerboseResolutionMode.SUCCESS)) {
+            return;
+        } else if (!success && !verboseResolutionMode.contains(VerboseResolutionMode.FAILURE)) {
+            return;
+        }
+
+        if (bestSoFar.name == names.init &&
+                bestSoFar.owner == syms.objectType.tsym &&
+                !verboseResolutionMode.contains(VerboseResolutionMode.OBJECT_INIT)) {
+            return; //skip diags for Object constructor resolution
+        } else if (site == syms.predefClass.type &&
+                !verboseResolutionMode.contains(VerboseResolutionMode.PREDEF)) {
+            return; //skip spurious diags for predef symbols (i.e. operators)
+        } else if (currentResolutionContext.internalResolution &&
+                !verboseResolutionMode.contains(VerboseResolutionMode.INTERNAL)) {
+            return;
+        }
+
+        int pos = 0;
+        int mostSpecificPos = -1;
+        ListBuffer<JCDiagnostic> subDiags = ListBuffer.lb();
+        for (Candidate c : currentResolutionContext.candidates) {
+            if (currentResolutionContext.step != c.step ||
+                    (c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.APPLICABLE)) ||
+                    (!c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.INAPPLICABLE))) {
+                continue;
+            } else {
+                subDiags.append(c.isApplicable() ?
+                        getVerboseApplicableCandidateDiag(pos, c.sym, c.mtype) :
+                        getVerboseInapplicableCandidateDiag(pos, c.sym, c.details));
+                if (c.sym == bestSoFar)
+                    mostSpecificPos = pos;
+                pos++;
+            }
+        }
+        String key = success ? "verbose.resolve.multi" : "verbose.resolve.multi.1";
+        JCDiagnostic main = diags.note(log.currentSource(), dpos, key, name,
+                site.tsym, mostSpecificPos, currentResolutionContext.step,
+                methodArguments(argtypes), methodArguments(typeargtypes));
+        JCDiagnostic d = new JCDiagnostic.MultilineDiagnostic(main, subDiags.toList());
+        log.report(d);
     }
 
-    protected Resolve(Context context) {
-        context.put(resolveKey, this);
-        syms = Symtab.instance(context);
-
-        varNotFound = new
-            SymbolNotFoundError(ABSENT_VAR);
-        wrongMethod = new
-            InapplicableSymbolError(syms.errSymbol);
-        wrongMethods = new
-            InapplicableSymbolsError(syms.errSymbol);
-        methodNotFound = new
-            SymbolNotFoundError(ABSENT_MTH);
-        typeNotFound = new
-            SymbolNotFoundError(ABSENT_TYP);
+    JCDiagnostic getVerboseApplicableCandidateDiag(int pos, Symbol sym, Type inst) {
+        JCDiagnostic subDiag = null;
+        if (inst.getReturnType().tag == FORALL) {
+            Type diagType = types.createMethodTypeWithReturn(inst.asMethodType(),
+                                                            ((ForAll)inst.getReturnType()).qtype);
+            subDiag = diags.fragment("partial.inst.sig", diagType);
+        } else if (sym.type.tag == FORALL) {
+            subDiag = diags.fragment("full.inst.sig", inst.asMethodType());
+        }
 
-        names = Names.instance(context);
-        log = Log.instance(context);
-        chk = Check.instance(context);
-        infer = Infer.instance(context);
-        reader = ClassReader.instance(context);
-        treeinfo = TreeInfo.instance(context);
-        types = Types.instance(context);
-        diags = JCDiagnostic.Factory.instance(context);
-        Source source = Source.instance(context);
-        boxingEnabled = source.allowBoxing();
-        varargsEnabled = source.allowVarargs();
-        Options options = Options.instance(context);
-        debugResolve = options.isSet("debugresolve");
-        verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options);
-        Target target = Target.instance(context);
-        allowMethodHandles = target.hasMethodHandles();
-        polymorphicSignatureScope = new Scope(syms.noSymbol);
+        String key = subDiag == null ?
+                "applicable.method.found" :
+                "applicable.method.found.1";
 
-        inapplicableMethodException = new InapplicableMethodException(diags);
+        return diags.fragment(key, pos, sym, subDiag);
     }
 
-    /** error symbols, which are returned when resolution fails
-     */
-    final SymbolNotFoundError varNotFound;
-    final InapplicableSymbolError wrongMethod;
-    final InapplicableSymbolsError wrongMethods;
-    final SymbolNotFoundError methodNotFound;
-    final SymbolNotFoundError typeNotFound;
+    JCDiagnostic getVerboseInapplicableCandidateDiag(int pos, Symbol sym, JCDiagnostic subDiag) {
+        return diags.fragment("not.applicable.method.found", pos, sym, subDiag);
+    }
+    // </editor-fold>
 
 /* ************************************************************************
  * Identifier resolution
@@ -804,17 +874,18 @@
         try {
             Type mt = rawInstantiate(env, site, sym, argtypes, typeargtypes,
                                allowBoxing, useVarargs, Warner.noWarnings);
-            if (!operator) addVerboseApplicableCandidateDiag(sym ,mt);
+            if (!operator)
+                currentResolutionContext.addApplicableCandidate(sym, mt);
         } catch (InapplicableMethodException ex) {
-            if (!operator) addVerboseInapplicableCandidateDiag(sym, ex.getDiagnostic());
+            if (!operator)
+                currentResolutionContext.addInapplicableCandidate(sym, ex.getDiagnostic());
             switch (bestSoFar.kind) {
             case ABSENT_MTH:
-                return wrongMethod.setWrongSym(sym, ex.getDiagnostic());
+                return wrongMethod;
             case WRONG_MTH:
                 if (operator) return bestSoFar;
-                wrongMethods.addCandidate(currentStep, wrongMethod.sym, wrongMethod.explanation);
             case WRONG_MTHS:
-                return wrongMethods.addCandidate(currentStep, sym, ex.getDiagnostic());
+                return wrongMethods;
             default:
                 return bestSoFar;
             }
@@ -823,40 +894,12 @@
             return (bestSoFar.kind == ABSENT_MTH)
                 ? new AccessError(env, site, sym)
                 : bestSoFar;
-            }
+        }
         return (bestSoFar.kind > AMBIGUOUS)
             ? sym
             : mostSpecific(sym, bestSoFar, env, site,
                            allowBoxing && operator, useVarargs);
     }
-    //where
-        void addVerboseApplicableCandidateDiag(Symbol sym, Type inst) {
-            if (!verboseResolutionMode.contains(VerboseResolutionMode.APPLICABLE))
-                return;
-
-            JCDiagnostic subDiag = null;
-            if (inst.getReturnType().tag == FORALL) {
-                Type diagType = types.createMethodTypeWithReturn(inst.asMethodType(),
-                                                                ((ForAll)inst.getReturnType()).qtype);
-                subDiag = diags.fragment("partial.inst.sig", diagType);
-            } else if (sym.type.tag == FORALL) {
-                subDiag = diags.fragment("full.inst.sig", inst.asMethodType());
-            }
-
-            String key = subDiag == null ?
-                    "applicable.method.found" :
-                    "applicable.method.found.1";
-
-            verboseResolutionCandidateDiags.put(sym,
-                    diags.fragment(key, verboseResolutionCandidateDiags.size(), sym, subDiag));
-        }
-
-        void addVerboseInapplicableCandidateDiag(Symbol sym, JCDiagnostic subDiag) {
-            if (!verboseResolutionMode.contains(VerboseResolutionMode.INAPPLICABLE))
-                return;
-            verboseResolutionCandidateDiags.put(sym,
-                    diags.fragment("not.applicable.method.found", verboseResolutionCandidateDiags.size(), sym, subDiag));
-        }
 
     /* Return the most specific of the two methods for a call,
      *  given that both are accessible and applicable.
@@ -1054,7 +1097,6 @@
                       boolean allowBoxing,
                       boolean useVarargs,
                       boolean operator) {
-        verboseResolutionCandidateDiags.clear();
         Symbol bestSoFar = methodNotFound;
         bestSoFar = findMethod(env,
                           site,
@@ -1127,37 +1169,6 @@
         }
         return bestSoFar;
     }
-    //where
-        void reportVerboseResolutionDiagnostic(DiagnosticPosition dpos, Name name, Type site, List<Type> argtypes, List<Type> typeargtypes, Symbol bestSoFar) {
-            boolean success = bestSoFar.kind < ERRONEOUS;
-
-            if (success && !verboseResolutionMode.contains(VerboseResolutionMode.SUCCESS)) {
-                return;
-            } else if (!success && !verboseResolutionMode.contains(VerboseResolutionMode.FAILURE)) {
-                return;
-            }
-
-            if (bestSoFar.name == names.init &&
-                    bestSoFar.owner == syms.objectType.tsym &&
-                    !verboseResolutionMode.contains(VerboseResolutionMode.OBJECT_INIT)) {
-                return; //skip diags for Object constructor resolution
-            } else if (site == syms.predefClass.type && !verboseResolutionMode.contains(VerboseResolutionMode.PREDEF)) {
-                return; //skip spurious diags for predef symbols (i.e. operators)
-            } else if (internalResolution && !verboseResolutionMode.contains(VerboseResolutionMode.INTERNAL)) {
-                return;
-            }
-
-            int pos = 0;
-            for (Symbol s : verboseResolutionCandidateDiags.keySet()) {
-                if (s == bestSoFar) break;
-                pos++;
-            }
-            String key = success ? "verbose.resolve.multi" : "verbose.resolve.multi.1";
-            JCDiagnostic main = diags.note(log.currentSource(), dpos, key, name, site.tsym, pos, currentStep,
-                    methodArguments(argtypes), methodArguments(typeargtypes));
-            JCDiagnostic d = new JCDiagnostic.MultilineDiagnostic(main, List.from(verboseResolutionCandidateDiags.values().toArray(new JCDiagnostic[verboseResolutionCandidateDiags.size()])));
-            log.report(d);
-        }
 
     /** Find unqualified method matching given name, type and value arguments.
      *  @param env       The current environment.
@@ -1591,32 +1602,33 @@
                          Name name,
                          List<Type> argtypes,
                          List<Type> typeargtypes) {
-        Symbol sym = startResolution();
-        List<MethodResolutionPhase> steps = methodResolutionSteps;
-        while (steps.nonEmpty() &&
-               steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
-               sym.kind >= ERRONEOUS) {
-            currentStep = steps.head;
-            sym = findFun(env, name, argtypes, typeargtypes,
-                    steps.head.isBoxingRequired,
-                    env.info.varArgs = steps.head.isVarargsRequired);
-            methodResolutionCache.put(steps.head, sym);
-            steps = steps.tail;
+        MethodResolutionContext prevResolutionContext = currentResolutionContext;
+        try {
+            currentResolutionContext = new MethodResolutionContext();
+            Symbol sym = methodNotFound;
+            List<MethodResolutionPhase> steps = methodResolutionSteps;
+            while (steps.nonEmpty() &&
+                   steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
+                   sym.kind >= ERRONEOUS) {
+                currentResolutionContext.step = steps.head;
+                sym = findFun(env, name, argtypes, typeargtypes,
+                        steps.head.isBoxingRequired,
+                        env.info.varArgs = steps.head.isVarargsRequired);
+                currentResolutionContext.resolutionCache.put(steps.head, sym);
+                steps = steps.tail;
+            }
+            if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error
+                MethodResolutionPhase errPhase =
+                        currentResolutionContext.firstErroneousResolutionPhase();
+                sym = access(currentResolutionContext.resolutionCache.get(errPhase),
+                        pos, env.enclClass.sym.type, name, false, argtypes, typeargtypes);
+                env.info.varArgs = errPhase.isVarargsRequired;
+            }
+            return sym;
         }
-        if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error
-            MethodResolutionPhase errPhase =
-                    firstErroneousResolutionPhase();
-            sym = access(methodResolutionCache.get(errPhase),
-                    pos, env.enclClass.sym.type, name, false, argtypes, typeargtypes);
-            env.info.varArgs = errPhase.isVarargsRequired;
+        finally {
+            currentResolutionContext = prevResolutionContext;
         }
-        return sym;
-    }
-
-    private Symbol startResolution() {
-        wrongMethod.clear();
-        wrongMethods.clear();
-        return methodNotFound;
     }
 
     /** Resolve a qualified method identifier
@@ -1636,40 +1648,53 @@
     Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env,
                                   Symbol location, Type site, Name name, List<Type> argtypes,
                                   List<Type> typeargtypes) {
-        Symbol sym = startResolution();
-        List<MethodResolutionPhase> steps = methodResolutionSteps;
-        while (steps.nonEmpty() &&
-               steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
-               sym.kind >= ERRONEOUS) {
-            currentStep = steps.head;
-            sym = findMethod(env, site, name, argtypes, typeargtypes,
-                    steps.head.isBoxingRequired(),
-                    env.info.varArgs = steps.head.isVarargsRequired(), false);
-            methodResolutionCache.put(steps.head, sym);
-            steps = steps.tail;
-        }
-        if (sym.kind >= AMBIGUOUS) {
-            if (site.tsym.isPolymorphicSignatureGeneric()) {
-                //polymorphic receiver - synthesize new method symbol
+        return resolveQualifiedMethod(new MethodResolutionContext(), pos, env, location, site, name, argtypes, typeargtypes);
+    }
+    private Symbol resolveQualifiedMethod(MethodResolutionContext resolveContext,
+                                  DiagnosticPosition pos, Env<AttrContext> env,
+                                  Symbol location, Type site, Name name, List<Type> argtypes,
+                                  List<Type> typeargtypes) {
+        MethodResolutionContext prevResolutionContext = currentResolutionContext;
+        try {
+            currentResolutionContext = resolveContext;
+            Symbol sym = methodNotFound;
+            List<MethodResolutionPhase> steps = methodResolutionSteps;
+            while (steps.nonEmpty() &&
+                   steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
+                   sym.kind >= ERRONEOUS) {
+                currentResolutionContext.step = steps.head;
+                sym = findMethod(env, site, name, argtypes, typeargtypes,
+                        steps.head.isBoxingRequired(),
+                        env.info.varArgs = steps.head.isVarargsRequired(), false);
+                currentResolutionContext.resolutionCache.put(steps.head, sym);
+                steps = steps.tail;
+            }
+            if (sym.kind >= AMBIGUOUS) {
+                if (site.tsym.isPolymorphicSignatureGeneric()) {
+                    //polymorphic receiver - synthesize new method symbol
+                    env.info.varArgs = false;
+                    sym = findPolymorphicSignatureInstance(env,
+                            site, name, null, argtypes);
+                }
+                else {
+                    //if nothing is found return the 'first' error
+                    MethodResolutionPhase errPhase =
+                            currentResolutionContext.firstErroneousResolutionPhase();
+                    sym = access(currentResolutionContext.resolutionCache.get(errPhase),
+                            pos, location, site, name, true, argtypes, typeargtypes);
+                    env.info.varArgs = errPhase.isVarargsRequired;
+                }
+            } else if (allowMethodHandles && sym.isPolymorphicSignatureGeneric()) {
+                //non-instantiated polymorphic signature - synthesize new method symbol
                 env.info.varArgs = false;
                 sym = findPolymorphicSignatureInstance(env,
-                        site, name, null, argtypes);
+                        site, name, (MethodSymbol)sym, argtypes);
             }
-            else {
-                //if nothing is found return the 'first' error
-                MethodResolutionPhase errPhase =
-                        firstErroneousResolutionPhase();
-                sym = access(methodResolutionCache.get(errPhase),
-                        pos, location, site, name, true, argtypes, typeargtypes);
-                env.info.varArgs = errPhase.isVarargsRequired;
-            }
-        } else if (allowMethodHandles && sym.isPolymorphicSignatureGeneric()) {
-            //non-instantiated polymorphic signature - synthesize new method symbol
-            env.info.varArgs = false;
-            sym = findPolymorphicSignatureInstance(env,
-                    site, name, (MethodSymbol)sym, argtypes);
+            return sym;
         }
-        return sym;
+        finally {
+            currentResolutionContext = prevResolutionContext;
+        }
     }
 
     /** Find or create an implicit method of exactly the given type (after erasure).
@@ -1726,19 +1751,14 @@
                                         Type site, Name name,
                                         List<Type> argtypes,
                                         List<Type> typeargtypes) {
-        boolean prevInternal = internalResolution;
-        try {
-            internalResolution = true;
-            Symbol sym = resolveQualifiedMethod(
-                pos, env, site.tsym, site, name, argtypes, typeargtypes);
-            if (sym.kind == MTH) return (MethodSymbol)sym;
-            else throw new FatalError(
-                     diags.fragment("fatal.err.cant.locate.meth",
-                                    name));
-        }
-        finally {
-            internalResolution = prevInternal;
-        }
+        MethodResolutionContext resolveContext = new MethodResolutionContext();
+        resolveContext.internalResolution = true;
+        Symbol sym = resolveQualifiedMethod(resolveContext, pos, env, site.tsym,
+                site, name, argtypes, typeargtypes);
+        if (sym.kind == MTH) return (MethodSymbol)sym;
+        else throw new FatalError(
+                 diags.fragment("fatal.err.cant.locate.meth",
+                                name));
     }
 
     /** Resolve constructor.
@@ -1755,25 +1775,40 @@
                               Type site,
                               List<Type> argtypes,
                               List<Type> typeargtypes) {
-        Symbol sym = startResolution();
-        List<MethodResolutionPhase> steps = methodResolutionSteps;
-        while (steps.nonEmpty() &&
-               steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
-               sym.kind >= ERRONEOUS) {
-            currentStep = steps.head;
-            sym = resolveConstructor(pos, env, site, argtypes, typeargtypes,
-                    steps.head.isBoxingRequired(),
-                    env.info.varArgs = steps.head.isVarargsRequired());
-            methodResolutionCache.put(steps.head, sym);
-            steps = steps.tail;
+        return resolveConstructor(new MethodResolutionContext(), pos, env, site, argtypes, typeargtypes);
+    }
+    private Symbol resolveConstructor(MethodResolutionContext resolveContext,
+                              DiagnosticPosition pos,
+                              Env<AttrContext> env,
+                              Type site,
+                              List<Type> argtypes,
+                              List<Type> typeargtypes) {
+        MethodResolutionContext prevResolutionContext = currentResolutionContext;
+        try {
+            currentResolutionContext = resolveContext;
+            Symbol sym = methodNotFound;
+            List<MethodResolutionPhase> steps = methodResolutionSteps;
+            while (steps.nonEmpty() &&
+                   steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
+                   sym.kind >= ERRONEOUS) {
+                currentResolutionContext.step = steps.head;
+                sym = findConstructor(pos, env, site, argtypes, typeargtypes,
+                        steps.head.isBoxingRequired(),
+                        env.info.varArgs = steps.head.isVarargsRequired());
+                currentResolutionContext.resolutionCache.put(steps.head, sym);
+                steps = steps.tail;
+            }
+            if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error
+                MethodResolutionPhase errPhase = currentResolutionContext.firstErroneousResolutionPhase();
+                sym = access(currentResolutionContext.resolutionCache.get(errPhase),
+                        pos, site, names.init, true, argtypes, typeargtypes);
+                env.info.varArgs = errPhase.isVarargsRequired();
+            }
+            return sym;
         }
-        if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error
-            MethodResolutionPhase errPhase = firstErroneousResolutionPhase();
-            sym = access(methodResolutionCache.get(errPhase),
-                    pos, site, names.init, true, argtypes, typeargtypes);
-            env.info.varArgs = errPhase.isVarargsRequired();
+        finally {
+            currentResolutionContext = prevResolutionContext;
         }
-        return sym;
     }
 
     /** Resolve constructor using diamond inference.
@@ -1791,38 +1826,82 @@
                               Type site,
                               List<Type> argtypes,
                               List<Type> typeargtypes) {
-        Symbol sym = startResolution();
-        List<MethodResolutionPhase> steps = methodResolutionSteps;
-        while (steps.nonEmpty() &&
-               steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
-               sym.kind >= ERRONEOUS) {
-            currentStep = steps.head;
-            sym = resolveConstructor(pos, env, site, argtypes, typeargtypes,
-                    steps.head.isBoxingRequired(),
-                    env.info.varArgs = steps.head.isVarargsRequired());
-            methodResolutionCache.put(steps.head, sym);
-            steps = steps.tail;
+        MethodResolutionContext prevResolutionContext = currentResolutionContext;
+        try {
+            currentResolutionContext = new MethodResolutionContext();
+            Symbol sym = methodNotFound;
+            List<MethodResolutionPhase> steps = methodResolutionSteps;
+            while (steps.nonEmpty() &&
+                   steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
+                   sym.kind >= ERRONEOUS) {
+                currentResolutionContext.step = steps.head;
+                sym = findDiamond(env, site, argtypes, typeargtypes,
+                        steps.head.isBoxingRequired(),
+                        env.info.varArgs = steps.head.isVarargsRequired());
+                currentResolutionContext.resolutionCache.put(steps.head, sym);
+                steps = steps.tail;
+            }
+            if (sym.kind >= AMBIGUOUS) {
+                final JCDiagnostic details = sym.kind == WRONG_MTH ?
+                                currentResolutionContext.candidates.head.details :
+                                null;
+                Symbol errSym = new ResolveError(WRONG_MTH, "diamond error") {
+                    @Override
+                    JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos,
+                            Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
+                        String key = details == null ?
+                            "cant.apply.diamond" :
+                            "cant.apply.diamond.1";
+                        return diags.create(dkind, log.currentSource(), pos, key,
+                                diags.fragment("diamond", site.tsym), details);
+                    }
+                };
+                MethodResolutionPhase errPhase = currentResolutionContext.firstErroneousResolutionPhase();
+                sym = access(errSym, pos, site, names.init, true, argtypes, typeargtypes);
+                env.info.varArgs = errPhase.isVarargsRequired();
+            }
+            return sym;
         }
-        if (sym.kind >= AMBIGUOUS) {
-            final JCDiagnostic details = sym.kind == WRONG_MTH ?
-                ((InapplicableSymbolError)sym).explanation :
-                null;
-            Symbol errSym = new ResolveError(WRONG_MTH, "diamond error") {
-                @Override
-                JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos,
-                        Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
-                    String key = details == null ?
-                        "cant.apply.diamond" :
-                        "cant.apply.diamond.1";
-                    return diags.create(dkind, log.currentSource(), pos, key,
-                            diags.fragment("diamond", site.tsym), details);
-                }
-            };
-            MethodResolutionPhase errPhase = firstErroneousResolutionPhase();
-            sym = access(errSym, pos, site, names.init, true, argtypes, typeargtypes);
-            env.info.varArgs = errPhase.isVarargsRequired();
+        finally {
+            currentResolutionContext = prevResolutionContext;
         }
-        return sym;
+    }
+
+    /** This method scans all the constructor symbol in a given class scope -
+     *  assuming that the original scope contains a constructor of the kind:
+     *  Foo(X x, Y y), where X,Y are class type-variables declared in Foo,
+     *  a method check is executed against the modified constructor type:
+     *  <X,Y>Foo<X,Y>(X x, Y y). This is crucial in order to enable diamond
+     *  inference. The inferred return type of the synthetic constructor IS
+     *  the inferred type for the diamond operator.
+     */
+    private Symbol findDiamond(Env<AttrContext> env,
+                              Type site,
+                              List<Type> argtypes,
+                              List<Type> typeargtypes,
+                              boolean allowBoxing,
+                              boolean useVarargs) {
+        Symbol bestSoFar = methodNotFound;
+        for (Scope.Entry e = site.tsym.members().lookup(names.init);
+             e.scope != null;
+             e = e.next()) {
+            //- System.out.println(" e " + e.sym);
+            if (e.sym.kind == MTH &&
+                (e.sym.flags_field & SYNTHETIC) == 0) {
+                    List<Type> oldParams = e.sym.type.tag == FORALL ?
+                            ((ForAll)e.sym.type).tvars :
+                            List.<Type>nil();
+                    Type constrType = new ForAll(site.tsym.type.getTypeArguments().appendList(oldParams),
+                            types.createMethodTypeWithReturn(e.sym.type.asMethodType(), site));
+                    bestSoFar = selectBest(env, site, argtypes, typeargtypes,
+                            new MethodSymbol(e.sym.flags(), names.init, constrType, site.tsym),
+                            bestSoFar,
+                            allowBoxing,
+                            useVarargs,
+                            false);
+            }
+        }
+        return bestSoFar;
     }
 
     /** Resolve constructor.
@@ -1841,10 +1920,25 @@
                               List<Type> typeargtypes,
                               boolean allowBoxing,
                               boolean useVarargs) {
+        MethodResolutionContext prevResolutionContext = currentResolutionContext;
+        try {
+            currentResolutionContext = new MethodResolutionContext();
+            return findConstructor(pos, env, site, argtypes, typeargtypes, allowBoxing, useVarargs);
+        }
+        finally {
+            currentResolutionContext = prevResolutionContext;
+        }
+    }
+
+    Symbol findConstructor(DiagnosticPosition pos, Env<AttrContext> env,
+                              Type site, List<Type> argtypes,
+                              List<Type> typeargtypes,
+                              boolean allowBoxing,
+                              boolean useVarargs) {
         Symbol sym = findMethod(env, site,
-                                names.init, argtypes,
-                                typeargtypes, allowBoxing,
-                                useVarargs, false);
+                                    names.init, argtypes,
+                                    typeargtypes, allowBoxing,
+                                    useVarargs, false);
         chk.checkDeprecated(pos, env.info.scope.owner, sym);
         return sym;
     }
@@ -1860,8 +1954,9 @@
                                         Type site,
                                         List<Type> argtypes,
                                         List<Type> typeargtypes) {
-        Symbol sym = resolveConstructor(
-            pos, env, site, argtypes, typeargtypes);
+        MethodResolutionContext resolveContext = new MethodResolutionContext();
+        resolveContext.internalResolution = true;
+        Symbol sym = resolveConstructor(resolveContext, pos, env, site, argtypes, typeargtypes);
         if (sym.kind == MTH) return (MethodSymbol)sym;
         else throw new FatalError(
                  diags.fragment("fatal.err.cant.locate.ctor", site));
@@ -1875,15 +1970,21 @@
      */
     Symbol resolveOperator(DiagnosticPosition pos, JCTree.Tag optag,
                            Env<AttrContext> env, List<Type> argtypes) {
-        startResolution();
-        Name name = treeinfo.operatorName(optag);
-        Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes,
-                                null, false, false, true);
-        if (boxingEnabled && sym.kind >= WRONG_MTHS)
-            sym = findMethod(env, syms.predefClass.type, name, argtypes,
-                             null, true, false, true);
-        return access(sym, pos, env.enclClass.sym.type, name,
-                      false, argtypes, null);
+        MethodResolutionContext prevResolutionContext = currentResolutionContext;
+        try {
+            currentResolutionContext = new MethodResolutionContext();
+            Name name = treeinfo.operatorName(optag);
+            Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes,
+                                    null, false, false, true);
+            if (boxingEnabled && sym.kind >= WRONG_MTHS)
+                sym = findMethod(env, syms.predefClass.type, name, argtypes,
+                                 null, true, false, true);
+            return access(sym, pos, env.enclClass.sym.type, name,
+                          false, argtypes, null);
+        }
+        finally {
+            currentResolutionContext = prevResolutionContext;
+        }
     }
 
     /** Resolve operator.
@@ -1996,9 +2097,10 @@
  *  ResolveError classes, indicating error situations when accessing symbols
  ****************************************************************************/
 
-    public void logAccessError(Env<AttrContext> env, JCTree tree, Type type) {
-        AccessError error = new AccessError(env, type.getEnclosingType(), type.tsym);
-        logResolveError(error, tree.pos(), type.getEnclosingType().tsym, type.getEnclosingType(), null, null, null);
+    //used by TransTypes when checking target type of synthetic cast
+    public void logAccessErrorInternal(Env<AttrContext> env, JCTree tree, Type type) {
+        AccessError error = new AccessError(env, env.enclClass.type, type.tsym);
+        logResolveError(error, tree.pos(), env.enclClass.sym, env.enclClass.type, null, null, null);
     }
     //where
     private void logResolveError(ResolveError error,
@@ -2227,34 +2329,24 @@
      * (either a method, a constructor or an operand) is not applicable
      * given an actual arguments/type argument list.
      */
-    class InapplicableSymbolError extends InvalidSymbolError {
+    class InapplicableSymbolError extends ResolveError {
 
-        /** An auxiliary explanation set in case of instantiation errors. */
-        JCDiagnostic explanation;
-
-        InapplicableSymbolError(Symbol sym) {
-            super(WRONG_MTH, sym, "inapplicable symbol error");
+        InapplicableSymbolError() {
+            super(WRONG_MTH, "inapplicable symbol error");
         }
 
-        /** Update sym and explanation and return this.
-         */
-        InapplicableSymbolError setWrongSym(Symbol sym, JCDiagnostic explanation) {
-            this.sym = sym;
-            if (this.sym == sym && explanation != null)
-                this.explanation = explanation; //update the details
-            return this;
-        }
-
-        /** Update sym and return this.
-         */
-        InapplicableSymbolError setWrongSym(Symbol sym) {
-            this.sym = sym;
-            return this;
+        protected InapplicableSymbolError(int kind, String debugName) {
+            super(kind, debugName);
         }
 
         @Override
         public String toString() {
-            return super.toString() + " explanation=" + explanation;
+            return super.toString();
+        }
+
+        @Override
+        public boolean exists() {
+            return true;
         }
 
         @Override
@@ -2279,27 +2371,40 @@
                         key, name, first, second);
             }
             else {
-                Symbol ws = sym.asMemberOf(site, types);
+                Candidate c = errCandidate();
+                Symbol ws = c.sym.asMemberOf(site, types);
                 return diags.create(dkind, log.currentSource(), pos,
-                          "cant.apply.symbol" + (explanation != null ? ".1" : ""),
+                          "cant.apply.symbol" + (c.details != null ? ".1" : ""),
                           kindName(ws),
                           ws.name == names.init ? ws.owner.name : ws.name,
                           methodArguments(ws.type.getParameterTypes()),
                           methodArguments(argtypes),
                           kindName(ws.owner),
                           ws.owner.type,
-                          explanation);
+                          c.details);
             }
         }
 
-        void clear() {
-            explanation = null;
-        }
-
         @Override
         public Symbol access(Name name, TypeSymbol location) {
             return types.createErrorType(name, location, syms.errSymbol.type).tsym;
         }
+
+        protected boolean shouldReport(Candidate c) {
+            return !c.isApplicable() &&
+                    (((c.sym.flags() & VARARGS) != 0 && c.step == VARARITY) ||
+                      (c.sym.flags() & VARARGS) == 0 && c.step == (boxingEnabled ? BOX : BASIC));
+        }
+
+        private Candidate errCandidate() {
+            for (Candidate c : currentResolutionContext.candidates) {
+                if (shouldReport(c)) {
+                    return c;
+                }
+            }
+            Assert.error();
+            return null;
+        }
     }
 
     /**
@@ -2307,11 +2412,9 @@
      * (either methods, constructors or operands) is not applicable
      * given an actual arguments/type argument list.
      */
-    class InapplicableSymbolsError extends ResolveError {
+    class InapplicableSymbolsError extends InapplicableSymbolError {
 
-        private List<Candidate> candidates = List.nil();
-
-        InapplicableSymbolsError(Symbol sym) {
+        InapplicableSymbolsError() {
             super(WRONG_MTHS, "inapplicable symbols");
         }
 
@@ -2323,7 +2426,7 @@
                 Name name,
                 List<Type> argtypes,
                 List<Type> typeargtypes) {
-            if (candidates.nonEmpty()) {
+            if (currentResolutionContext.candidates.nonEmpty()) {
                 JCDiagnostic err = diags.create(dkind,
                         log.currentSource(),
                         pos,
@@ -2341,68 +2444,24 @@
         //where
         List<JCDiagnostic> candidateDetails(Type site) {
             List<JCDiagnostic> details = List.nil();
-            for (Candidate c : candidates)
-                details = details.prepend(c.getDiagnostic(site));
+            for (Candidate c : currentResolutionContext.candidates) {
+                if (!shouldReport(c)) continue;
+                JCDiagnostic detailDiag = diags.fragment("inapplicable.method",
+                        Kinds.kindName(c.sym),
+                        c.sym.location(site, types),
+                        c.sym.asMemberOf(site, types),
+                        c.details);
+                details = details.prepend(detailDiag);
+            }
             return details.reverse();
         }
 
-        Symbol addCandidate(MethodResolutionPhase currentStep, Symbol sym, JCDiagnostic details) {
-            Candidate c = new Candidate(currentStep, sym, details);
-            if (c.isValid() && !candidates.contains(c))
-                candidates = candidates.append(c);
-            return this;
-        }
-
-        void clear() {
-            candidates = List.nil();
-        }
-
         private Name getName() {
-            Symbol sym = candidates.head.sym;
+            Symbol sym = currentResolutionContext.candidates.head.sym;
             return sym.name == names.init ?
                 sym.owner.name :
                 sym.name;
         }
-
-        private class Candidate {
-
-            final MethodResolutionPhase step;
-            final Symbol sym;
-            final JCDiagnostic details;
-
-            private Candidate(MethodResolutionPhase step, Symbol sym, JCDiagnostic details) {
-                this.step = step;
-                this.sym = sym;
-                this.details = details;
-            }
-
-            JCDiagnostic getDiagnostic(Type site) {
-                return diags.fragment("inapplicable.method",
-                        Kinds.kindName(sym),
-                        sym.location(site, types),
-                        sym.asMemberOf(site, types),
-                        details);
-            }
-
-            @Override
-            public boolean equals(Object o) {
-                if (o instanceof Candidate) {
-                    Symbol s1 = this.sym;
-                    Symbol s2 = ((Candidate)o).sym;
-                    if  ((s1 != s2 &&
-                        (s1.overrides(s2, s1.owner.type.tsym, types, false) ||
-                        (s2.overrides(s1, s2.owner.type.tsym, types, false)))) ||
-                        ((s1.isConstructor() || s2.isConstructor()) && s1.owner != s2.owner))
-                        return true;
-                }
-                return false;
-            }
-
-            boolean isValid() {
-                return  (((sym.flags() & VARARGS) != 0 && step == VARARITY) ||
-                          (sym.flags() & VARARGS) == 0 && step == (boxingEnabled ? BOX : BASIC));
-            }
-        }
     }
 
     /**
@@ -2563,29 +2622,91 @@
         }
     }
 
-    private Map<MethodResolutionPhase, Symbol> methodResolutionCache =
-        new HashMap<MethodResolutionPhase, Symbol>(MethodResolutionPhase.values().length);
-
-    private Map<Symbol, JCDiagnostic> verboseResolutionCandidateDiags =
-        new LinkedHashMap<Symbol, JCDiagnostic>();
-
     final List<MethodResolutionPhase> methodResolutionSteps = List.of(BASIC, BOX, VARARITY);
 
-    private MethodResolutionPhase currentStep = null;
+    /**
+     * A resolution context is used to keep track of intermediate results of
+     * overload resolution, such as list of method that are not applicable
+     * (used to generate more precise diagnostics) and so on. Resolution contexts
+     * can be nested - this means that when each overload resolution routine should
+     * work within the resolution context it created.
+     */
+    class MethodResolutionContext {
+
+        private List<Candidate> candidates = List.nil();
+
+        private Map<MethodResolutionPhase, Symbol> resolutionCache =
+            new EnumMap<MethodResolutionPhase, Symbol>(MethodResolutionPhase.class);
+
+        private MethodResolutionPhase step = null;
+
+        private boolean internalResolution = false;
 
-    private boolean internalResolution = false;
+        private MethodResolutionPhase firstErroneousResolutionPhase() {
+            MethodResolutionPhase bestSoFar = BASIC;
+            Symbol sym = methodNotFound;
+            List<MethodResolutionPhase> steps = methodResolutionSteps;
+            while (steps.nonEmpty() &&
+                   steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
+                   sym.kind >= WRONG_MTHS) {
+                sym = resolutionCache.get(steps.head);
+                bestSoFar = steps.head;
+                steps = steps.tail;
+            }
+            return bestSoFar;
+        }
+
+        void addInapplicableCandidate(Symbol sym, JCDiagnostic details) {
+            Candidate c = new Candidate(currentResolutionContext.step, sym, details, null);
+            if (!candidates.contains(c))
+                candidates = candidates.append(c);
+        }
+
+        void addApplicableCandidate(Symbol sym, Type mtype) {
+            Candidate c = new Candidate(currentResolutionContext.step, sym, null, mtype);
+            candidates = candidates.append(c);
+        }
 
-    private MethodResolutionPhase firstErroneousResolutionPhase() {
-        MethodResolutionPhase bestSoFar = BASIC;
-        Symbol sym = methodNotFound;
-        List<MethodResolutionPhase> steps = methodResolutionSteps;
-        while (steps.nonEmpty() &&
-               steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
-               sym.kind >= WRONG_MTHS) {
-            sym = methodResolutionCache.get(steps.head);
-            bestSoFar = steps.head;
-            steps = steps.tail;
+        /**
+         * This class represents an overload resolution candidate. There are two
+         * kinds of candidates: applicable methods and inapplicable methods;
+         * applicable methods have a pointer to the instantiated method type,
+         * while inapplicable candidates contain further details about the
+         * reason why the method has been considered inapplicable.
+         */
+        class Candidate {
+
+            final MethodResolutionPhase step;
+            final Symbol sym;
+            final JCDiagnostic details;
+            final Type mtype;
+
+            private Candidate(MethodResolutionPhase step, Symbol sym, JCDiagnostic details, Type mtype) {
+                this.step = step;
+                this.sym = sym;
+                this.details = details;
+                this.mtype = mtype;
+            }
+
+            @Override
+            public boolean equals(Object o) {
+                if (o instanceof Candidate) {
+                    Symbol s1 = this.sym;
+                    Symbol s2 = ((Candidate)o).sym;
+                    if  ((s1 != s2 &&
+                        (s1.overrides(s2, s1.owner.type.tsym, types, false) ||
+                        (s2.overrides(s1, s2.owner.type.tsym, types, false)))) ||
+                        ((s1.isConstructor() || s2.isConstructor()) && s1.owner != s2.owner))
+                        return true;
+                }
+                return false;
+            }
+
+            boolean isApplicable() {
+                return mtype != null;
+            }
         }
-        return bestSoFar;
     }
+
+    MethodResolutionContext currentResolutionContext = null;
 }
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java	Fri Mar 30 16:57:50 2012 -0700
@@ -107,7 +107,7 @@
         make.at(tree.pos);
         if (!types.isSameType(tree.type, target)) {
             if (!resolve.isAccessible(env, target.tsym))
-                resolve.logAccessError(env, tree, target);
+                resolve.logAccessErrorInternal(env, tree, target);
             tree = make.TypeCast(make.Type(target), tree).setType(target);
         }
         make.pos = oldpos;
--- a/langtools/src/share/classes/com/sun/tools/javac/file/Locations.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/file/Locations.java	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -648,7 +648,8 @@
             new SimpleLocationHandler(StandardLocation.SOURCE_PATH, Option.SOURCEPATH),
             new SimpleLocationHandler(StandardLocation.ANNOTATION_PROCESSOR_PATH, Option.PROCESSORPATH),
             new OutputLocationHandler((StandardLocation.CLASS_OUTPUT), Option.D),
-            new OutputLocationHandler((StandardLocation.SOURCE_OUTPUT), Option.S)
+            new OutputLocationHandler((StandardLocation.SOURCE_OUTPUT), Option.S),
+            new OutputLocationHandler((StandardLocation.NATIVE_HEADER_OUTPUT), Option.H)
         };
 
         for (LocationHandler h: handlers) {
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -69,11 +69,11 @@
      */
     private boolean verbose;
 
-    /** Switch: scrable private names.
+    /** Switch: scramble private names.
      */
     private boolean scramble;
 
-    /** Switch: scrable private names.
+    /** Switch: scramble private names.
      */
     private boolean scrambleAll;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java	Fri Mar 30 16:57:50 2012 -0700
@@ -0,0 +1,856 @@
+/*
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.javac.jvm;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+import java.util.StringTokenizer;
+
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.Name;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.ArrayType;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.NoType;
+import javax.lang.model.type.PrimitiveType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.TypeVariable;
+import javax.lang.model.type.TypeVisitor;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.SimpleTypeVisitor8;
+import javax.lang.model.util.Types;
+
+import javax.tools.FileObject;
+import javax.tools.JavaFileManager;
+import javax.tools.StandardLocation;
+
+import com.sun.tools.javac.code.Attribute;
+import com.sun.tools.javac.code.Flags;
+import com.sun.tools.javac.code.Kinds;
+import com.sun.tools.javac.code.Scope;
+import com.sun.tools.javac.code.Symbol.ClassSymbol;
+import com.sun.tools.javac.code.Symtab;
+import com.sun.tools.javac.model.JavacElements;
+import com.sun.tools.javac.model.JavacTypes;
+import com.sun.tools.javac.util.Assert;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.Log;
+import com.sun.tools.javac.util.Options;
+
+import static com.sun.tools.javac.main.Option.*;
+
+/** This class provides operations to write native header files for classes.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+public class JNIWriter {
+    protected static final Context.Key<JNIWriter> jniWriterKey =
+        new Context.Key<JNIWriter>();
+
+    /** Access to files. */
+    private final JavaFileManager fileManager;
+
+    JavacElements elements;
+    JavacTypes types;
+
+    /** The log to use for verbose output.
+     */
+    private final Log log;
+
+    /** Switch: verbose output.
+     */
+    private boolean verbose;
+
+    /** Switch: check all nested classes of top level class
+     */
+    private boolean checkAll;
+
+    private Mangle mangler;
+
+    private Context context;
+
+    private Symtab syms;
+
+    private String lineSep;
+
+    private final boolean isWindows =
+        System.getProperty("os.name").startsWith("Windows");
+
+    /** Get the ClassWriter instance for this context. */
+    public static JNIWriter instance(Context context) {
+        JNIWriter instance = context.get(jniWriterKey);
+        if (instance == null)
+            instance = new JNIWriter(context);
+        return instance;
+    }
+
+    /** Construct a class writer, given an options table.
+     */
+    private JNIWriter(Context context) {
+        context.put(jniWriterKey, this);
+        fileManager = context.get(JavaFileManager.class);
+        log = Log.instance(context);
+
+        Options options = Options.instance(context);
+        verbose = options.isSet(VERBOSE);
+        checkAll = options.isSet("javah:full");
+
+        this.context = context; // for lazyInit()
+        syms = Symtab.instance(context);
+
+        lineSep = System.getProperty("line.separator");
+    }
+
+    private void lazyInit() {
+        if (mangler == null) {
+            elements = JavacElements.instance(context);
+            types = JavacTypes.instance(context);
+            mangler = new Mangle(elements, types);
+        }
+    }
+
+    public boolean needsHeader(ClassSymbol c) {
+        if (c.isLocal() || (c.flags() & Flags.SYNTHETIC) != 0)
+            return false;
+
+        if (checkAll)
+            return needsHeader(c.outermostClass(), true);
+        else
+            return needsHeader(c, false);
+    }
+
+    private boolean needsHeader(ClassSymbol c, boolean checkNestedClasses) {
+        if (c.isLocal() || (c.flags() & Flags.SYNTHETIC) != 0)
+            return false;
+
+        for (Attribute.Compound a: c.attributes_field) {
+            if (a.type.tsym == syms.nativeHeaderType.tsym)
+                return true;
+        }
+        for (Scope.Entry i = c.members_field.elems; i != null; i = i.sibling) {
+            if (i.sym.kind == Kinds.MTH && (i.sym.flags() & Flags.NATIVE) != 0)
+                return true;
+        }
+        if (checkNestedClasses) {
+            for (Scope.Entry i = c.members_field.elems; i != null; i = i.sibling) {
+                if ((i.sym.kind == Kinds.TYP) && needsHeader(((ClassSymbol) i.sym), true))
+                    return true;
+            }
+        }
+        return false;
+    }
+
+    /** Emit a class file for a given class.
+     *  @param c      The class from which a class file is generated.
+     */
+    public FileObject write(ClassSymbol c)
+        throws IOException
+    {
+        String className = c.flatName().toString();
+        FileObject outFile
+            = fileManager.getFileForOutput(StandardLocation.NATIVE_HEADER_OUTPUT,
+                "", className.replaceAll("[.$]", "_") + ".h", null);
+        Writer out = outFile.openWriter();
+        try {
+            write(out, c);
+            if (verbose)
+                log.printVerbose("wrote.file", outFile);
+            out.close();
+            out = null;
+        } finally {
+            if (out != null) {
+                // if we are propogating an exception, delete the file
+                out.close();
+                outFile.delete();
+                outFile = null;
+            }
+        }
+        return outFile; // may be null if write failed
+    }
+
+    public void write(Writer out, ClassSymbol sym)
+            throws IOException {
+        lazyInit();
+        try {
+            String cname = mangler.mangle(sym.fullname, Mangle.Type.CLASS);
+            println(out, fileTop());
+            println(out, includes());
+            println(out, guardBegin(cname));
+            println(out, cppGuardBegin());
+
+            writeStatics(out, sym);
+            writeMethods(out, sym, cname);
+
+            println(out, cppGuardEnd());
+            println(out, guardEnd(cname));
+        } catch (TypeSignature.SignatureException e) {
+            throw new IOException(e);
+        }
+    }
+
+    protected void writeStatics(Writer out, ClassSymbol sym) throws IOException {
+        List<VariableElement> classfields = getAllFields(sym);
+
+        for (VariableElement v: classfields) {
+            if (!v.getModifiers().contains(Modifier.STATIC))
+                continue;
+            String s = null;
+            s = defineForStatic(sym, v);
+            if (s != null) {
+                println(out, s);
+            }
+        }
+    }
+
+    /**
+     * Including super class fields.
+     */
+    List<VariableElement> getAllFields(TypeElement subclazz) {
+        List<VariableElement> fields = new ArrayList<VariableElement>();
+        TypeElement cd = null;
+        Stack<TypeElement> s = new Stack<TypeElement>();
+
+        cd = subclazz;
+        while (true) {
+            s.push(cd);
+            TypeElement c = (TypeElement) (types.asElement(cd.getSuperclass()));
+            if (c == null)
+                break;
+            cd = c;
+        }
+
+        while (!s.empty()) {
+            cd = s.pop();
+            fields.addAll(ElementFilter.fieldsIn(cd.getEnclosedElements()));
+        }
+
+        return fields;
+    }
+
+    protected String defineForStatic(TypeElement c, VariableElement f) {
+        CharSequence cnamedoc = c.getQualifiedName();
+        CharSequence fnamedoc = f.getSimpleName();
+
+        String cname = mangler.mangle(cnamedoc, Mangle.Type.CLASS);
+        String fname = mangler.mangle(fnamedoc, Mangle.Type.FIELDSTUB);
+
+        Assert.check(f.getModifiers().contains(Modifier.STATIC));
+
+        if (f.getModifiers().contains(Modifier.FINAL)) {
+            Object value = null;
+
+            value = f.getConstantValue();
+
+            if (value != null) { /* so it is a ConstantExpression */
+                String constString = null;
+                if ((value instanceof Integer)
+                    || (value instanceof Byte)
+                    || (value instanceof Short)) {
+                    /* covers byte, short, int */
+                    constString = value.toString() + "L";
+                } else if (value instanceof Boolean) {
+                    constString = ((Boolean) value) ? "1L" : "0L";
+                } else if (value instanceof Character) {
+                    Character ch = (Character) value;
+                    constString = String.valueOf(((int) ch) & 0xffff) + "L";
+                } else if (value instanceof Long) {
+                    // Visual C++ supports the i64 suffix, not LL.
+                    if (isWindows)
+                        constString = value.toString() + "i64";
+                    else
+                        constString = value.toString() + "LL";
+                } else if (value instanceof Float) {
+                    /* bug for bug */
+                    float fv = ((Float)value).floatValue();
+                    if (Float.isInfinite(fv))
+                        constString = ((fv < 0) ? "-" : "") + "Inff";
+                    else
+                        constString = value.toString() + "f";
+                } else if (value instanceof Double) {
+                    /* bug for bug */
+                    double d = ((Double)value).doubleValue();
+                    if (Double.isInfinite(d))
+                        constString = ((d < 0) ? "-" : "") + "InfD";
+                    else
+                        constString = value.toString();
+                }
+
+                if (constString != null) {
+                    StringBuilder s = new StringBuilder("#undef ");
+                    s.append(cname); s.append("_"); s.append(fname); s.append(lineSep);
+                    s.append("#define "); s.append(cname); s.append("_");
+                    s.append(fname); s.append(" "); s.append(constString);
+                    return s.toString();
+                }
+
+            }
+        }
+
+        return null;
+    }
+
+
+    protected void writeMethods(Writer out, ClassSymbol sym, String cname)
+            throws IOException, TypeSignature.SignatureException {
+        List<ExecutableElement> classmethods = ElementFilter.methodsIn(sym.getEnclosedElements());
+        for (ExecutableElement md: classmethods) {
+            if(md.getModifiers().contains(Modifier.NATIVE)){
+                TypeMirror mtr = types.erasure(md.getReturnType());
+                String sig = signature(md);
+                TypeSignature newtypesig = new TypeSignature(elements);
+                CharSequence methodName = md.getSimpleName();
+                boolean longName = false;
+                for (ExecutableElement md2: classmethods) {
+                    if ((md2 != md)
+                        && (methodName.equals(md2.getSimpleName()))
+                        && (md2.getModifiers().contains(Modifier.NATIVE)))
+                        longName = true;
+
+                }
+                println(out, "/*");
+                println(out, " * Class:     " + cname);
+                println(out, " * Method:    " +
+                           mangler.mangle(methodName, Mangle.Type.FIELDSTUB));
+                println(out, " * Signature: " + newtypesig.getTypeSignature(sig, mtr));
+                println(out, " */");
+                println(out, "JNIEXPORT " + jniType(mtr) +
+                           " JNICALL " +
+                           mangler.mangleMethod(md, sym,
+                                               (longName) ?
+                                               Mangle.Type.METHOD_JNI_LONG :
+                                               Mangle.Type.METHOD_JNI_SHORT));
+                print(out, "  (JNIEnv *, ");
+                List<? extends VariableElement> paramargs = md.getParameters();
+                List<TypeMirror> args = new ArrayList<TypeMirror>();
+                for (VariableElement p: paramargs) {
+                    args.add(types.erasure(p.asType()));
+                }
+                if (md.getModifiers().contains(Modifier.STATIC))
+                    print(out, "jclass");
+                else
+                    print(out, "jobject");
+
+                for (TypeMirror arg: args) {
+                    print(out, ", ");
+                    print(out, jniType(arg));
+                }
+                println(out, ");"
+                        + lineSep);
+            }
+        }
+    }
+
+    // c.f. MethodDoc.signature
+    String signature(ExecutableElement e) {
+        StringBuilder sb = new StringBuilder("(");
+        String sep = "";
+        for (VariableElement p: e.getParameters()) {
+            sb.append(sep);
+            sb.append(types.erasure(p.asType()).toString());
+            sep = ",";
+        }
+        sb.append(")");
+        return sb.toString();
+    }
+
+    protected final String jniType(TypeMirror t) {
+        TypeElement throwable = elements.getTypeElement("java.lang.Throwable");
+        TypeElement jClass = elements.getTypeElement("java.lang.Class");
+        TypeElement jString = elements.getTypeElement("java.lang.String");
+        Element tclassDoc = types.asElement(t);
+
+
+        switch (t.getKind()) {
+            case ARRAY: {
+                TypeMirror ct = ((ArrayType) t).getComponentType();
+                switch (ct.getKind()) {
+                    case BOOLEAN:  return "jbooleanArray";
+                    case BYTE:     return "jbyteArray";
+                    case CHAR:     return "jcharArray";
+                    case SHORT:    return "jshortArray";
+                    case INT:      return "jintArray";
+                    case LONG:     return "jlongArray";
+                    case FLOAT:    return "jfloatArray";
+                    case DOUBLE:   return "jdoubleArray";
+                    case ARRAY:
+                    case DECLARED: return "jobjectArray";
+                    default: throw new Error(ct.toString());
+                }
+            }
+
+            case VOID:     return "void";
+            case BOOLEAN:  return "jboolean";
+            case BYTE:     return "jbyte";
+            case CHAR:     return "jchar";
+            case SHORT:    return "jshort";
+            case INT:      return "jint";
+            case LONG:     return "jlong";
+            case FLOAT:    return "jfloat";
+            case DOUBLE:   return "jdouble";
+
+            case DECLARED: {
+                if (tclassDoc.equals(jString))
+                    return "jstring";
+                else if (types.isAssignable(t, throwable.asType()))
+                    return "jthrowable";
+                else if (types.isAssignable(t, jClass.asType()))
+                    return "jclass";
+                else
+                    return "jobject";
+            }
+        }
+
+        Assert.check(false, "jni unknown type");
+        return null; /* dead code. */
+    }
+
+    protected String fileTop() {
+        return "/* DO NOT EDIT THIS FILE - it is machine generated */";
+    }
+
+    protected String includes() {
+        return "#include <jni.h>";
+    }
+
+    /*
+     * Deal with the C pre-processor.
+     */
+    protected String cppGuardBegin() {
+        return "#ifdef __cplusplus" + lineSep
+                + "extern \"C\" {" + lineSep
+                + "#endif";
+    }
+
+    protected String cppGuardEnd() {
+        return "#ifdef __cplusplus" + lineSep
+                + "}" + lineSep
+                + "#endif";
+    }
+
+    protected String guardBegin(String cname) {
+        return "/* Header for class " + cname + " */" + lineSep
+                + lineSep
+                + "#ifndef _Included_" + cname + lineSep
+                + "#define _Included_" + cname;
+    }
+
+    protected String guardEnd(String cname) {
+        return "#endif";
+    }
+
+    protected void print(Writer out, String text) throws IOException {
+        out.write(text);
+    }
+
+    protected void println(Writer out, String text) throws IOException {
+        out.write(text);
+        out.write(lineSep);
+    }
+
+
+    private static class Mangle {
+
+        public static class Type {
+            public static final int CLASS            = 1;
+            public static final int FIELDSTUB        = 2;
+            public static final int FIELD            = 3;
+            public static final int JNI              = 4;
+            public static final int SIGNATURE        = 5;
+            public static final int METHOD_JDK_1     = 6;
+            public static final int METHOD_JNI_SHORT = 7;
+            public static final int METHOD_JNI_LONG  = 8;
+        };
+
+        private Elements elems;
+        private Types types;
+
+        Mangle(Elements elems, Types types) {
+            this.elems = elems;
+            this.types = types;
+        }
+
+        public final String mangle(CharSequence name, int mtype) {
+            StringBuilder result = new StringBuilder(100);
+            int length = name.length();
+
+            for (int i = 0; i < length; i++) {
+                char ch = name.charAt(i);
+                if (isalnum(ch)) {
+                    result.append(ch);
+                } else if ((ch == '.') &&
+                           mtype == Mangle.Type.CLASS) {
+                    result.append('_');
+                } else if (( ch == '$') &&
+                           mtype == Mangle.Type.CLASS) {
+                    result.append('_');
+                    result.append('_');
+                } else if (ch == '_' && mtype == Mangle.Type.FIELDSTUB) {
+                    result.append('_');
+                } else if (ch == '_' && mtype == Mangle.Type.CLASS) {
+                    result.append('_');
+                } else if (mtype == Mangle.Type.JNI) {
+                    String esc = null;
+                    if (ch == '_')
+                        esc = "_1";
+                    else if (ch == '.')
+                        esc = "_";
+                    else if (ch == ';')
+                        esc = "_2";
+                    else if (ch == '[')
+                        esc = "_3";
+                    if (esc != null) {
+                        result.append(esc);
+                    } else {
+                        result.append(mangleChar(ch));
+                    }
+                } else if (mtype == Mangle.Type.SIGNATURE) {
+                    if (isprint(ch)) {
+                        result.append(ch);
+                    } else {
+                        result.append(mangleChar(ch));
+                    }
+                } else {
+                    result.append(mangleChar(ch));
+                }
+            }
+
+            return result.toString();
+        }
+
+        public String mangleMethod(ExecutableElement method, TypeElement clazz,
+                                          int mtype) throws TypeSignature.SignatureException {
+            StringBuilder result = new StringBuilder(100);
+            result.append("Java_");
+
+            if (mtype == Mangle.Type.METHOD_JDK_1) {
+                result.append(mangle(clazz.getQualifiedName(), Mangle.Type.CLASS));
+                result.append('_');
+                result.append(mangle(method.getSimpleName(),
+                                     Mangle.Type.FIELD));
+                result.append("_stub");
+                return result.toString();
+            }
+
+            /* JNI */
+            result.append(mangle(getInnerQualifiedName(clazz), Mangle.Type.JNI));
+            result.append('_');
+            result.append(mangle(method.getSimpleName(),
+                                 Mangle.Type.JNI));
+            if (mtype == Mangle.Type.METHOD_JNI_LONG) {
+                result.append("__");
+                String typesig = signature(method);
+                TypeSignature newTypeSig = new TypeSignature(elems);
+                String sig = newTypeSig.getTypeSignature(typesig,  method.getReturnType());
+                sig = sig.substring(1);
+                sig = sig.substring(0, sig.lastIndexOf(')'));
+                sig = sig.replace('/', '.');
+                result.append(mangle(sig, Mangle.Type.JNI));
+            }
+
+            return result.toString();
+        }
+        //where
+            private String getInnerQualifiedName(TypeElement clazz) {
+                return elems.getBinaryName(clazz).toString();
+            }
+
+        public final String mangleChar(char ch) {
+            String s = Integer.toHexString(ch);
+            int nzeros = 5 - s.length();
+            char[] result = new char[6];
+            result[0] = '_';
+            for (int i = 1; i <= nzeros; i++)
+                result[i] = '0';
+            for (int i = nzeros+1, j = 0; i < 6; i++, j++)
+                result[i] = s.charAt(j);
+            return new String(result);
+        }
+
+        // Warning: duplicated in Gen
+        private String signature(ExecutableElement e) {
+            StringBuilder sb = new StringBuilder();
+            String sep = "(";
+            for (VariableElement p: e.getParameters()) {
+                sb.append(sep);
+                sb.append(types.erasure(p.asType()).toString());
+                sep = ",";
+            }
+            sb.append(")");
+            return sb.toString();
+        }
+
+        /* Warning: Intentional ASCII operation. */
+        private static boolean isalnum(char ch) {
+            return ch <= 0x7f && /* quick test */
+                ((ch >= 'A' && ch <= 'Z') ||
+                 (ch >= 'a' && ch <= 'z') ||
+                 (ch >= '0' && ch <= '9'));
+        }
+
+        /* Warning: Intentional ASCII operation. */
+        private static boolean isprint(char ch) {
+            return ch >= 32 && ch <= 126;
+        }
+    }
+
+    private static class TypeSignature {
+        static class SignatureException extends Exception {
+            private static final long serialVersionUID = 1L;
+            SignatureException(String reason) {
+                super(reason);
+            }
+        }
+
+        Elements elems;
+
+        /* Signature Characters */
+
+        private static final String SIG_VOID                   = "V";
+        private static final String SIG_BOOLEAN                = "Z";
+        private static final String SIG_BYTE                   = "B";
+        private static final String SIG_CHAR                   = "C";
+        private static final String SIG_SHORT                  = "S";
+        private static final String SIG_INT                    = "I";
+        private static final String SIG_LONG                   = "J";
+        private static final String SIG_FLOAT                  = "F";
+        private static final String SIG_DOUBLE                 = "D";
+        private static final String SIG_ARRAY                  = "[";
+        private static final String SIG_CLASS                  = "L";
+
+
+
+        public TypeSignature(Elements elems){
+            this.elems = elems;
+        }
+
+        /*
+         * Returns the type signature of a field according to JVM specs
+         */
+        public String getTypeSignature(String javasignature) throws SignatureException {
+            return getParamJVMSignature(javasignature);
+        }
+
+        /*
+         * Returns the type signature of a method according to JVM specs
+         */
+        public String getTypeSignature(String javasignature, TypeMirror returnType)
+                throws SignatureException {
+            String signature = null; //Java type signature.
+            String typeSignature = null; //Internal type signature.
+            List<String> params = new ArrayList<String>(); //List of parameters.
+            String paramsig = null; //Java parameter signature.
+            String paramJVMSig = null; //Internal parameter signature.
+            String returnSig = null; //Java return type signature.
+            String returnJVMType = null; //Internal return type signature.
+            int dimensions = 0; //Array dimension.
+
+            int startIndex = -1;
+            int endIndex = -1;
+            StringTokenizer st = null;
+            int i = 0;
+
+            // Gets the actual java signature without parentheses.
+            if (javasignature != null) {
+                startIndex = javasignature.indexOf("(");
+                endIndex = javasignature.indexOf(")");
+            }
+
+            if (((startIndex != -1) && (endIndex != -1))
+                &&(startIndex+1 < javasignature.length())
+                &&(endIndex < javasignature.length())) {
+                signature = javasignature.substring(startIndex+1, endIndex);
+            }
+
+            // Separates parameters.
+            if (signature != null) {
+                if (signature.indexOf(",") != -1) {
+                    st = new StringTokenizer(signature, ",");
+                    if (st != null) {
+                        while (st.hasMoreTokens()) {
+                            params.add(st.nextToken());
+                        }
+                    }
+                } else {
+                    params.add(signature);
+                }
+            }
+
+            /* JVM type signature. */
+            typeSignature = "(";
+
+            // Gets indivisual internal parameter signature.
+            while (params.isEmpty() != true) {
+                paramsig = params.remove(i).trim();
+                paramJVMSig  = getParamJVMSignature(paramsig);
+                if (paramJVMSig != null) {
+                    typeSignature += paramJVMSig;
+                }
+            }
+
+            typeSignature += ")";
+
+            // Get internal return type signature.
+
+            returnJVMType = "";
+            if (returnType != null) {
+                dimensions = dimensions(returnType);
+            }
+
+            //Gets array dimension of return type.
+            while (dimensions-- > 0) {
+                returnJVMType += "[";
+            }
+            if (returnType != null) {
+                returnSig = qualifiedTypeName(returnType);
+                returnJVMType += getComponentType(returnSig);
+            } else {
+                System.out.println("Invalid return type.");
+            }
+
+            typeSignature += returnJVMType;
+
+            return typeSignature;
+        }
+
+        /*
+         * Returns internal signature of a parameter.
+         */
+        private String getParamJVMSignature(String paramsig) throws SignatureException {
+            String paramJVMSig = "";
+            String componentType ="";
+
+            if(paramsig != null){
+
+                if(paramsig.indexOf("[]") != -1) {
+                    // Gets array dimension.
+                    int endindex = paramsig.indexOf("[]");
+                    componentType = paramsig.substring(0, endindex);
+                    String dimensionString =  paramsig.substring(endindex);
+                    if(dimensionString != null){
+                        while(dimensionString.indexOf("[]") != -1){
+                            paramJVMSig += "[";
+                            int beginindex = dimensionString.indexOf("]") + 1;
+                            if(beginindex < dimensionString.length()){
+                                dimensionString = dimensionString.substring(beginindex);
+                            }else
+                                dimensionString = "";
+                        }
+                    }
+                } else componentType = paramsig;
+
+                paramJVMSig += getComponentType(componentType);
+            }
+            return paramJVMSig;
+        }
+
+        /*
+         * Returns internal signature of a component.
+         */
+        private String getComponentType(String componentType) throws SignatureException {
+
+            String JVMSig = "";
+
+            if(componentType != null){
+                if(componentType.equals("void")) JVMSig += SIG_VOID ;
+                else if(componentType.equals("boolean"))  JVMSig += SIG_BOOLEAN ;
+                else if(componentType.equals("byte")) JVMSig += SIG_BYTE ;
+                else if(componentType.equals("char"))  JVMSig += SIG_CHAR ;
+                else if(componentType.equals("short"))  JVMSig += SIG_SHORT ;
+                else if(componentType.equals("int"))  JVMSig += SIG_INT ;
+                else if(componentType.equals("long"))  JVMSig += SIG_LONG ;
+                else if(componentType.equals("float")) JVMSig += SIG_FLOAT ;
+                else if(componentType.equals("double"))  JVMSig += SIG_DOUBLE ;
+                else {
+                    if(!componentType.equals("")){
+                        TypeElement classNameDoc = elems.getTypeElement(componentType);
+
+                        if(classNameDoc == null){
+                            throw new SignatureException(componentType);
+                        }else {
+                            String classname = classNameDoc.getQualifiedName().toString();
+                            String newclassname = classname.replace('.', '/');
+                            JVMSig += "L";
+                            JVMSig += newclassname;
+                            JVMSig += ";";
+                        }
+                    }
+                }
+            }
+            return JVMSig;
+        }
+
+        int dimensions(TypeMirror t) {
+            if (t.getKind() != TypeKind.ARRAY)
+                return 0;
+            return 1 + dimensions(((ArrayType) t).getComponentType());
+        }
+
+
+        String qualifiedTypeName(TypeMirror type) {
+            TypeVisitor<Name, Void> v = new SimpleTypeVisitor8<Name, Void>() {
+                @Override
+                public Name visitArray(ArrayType t, Void p) {
+                    return t.getComponentType().accept(this, p);
+                }
+
+                @Override
+                public Name visitDeclared(DeclaredType t, Void p) {
+                    return ((TypeElement) t.asElement()).getQualifiedName();
+                }
+
+                @Override
+                public Name visitPrimitive(PrimitiveType t, Void p) {
+                    return elems.getName(t.toString());
+                }
+
+                @Override
+                public Name visitNoType(NoType t, Void p) {
+                    if (t.getKind() == TypeKind.VOID)
+                        return elems.getName("void");
+                    return defaultAction(t, p);
+                }
+
+                @Override
+                public Name visitTypeVariable(TypeVariable t, Void p) {
+                    return t.getUpperBound().accept(this, p);
+                }
+            };
+            return v.visit(type).toString();
+        }
+    }
+
+}
--- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Fri Mar 30 16:57:50 2012 -0700
@@ -44,6 +44,8 @@
 import javax.tools.DiagnosticListener;
 import javax.tools.JavaFileManager;
 import javax.tools.JavaFileObject;
+import javax.tools.StandardLocation;
+
 import static javax.tools.StandardLocation.CLASS_OUTPUT;
 
 import com.sun.source.util.TaskEvent;
@@ -60,6 +62,7 @@
 import com.sun.tools.javac.tree.JCTree.*;
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.Log.WriterKind;
+
 import static com.sun.tools.javac.main.Option.*;
 import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*;
 import static com.sun.tools.javac.util.ListBuffer.lb;
@@ -227,6 +230,10 @@
      */
     protected ClassWriter writer;
 
+    /** The native header writer.
+     */
+    protected JNIWriter jniWriter;
+
     /** The module for the symbol table entry phases.
      */
     protected Enter enter;
@@ -330,6 +337,7 @@
         reader = ClassReader.instance(context);
         make = TreeMaker.instance(context);
         writer = ClassWriter.instance(context);
+        jniWriter = JNIWriter.instance(context);
         enter = Enter.instance(context);
         todo = Todo.instance(context);
 
@@ -1450,8 +1458,13 @@
                 JavaFileObject file;
                 if (usePrintSource)
                     file = printSource(env, cdef);
-                else
+                else {
+                    if (fileManager.hasLocation(StandardLocation.NATIVE_HEADER_OUTPUT)
+                            && jniWriter.needsHeader(cdef.sym)) {
+                        jniWriter.write(cdef.sym);
+                    }
                     file = genCode(env, cdef);
+                }
                 if (results != null && file != null)
                     results.add(file);
             } catch (IOException ex) {
--- a/langtools/src/share/classes/com/sun/tools/javac/main/Option.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/Option.java	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -160,6 +160,8 @@
 
     S("-s", "opt.arg.directory", "opt.sourceDest", STANDARD, FILEMANAGER),
 
+    H("-h", "opt.arg.directory", "opt.headerDest", STANDARD, FILEMANAGER),
+
     IMPLICIT("-implicit:", "opt.implicit", STANDARD, BASIC, ONEOF, "none", "class"),
 
     ENCODING("-encoding", "opt.arg.encoding", "opt.encoding", STANDARD, FILEMANAGER) {
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/javac.properties	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/javac.properties	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -61,6 +61,8 @@
     Specify where to place generated class files
 javac.opt.sourceDest=\
     Specify where to place generated source files
+javac.opt.headerDest=\
+    Specify where to place generated native header files
 javac.opt.J=\
     Pass <flag> directly to the runtime system
 javac.opt.encoding=\
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -102,6 +102,16 @@
         setOpname(MOD, "%", names);
     }
 
+    public static List<JCExpression> args(JCTree t) {
+        switch (t.getTag()) {
+            case APPLY:
+                return ((JCMethodInvocation)t).args;
+            case NEWCLASS:
+                return ((JCNewClass)t).args;
+            default:
+                return null;
+        }
+    }
 
     /** Return name of operator with given tree tag.
      */
--- a/langtools/src/share/classes/javax/tools/StandardLocation.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/src/share/classes/javax/tools/StandardLocation.java	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -66,7 +66,13 @@
      * Location to search for platform classes.  Sometimes called
      * the boot class path.
      */
-    PLATFORM_CLASS_PATH;
+    PLATFORM_CLASS_PATH,
+
+    /**
+     * Location of new native header files.
+     * @since 1.8
+     */
+    NATIVE_HEADER_OUTPUT;
 
     /**
      * Gets a location object with the given name.  The following
@@ -97,6 +103,13 @@
     public String getName() { return name(); }
 
     public boolean isOutputLocation() {
-        return this == CLASS_OUTPUT || this == SOURCE_OUTPUT;
+        switch (this) {
+            case CLASS_OUTPUT:
+            case SOURCE_OUTPUT:
+            case NATIVE_HEADER_OUTPUT:
+                return true;
+            default:
+                return false;
+        }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/javax/tools/annotation/GenerateNativeHeader.java	Fri Mar 30 16:57:50 2012 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package javax.tools.annotation;
+
+import java.lang.annotation.*;
+import static java.lang.annotation.RetentionPolicy.*;
+import static java.lang.annotation.ElementType.*;
+
+/**
+ * An annotation used to indicate that a native header file
+ * should be generated for this class.
+ *
+ * Normally, the presence of native methods is a sufficient
+ * indication of the need for a native header file.  However,
+ * in some cases, a class may contain constants of interest to
+ * native code, without containing any native methods.
+ *
+ * @since 1.8
+ */
+@Documented
+@Target(TYPE)
+@Retention(SOURCE)
+public @interface GenerateNativeHeader {
+}
--- a/langtools/test/Makefile	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/test/Makefile	Fri Mar 30 16:57:50 2012 -0700
@@ -36,6 +36,14 @@
     ARCH=i586
   endif
 endif
+ifeq ($(OSNAME), Darwin)
+  PLATFORM = bsd
+  JT_PLATFORM = linux
+  ARCH = $(shell uname -m)
+  ifeq ($(ARCH), i386)
+    ARCH=i586
+  endif
+endif
 ifeq ($(OSNAME), Windows_NT)
   # MKS
   PLATFORM=windows
@@ -251,6 +259,7 @@
 # JTREG_REFERENCE
 #	(Optional) reference results (e.g. work, report or summary.txt)
 #
+jtreg_tests: jtreg-tests
 jtreg-tests: check-jtreg FRC
 	@rm -f -r $(JTREG_OUTPUT_DIR)/JTwork $(JTREG_OUTPUT_DIR)/JTreport \
 	    $(JTREG_OUTPUT_DIR)/diff.html $(JTREG_OUTPUT_DIR)/status.txt
--- a/langtools/test/jprt.config	Fri Mar 30 15:43:13 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,159 +0,0 @@
-#!echo "This is not a shell script"
-#############################################################################
-# Copyright (c) 2006, 2007, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#############################################################################
-#
-# JPRT shell configuration for testing.
-#
-# Input environment variables:
-#    Windows Only:
-#      PATH
-#      ROOTDIR
-#
-# Output variable settings:
-#    make    Full path to GNU make
-#
-# Output environment variables:
-#    PATH
-#
-#############################################################################
-
-#############################################################################
-# Error
-error() # message
-{
-  echo "ERROR: $1"
-  exit 6
-}
-# Directory must exist
-dirMustExist() # dir name
-{
-  if [ ! -d "$1" ] ; then
-    error "Directory for $2 does not exist: $1"
-  fi
-}
-# File must exist
-fileMustExist() # dir name
-{
-  if [ ! -f "$1" ] ; then
-    error "File for $2 does not exist: $1"
-  fi
-}
-#############################################################################
-
-# Should be set by JPRT as the 3 basic inputs
-slashjava="${ALT_SLASH_JAVA}"
-if [ "${slashjava}" = "" ] ; then
-  slashjava=/java
-fi
-
-# Check input
-dirMustExist "${slashjava}"  ALT_SLASH_JAVA
-
-# Uses 'uname -s', but only expect SunOS or Linux, assume Windows otherwise.
-osname=`uname -s`
-if [ "${osname}" = SunOS ] ; then
-   
-    # SOLARIS: Sparc or X86
-    osarch=`uname -p`
-    if [ "${osarch}" = sparc ] ; then
-	solaris_arch=sparc
-    else
-	solaris_arch=i386
-    fi
-
-    # Add basic solaris system paths
-    path4sdk=/usr/ccs/bin:/usr/ccs/lib:/usr/bin:/bin:/usr/sfw/bin
-
-    # Find GNU make
-    make=/usr/sfw/bin/gmake
-    if [ ! -f ${make} ] ; then
-	make=/opt/sfw/bin/gmake
-	if [ ! -f ${make} ] ; then
-	    make=${slashjava}/devtools/${solaris_arch}/bin/gnumake
-        fi 
-    fi
-    fileMustExist "${make}" make
-
-    # File creation mask
-    umask 002
-
-elif [ "${osname}" = Linux ] ; then
-   
-    # Add basic paths
-    path4sdk=/usr/bin:/bin:/usr/sbin:/sbin
-
-    # Find GNU make
-    make=/usr/bin/make
-    fileMustExist "${make}" make
-
-    umask 002
-
-else
-
-    # Windows: Differs on CYGWIN vs. MKS.
-   
-    # We need to determine if we are running a CYGWIN shell or an MKS shell
-    #    (if uname isn't available, then it will be unix_toolset=unknown)
-    unix_toolset=unknown
-    if [ "`uname -a | fgrep Cygwin`" = "" -a -d "${ROOTDIR}" ] ; then
-        # We kind of assume ROOTDIR is where MKS is and it's ok
-        unix_toolset=MKS
-        mkshome=`dosname -s "${ROOTDIR}"`
-        # Most unix utilities are in the mksnt directory of ROOTDIR
-        unixcommand_path="${mkshome}/mksnt"
-        path4sdk="${unixcommand_path}"
-	devtools_path="${slashjava}/devtools/win32/bin"
-	path4sdk="${devtools_path};${path4sdk}"
-        # Find GNU make
-        make="${devtools_path}/gnumake.exe"
-        fileMustExist "${make}" make
-    elif [ "`uname -a | fgrep Cygwin`" != "" -a -f /bin/cygpath ] ; then
-        # For CYGWIN, uname will have "Cygwin" in it, and /bin/cygpath should exist
-        unix_toolset=CYGWIN
-        # Most unix utilities are in the /usr/bin
-        unixcommand_path="/usr/bin"
-        path4sdk="${unixcommand_path}"
-        # Find GNU make
-        make="${unixcommand_path}/make.exe"
-        fileMustExist "${make}" make
-    else
-      echo "WARNING: Cannot figure out if this is MKS or CYGWIN"
-    fi
-
-    
-    # For windows, it's hard to know where the system is, so we just add this
-    #    to PATH.
-    slash_path="`echo ${path4sdk} | sed -e 's@\\\\@/@g' -e 's@//@/@g' -e 's@/$@@' -e 's@/;@;@g'`"
-    path4sdk="${slash_path};${PATH}"
-    
-    # Convert path4sdk to cygwin style
-    if [ "${unix_toolset}" = CYGWIN ] ; then
-	path4sdk="`/usr/bin/cygpath -p ${path4sdk}`"
-    fi
-
-fi
-
-# Export PATH setting
-PATH="${path4sdk}"
-export PATH
-
--- a/langtools/test/tools/javac/4846262/Test.sh	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/test/tools/javac/4846262/Test.sh	Fri Mar 30 16:57:50 2012 -0700
@@ -44,7 +44,7 @@
 # set platform-dependent variables
 OS=`uname -s`
 case "$OS" in
-  SunOS | Linux )
+  SunOS | Linux | Darwin )
     FS="/"
     ;;
   CYGWIN* )
--- a/langtools/test/tools/javac/6302184/T6302184.sh	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/test/tools/javac/6302184/T6302184.sh	Fri Mar 30 16:57:50 2012 -0700
@@ -41,7 +41,7 @@
 # set platform-dependent variables
 OS=`uname -s`
 case "$OS" in
-  SunOS | Linux )
+  SunOS | Linux | Darwin )
     FS="/"
     ;;
   CYGWIN* )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/7132880/T7132880.java	Fri Mar 30 16:57:50 2012 -0700
@@ -0,0 +1,60 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 7132880
+ * @summary Resolve should support nested resolution contexts
+ * @compile/fail/ref=T7132880.out -XDrawDiagnostics T7132880.java
+ */
+class Outer {
+    void m1(String s) { }
+    void m2(int i1, int i2) { }
+
+    class Inner {
+        void test() {
+           //ok - no method named 'm' in Inner - hence, class to search is Outer
+           m1("");
+        }
+    }
+
+    class Inner1 {
+        void m1(Integer i) { }
+
+        void test() {
+           //error - Inner1 defines an incompatible method - hence, class to search is Inner1
+           m1("");
+        }
+    }
+
+    class Inner2 {
+        private void m1(Integer i) { }
+        private void m1(Double d) { }
+
+        void test() {
+           //error - Inner2 defines multiple incompatible methods - hence, class to search is Inner2
+           m1("");
+        }
+    }
+
+    class Inner3 {
+        private void m2(Object o, int i) { }
+        private void m2(int i, Object o) { }
+
+        void test() {
+           //error - Inner3 defines multiple ambiguous methods - hence, class to search is Inner3
+           m2(1, 1);
+        }
+    }
+
+    class Inner4 extends Inner2 {
+        void test() {
+           //ok - Inner2 defines multiple incompatible inaccessible methods - hence, class to search is Outer
+           m1("");
+        }
+    }
+
+    class Inner5 extends Inner3 {
+        void test() {
+           //ok - Inner3 defines multiple inaccessible ambiguous methods - hence, class to search is Outer
+           m2(1, 1);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/7132880/T7132880.out	Fri Mar 30 16:57:50 2012 -0700
@@ -0,0 +1,4 @@
+T7132880.java:23:12: compiler.err.cant.apply.symbol.1: kindname.method, m1, java.lang.Integer, java.lang.String, kindname.class, Outer.Inner1, (compiler.misc.no.conforming.assignment.exists: java.lang.String, java.lang.Integer)
+T7132880.java:33:12: compiler.err.cant.apply.symbols: kindname.method, m1, java.lang.String,{(compiler.misc.inapplicable.method: kindname.method, Outer.Inner2, m1(java.lang.Double), (compiler.misc.no.conforming.assignment.exists: java.lang.String, java.lang.Double)),(compiler.misc.inapplicable.method: kindname.method, Outer.Inner2, m1(java.lang.Integer), (compiler.misc.no.conforming.assignment.exists: java.lang.String, java.lang.Integer))}
+T7132880.java:43:12: compiler.err.ref.ambiguous: m2, kindname.method, m2(java.lang.Object,int), Outer.Inner3, kindname.method, m2(int,java.lang.Object), Outer.Inner3
+3 errors
--- a/langtools/test/tools/javac/ClassPathTest/ClassPathTest.sh	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/test/tools/javac/ClassPathTest/ClassPathTest.sh	Fri Mar 30 16:57:50 2012 -0700
@@ -56,7 +56,7 @@
 # set platform-dependent variables
 OS=`uname -s`
 case "$OS" in
-  SunOS | Linux | CYGWIN* )
+  SunOS | Linux | Darwin | CYGWIN* )
     FS="/"
     ;;
   Windows* )
--- a/langtools/test/tools/javac/ExtDirs/ExtDirs.sh	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/test/tools/javac/ExtDirs/ExtDirs.sh	Fri Mar 30 16:57:50 2012 -0700
@@ -54,7 +54,7 @@
 # set platform-dependent variables
 OS=`uname -s`
 case "$OS" in
-  SunOS | Linux )
+  SunOS | Linux | Darwin )
     PS=":"
     FS="/"
     ;;
--- a/langtools/test/tools/javac/MissingInclude.sh	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/test/tools/javac/MissingInclude.sh	Fri Mar 30 16:57:50 2012 -0700
@@ -47,7 +47,7 @@
 # set platform-dependent variables
 OS=`uname -s`
 case "$OS" in
-  SunOS | Linux | CYGWIN* )
+  SunOS | Linux | Darwin | CYGWIN* )
     FS="/"
     ;;
   Windows* )
--- a/langtools/test/tools/javac/ProtectedInnerClass/ProtectedInnerClass.sh	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/test/tools/javac/ProtectedInnerClass/ProtectedInnerClass.sh	Fri Mar 30 16:57:50 2012 -0700
@@ -52,7 +52,7 @@
 # set platform-dependent variables
 OS=`uname -s`
 case "$OS" in
-  SunOS | Linux )
+  SunOS | Linux | Darwin )
     PS=":"
     FS="/"
     ;;
--- a/langtools/test/tools/javac/T5090006/compiler.sh	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/test/tools/javac/T5090006/compiler.sh	Fri Mar 30 16:57:50 2012 -0700
@@ -47,7 +47,7 @@
 # set platform-dependent variables
 OS=`uname -s`
 case "$OS" in
-  SunOS | Linux | CYGWIN* )
+  SunOS | Linux | Darwin | CYGWIN* )
     FS="/"
     ;;
   Windows* )
--- a/langtools/test/tools/javac/api/7086261/T7086261.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/test/tools/javac/api/7086261/T7086261.java	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 20011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/constDebug/ConstDebug.sh	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/test/tools/javac/constDebug/ConstDebug.sh	Fri Mar 30 16:57:50 2012 -0700
@@ -47,7 +47,7 @@
 # set platform-dependent variables
 OS=`uname -s`
 case "$OS" in
-  SunOS | Linux )
+  SunOS | Linux | Darwin )
     PS=":"
     FS="/"
     ;;
--- a/langtools/test/tools/javac/diags/CheckResourceKeys.java	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/test/tools/javac/diags/CheckResourceKeys.java	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -259,6 +259,7 @@
             "application.home", // in Paths.java
             "env.class.path",
             "line.separator",
+            "os.name",
             "user.dir",
             // file names
             "ct.sym",
--- a/langtools/test/tools/javac/fatalErrors/NoJavaLang.sh	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/test/tools/javac/fatalErrors/NoJavaLang.sh	Fri Mar 30 16:57:50 2012 -0700
@@ -48,7 +48,7 @@
 # set platform-dependent variables
 OS=`uname -s`
 case "$OS" in
-  SunOS | Linux )
+  SunOS | Linux | Darwin )
     FS="/"
     ;;
   CYGWIN* )
--- a/langtools/test/tools/javac/generics/6723444/T6723444.out	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/test/tools/javac/generics/6723444/T6723444.out	Fri Mar 30 16:57:50 2012 -0700
@@ -1,5 +1,5 @@
-T6723444.java:42:9: compiler.err.unreported.exception.need.to.catch.or.throw: X2
-T6723444.java:43:9: compiler.err.unreported.exception.need.to.catch.or.throw: X2
+T6723444.java:42:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
+T6723444.java:43:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
 T6723444.java:45:32: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
 T6723444.java:46:17: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
 T6723444.java:48:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/7151070/T7151070.java	Fri Mar 30 16:57:50 2012 -0700
@@ -0,0 +1,25 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug     7151070
+ * @summary NullPointerException in Resolve.isAccessible
+ * @compile/fail/ref=T7151070.out -XDrawDiagnostics T7151070.java
+ */
+
+class T7151070a {
+    private static class PrivateCls { }
+    public static class PublicCls extends PrivateCls { }
+
+    public void m(PrivateCls p) { }
+}
+
+class T7151070b {
+    public void test(Test<T7151070a.PublicCls> obj, T7151070a outer) {
+        outer.m(obj.get());
+    }
+
+    public static class Test<T> {
+        public T get() {
+            return null;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/7151070/T7151070.out	Fri Mar 30 16:57:50 2012 -0700
@@ -0,0 +1,2 @@
+T7151070.java:17:24: compiler.err.report.access: T7151070a.PrivateCls, private, T7151070a
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/7151802/T7151802.java	Fri Mar 30 16:57:50 2012 -0700
@@ -0,0 +1,43 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug     7151802
+ * @summary compiler update caused sqe test failed
+ * @compile/fail/ref=T7151802.out -Werror -Xlint:unchecked -XDrawDiagnostics T7151802.java
+ */
+class T7151802 {
+    static class Foo<X> { }
+
+    static class SubFoo<X> extends Foo<X> { }
+
+    //generic - bound - arg - non-slilent
+    <Z extends Foo<String>> void get1(Z fz) { }
+    void test1(Foo foo) { get1(foo); }
+
+    //generic - bound - arg - silent
+    <Z extends Foo<?>> void get2(Z fz) { }
+    void test2(Foo foo) { get2(foo); }
+
+    //generic - nobound - arg - non-slilent
+    <Z> void get3(Foo<Z> fz) { }
+    void test(Foo foo) { get3(foo); }
+
+    //generic - nobound - arg - slilent
+    <Z> void get4(Foo<?> fz) { }
+    void test4(Foo foo) { get4(foo); }
+
+    //generic - bound - ret - non-slilent
+    <Z extends Foo<String>> Z get5() { return null; }
+    void test5() { SubFoo sf = get5(); }
+
+    //generic - bound - ret - slilent
+    static <Z extends Foo<?>> Z get6() { return null; }
+    void test6() { SubFoo sf = get6(); }
+
+    //nogeneric - nobound - arg - non-slilent
+    void get7(Foo<String> fz) { }
+    void test7(Foo foo) { get7(foo); }
+
+    //nogeneric - nobound - arg - slilent
+    static void get8(Foo<?> fz) { }
+    void test8(Foo foo) { get8(foo); }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/7151802/T7151802.out	Fri Mar 30 16:57:50 2012 -0700
@@ -0,0 +1,9 @@
+T7151802.java:14:31: compiler.warn.unchecked.meth.invocation.applied: kindname.method, get1, Z, T7151802.Foo, kindname.class, T7151802
+T7151802.java:22:31: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T7151802.Foo, T7151802.Foo<Z>
+T7151802.java:22:30: compiler.warn.unchecked.meth.invocation.applied: kindname.method, get3, T7151802.Foo<Z>, T7151802.Foo, kindname.class, T7151802
+T7151802.java:30:36: compiler.warn.unchecked.meth.invocation.applied: kindname.method, get5, compiler.misc.no.args, compiler.misc.no.args, kindname.class, T7151802
+T7151802.java:38:32: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T7151802.Foo, T7151802.Foo<java.lang.String>
+T7151802.java:38:31: compiler.warn.unchecked.meth.invocation.applied: kindname.method, get7, T7151802.Foo<java.lang.String>, T7151802.Foo, kindname.class, T7151802
+- compiler.err.warnings.and.werror
+1 error
+6 warnings
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/rawOverride/T7148556.java	Fri Mar 30 16:57:50 2012 -0700
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7148556
+ * @summary Implementing a generic interface causes a public clone() to become inaccessible
+ * @compile T7148556.java
+ */
+
+class T7148556 {
+
+    interface A extends Cloneable {
+       public Object clone();
+    }
+
+    interface B extends A, java.util.List { }
+
+    void test(B b) {
+        b.clone();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/typevars/T7148242.java	Fri Mar 30 16:57:50 2012 -0700
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug     7148242
+ * @summary Regression: valid code rejected during generic type well-formedness check
+ * @compile T7148242.java
+ */
+class T7148242 {
+   static abstract class A<K, V, I extends Pair<K, V>, I2 extends Pair<V, K>> {
+      abstract A<V, K, I2, I> test();
+   }
+   static class Pair<K, V> { }
+}
--- a/langtools/test/tools/javac/innerClassFile/Driver.sh	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/test/tools/javac/innerClassFile/Driver.sh	Fri Mar 30 16:57:50 2012 -0700
@@ -53,7 +53,7 @@
 # set platform-dependent variables
 OS=`uname -s`
 case "$OS" in
-  SunOS | Linux | CYGWIN* )
+  SunOS | Linux | Darwin | CYGWIN* )
     FS="/"
     ;;
   Windows* )
--- a/langtools/test/tools/javac/javazip/Test.sh	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/test/tools/javac/javazip/Test.sh	Fri Mar 30 16:57:50 2012 -0700
@@ -41,7 +41,7 @@
 # set platform-dependent variables
 OS=`uname -s`
 case "$OS" in
-  SunOS | Linux )
+  SunOS | Linux | Darwin )
     FS="/"
     SCR=`pwd`
     ;;
--- a/langtools/test/tools/javac/links/links.sh	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/test/tools/javac/links/links.sh	Fri Mar 30 16:57:50 2012 -0700
@@ -53,7 +53,7 @@
 # set platform-dependent variables
 OS=`uname -s`
 case "$OS" in
-  SunOS | Linux )
+  SunOS | Linux | Darwin )
     NULL=/dev/null
     PS=":"
     FS="/"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/nativeHeaders/NativeHeaderTest.java	Fri Mar 30 16:57:50 2012 -0700
@@ -0,0 +1,274 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7150368
+ * @summary javac should include basic ability to generate native headers
+ */
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+
+import com.sun.source.util.JavacTask;
+import com.sun.tools.javac.api.JavacTool;
+
+public class NativeHeaderTest {
+    public static void main(String... args) throws Exception {
+        new NativeHeaderTest().run();
+    }
+
+    /** How to invoke javac. */
+    enum RunKind {
+        /** Use the command line entry point. */
+        CMD,
+        /** Use the JavaCompiler API. */
+        API
+    };
+
+    /** Which classes for which to generate headers. */
+    enum GenKind {
+        /** Just classes with native methods or the marker annotation. */
+        SIMPLE,
+        /** All appropriate classes within the top level class. */
+        FULL
+    };
+
+    // ---------- Test cases, invoked reflectively via run. ----------
+
+    @Test
+    void simpleTest(RunKind rk, GenKind gk) throws Exception {
+        List<File> files = new ArrayList<File>();
+        files.add(createFile("p/C.java",
+                "class C { native void m(); }"));
+
+        Set<String> expect = createSet("C.h");
+
+        test(rk, gk, files, expect);
+    }
+
+    @Test
+    void nestedClassTest(RunKind rk, GenKind gk) throws Exception {
+        List<File> files = new ArrayList<File>();
+        files.add(createFile("p/C.java",
+                "class C { static class Inner { native void m(); } }"));
+
+        Set<String> expect = createSet("C_Inner.h");
+        if (gk == GenKind.FULL) expect.add("C.h");
+
+        test(rk, gk, files, expect);
+    }
+
+    @Test
+    void localClassTest(RunKind rk, GenKind gk) throws Exception {
+        List<File> files = new ArrayList<File>();
+        files.add(createFile("p/C.java",
+                "class C { native void m(); void m2() { class Local { } } }"));
+
+        Set<String> expect = createSet("C.h");
+
+        test(rk, gk, files, expect);
+    }
+
+    @Test
+    void syntheticClassTest(RunKind rk, GenKind gk) throws Exception {
+        List<File> files = new ArrayList<File>();
+        files.add(createFile("p/C.java",
+                "class C {\n"
+                + "    private C() { }\n"
+                + "    class Inner extends C { native void m(); }\n"
+                + "}"));
+
+        Set<String> expect = createSet("C_Inner.h");
+        if (gk == GenKind.FULL) expect.add("C.h");
+
+        test(rk, gk, files, expect);
+
+        // double check the synthetic class was generated
+        checkEqual("generatedClasses",
+                createSet("C.class", "C$1.class", "C$Inner.class"),
+                createSet(classesDir.list()));
+    }
+
+    @Test
+    void annoTest(RunKind rk, GenKind gk) throws Exception {
+        List<File> files = new ArrayList<File>();
+        files.add(createFile("p/C.java",
+                "@javax.tools.annotation.GenerateNativeHeader class C { }"));
+
+        Set<String> expect = createSet("C.h");
+
+        test(rk, gk, files, expect);
+    }
+
+    @Test
+    void annoNestedClassTest(RunKind rk, GenKind gk) throws Exception {
+        List<File> files = new ArrayList<File>();
+        files.add(createFile("p/C.java",
+                "class C { @javax.tools.annotation.GenerateNativeHeader class Inner { } }"));
+
+        Set<String> expect = createSet("C_Inner.h");
+        if (gk == GenKind.FULL) expect.add("C.h");
+
+        test(rk, gk, files, expect);
+    }
+
+    /**
+     * The worker method for each test case.
+     * Compile the files and verify that exactly the expected set of header files
+     * is generated.
+     */
+    void test(RunKind rk, GenKind gk, List<File> files, Set<String> expect) throws Exception {
+        List<String> args = new ArrayList<String>();
+        if (gk == GenKind.FULL)
+            args.add("-XDjavah:full");
+
+        switch (rk) {
+            case CMD:
+                args.add("-d");
+                args.add(classesDir.getPath());
+                args.add("-h");
+                args.add(headersDir.getPath());
+                for (File f: files)
+                    args.add(f.getPath());
+                int rc = com.sun.tools.javac.Main.compile(args.toArray(new String[args.size()]));
+                if (rc != 0)
+                    throw new Exception("compilation failed, rc=" + rc);
+                break;
+
+            case API:
+                fm.setLocation(StandardLocation.SOURCE_PATH, Arrays.asList(srcDir));
+                fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(classesDir));
+                fm.setLocation(StandardLocation.NATIVE_HEADER_OUTPUT, Arrays.asList(headersDir));
+                JavacTask task = javac.getTask(null, fm, null, args, null,
+                        fm.getJavaFileObjectsFromFiles(files));
+                if (!task.call())
+                    throw new Exception("compilation failed");
+                break;
+        }
+
+        Set<String> found = createSet(headersDir.list());
+        checkEqual("header files", expect, found);
+    }
+
+    /** Marker annotation for test cases. */
+    @Retention(RetentionPolicy.RUNTIME)
+    @interface Test { }
+
+    /** Combo test to run all test cases in all modes. */
+    void run() throws Exception {
+        javac = JavacTool.create();
+        fm = javac.getStandardFileManager(null, null, null);
+
+        for (RunKind rk: RunKind.values()) {
+            for (GenKind gk: GenKind.values()) {
+                for (Method m: getClass().getDeclaredMethods()) {
+                    Annotation a = m.getAnnotation(Test.class);
+                    if (a != null) {
+                        init(rk, gk, m.getName());
+                        try {
+                            m.invoke(this, new Object[] { rk, gk });
+                        } catch (InvocationTargetException e) {
+                            Throwable cause = e.getCause();
+                            throw (cause instanceof Exception) ? ((Exception) cause) : e;
+                        }
+                        System.err.println();
+                    }
+                }
+            }
+        }
+        System.err.println(testCount + " tests" + ((errorCount == 0) ? "" : ", " + errorCount + " errors"));
+        if (errorCount > 0)
+            throw new Exception(errorCount + " errors found");
+    }
+
+    /**
+     * Init directories for a test case.
+     */
+    void init(RunKind rk, GenKind gk, String name) throws IOException {
+        System.err.println("Test " + rk + " " + gk + " " + name);
+        testCount++;
+
+        testDir = new File(rk.toString().toLowerCase() + "_" + gk.toString().toLowerCase() + "-" + name);
+        srcDir = new File(testDir, "src");
+        srcDir.mkdirs();
+        classesDir = new File(testDir, "classes");
+        classesDir.mkdirs();
+        headersDir = new File(testDir, "headers");
+        headersDir.mkdirs();
+    }
+
+    /** Create a source file with given body text. */
+    File createFile(String path, final String body) throws IOException {
+        File f = new File(srcDir, path);
+        f.getParentFile().mkdirs();
+        try (FileWriter out = new FileWriter(f)) {
+            out.write(body);
+        }
+        return f;
+    }
+
+    /** Convenience method to create a set of items. */
+    <T> Set<T> createSet(T... items) {
+        return new HashSet<T>(Arrays.asList(items));
+    }
+
+    /** Convenience method to check two values are equal, and report an error if not. */
+    <T> void checkEqual(String label, T expect, T found) {
+        if ((found == null) ? (expect == null) : found.equals(expect))
+            return;
+        System.err.println("Error: mismatch");
+        System.err.println("  expected: " + expect);
+        System.err.println("     found: " + found);
+        errorCount++;
+    }
+
+    // Shared across API test cases
+    JavacTool javac;
+    StandardJavaFileManager fm;
+
+    // Directories set up by init
+    File testDir;
+    File srcDir;
+    File classesDir;
+    File headersDir;
+
+    // Statistics
+    int testCount;
+    int errorCount;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/nativeHeaders/javahComparison/CompareTest.java	Fri Mar 30 16:57:50 2012 -0700
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2007,2012 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7150368
+ * @summary javac should include basic ability to generate native headers
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class CompareTest {
+    public static void main(String... args) throws Exception {
+        new CompareTest().run();
+    }
+
+    void run() throws Exception {
+        File srcDir = new File(System.getProperty("test.src"));
+        File classesDir = new File("classes");
+        classesDir.mkdirs();
+        File javacHeaders = new File("headers.javac");
+        javacHeaders.mkdirs();
+        File javahHeaders = new File("headers.javah");
+        javahHeaders.mkdirs();
+
+        List<String> javacArgs = new ArrayList<String>();
+        javacArgs.add("-d");
+        javacArgs.add(classesDir.getPath());
+        javacArgs.add("-h");
+        javacArgs.add(javacHeaders.getPath());
+        javacArgs.add("-XDjavah:full");
+
+        for (File f: srcDir.listFiles()) {
+            if (f.getName().matches("TestClass[0-9]+\\.java")) {
+                sourceFileCount++;
+                javacArgs.add(f.getPath());
+            }
+        }
+
+        int rc = com.sun.tools.javac.Main.compile(javacArgs.toArray(new String[javacArgs.size()]));
+        if (rc != 0)
+            throw new Exception("javac failed; rc=" + rc);
+
+        List<String> javahArgs = new ArrayList<String>();
+        javahArgs.add("-d");
+        javahArgs.add(javahHeaders.getPath());
+
+        for (File f: classesDir.listFiles()) {
+            if (f.getName().endsWith(".class")) {
+                javahArgs.add(inferBinaryName(f));
+            }
+        }
+
+        PrintWriter pw = new PrintWriter(System.out, true);
+        rc = com.sun.tools.javah.Main.run(javahArgs.toArray(new String[javahArgs.size()]), pw);
+        if (rc != 0)
+            throw new Exception("javah failed; rc=" + rc);
+
+        compare(javahHeaders, javacHeaders);
+
+        int javahHeaderCount = javahHeaders.list().length;
+        int javacHeaderCount = javacHeaders.list().length;
+
+        System.out.println(sourceFileCount + " .java files found");
+        System.out.println(javacHeaderCount + " .h files generated by javac");
+        System.out.println(javahHeaderCount + " .h files generated by javah");
+        System.out.println(compareCount + " header files compared");
+
+        if (javacHeaderCount != javahHeaderCount || javacHeaderCount != compareCount)
+            error("inconsistent counts");
+
+        if (errors > 0)
+            throw new Exception(errors + " errors occurred");
+    }
+
+    String inferBinaryName(File file) {
+        String name = file.getName();
+        return name.substring(0, name.length() - ".class".length()).replace("$", ".");
+    }
+
+    /** Compare two directories.
+     *  @param f1 The golden directory
+     *  @param f2 The directory to be compared
+     */
+    void compare(File f1, File f2) {
+        compare(f1, f2, null);
+    }
+
+    /** Compare two files or directories
+     *  @param f1 The golden directory
+     *  @param f2 The directory to be compared
+     *  @param p An optional path identifying a file within the two directories
+     */
+    void compare(File f1, File f2, String p) {
+        File f1p = (p == null ? f1 : new File(f1, p));
+        File f2p = (p == null ? f2 : new File(f2, p));
+        if (f1p.isDirectory() && f2p.isDirectory()) {
+            Set<String> children = new HashSet<String>();
+            children.addAll(Arrays.asList(f1p.list()));
+            children.addAll(Arrays.asList(f2p.list()));
+            for (String c: children) {
+                compare(f1, f2, new File(p, c).getPath()); // null-safe for p
+            }
+        }
+        else if (f1p.isFile() && f2p.isFile()) {
+            System.out.println("checking " + p);
+            compareCount++;
+            String s1 = read(f1p);
+            String s2 = read(f2p);
+            if (!s1.equals(s2)) {
+                System.out.println("File: " + f1p + "\n" + s1);
+                System.out.println("File: " + f2p + "\n" + s2);
+                error("Files differ: " + f1p + " " + f2p);
+            }
+        }
+        else if (f1p.exists() && !f2p.exists())
+            error("Only in " + f1 + ": " + p);
+        else if (f2p.exists() && !f1p.exists())
+            error("Only in " + f2 + ": " + p);
+        else
+            error("Files differ: " + f1p + " " + f2p);
+    }
+
+    private String read(File f) {
+        try {
+            return new String(Files.readAllBytes(f.toPath()));
+        } catch (IOException e) {
+            error("error reading " + f + ": " + e);
+            return "";
+        }
+    }
+
+    private void error(String msg) {
+        System.out.println(msg);
+        errors++;
+    }
+
+    private int errors;
+    private int compareCount;
+    private int sourceFileCount;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass1.java	Fri Mar 30 16:57:50 2012 -0700
@@ -0,0 +1,475 @@
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.List;
+
+public class TestClass1 {
+    // simple types
+    byte b;
+    short s;
+    int i;
+    long l;
+    float f;
+    double d;
+    Object o;
+    String t;
+    List<String> g;
+
+    // constants
+    static final byte bc = 0;
+    static final short sc = 0;
+    static final int ic = 0;
+    static final long lc = 0;
+    static final float fc = 0;
+    static final double dc = 0;
+    static final Object oc = null;
+    static final String tc = "";
+    static final List<String> gc = null;
+
+    // simple arrays
+    byte[] ba;
+    short[] sa; // not handled corrected by javah v6
+    int[] ia;
+    long[] la;
+    float[] fa;
+    double[] da;
+    Object[] oa;
+    String[] ta;
+    List<String>[] ga;
+
+    // multidimensional arrays
+    byte[][] baa;
+    short[][] saa;
+    int[][] iaa;
+    long[][] laa;
+    float[][] faa;
+    double[][] daa;
+    Object[][] oaa;
+    String[][] taa;
+    List<String>[] gaa;
+
+    // simple Java methods
+    byte bm() { return 0; }
+    short sm() { return 0; }
+    int im() { return 0; }
+    long lm() { return 0; }
+    float fm() { return 0; }
+    double dm() { return 0; }
+    Object om() { return null; }
+    String tm() { return ""; }
+    List<String> gm() { return null; }
+    void vm() { }
+    byte[] bam() { return null; }
+    short[] sam() { return null; }
+    int[] iam() { return null; }
+    long[] lam() { return null; }
+    float[] fam() { return null; }
+    double[] dam() { return null; }
+    Object[] oam() { return null; }
+    String[] tam() { return null; }
+    List<String>[] gam() { return null; }
+    byte[][] baam() { return null; }
+    short[][] saam() { return null; }
+    int[][] iaam() { return null; }
+    long[][] laam() { return null; }
+    float[][] faam() { return null; }
+    double[][] daam() { return null; }
+    Object[][] oaam() { return null; }
+    String[][] taam() { return null; }
+    List<String>[] gaam() { return null; }
+
+    // simple native methods
+    native byte bmn();
+    native short smn();
+    native int imn();
+    native long lmn();
+    native float fmn();
+    native double dmn();
+    native Object omn();
+    native String tmn();
+    native List<String> gmn();
+    native void vmn();
+    native byte[] bamn();
+    native short[] samn();
+    native int[] iamn();
+    native long[] lamn();
+    native float[] famn();
+    native double[] damn();
+    native Object[] oamn();
+    native String[] tamn();
+    native List<String>[] gamn();
+    native byte[][] baamn();
+    native short[][] saamn();
+    native int[][] iaamn();
+    native long[][] laamn();
+    native float[][] faamn();
+    native double[][] daamn();
+    native Object[][] oaamn();
+    native String[][] taamn();
+    native List<String>[] gaamn();
+
+    // overloaded Java methods
+    byte bm1() { return 0; }
+    short sm1() { return 0; }
+    int im1() { return 0; }
+    long lm1() { return 0; }
+    float fm1() { return 0; }
+    double dm1() { return 0; }
+    Object om1() { return null; }
+    String tm1() { return ""; }
+    List<String> gm1() { return null; }
+    void vm1() { }
+
+    byte bm2(int i) { return 0; }
+    short sm2(int i) { return 0; }
+    int im2(int i) { return 0; }
+    long lm2(int i) { return 0; }
+    float fm2(int i) { return 0; }
+    double dm2(int i) { return 0; }
+    Object om2(int i) { return null; }
+    String tm2(int i) { return ""; }
+    List<String> gm2(int i) { return null; }
+    void vm2(int i) { }
+
+    // overloaded native methods
+    native byte bmn1();
+    native short smn1();
+    native int imn1();
+    native long lmn1();
+    native float fmn1();
+    native double dmn1();
+    native Object omn1();
+    native String tmn1();
+    native List<String> gmn1();
+    native void vmn1();
+
+    native byte bmn2(int i);
+    native short smn2(int i);
+    native int imn2(int i);
+    native long lmn2(int i);
+    native float fmn2(int i);
+    native double dmn2(int i);
+    native Object omn2(int i);
+    native String tmn2(int i);
+    native List<String> gmn2(int i);
+    native void vmn2(int i);
+
+    // arg types for Java methods
+    void mb(byte b) { }
+    void ms(short s) { }
+    void mi(int i) { }
+    void ml(long l) { }
+    void mf(float f) { }
+    void md(double d) { }
+    void mo(Object o) { }
+    void mt(String t) { }
+    void mg(List<String> g) { }
+
+    // arg types for native methods
+    native void mbn(byte b);
+    native void msn(short s);
+    native void min(int i);
+    native void mln(long l);
+    native void mfn(float f);
+    native void mdn(double d);
+    native void mon(Object o);
+    native void mtn(String t);
+    native void mgn(List<String> g);
+
+    static class Inner1 {
+        // simple types
+        byte b;
+        short s;
+        int i;
+        long l;
+        float f;
+        double d;
+        Object o;
+        String t;
+        List<String> g;
+
+        // constants
+        static final byte bc = 0;
+        static final short sc = 0;
+        static final int ic = 0;
+        static final long lc = 0;
+        static final float fc = 0;
+        static final double dc = 0;
+        static final Object oc = null;
+        static final String tc = "";
+        static final List<String> gc = null;
+
+        // simple arrays
+        byte[] ba;
+        // short[] sa; // not handled corrected by javah v6
+        int[] ia;
+        long[] la;
+        float[] fa;
+        double[] da;
+        Object[] oa;
+        String[] ta;
+        List<String>[] ga;
+
+        // multidimensional arrays
+        byte[][] baa;
+        short[][] saa;
+        int[][] iaa;
+        long[][] laa;
+        float[][] faa;
+        double[][] daa;
+        Object[][] oaa;
+        String[][] taa;
+        List<String>[] gaa;
+
+        // simple Java methods
+        byte bm() { return 0; }
+        short sm() { return 0; }
+        int im() { return 0; }
+        long lm() { return 0; }
+        float fm() { return 0; }
+        double dm() { return 0; }
+        Object om() { return null; }
+        String tm() { return ""; }
+        List<String> gm() { return null; }
+        void vm() { }
+
+        // simple native methods
+        native byte bmn();
+        native short smn();
+        native int imn();
+        native long lmn();
+        native float fmn();
+        native double dmn();
+        native Object omn();
+        native String tmn();
+        native List<String> gmn();
+        native void vmn();
+
+        // overloaded Java methods
+        byte bm1() { return 0; }
+        short sm1() { return 0; }
+        int im1() { return 0; }
+        long lm1() { return 0; }
+        float fm1() { return 0; }
+        double dm1() { return 0; }
+        Object om1() { return null; }
+        String tm1() { return ""; }
+        List<String> gm1() { return null; }
+        void vm1() { }
+
+        byte bm2(int i) { return 0; }
+        short sm2(int i) { return 0; }
+        int im2(int i) { return 0; }
+        long lm2(int i) { return 0; }
+        float fm2(int i) { return 0; }
+        double dm2(int i) { return 0; }
+        Object om2(int i) { return null; }
+        String tm2(int i) { return ""; }
+        List<String> gm2(int i) { return null; }
+        void vm2(int i) { }
+
+        // overloaded native methods
+        native byte bmn1();
+        native short smn1();
+        native int imn1();
+        native long lmn1();
+        native float fmn1();
+        native double dmn1();
+        native Object omn1();
+        native String tmn1();
+        native List<String> gmn1();
+        native void vmn1();
+
+        native byte bmn2(int i);
+        native short smn2(int i);
+        native int imn2(int i);
+        native long lmn2(int i);
+        native float fmn2(int i);
+        native double dmn2(int i);
+        native Object omn2(int i);
+        native String tmn2(int i);
+        native List<String> gmn2(int i);
+        native void vmn2(int i);
+
+        // arg types for Java methods
+        void mb(byte b) { }
+        void ms(short s) { }
+        void mi(int i) { }
+        void ml(long l) { }
+        void mf(float f) { }
+        void md(double d) { }
+        void mo(Object o) { }
+        void mt(String t) { }
+        void mg(List<String> g) { }
+
+        // arg types for native methods
+        native void mbn(byte b);
+        native void msn(short s);
+        native void min(int i);
+        native void mln(long l);
+        native void mfn(float f);
+        native void mdn(double d);
+        native void mon(Object o);
+        native void mtn(String t);
+        native void mgn(List<String> g);
+    }
+
+    class Inner2 {
+        // simple types
+        byte b;
+        short s;
+        int i;
+        long l;
+        float f;
+        double d;
+        Object o;
+        String t;
+        List<String> g;
+
+        // constants
+        static final byte bc = 0;
+        static final short sc = 0;
+        static final int ic = 0;
+        static final long lc = 0;
+        static final float fc = 0;
+        static final double dc = 0;
+        //static final Object oc = null;
+        static final String tc = "";
+        //static final List<String> gc = null;
+
+        // simple arrays
+        byte[] ba;
+        // short[] sa; // not handled corrected by javah v6
+        int[] ia;
+        long[] la;
+        float[] fa;
+        double[] da;
+        Object[] oa;
+        String[] ta;
+        List<String>[] ga;
+
+        // multidimensional arrays
+        byte[][] baa;
+        short[][] saa;
+        int[][] iaa;
+        long[][] laa;
+        float[][] faa;
+        double[][] daa;
+        Object[][] oaa;
+        String[][] taa;
+        List<String>[] gaa;
+
+        // simple Java methods
+        byte bm() { return 0; }
+        short sm() { return 0; }
+        int im() { return 0; }
+        long lm() { return 0; }
+        float fm() { return 0; }
+        double dm() { return 0; }
+        Object om() { return null; }
+        String tm() { return ""; }
+        List<String> gm() { return null; }
+        void vm() { }
+
+        // simple native methods
+        native byte bmn();
+        native short smn();
+        native int imn();
+        native long lmn();
+        native float fmn();
+        native double dmn();
+        native Object omn();
+        native String tmn();
+        native List<String> gmn();
+        native void vmn();
+
+        // overloaded Java methods
+        byte bm1() { return 0; }
+        short sm1() { return 0; }
+        int im1() { return 0; }
+        long lm1() { return 0; }
+        float fm1() { return 0; }
+        double dm1() { return 0; }
+        Object om1() { return null; }
+        String tm1() { return ""; }
+        List<String> gm1() { return null; }
+        void vm1() { }
+
+        byte bm2(int i) { return 0; }
+        short sm2(int i) { return 0; }
+        int im2(int i) { return 0; }
+        long lm2(int i) { return 0; }
+        float fm2(int i) { return 0; }
+        double dm2(int i) { return 0; }
+        Object om2(int i) { return null; }
+        String tm2(int i) { return ""; }
+        List<String> gm2(int i) { return null; }
+        void vm2(int i) { }
+
+        // overloaded native methods
+        native byte bmn1();
+        native short smn1();
+        native int imn1();
+        native long lmn1();
+        native float fmn1();
+        native double dmn1();
+        native Object omn1();
+        native String tmn1();
+        native List<String> gmn1();
+        native void vmn1();
+
+        native byte bmn2(int i);
+        native short smn2(int i);
+        native int imn2(int i);
+        native long lmn2(int i);
+        native float fmn2(int i);
+        native double dmn2(int i);
+        native Object omn2(int i);
+        native String tmn2(int i);
+        native List<String> gmn2(int i);
+        native void vmn2(int i);
+
+        // arg types for Java methods
+        void mb(byte b) { }
+        void ms(short s) { }
+        void mi(int i) { }
+        void ml(long l) { }
+        void mf(float f) { }
+        void md(double d) { }
+        void mo(Object o) { }
+        void mt(String t) { }
+        void mg(List<String> g) { }
+
+        // arg types for native methods
+        native void mbn(byte b);
+        native void msn(short s);
+        native void min(int i);
+        native void mln(long l);
+        native void mfn(float f);
+        native void mdn(double d);
+        native void mon(Object o);
+        native void mtn(String t);
+        native void mgn(List<String> g);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass2.java	Fri Mar 30 16:57:50 2012 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.tools.annotation.GenerateNativeHeader;
+
+@GenerateNativeHeader
+public class TestClass2 {
+    byte b;
+    short s;
+    int i;
+    long l;
+    float f;
+    double d;
+    Object o;
+    String t;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass3.java	Fri Mar 30 16:57:50 2012 -0700
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.tools.annotation.GenerateNativeHeader;
+
+@GenerateNativeHeader
+public class TestClass3 {
+    public int tc3;
+
+    public class Inner1 {
+        public int tc3i1;
+
+        public class Inner1A {
+            public int tc3i1i1a;
+        }
+
+        public class Inner1B {
+            public int tc3i1i1b;
+        }
+    }
+
+    public class Inner2 {
+        public int tc321;
+
+        public class Inner2A {
+            public int tc3i2i2a;
+        }
+
+        public class Inner2B {
+            public int tc3i2i2b;
+        }
+    }
+}
+
--- a/langtools/test/tools/javac/newlines/Newlines.sh	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/test/tools/javac/newlines/Newlines.sh	Fri Mar 30 16:57:50 2012 -0700
@@ -50,7 +50,7 @@
 # set platform-dependent variables
 OS=`uname -s`
 case "$OS" in
-  SunOS | Linux | CYGWIN* )
+  SunOS | Linux | Darwin | CYGWIN* )
     FS="/"
     ;;
   Windows* )
--- a/langtools/test/tools/javac/stackmap/T4955930.sh	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/test/tools/javac/stackmap/T4955930.sh	Fri Mar 30 16:57:50 2012 -0700
@@ -41,7 +41,7 @@
 # set platform-dependent variables
 OS=`uname -s`
 case "$OS" in
-  SunOS | Linux | CYGWIN* )
+  SunOS | Linux | Darwin | CYGWIN* )
     FS="/"
     ;;
   Windows_95 | Windows_98 | Windows_NT )
--- a/langtools/test/tools/javac/unicode/SupplementaryJavaID6.sh	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/test/tools/javac/unicode/SupplementaryJavaID6.sh	Fri Mar 30 16:57:50 2012 -0700
@@ -55,7 +55,7 @@
 # set platform-dependent variables
 OS=`uname -s`
 case "$OS" in
-  SunOS | Linux )
+  SunOS | Linux | Darwin )
     if [ -d /usr/lib/locale/en_US.UTF-8 -o -d /usr/lib/locale/en_US.utf8 ]
     then
         ENV="env LANG=en_US.UTF-8"
--- a/langtools/test/tools/javah/6257087/foo.sh	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/test/tools/javah/6257087/foo.sh	Fri Mar 30 16:57:50 2012 -0700
@@ -41,7 +41,7 @@
 # set platform-dependent variables
 OS=`uname -s`
 case "$OS" in
-  SunOS | Linux )
+  SunOS | Linux | Darwin )
     PS=":"
     FS="/"
     ;;
--- a/langtools/test/tools/javah/ConstMacroTest.sh	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/test/tools/javah/ConstMacroTest.sh	Fri Mar 30 16:57:50 2012 -0700
@@ -56,7 +56,7 @@
 # set platform-dependent variables
 OS=`uname -s`
 case "$OS" in
-  SunOS | Linux )
+  SunOS | Linux | Darwin )
     PS=":"
     FS="/"
     ;;
--- a/langtools/test/tools/javah/MissingParamClassTest.sh	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/test/tools/javah/MissingParamClassTest.sh	Fri Mar 30 16:57:50 2012 -0700
@@ -58,7 +58,7 @@
 # set platform-dependent variables
 OS=`uname -s`
 case "$OS" in
-  SunOS | Linux | CYGWIN* )
+  SunOS | Linux | Darwin | CYGWIN* )
     PS=":"
     FS="/"
     ;;
--- a/langtools/test/tools/javah/ReadOldClass.sh	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/test/tools/javah/ReadOldClass.sh	Fri Mar 30 16:57:50 2012 -0700
@@ -43,7 +43,7 @@
 # set platform-dependent variables
 OS=`uname -s`
 case "$OS" in
-  SunOS | Linux | CYGWIN* )
+  SunOS | Linux | Darwin | CYGWIN* )
     PS=":"
     FS="/"
     ;;
--- a/langtools/test/tools/javap/pathsep.sh	Fri Mar 30 15:43:13 2012 -0700
+++ b/langtools/test/tools/javap/pathsep.sh	Fri Mar 30 16:57:50 2012 -0700
@@ -40,7 +40,7 @@
 # set platform-dependent variables
 OS=`uname -s`
 case "$OS" in
-  SunOS | Linux | CYGWIN* )
+  SunOS | Linux | Darwin | CYGWIN* )
     FS="/"
     ;;
   Windows* )
--- a/make/Defs-internal.gmk	Fri Mar 30 15:43:13 2012 -0700
+++ b/make/Defs-internal.gmk	Fri Mar 30 16:57:50 2012 -0700
@@ -79,7 +79,7 @@
 # Find all build_time_* files and print their contents in a list sorted
 # on the name of the sub repository.
 define ReportBuildTimes
-$(PRINTF) "-- Build times ----------\nTarget %s\nStart %s\nEnd   %s\n%s\n%s\n-------------------------\n" \
+$(PRINTF) -- "-- Build times ----------\nTarget %s\nStart %s\nEnd   %s\n%s\n%s\n-------------------------\n" \
 $1 \
 "`$(CAT) $(BUILDTIMESDIR)/build_time_start_TOTAL_human_readable`" \
 "`$(CAT) $(BUILDTIMESDIR)/build_time_end_TOTAL_human_readable`" \
--- a/make/jprt.properties	Fri Mar 30 15:43:13 2012 -0700
+++ b/make/jprt.properties	Fri Mar 30 16:57:50 2012 -0700
@@ -39,6 +39,7 @@
     solaris_x64_5.10-{product|fastdebug}, 			\
     linux_i586_2.6-{product|fastdebug}, 			\
     linux_x64_2.6-{product|fastdebug}, 				\
+    macosx_x64_10.7-{product|fastdebug}, 			\
     windows_i586_5.1-{product|fastdebug}, 			\
     windows_x64_5.2-{product|fastdebug}
 
@@ -53,6 +54,7 @@
     solaris_x64_5.10-product-c2-TESTNAME, 			\
     linux_i586_2.6-product-{c1|c2}-TESTNAME, 			\
     linux_x64_2.6-product-c2-TESTNAME, 				\
+    macosx_x64_10.7-product-c2-TESTNAME, 			\
     windows_i586_5.1-product-c1-TESTNAME, 			\
     windows_x64_5.2-product-c2-TESTNAME