changeset 30203:34c211308dc5

Merge
author zmajo
date Fri, 27 Mar 2015 14:52:45 +0000
parents 6f5c48bd9b82 f71778abd2d4
children 4f690700bbb9
files hotspot/src/share/vm/memory/specialized_oop_closures.cpp jdk/make/gensrc/Gensrc-jdk.jconsole.gmk jdk/src/jdk.jconsole/share/classes/sun/tools/jconsole/Version.java.template
diffstat 474 files changed, 18603 insertions(+), 5654 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Fri Mar 27 10:57:42 2015 +0100
+++ b/.hgtags	Fri Mar 27 14:52:45 2015 +0000
@@ -297,3 +297,4 @@
 d6224d6021459ac8b3832e822f5acc849fa944af jdk9-b52
 874d76e4699dfcd61ae1826c9fe0ddc1610ad598 jdk9-b53
 82cd31c5d6ca8d4c1653f4eb1c09eb2d9a3b2813 jdk9-b54
+c97e2d1bad9708d379793ba2a4c848eda14c741e jdk9-b55
--- a/.hgtags-top-repo	Fri Mar 27 10:57:42 2015 +0100
+++ b/.hgtags-top-repo	Fri Mar 27 14:52:45 2015 +0000
@@ -297,3 +297,4 @@
 1822e59f17121b09e7899cf338cfb6e37fe5fceb jdk9-b52
 d6ed47125a76cd1cf8a100568507bfb5e9669d9f jdk9-b53
 cb7367141e910e265b8344a8facee740bd1e5467 jdk9-b54
+0c37a832458f0e0b7d2a3f1a6f69aeae311aeb18 jdk9-b55
--- a/common/autoconf/configure.ac	Fri Mar 27 10:57:42 2015 +0100
+++ b/common/autoconf/configure.ac	Fri Mar 27 14:52:45 2015 +0000
@@ -54,6 +54,7 @@
 
 AC_DEFUN_ONCE([CUSTOM_EARLY_HOOK])
 AC_DEFUN_ONCE([CUSTOM_LATE_HOOK])
+AC_DEFUN_ONCE([CUSTOM_CONFIG_OUTPUT_GENERATED_HOOK])
 AC_DEFUN_ONCE([CUSTOM_SUMMARY_AND_WARNINGS_HOOK])
 
 # This line needs to be here, verbatim, after all includes and the dummy hook
@@ -265,6 +266,7 @@
 
 # Create the actual output files. Now the main work of configure is done.
 AC_OUTPUT
+CUSTOM_CONFIG_OUTPUT_GENERATED_HOOK
 
 # Try to move the config.log file to the output directory.
 if test -e ./config.log; then
--- a/common/autoconf/flags.m4	Fri Mar 27 10:57:42 2015 +0100
+++ b/common/autoconf/flags.m4	Fri Mar 27 14:52:45 2015 +0000
@@ -481,9 +481,8 @@
     CFLAGS_JDKLIB_EXTRA="${CFLAGS_JDKLIB_EXTRA} -errtags=yes -errfmt"
     CXXFLAGS_JDKLIB_EXTRA="${CXXFLAGS_JDKLIB_EXTRA} -errtags=yes -errfmt"
   elif test "x$TOOLCHAIN_TYPE" = xxlc; then
-    LDFLAGS_JDK="${LDFLAGS_JDK} -q64 -brtl -bnolibpath -liconv -bexpall"
-    CFLAGS_JDK="${CFLAGS_JDK} -qchars=signed -q64 -qfullpath -qsaveopt"
-    CXXFLAGS_JDK="${CXXFLAGS_JDK} -qchars=signed -q64 -qfullpath -qsaveopt"
+    CFLAGS_JDK="${CFLAGS_JDK} -qchars=signed -qfullpath -qsaveopt"
+    CXXFLAGS_JDK="${CXXFLAGS_JDK} -qchars=signed -qfullpath -qsaveopt"
   fi
 
   if test "x$CFLAGS" != "x${ADDED_CFLAGS}"; then
@@ -762,6 +761,8 @@
   elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
     LDFLAGS_JDK="$LDFLAGS_JDK -z defs -xildoff -ztext"
     LDFLAGS_CXX_JDK="$LDFLAGS_CXX_JDK -norunpath -xnolib"
+  elif test "x$TOOLCHAIN_TYPE" = xxlc; then
+    LDFLAGS_JDK="${LDFLAGS_JDK} -brtl -bnolibpath -liconv -bexpall -bernotok"
   fi
 
   # Customize LDFLAGS for executables
--- a/common/autoconf/generated-configure.sh	Fri Mar 27 10:57:42 2015 +0100
+++ b/common/autoconf/generated-configure.sh	Fri Mar 27 14:52:45 2015 +0000
@@ -4362,13 +4362,14 @@
 
 
 
+
 # This line needs to be here, verbatim, after all includes and the dummy hook
 # definitions. It is replaced with custom functionality when building
 # custom sources.
 #CUSTOM_AUTOCONF_INCLUDE
 
 # Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1425994551
+DATE_WHEN_GENERATED=1426774983
 
 ###############################################################################
 #
@@ -41173,7 +41174,7 @@
 
 
       # jtreg win32 script works for everybody
-      JTREGEXE="$JT_HOME/win32/bin/jtreg"
+      JTREGEXE="$JT_HOME/bin/jtreg"
 
       if test ! -f "$JTREGEXE"; then
         as_fn_error $? "JTReg executable does not exist: $JTREGEXE" "$LINENO" 5
@@ -42372,9 +42373,8 @@
     CFLAGS_JDKLIB_EXTRA="${CFLAGS_JDKLIB_EXTRA} -errtags=yes -errfmt"
     CXXFLAGS_JDKLIB_EXTRA="${CXXFLAGS_JDKLIB_EXTRA} -errtags=yes -errfmt"
   elif test "x$TOOLCHAIN_TYPE" = xxlc; then
-    LDFLAGS_JDK="${LDFLAGS_JDK} -q64 -brtl -bnolibpath -liconv -bexpall"
-    CFLAGS_JDK="${CFLAGS_JDK} -qchars=signed -q64 -qfullpath -qsaveopt"
-    CXXFLAGS_JDK="${CXXFLAGS_JDK} -qchars=signed -q64 -qfullpath -qsaveopt"
+    CFLAGS_JDK="${CFLAGS_JDK} -qchars=signed -qfullpath -qsaveopt"
+    CXXFLAGS_JDK="${CXXFLAGS_JDK} -qchars=signed -qfullpath -qsaveopt"
   fi
 
   if test "x$CFLAGS" != "x${ADDED_CFLAGS}"; then
@@ -42668,6 +42668,8 @@
   elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
     LDFLAGS_JDK="$LDFLAGS_JDK -z defs -xildoff -ztext"
     LDFLAGS_CXX_JDK="$LDFLAGS_CXX_JDK -norunpath -xnolib"
+  elif test "x$TOOLCHAIN_TYPE" = xxlc; then
+    LDFLAGS_JDK="${LDFLAGS_JDK} -brtl -bnolibpath -liconv -bexpall -bernotok"
   fi
 
   # Customize LDFLAGS for executables
@@ -52969,6 +52971,7 @@
 fi
 
 
+
 # Try to move the config.log file to the output directory.
 if test -e ./config.log; then
   $MV -f ./config.log "$OUTPUT_ROOT/config.log" 2> /dev/null
--- a/common/autoconf/toolchain.m4	Fri Mar 27 10:57:42 2015 +0100
+++ b/common/autoconf/toolchain.m4	Fri Mar 27 14:52:45 2015 +0000
@@ -763,7 +763,7 @@
       BASIC_FIXUP_PATH([JT_HOME])
 
       # jtreg win32 script works for everybody
-      JTREGEXE="$JT_HOME/win32/bin/jtreg"
+      JTREGEXE="$JT_HOME/bin/jtreg"
 
       if test ! -f "$JTREGEXE"; then
         AC_MSG_ERROR([JTReg executable does not exist: $JTREGEXE])
--- a/corba/.hgtags	Fri Mar 27 10:57:42 2015 +0100
+++ b/corba/.hgtags	Fri Mar 27 14:52:45 2015 +0000
@@ -297,3 +297,4 @@
 b8538bbb6f224ab1dabba579137099c166ad4724 jdk9-b52
 aadc16ca5ab7d56f92ef9dbfa443595a939241b4 jdk9-b53
 d469c5ad0c763e325a78e0af3016878a57dfc5cc jdk9-b54
+734ca5311a225711b79618f3e92f47f07c82154a jdk9-b55
--- a/hotspot/.hgtags	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/.hgtags	Fri Mar 27 14:52:45 2015 +0000
@@ -457,3 +457,4 @@
 9fb7fdc554db5be5c5b10f88f529ec3b870c44e3 jdk9-b52
 effd5ef0c3eb4bb85aa975c489d6761dbf13ad6a jdk9-b53
 c3b117fa5bdedfafd9ed236403e6d406911195b1 jdk9-b54
+be49ab55e5c498c5077bbf58c2737100d1992339 jdk9-b55
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java	Fri Mar 27 14:52:45 2015 +0000
@@ -123,6 +123,7 @@
 
   private static Type intxType;
   private static Type uintxType;
+  private static Type sizetType;
   private static CIntegerType boolType;
   private Boolean sharingEnabled;
   private Boolean compressedOopsEnabled;
@@ -175,7 +176,7 @@
 
      public long getIntx() {
         if (Assert.ASSERTS_ENABLED) {
-           Assert.that(isIntx(), "not a intx flag!");
+           Assert.that(isIntx(), "not an intx flag!");
         }
         return addr.getCIntegerAt(0, intxType.getSize(), false);
      }
@@ -191,6 +192,17 @@
         return addr.getCIntegerAt(0, uintxType.getSize(), true);
      }
 
+     public boolean isSizet() {
+        return type.equals("size_t");
+     }
+
+     public long getSizet() {
+        if (Assert.ASSERTS_ENABLED) {
+           Assert.that(isSizet(), "not a size_t flag!");
+        }
+        return addr.getCIntegerAt(0, sizetType.getSize(), true);
+     }
+
      public String getValue() {
         if (isBool()) {
            return new Boolean(getBool()).toString();
@@ -198,6 +210,8 @@
            return new Long(getIntx()).toString();
         } else if (isUIntx()) {
            return new Long(getUIntx()).toString();
+        } else if (isSizet()) {
+            return new Long(getSizet()).toString();
         } else {
            return null;
         }
@@ -323,6 +337,7 @@
 
     intxType = db.lookupType("intx");
     uintxType = db.lookupType("uintx");
+    sizetType = db.lookupType("size_t");
     boolType = (CIntegerType) db.lookupType("bool");
 
     minObjAlignmentInBytes = getObjectAlignmentInBytes();
--- a/hotspot/make/aix/makefiles/adlc.make	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/make/aix/makefiles/adlc.make	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1999, 2015, 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
@@ -140,13 +140,7 @@
 # Note "+="; it is a hook so flags.make can add more flags, like -g or -DFOO.
 ADLCFLAGS += -q -T
 
-# Normally, debugging is done directly on the ad_<arch>*.cpp files.
-# But -g will put #line directives in those files pointing back to <arch>.ad.
-# Some builds of gcc 3.2 have a bug that gets tickled by the extra #line directives
-# so skip it for 3.2 and ealier.
-ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 3 \) \| \( \( $(CC_VER_MAJOR) = 3 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "0"
 ADLCFLAGS += -g
-endif
 
 ifdef LP64
 ADLCFLAGS += -D_LP64
--- a/hotspot/make/aix/makefiles/ppc64.make	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/make/aix/makefiles/ppc64.make	Fri Mar 27 14:52:45 2015 +0000
@@ -1,6 +1,6 @@
 #
-# Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
-# Copyright 2012, 2013 SAP AG. All rights reserved.
+# Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright 2012, 2015 SAP AG. 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
@@ -71,9 +71,6 @@
 OPT_CFLAGS/sharedRuntimeTrig.o = $(OPT_CFLAGS/NOOPT)
 OPT_CFLAGS/sharedRuntimeTrans.o = $(OPT_CFLAGS/NOOPT)
 
-# xlc 10.01 parameters for ipa compile.
-QIPA_COMPILE=$(if $(CXX_IS_V10),-qipa)
-
 # Xlc 10.1 parameters for aggressive optimization:
 # - qhot=level=1: Most aggressive loop optimizations.
 # - qignerrno: Assume errno is not modified by system calls.
@@ -88,7 +85,7 @@
 OPT_CFLAGS/synchronizer.o = $(OPT_CFLAGS) -qnoinline
 
 # Set all the xlC V10.1 options here.
-OPT_CFLAGS += $(QIPA_COMPILE) $(QV10_OPT) $(QV10_OPT_AGGRESSIVE)
+OPT_CFLAGS += $(QV10_OPT) $(QV10_OPT_AGGRESSIVE)
 
 export OBJECT_MODE=64
 
--- a/hotspot/make/aix/makefiles/xlc.make	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/make/aix/makefiles/xlc.make	Fri Mar 27 14:52:45 2015 +0000
@@ -1,6 +1,6 @@
 #
-# Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
-# Copyright (c) 2012, 2013 SAP. All rights reserved.
+# Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 2015 SAP. 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,13 +34,17 @@
 
 AS  = $(CC) -c
 
-# get xlc version
-CXX_VERSION   := $(shell $(CXX) -qversion 2>&1 | sed -n 's/.*Version: \([0-9.]*\)/\1/p')
+# get xlc version which comes as VV.RR.MMMM.LLLL where 'VV' is the version,
+# 'RR' is the release, 'MMMM' is the modification and 'LLLL' is the level.
+# We only use 'VV.RR.LLLL' to avoid integer overflows in bash when comparing
+# the version numbers (some shells only support 32-bit integer compares!).
+CXX_VERSION := $(shell $(CXX) -qversion 2>&1 | \
+                   sed -n 's/.*Version: \([0-9]\{2\}\).\([0-9]\{2\}\).[0-9]\{4\}.\([0-9]\{4\}\)/\1\2\3/p')
 
 # xlc 08.00.0000.0023 and higher supports -qtune=balanced
-CXX_SUPPORTS_BALANCED_TUNING=$(shell if [ $(subst .,,$(CXX_VERSION)) -ge 080000000023 ] ; then echo "true" ; fi)
+CXX_SUPPORTS_BALANCED_TUNING := $(shell if [ $(CXX_VERSION) -ge 08000023 ] ; then echo "true" ; fi)
 # xlc 10.01 is used with aggressive optimizations to boost performance
-CXX_IS_V10=$(shell if [ $(subst .,,$(CXX_VERSION)) -ge 100100000000 ] ; then echo "true" ; fi)
+CXX_IS_V10 := $(shell if [ $(CXX_VERSION) -ge 10010000 ] ; then echo "true" ; fi)
 
 # check for precompiled headers support
 
--- a/hotspot/make/linux/makefiles/gcc.make	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/make/linux/makefiles/gcc.make	Fri Mar 27 14:52:45 2015 +0000
@@ -207,7 +207,7 @@
   WARNINGS_ARE_ERRORS += -Wno-return-type -Wno-empty-body
 endif
 
-WARNING_FLAGS = -Wpointer-arith -Wsign-compare -Wundef -Wunused-function -Wunused-value -Wformat=2 -Wreturn-type
+WARNING_FLAGS = -Wpointer-arith -Wsign-compare -Wundef -Wunused-function -Wunused-value -Wformat=2 -Wreturn-type -Woverloaded-virtual
 
 ifeq ($(USE_CLANG),)
   # Since GCC 4.3, -Wconversion has changed its meanings to warn these implicit
--- a/hotspot/src/cpu/aarch64/vm/aarch64.ad	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/cpu/aarch64/vm/aarch64.ad	Fri Mar 27 14:52:45 2015 +0000
@@ -6087,7 +6087,7 @@
 %}
 
 // Store Byte
-instruct storeB_volatile(iRegI src, /* sync_memory*/indirect mem)
+instruct storeB_volatile(iRegIorL2I src, /* sync_memory*/indirect mem)
 %{
   match(Set mem (StoreB mem src));
 
@@ -6100,7 +6100,7 @@
 %}
 
 // Store Char/Short
-instruct storeC_volatile(iRegI src, /* sync_memory*/indirect mem)
+instruct storeC_volatile(iRegIorL2I src, /* sync_memory*/indirect mem)
 %{
   match(Set mem (StoreC mem src));
 
@@ -6256,7 +6256,7 @@
 // ============================================================================
 // Zero Count Instructions
 
-instruct countLeadingZerosI(iRegINoSp dst, iRegI src) %{
+instruct countLeadingZerosI(iRegINoSp dst, iRegIorL2I src) %{
   match(Set dst (CountLeadingZerosI src));
 
   ins_cost(INSN_COST);
@@ -6280,7 +6280,7 @@
   ins_pipe(ialu_reg);
 %}
 
-instruct countTrailingZerosI(iRegINoSp dst, iRegI src) %{
+instruct countTrailingZerosI(iRegINoSp dst, iRegIorL2I src) %{
   match(Set dst (CountTrailingZerosI src));
 
   ins_cost(INSN_COST * 2);
@@ -6966,7 +6966,7 @@
 // which throws a ShouldNotHappen. So, we have to provide two flavours
 // of each rule, one for a cmpOp and a second for a cmpOpU (sigh).
 
-instruct cmovI_reg_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegI src1, iRegI src2) %{
+instruct cmovI_reg_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
   match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2)));
 
   ins_cost(INSN_COST * 2);
@@ -6982,7 +6982,7 @@
   ins_pipe(icond_reg_reg);
 %}
 
-instruct cmovUI_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegI src1, iRegI src2) %{
+instruct cmovUI_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
   match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2)));
 
   ins_cost(INSN_COST * 2);
@@ -7007,7 +7007,7 @@
 // we ought only to be able to cull one of these variants as the ideal
 // transforms ought always to order the zero consistently (to left/right?)
 
-instruct cmovI_zero_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, iRegI src) %{
+instruct cmovI_zero_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{
   match(Set dst (CMoveI (Binary cmp cr) (Binary zero src)));
 
   ins_cost(INSN_COST * 2);
@@ -7023,7 +7023,7 @@
   ins_pipe(icond_reg);
 %}
 
-instruct cmovUI_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, iRegI src) %{
+instruct cmovUI_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{
   match(Set dst (CMoveI (Binary cmp cr) (Binary zero src)));
 
   ins_cost(INSN_COST * 2);
@@ -7039,7 +7039,7 @@
   ins_pipe(icond_reg);
 %}
 
-instruct cmovI_reg_zero(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegI src, immI0 zero) %{
+instruct cmovI_reg_zero(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{
   match(Set dst (CMoveI (Binary cmp cr) (Binary src zero)));
 
   ins_cost(INSN_COST * 2);
@@ -7055,7 +7055,7 @@
   ins_pipe(icond_reg);
 %}
 
-instruct cmovUI_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegI src, immI0 zero) %{
+instruct cmovUI_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{
   match(Set dst (CMoveI (Binary cmp cr) (Binary src zero)));
 
   ins_cost(INSN_COST * 2);
@@ -7507,7 +7507,7 @@
   ins_pipe(ialu_reg_reg);
 %}
 
-instruct addI_reg_imm(iRegINoSp dst, iRegI src1, immIAddSub src2) %{
+instruct addI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{
   match(Set dst (AddI src1 src2));
 
   ins_cost(INSN_COST);
@@ -7900,7 +7900,7 @@
   ins_pipe(idiv_reg_reg);
 %}
 
-instruct signExtract(iRegINoSp dst, iRegI src1, immI_31 div1, immI_31 div2) %{
+instruct signExtract(iRegINoSp dst, iRegIorL2I src1, immI_31 div1, immI_31 div2) %{
   match(Set dst (URShiftI (RShiftI src1 div1) div2));
   ins_cost(INSN_COST);
   format %{ "lsrw $dst, $src1, $div1" %}
@@ -7910,7 +7910,7 @@
   ins_pipe(ialu_reg_shift);
 %}
 
-instruct div2Round(iRegINoSp dst, iRegI src, immI_31 div1, immI_31 div2) %{
+instruct div2Round(iRegINoSp dst, iRegIorL2I src, immI_31 div1, immI_31 div2) %{
   match(Set dst (AddI src (URShiftI (RShiftI src div1) div2)));
   ins_cost(INSN_COST);
   format %{ "addw $dst, $src, LSR $div1" %}
@@ -8220,7 +8220,7 @@
   ins_pipe(ialu_reg);
 %}
 instruct regI_not_reg(iRegINoSp dst,
-                         iRegI src1, immI_M1 m1,
+                         iRegIorL2I src1, immI_M1 m1,
                          rFlagsReg cr) %{
   match(Set dst (XorI src1 m1));
   ins_cost(INSN_COST);
@@ -8237,10 +8237,27 @@
 %}
 
 instruct AndI_reg_not_reg(iRegINoSp dst,
-                         iRegI src1, iRegI src2, immI_M1 m1,
+                         iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1,
                          rFlagsReg cr) %{
   match(Set dst (AndI src1 (XorI src2 m1)));
   ins_cost(INSN_COST);
+  format %{ "bicw  $dst, $src1, $src2" %}
+
+  ins_encode %{
+    __ bicw(as_Register($dst$$reg),
+              as_Register($src1$$reg),
+              as_Register($src2$$reg),
+              Assembler::LSL, 0);
+  %}
+
+  ins_pipe(ialu_reg_reg);
+%}
+
+instruct AndL_reg_not_reg(iRegLNoSp dst,
+                         iRegL src1, iRegL src2, immL_M1 m1,
+                         rFlagsReg cr) %{
+  match(Set dst (AndL src1 (XorL src2 m1)));
+  ins_cost(INSN_COST);
   format %{ "bic  $dst, $src1, $src2" %}
 
   ins_encode %{
@@ -8253,15 +8270,15 @@
   ins_pipe(ialu_reg_reg);
 %}
 
-instruct AndL_reg_not_reg(iRegLNoSp dst,
-                         iRegL src1, iRegL src2, immL_M1 m1,
+instruct OrI_reg_not_reg(iRegINoSp dst,
+                         iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1,
                          rFlagsReg cr) %{
-  match(Set dst (AndL src1 (XorL src2 m1)));
-  ins_cost(INSN_COST);
-  format %{ "bic  $dst, $src1, $src2" %}
-
-  ins_encode %{
-    __ bic(as_Register($dst$$reg),
+  match(Set dst (OrI src1 (XorI src2 m1)));
+  ins_cost(INSN_COST);
+  format %{ "ornw  $dst, $src1, $src2" %}
+
+  ins_encode %{
+    __ ornw(as_Register($dst$$reg),
               as_Register($src1$$reg),
               as_Register($src2$$reg),
               Assembler::LSL, 0);
@@ -8270,10 +8287,10 @@
   ins_pipe(ialu_reg_reg);
 %}
 
-instruct OrI_reg_not_reg(iRegINoSp dst,
-                         iRegI src1, iRegI src2, immI_M1 m1,
+instruct OrL_reg_not_reg(iRegLNoSp dst,
+                         iRegL src1, iRegL src2, immL_M1 m1,
                          rFlagsReg cr) %{
-  match(Set dst (OrI src1 (XorI src2 m1)));
+  match(Set dst (OrL src1 (XorL src2 m1)));
   ins_cost(INSN_COST);
   format %{ "orn  $dst, $src1, $src2" %}
 
@@ -8287,15 +8304,15 @@
   ins_pipe(ialu_reg_reg);
 %}
 
-instruct OrL_reg_not_reg(iRegLNoSp dst,
-                         iRegL src1, iRegL src2, immL_M1 m1,
+instruct XorI_reg_not_reg(iRegINoSp dst,
+                         iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1,
                          rFlagsReg cr) %{
-  match(Set dst (OrL src1 (XorL src2 m1)));
-  ins_cost(INSN_COST);
-  format %{ "orn  $dst, $src1, $src2" %}
-
-  ins_encode %{
-    __ orn(as_Register($dst$$reg),
+  match(Set dst (XorI m1 (XorI src2 src1)));
+  ins_cost(INSN_COST);
+  format %{ "eonw  $dst, $src1, $src2" %}
+
+  ins_encode %{
+    __ eonw(as_Register($dst$$reg),
               as_Register($src1$$reg),
               as_Register($src2$$reg),
               Assembler::LSL, 0);
@@ -8304,10 +8321,10 @@
   ins_pipe(ialu_reg_reg);
 %}
 
-instruct XorI_reg_not_reg(iRegINoSp dst,
-                         iRegI src1, iRegI src2, immI_M1 m1,
+instruct XorL_reg_not_reg(iRegLNoSp dst,
+                         iRegL src1, iRegL src2, immL_M1 m1,
                          rFlagsReg cr) %{
-  match(Set dst (XorI m1 (XorI src2 src1)));
+  match(Set dst (XorL m1 (XorL src2 src1)));
   ins_cost(INSN_COST);
   format %{ "eon  $dst, $src1, $src2" %}
 
@@ -8321,25 +8338,8 @@
   ins_pipe(ialu_reg_reg);
 %}
 
-instruct XorL_reg_not_reg(iRegLNoSp dst,
-                         iRegL src1, iRegL src2, immL_M1 m1,
-                         rFlagsReg cr) %{
-  match(Set dst (XorL m1 (XorL src2 src1)));
-  ins_cost(INSN_COST);
-  format %{ "eon  $dst, $src1, $src2" %}
-
-  ins_encode %{
-    __ eon(as_Register($dst$$reg),
-              as_Register($src1$$reg),
-              as_Register($src2$$reg),
-              Assembler::LSL, 0);
-  %}
-
-  ins_pipe(ialu_reg_reg);
-%}
-
 instruct AndI_reg_URShift_not_reg(iRegINoSp dst,
-                         iRegI src1, iRegI src2,
+                         iRegIorL2I src1, iRegIorL2I src2,
                          immI src3, immI_M1 src4, rFlagsReg cr) %{
   match(Set dst (AndI src1 (XorI(URShiftI src2 src3) src4)));
   ins_cost(1.9 * INSN_COST);
@@ -8375,7 +8375,7 @@
 %}
 
 instruct AndI_reg_RShift_not_reg(iRegINoSp dst,
-                         iRegI src1, iRegI src2,
+                         iRegIorL2I src1, iRegIorL2I src2,
                          immI src3, immI_M1 src4, rFlagsReg cr) %{
   match(Set dst (AndI src1 (XorI(RShiftI src2 src3) src4)));
   ins_cost(1.9 * INSN_COST);
@@ -8411,7 +8411,7 @@
 %}
 
 instruct AndI_reg_LShift_not_reg(iRegINoSp dst,
-                         iRegI src1, iRegI src2,
+                         iRegIorL2I src1, iRegIorL2I src2,
                          immI src3, immI_M1 src4, rFlagsReg cr) %{
   match(Set dst (AndI src1 (XorI(LShiftI src2 src3) src4)));
   ins_cost(1.9 * INSN_COST);
@@ -8447,7 +8447,7 @@
 %}
 
 instruct XorI_reg_URShift_not_reg(iRegINoSp dst,
-                         iRegI src1, iRegI src2,
+                         iRegIorL2I src1, iRegIorL2I src2,
                          immI src3, immI_M1 src4, rFlagsReg cr) %{
   match(Set dst (XorI src4 (XorI(URShiftI src2 src3) src1)));
   ins_cost(1.9 * INSN_COST);
@@ -8483,7 +8483,7 @@
 %}
 
 instruct XorI_reg_RShift_not_reg(iRegINoSp dst,
-                         iRegI src1, iRegI src2,
+                         iRegIorL2I src1, iRegIorL2I src2,
                          immI src3, immI_M1 src4, rFlagsReg cr) %{
   match(Set dst (XorI src4 (XorI(RShiftI src2 src3) src1)));
   ins_cost(1.9 * INSN_COST);
@@ -8519,7 +8519,7 @@
 %}
 
 instruct XorI_reg_LShift_not_reg(iRegINoSp dst,
-                         iRegI src1, iRegI src2,
+                         iRegIorL2I src1, iRegIorL2I src2,
                          immI src3, immI_M1 src4, rFlagsReg cr) %{
   match(Set dst (XorI src4 (XorI(LShiftI src2 src3) src1)));
   ins_cost(1.9 * INSN_COST);
@@ -8555,7 +8555,7 @@
 %}
 
 instruct OrI_reg_URShift_not_reg(iRegINoSp dst,
-                         iRegI src1, iRegI src2,
+                         iRegIorL2I src1, iRegIorL2I src2,
                          immI src3, immI_M1 src4, rFlagsReg cr) %{
   match(Set dst (OrI src1 (XorI(URShiftI src2 src3) src4)));
   ins_cost(1.9 * INSN_COST);
@@ -8591,7 +8591,7 @@
 %}
 
 instruct OrI_reg_RShift_not_reg(iRegINoSp dst,
-                         iRegI src1, iRegI src2,
+                         iRegIorL2I src1, iRegIorL2I src2,
                          immI src3, immI_M1 src4, rFlagsReg cr) %{
   match(Set dst (OrI src1 (XorI(RShiftI src2 src3) src4)));
   ins_cost(1.9 * INSN_COST);
@@ -8627,7 +8627,7 @@
 %}
 
 instruct OrI_reg_LShift_not_reg(iRegINoSp dst,
-                         iRegI src1, iRegI src2,
+                         iRegIorL2I src1, iRegIorL2I src2,
                          immI src3, immI_M1 src4, rFlagsReg cr) %{
   match(Set dst (OrI src1 (XorI(LShiftI src2 src3) src4)));
   ins_cost(1.9 * INSN_COST);
@@ -8663,7 +8663,7 @@
 %}
 
 instruct AndI_reg_URShift_reg(iRegINoSp dst,
-                         iRegI src1, iRegI src2,
+                         iRegIorL2I src1, iRegIorL2I src2,
                          immI src3, rFlagsReg cr) %{
   match(Set dst (AndI src1 (URShiftI src2 src3)));
 
@@ -8701,7 +8701,7 @@
 %}
 
 instruct AndI_reg_RShift_reg(iRegINoSp dst,
-                         iRegI src1, iRegI src2,
+                         iRegIorL2I src1, iRegIorL2I src2,
                          immI src3, rFlagsReg cr) %{
   match(Set dst (AndI src1 (RShiftI src2 src3)));
 
@@ -8739,7 +8739,7 @@
 %}
 
 instruct AndI_reg_LShift_reg(iRegINoSp dst,
-                         iRegI src1, iRegI src2,
+                         iRegIorL2I src1, iRegIorL2I src2,
                          immI src3, rFlagsReg cr) %{
   match(Set dst (AndI src1 (LShiftI src2 src3)));
 
@@ -8777,7 +8777,7 @@
 %}
 
 instruct XorI_reg_URShift_reg(iRegINoSp dst,
-                         iRegI src1, iRegI src2,
+                         iRegIorL2I src1, iRegIorL2I src2,
                          immI src3, rFlagsReg cr) %{
   match(Set dst (XorI src1 (URShiftI src2 src3)));
 
@@ -8815,7 +8815,7 @@
 %}
 
 instruct XorI_reg_RShift_reg(iRegINoSp dst,
-                         iRegI src1, iRegI src2,
+                         iRegIorL2I src1, iRegIorL2I src2,
                          immI src3, rFlagsReg cr) %{
   match(Set dst (XorI src1 (RShiftI src2 src3)));
 
@@ -8853,7 +8853,7 @@
 %}
 
 instruct XorI_reg_LShift_reg(iRegINoSp dst,
-                         iRegI src1, iRegI src2,
+                         iRegIorL2I src1, iRegIorL2I src2,
                          immI src3, rFlagsReg cr) %{
   match(Set dst (XorI src1 (LShiftI src2 src3)));
 
@@ -8891,7 +8891,7 @@
 %}
 
 instruct OrI_reg_URShift_reg(iRegINoSp dst,
-                         iRegI src1, iRegI src2,
+                         iRegIorL2I src1, iRegIorL2I src2,
                          immI src3, rFlagsReg cr) %{
   match(Set dst (OrI src1 (URShiftI src2 src3)));
 
@@ -8929,7 +8929,7 @@
 %}
 
 instruct OrI_reg_RShift_reg(iRegINoSp dst,
-                         iRegI src1, iRegI src2,
+                         iRegIorL2I src1, iRegIorL2I src2,
                          immI src3, rFlagsReg cr) %{
   match(Set dst (OrI src1 (RShiftI src2 src3)));
 
@@ -8967,7 +8967,7 @@
 %}
 
 instruct OrI_reg_LShift_reg(iRegINoSp dst,
-                         iRegI src1, iRegI src2,
+                         iRegIorL2I src1, iRegIorL2I src2,
                          immI src3, rFlagsReg cr) %{
   match(Set dst (OrI src1 (LShiftI src2 src3)));
 
@@ -9005,7 +9005,7 @@
 %}
 
 instruct AddI_reg_URShift_reg(iRegINoSp dst,
-                         iRegI src1, iRegI src2,
+                         iRegIorL2I src1, iRegIorL2I src2,
                          immI src3, rFlagsReg cr) %{
   match(Set dst (AddI src1 (URShiftI src2 src3)));
 
@@ -9043,7 +9043,7 @@
 %}
 
 instruct AddI_reg_RShift_reg(iRegINoSp dst,
-                         iRegI src1, iRegI src2,
+                         iRegIorL2I src1, iRegIorL2I src2,
                          immI src3, rFlagsReg cr) %{
   match(Set dst (AddI src1 (RShiftI src2 src3)));
 
@@ -9081,7 +9081,7 @@
 %}
 
 instruct AddI_reg_LShift_reg(iRegINoSp dst,
-                         iRegI src1, iRegI src2,
+                         iRegIorL2I src1, iRegIorL2I src2,
                          immI src3, rFlagsReg cr) %{
   match(Set dst (AddI src1 (LShiftI src2 src3)));
 
@@ -9119,7 +9119,7 @@
 %}
 
 instruct SubI_reg_URShift_reg(iRegINoSp dst,
-                         iRegI src1, iRegI src2,
+                         iRegIorL2I src1, iRegIorL2I src2,
                          immI src3, rFlagsReg cr) %{
   match(Set dst (SubI src1 (URShiftI src2 src3)));
 
@@ -9157,7 +9157,7 @@
 %}
 
 instruct SubI_reg_RShift_reg(iRegINoSp dst,
-                         iRegI src1, iRegI src2,
+                         iRegIorL2I src1, iRegIorL2I src2,
                          immI src3, rFlagsReg cr) %{
   match(Set dst (SubI src1 (RShiftI src2 src3)));
 
@@ -9195,7 +9195,7 @@
 %}
 
 instruct SubI_reg_LShift_reg(iRegINoSp dst,
-                         iRegI src1, iRegI src2,
+                         iRegIorL2I src1, iRegIorL2I src2,
                          immI src3, rFlagsReg cr) %{
   match(Set dst (SubI src1 (LShiftI src2 src3)));
 
@@ -9259,7 +9259,7 @@
 
 // Shift Left followed by Shift Right.
 // This idiom is used by the compiler for the i2b bytecode etc.
-instruct sbfmwI(iRegINoSp dst, iRegI src, immI lshift_count, immI rshift_count)
+instruct sbfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count)
 %{
   match(Set dst (RShiftI (LShiftI src lshift_count) rshift_count));
   // Make sure we are not going to exceed what sbfmw can do.
@@ -9305,7 +9305,7 @@
 
 // Shift Left followed by Shift Right.
 // This idiom is used by the compiler for the i2b bytecode etc.
-instruct ubfmwI(iRegINoSp dst, iRegI src, immI lshift_count, immI rshift_count)
+instruct ubfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count)
 %{
   match(Set dst (URShiftI (LShiftI src lshift_count) rshift_count));
   // Make sure we are not going to exceed what ubfmw can do.
@@ -9327,7 +9327,7 @@
 %}
 // Bitfield extract with shift & mask
 
-instruct ubfxwI(iRegINoSp dst, iRegI src, immI rshift, immI_bitmask mask)
+instruct ubfxwI(iRegINoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask)
 %{
   match(Set dst (AndI (URShiftI src rshift) mask));
 
@@ -9393,7 +9393,7 @@
   ins_pipe(ialu_reg_reg_extr);
 %}
 
-instruct extrOrI(iRegINoSp dst, iRegI src1, iRegI src2, immI lshift, immI rshift, rFlagsReg cr)
+instruct extrOrI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr)
 %{
   match(Set dst (OrI (LShiftI src1 lshift) (URShiftI src2 rshift)));
   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 31));
@@ -9423,7 +9423,7 @@
   ins_pipe(ialu_reg_reg_extr);
 %}
 
-instruct extrAddI(iRegINoSp dst, iRegI src1, iRegI src2, immI lshift, immI rshift, rFlagsReg cr)
+instruct extrAddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr)
 %{
   match(Set dst (AddI (LShiftI src1 lshift) (URShiftI src2 rshift)));
   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 31));
@@ -9602,7 +9602,7 @@
 %};
 
 
-instruct AddExtI_sxth(iRegINoSp dst, iRegI src1, iRegI src2, immI_16 lshift, immI_16 rshift, rFlagsReg cr)
+instruct AddExtI_sxth(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_16 lshift, immI_16 rshift, rFlagsReg cr)
 %{
   match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift)));
   ins_cost(INSN_COST);
@@ -9615,7 +9615,7 @@
   ins_pipe(ialu_reg_reg);
 %}
 
-instruct AddExtI_sxtb(iRegINoSp dst, iRegI src1, iRegI src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr)
+instruct AddExtI_sxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr)
 %{
   match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift)));
   ins_cost(INSN_COST);
@@ -9628,7 +9628,7 @@
   ins_pipe(ialu_reg_reg);
 %}
 
-instruct AddExtI_uxtb(iRegINoSp dst, iRegI src1, iRegI src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr)
+instruct AddExtI_uxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr)
 %{
   match(Set dst (AddI src1 (URShiftI (LShiftI src2 lshift) rshift)));
   ins_cost(INSN_COST);
@@ -9694,7 +9694,7 @@
 %}
 
 
-instruct AddExtI_uxtb_and(iRegINoSp dst, iRegI src1, iRegI src2, immI_255 mask, rFlagsReg cr)
+instruct AddExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr)
 %{
   match(Set dst (AddI src1 (AndI src2 mask)));
   ins_cost(INSN_COST);
@@ -9707,7 +9707,7 @@
   ins_pipe(ialu_reg_reg);
 %}
 
-instruct AddExtI_uxth_and(iRegINoSp dst, iRegI src1, iRegI src2, immI_65535 mask, rFlagsReg cr)
+instruct AddExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr)
 %{
   match(Set dst (AddI src1 (AndI src2 mask)));
   ins_cost(INSN_COST);
@@ -9759,7 +9759,7 @@
   ins_pipe(ialu_reg_reg);
 %}
 
-instruct SubExtI_uxtb_and(iRegINoSp dst, iRegI src1, iRegI src2, immI_255 mask, rFlagsReg cr)
+instruct SubExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr)
 %{
   match(Set dst (SubI src1 (AndI src2 mask)));
   ins_cost(INSN_COST);
@@ -9772,7 +9772,7 @@
   ins_pipe(ialu_reg_reg);
 %}
 
-instruct SubExtI_uxth_and(iRegINoSp dst, iRegI src1, iRegI src2, immI_65535 mask, rFlagsReg cr)
+instruct SubExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr)
 %{
   match(Set dst (SubI src1 (AndI src2 mask)));
   ins_cost(INSN_COST);
@@ -10374,7 +10374,7 @@
 %}
 
 // this pattern occurs in bigmath arithmetic
-instruct convUI2L_reg_reg(iRegLNoSp dst, iRegI src, immL_32bits mask)
+instruct convUI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src, immL_32bits mask)
 %{
   match(Set dst (AndL (ConvI2L src) mask));
 
@@ -10400,7 +10400,7 @@
   ins_pipe(ialu_reg);
 %}
 
-instruct convI2B(iRegINoSp dst, iRegI src, rFlagsReg cr)
+instruct convI2B(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr)
 %{
   match(Set dst (Conv2B src));
   effect(KILL cr);
@@ -10488,7 +10488,7 @@
   ins_pipe(pipe_class_default);
 %}
 
-instruct convI2F_reg_reg(vRegF dst, iRegI src) %{
+instruct convI2F_reg_reg(vRegF dst, iRegIorL2I src) %{
   match(Set dst (ConvI2F src));
 
   ins_cost(INSN_COST * 5);
@@ -10540,7 +10540,7 @@
   ins_pipe(pipe_class_default);
 %}
 
-instruct convI2D_reg_reg(vRegD dst, iRegI src) %{
+instruct convI2D_reg_reg(vRegD dst, iRegIorL2I src) %{
   match(Set dst (ConvI2D src));
 
   ins_cost(INSN_COST * 5);
@@ -10803,7 +10803,7 @@
 // ============================================================================
 // Overflow Math Instructions
 
-instruct overflowAddI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2)
+instruct overflowAddI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2)
 %{
   match(Set cr (OverflowAddI op1 op2));
 
@@ -10816,7 +10816,7 @@
   ins_pipe(icmp_reg_reg);
 %}
 
-instruct overflowAddI_reg_imm(rFlagsReg cr, iRegI op1, immIAddSub op2)
+instruct overflowAddI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2)
 %{
   match(Set cr (OverflowAddI op1 op2));
 
@@ -10855,7 +10855,7 @@
   ins_pipe(icmp_reg_imm);
 %}
 
-instruct overflowSubI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2)
+instruct overflowSubI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2)
 %{
   match(Set cr (OverflowSubI op1 op2));
 
@@ -10868,7 +10868,7 @@
   ins_pipe(icmp_reg_reg);
 %}
 
-instruct overflowSubI_reg_imm(rFlagsReg cr, iRegI op1, immIAddSub op2)
+instruct overflowSubI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2)
 %{
   match(Set cr (OverflowSubI op1 op2));
 
@@ -10907,7 +10907,7 @@
   ins_pipe(icmp_reg_imm);
 %}
 
-instruct overflowNegI_reg(rFlagsReg cr, immI0 zero, iRegI op1)
+instruct overflowNegI_reg(rFlagsReg cr, immI0 zero, iRegIorL2I op1)
 %{
   match(Set cr (OverflowSubI zero op1));
 
@@ -10933,7 +10933,7 @@
   ins_pipe(icmp_reg_imm);
 %}
 
-instruct overflowMulI_reg(rFlagsReg cr, iRegI op1, iRegI op2)
+instruct overflowMulI_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2)
 %{
   match(Set cr (OverflowMulI op1 op2));
 
@@ -10954,7 +10954,7 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct overflowMulI_reg_branch(cmpOp cmp, iRegI op1, iRegI op2, label labl, rFlagsReg cr)
+instruct overflowMulI_reg_branch(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, label labl, rFlagsReg cr)
 %{
   match(If cmp (OverflowMulI op1 op2));
   predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow
@@ -11424,7 +11424,7 @@
 
 %}
 
-instruct cmpLTMask_reg_reg(iRegINoSp dst, iRegI p, iRegI q, rFlagsReg cr)
+instruct cmpLTMask_reg_reg(iRegINoSp dst, iRegIorL2I p, iRegIorL2I q, rFlagsReg cr)
 %{
   match(Set dst (CmpLTMask p q));
   effect(KILL cr);
@@ -11445,7 +11445,7 @@
   ins_pipe(ialu_reg_reg);
 %}
 
-instruct cmpLTMask_reg_zero(iRegINoSp dst, iRegI src, immI0 zero, rFlagsReg cr)
+instruct cmpLTMask_reg_zero(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr)
 %{
   match(Set dst (CmpLTMask src zero));
   effect(KILL cr);
@@ -11579,7 +11579,7 @@
 // shorter than (cmp; branch), have the additional benefit of not
 // killing the flags.
 
-instruct cmpI_imm0_branch(cmpOp cmp, iRegI op1, immI0 op2, label labl, rFlagsReg cr) %{
+instruct cmpI_imm0_branch(cmpOp cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsReg cr) %{
   match(If cmp (CmpI op1 op2));
   predicate(n->in(1)->as_Bool()->_test._test == BoolTest::ne
             || n->in(1)->as_Bool()->_test._test == BoolTest::eq);
--- a/hotspot/src/cpu/aarch64/vm/aarch64_ad.m4	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/cpu/aarch64/vm/aarch64_ad.m4	Fri Mar 27 14:52:45 2015 +0000
@@ -24,11 +24,13 @@
 dnl and shift patterns patterns used in aarch64.ad.
 dnl
 // BEGIN This section of the file is automatically generated. Do not edit --------------
-
+dnl
+define(`ORL2I', `ifelse($1,I,orL2I)')
+dnl
 define(`BASE_SHIFT_INSN',
 `
 instruct $2$1_reg_$4_reg(iReg$1NoSp dst,
-                         iReg$1 src1, iReg$1 src2,
+                         iReg$1`'ORL2I($1) src1, iReg$1`'ORL2I($1) src2,
                          immI src3, rFlagsReg cr) %{
   match(Set dst ($2$1 src1 ($4$1 src2 src3)));
 
@@ -48,7 +50,7 @@
 define(`BASE_INVERTED_INSN',
 `
 instruct $2$1_reg_not_reg(iReg$1NoSp dst,
-                         iReg$1 src1, iReg$1 src2, imm$1_M1 m1,
+                         iReg$1`'ORL2I($1) src1, iReg$1`'ORL2I($1) src2, imm$1_M1 m1,
                          rFlagsReg cr) %{
 dnl This ifelse is because hotspot reassociates (xor (xor ..)..)
 dnl into this canonical form.
@@ -70,7 +72,7 @@
 define(`INVERTED_SHIFT_INSN',
 `
 instruct $2$1_reg_$4_not_reg(iReg$1NoSp dst,
-                         iReg$1 src1, iReg$1 src2,
+                         iReg$1`'ORL2I($1) src1, iReg$1`'ORL2I($1) src2,
                          immI src3, imm$1_M1 src4, rFlagsReg cr) %{
 dnl This ifelse is because hotspot reassociates (xor (xor ..)..)
 dnl into this canonical form.
@@ -92,7 +94,7 @@
 %}')dnl
 define(`NOT_INSN',
 `instruct reg$1_not_reg(iReg$1NoSp dst,
-                         iReg$1 src1, imm$1_M1 m1,
+                         iReg$1`'ORL2I($1) src1, imm$1_M1 m1,
                          rFlagsReg cr) %{
   match(Set dst (Xor$1 src1 m1));
   ins_cost(INSN_COST);
@@ -113,7 +115,7 @@
 BASE_SHIFT_INSN(L, $1, $2, $3, $4)')dnl
 dnl
 define(`BOTH_INVERTED_INSNS',
-`BASE_INVERTED_INSN(I, $1, $2, $3, $4)
+`BASE_INVERTED_INSN(I, $1, $2w, $3, $4)
 BASE_INVERTED_INSN(L, $1, $2, $3, $4)')dnl
 dnl
 define(`BOTH_INVERTED_SHIFT_INSNS',
@@ -149,7 +151,7 @@
 define(`BFM_INSN',`
 // Shift Left followed by Shift Right.
 // This idiom is used by the compiler for the i2b bytecode etc.
-instruct $4$1(iReg$1NoSp dst, iReg$1 src, immI lshift_count, immI rshift_count)
+instruct $4$1(iReg$1NoSp dst, iReg$1`'ORL2I($1) src, immI lshift_count, immI rshift_count)
 %{
   match(Set dst EXTEND($1, $3, src, lshift_count, rshift_count));
   // Make sure we are not going to exceed what $4 can do.
@@ -176,7 +178,7 @@
 dnl
 // Bitfield extract with shift & mask
 define(`BFX_INSN',
-`instruct $3$1(iReg$1NoSp dst, iReg$1 src, immI rshift, imm$1_bitmask mask)
+`instruct $3$1(iReg$1NoSp dst, iReg$1`'ORL2I($1) src, immI rshift, imm$1_bitmask mask)
 %{
   match(Set dst (And$1 ($2$1 src rshift) mask));
 
@@ -215,7 +217,7 @@
 // Rotations
 
 define(`EXTRACT_INSN',
-`instruct extr$3$1(iReg$1NoSp dst, iReg$1 src1, iReg$1 src2, immI lshift, immI rshift, rFlagsReg cr)
+`instruct extr$3$1(iReg$1NoSp dst, iReg$1`'ORL2I($1) src1, iReg$1`'ORL2I($1) src2, immI lshift, immI rshift, rFlagsReg cr)
 %{
   match(Set dst ($3$1 (LShift$1 src1 lshift) (URShift$1 src2 rshift)));
   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & $2));
@@ -299,7 +301,7 @@
 // Add/subtract (extended)
 dnl ADD_SUB_EXTENDED(mode, size, add node, shift node, insn, shift type, wordsize
 define(`ADD_SUB_CONV', `
-instruct $3Ext$1(iReg$2NoSp dst, iReg$2 src1, iReg$1orL2I src2, rFlagsReg cr)
+instruct $3Ext$1(iReg$2NoSp dst, iReg$2`'ORL2I($2) src1, iReg$1`'ORL2I($1) src2, rFlagsReg cr)
 %{
   match(Set dst ($3$2 src1 (ConvI2L src2)));
   ins_cost(INSN_COST);
@@ -315,7 +317,7 @@
 ADD_SUB_CONV(I,L,Sub,sub,sxtw);
 dnl
 define(`ADD_SUB_EXTENDED', `
-instruct $3Ext$1_$6(iReg$1NoSp dst, iReg$1 src1, iReg$1 src2, immI_`'eval($7-$2) lshift, immI_`'eval($7-$2) rshift, rFlagsReg cr)
+instruct $3Ext$1_$6(iReg$1NoSp dst, iReg$1`'ORL2I($1) src1, iReg$1`'ORL2I($1) src2, immI_`'eval($7-$2) lshift, immI_`'eval($7-$2) rshift, rFlagsReg cr)
 %{
   match(Set dst ($3$1 src1 EXTEND($1, $4, src2, lshift, rshift)));
   ins_cost(INSN_COST);
@@ -337,7 +339,7 @@
 dnl
 dnl ADD_SUB_ZERO_EXTEND(mode, size, add node, insn, shift type)
 define(`ADD_SUB_ZERO_EXTEND', `
-instruct $3Ext$1_$5_and(iReg$1NoSp dst, iReg$1 src1, iReg$1 src2, imm$1_$2 mask, rFlagsReg cr)
+instruct $3Ext$1_$5_and(iReg$1NoSp dst, iReg$1`'ORL2I($1) src1, iReg$1`'ORL2I($1) src2, imm$1_$2 mask, rFlagsReg cr)
 %{
   match(Set dst ($3$1 src1 (And$1 src2 mask)));
   ins_cost(INSN_COST);
--- a/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2014, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -673,7 +673,6 @@
   void  gen_write_ref_array_pre_barrier(Register addr, Register count, bool dest_uninitialized) {
     BarrierSet* bs = Universe::heap()->barrier_set();
     switch (bs->kind()) {
-    case BarrierSet::G1SATBCT:
     case BarrierSet::G1SATBCTLogging:
       // With G1, don't generate the call if we statically know that the target in uninitialized
       if (!dest_uninitialized) {
@@ -719,7 +718,6 @@
     assert_different_registers(start, end, scratch);
     BarrierSet* bs = Universe::heap()->barrier_set();
     switch (bs->kind()) {
-      case BarrierSet::G1SATBCT:
       case BarrierSet::G1SATBCTLogging:
 
         {
--- a/hotspot/src/cpu/aarch64/vm/templateTable_aarch64.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/cpu/aarch64/vm/templateTable_aarch64.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2014, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -150,7 +150,6 @@
   assert(val == noreg || val == r0, "parameter is just for looks");
   switch (barrier) {
 #if INCLUDE_ALL_GCS
-    case BarrierSet::G1SATBCT:
     case BarrierSet::G1SATBCTLogging:
       {
         // flatten object address if needed
--- a/hotspot/src/cpu/ppc/vm/c2_globals_ppc.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/cpu/ppc/vm/c2_globals_ppc.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2012, 2014 SAP AG. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -49,7 +49,7 @@
 define_pd_global(intx, MinJumpTableSize,             10);
 define_pd_global(intx, INTPRESSURE,                  25);
 define_pd_global(intx, InteriorEntryAlignment,       16);
-define_pd_global(intx, NewSizeThreadIncrease,        ScaleForWordSize(4*K));
+define_pd_global(size_t, NewSizeThreadIncrease,      ScaleForWordSize(4*K));
 define_pd_global(intx, RegisterCostAreaRatio,        16000);
 define_pd_global(bool, UseTLAB,                      true);
 define_pd_global(bool, ResizeTLAB,                   true);
@@ -85,14 +85,14 @@
 define_pd_global(intx, CodeCacheExpansionSize,       64*K);
 
 // Ergonomics related flags
-define_pd_global(uint64_t,MaxRAM,                    4ULL*G);
+define_pd_global(uint64_t, MaxRAM,                   4ULL*G);
 define_pd_global(uintx, CodeCacheMinBlockLength,     4);
 define_pd_global(uintx, CodeCacheMinimumUseSpace,    400*K);
 
 define_pd_global(bool,  TrapBasedRangeChecks,        true);
 
 // Heap related flags
-define_pd_global(uintx,MetaspaceSize,                ScaleForWordSize(16*M));
+define_pd_global(size_t, MetaspaceSize,              ScaleForWordSize(16*M));
 
 // Ergonomics related flags
 define_pd_global(bool, NeverActAsServerClassMachine, false);
--- a/hotspot/src/cpu/ppc/vm/globals_ppc.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/cpu/ppc/vm/globals_ppc.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2012, 2013 SAP AG. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -56,7 +56,7 @@
 define_pd_global(bool, UseMembar,             false);
 
 // GC Ergo Flags
-define_pd_global(uintx, CMSYoungGenPerWorker, 16*M);  // Default max size of CMS young gen, per GC worker thread.
+define_pd_global(size_t, CMSYoungGenPerWorker, 16*M);  // Default max size of CMS young gen, per GC worker thread.
 
 define_pd_global(uintx, TypeProfileLevel, 0);
 
--- a/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -608,7 +608,6 @@
   void gen_write_ref_array_pre_barrier(Register from, Register to, Register count, bool dest_uninitialized, Register Rtmp1) {
     BarrierSet* const bs = Universe::heap()->barrier_set();
     switch (bs->kind()) {
-      case BarrierSet::G1SATBCT:
       case BarrierSet::G1SATBCTLogging:
         // With G1, don't generate the call if we statically know that the target in uninitialized
         if (!dest_uninitialized) {
@@ -665,7 +664,6 @@
     BarrierSet* const bs = Universe::heap()->barrier_set();
 
     switch (bs->kind()) {
-      case BarrierSet::G1SATBCT:
       case BarrierSet::G1SATBCTLogging:
         {
           if (branchToEnd) {
--- a/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -66,7 +66,6 @@
 
   switch (barrier) {
 #if INCLUDE_ALL_GCS
-    case BarrierSet::G1SATBCT:
     case BarrierSet::G1SATBCTLogging:
       {
         // Load and record the previous value.
--- a/hotspot/src/cpu/sparc/vm/c1_globals_sparc.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/cpu/sparc/vm/c1_globals_sparc.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, 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
@@ -53,10 +53,10 @@
 define_pd_global(intx, CodeCacheExpansionSize,       32*K );
 define_pd_global(uintx, CodeCacheMinBlockLength,     1);
 define_pd_global(uintx, CodeCacheMinimumUseSpace,    400*K);
-define_pd_global(uintx, MetaspaceSize,               12*M );
+define_pd_global(size_t, MetaspaceSize,              12*M );
 define_pd_global(bool, NeverActAsServerClassMachine, true );
-define_pd_global(intx, NewSizeThreadIncrease,        16*K );
-define_pd_global(uint64_t,MaxRAM,                    1ULL*G);
+define_pd_global(size_t, NewSizeThreadIncrease,      16*K );
+define_pd_global(uint64_t, MaxRAM,                   1ULL*G);
 define_pd_global(intx, InitialCodeCacheSize,         160*K);
 #endif // !TIERED
 
--- a/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, 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
@@ -51,7 +51,7 @@
 define_pd_global(intx, FreqInlineSize,               175);
 define_pd_global(intx, INTPRESSURE,                  48);  // large register set
 define_pd_global(intx, InteriorEntryAlignment,       16);  // = CodeEntryAlignment
-define_pd_global(intx, NewSizeThreadIncrease, ScaleForWordSize(4*K));
+define_pd_global(size_t, NewSizeThreadIncrease,      ScaleForWordSize(4*K));
 define_pd_global(intx, RegisterCostAreaRatio,        12000);
 define_pd_global(bool, UseTLAB,                      true);
 define_pd_global(bool, ResizeTLAB,                   true);
@@ -90,7 +90,7 @@
 define_pd_global(intx, NonNMethodCodeHeapSize,       5*M );
 define_pd_global(intx, CodeCacheExpansionSize,       32*K);
 // Ergonomics related flags
-define_pd_global(uint64_t,MaxRAM,                    4ULL*G);
+define_pd_global(uint64_t, MaxRAM,                   4ULL*G);
 #endif
 define_pd_global(uintx, CodeCacheMinBlockLength,     4);
 define_pd_global(uintx, CodeCacheMinimumUseSpace,    400*K);
@@ -98,7 +98,7 @@
 define_pd_global(bool,  TrapBasedRangeChecks,        false); // Not needed on sparc.
 
 // Heap related flags
-define_pd_global(uintx,MetaspaceSize,    ScaleForWordSize(16*M));
+define_pd_global(size_t, MetaspaceSize,              ScaleForWordSize(16*M));
 
 // Ergonomics related flags
 define_pd_global(bool, NeverActAsServerClassMachine, false);
--- a/hotspot/src/cpu/sparc/vm/globals_sparc.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/cpu/sparc/vm/globals_sparc.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, 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
@@ -75,7 +75,7 @@
 define_pd_global(bool, UseMembar,            false);
 
 // GC Ergo Flags
-define_pd_global(uintx, CMSYoungGenPerWorker, 16*M);  // default max size of CMS young gen, per GC worker thread
+define_pd_global(size_t, CMSYoungGenPerWorker, 16*M);  // default max size of CMS young gen, per GC worker thread
 
 define_pd_global(uintx, TypeProfileLevel, 0);
 
--- a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -957,7 +957,6 @@
   void gen_write_ref_array_pre_barrier(Register addr, Register count, bool dest_uninitialized) {
     BarrierSet* bs = Universe::heap()->barrier_set();
     switch (bs->kind()) {
-      case BarrierSet::G1SATBCT:
       case BarrierSet::G1SATBCTLogging:
         // With G1, don't generate the call if we statically know that the target in uninitialized
         if (!dest_uninitialized) {
@@ -1005,7 +1004,6 @@
     BarrierSet* bs = Universe::heap()->barrier_set();
 
     switch (bs->kind()) {
-      case BarrierSet::G1SATBCT:
       case BarrierSet::G1SATBCTLogging:
         {
           // Get some new fresh output registers.
--- a/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, 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
@@ -56,7 +56,6 @@
   assert(index == noreg || offset == 0, "only one offset");
   switch (barrier) {
 #if INCLUDE_ALL_GCS
-    case BarrierSet::G1SATBCT:
     case BarrierSet::G1SATBCTLogging:
       {
         // Load and record the previous value.
--- a/hotspot/src/cpu/x86/vm/c1_globals_x86.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/cpu/x86/vm/c1_globals_x86.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, 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,39 +32,39 @@
 // (see c1_globals.hpp)
 
 #ifndef TIERED
-define_pd_global(bool, BackgroundCompilation,        true );
-define_pd_global(bool, UseTLAB,                      true );
-define_pd_global(bool, ResizeTLAB,                   true );
-define_pd_global(bool, InlineIntrinsics,             true );
-define_pd_global(bool, PreferInterpreterNativeStubs, false);
-define_pd_global(bool, ProfileTraps,                 false);
-define_pd_global(bool, UseOnStackReplacement,        true );
-define_pd_global(bool, TieredCompilation,            false);
-define_pd_global(intx, CompileThreshold,             1500 );
+define_pd_global(bool, BackgroundCompilation,          true );
+define_pd_global(bool, UseTLAB,                        true );
+define_pd_global(bool, ResizeTLAB,                     true );
+define_pd_global(bool, InlineIntrinsics,               true );
+define_pd_global(bool, PreferInterpreterNativeStubs,   false);
+define_pd_global(bool, ProfileTraps,                   false);
+define_pd_global(bool, UseOnStackReplacement,          true );
+define_pd_global(bool, TieredCompilation,              false);
+define_pd_global(intx, CompileThreshold,               1500 );
 
-define_pd_global(intx, OnStackReplacePercentage,     933  );
-define_pd_global(intx, FreqInlineSize,               325  );
-define_pd_global(intx, NewSizeThreadIncrease,        4*K  );
-define_pd_global(intx, InitialCodeCacheSize,         160*K);
-define_pd_global(intx, ReservedCodeCacheSize,        32*M );
-define_pd_global(intx, NonProfiledCodeHeapSize,      13*M );
-define_pd_global(intx, ProfiledCodeHeapSize,         14*M );
-define_pd_global(intx, NonNMethodCodeHeapSize,       5*M  );
-define_pd_global(bool, ProfileInterpreter,           false);
-define_pd_global(intx, CodeCacheExpansionSize,       32*K );
-define_pd_global(uintx, CodeCacheMinBlockLength,     1);
-define_pd_global(uintx, CodeCacheMinimumUseSpace,    400*K);
-define_pd_global(uintx, MetaspaceSize,               12*M );
-define_pd_global(bool, NeverActAsServerClassMachine, true );
-define_pd_global(uint64_t,MaxRAM,                    1ULL*G);
-define_pd_global(bool, CICompileOSR,                 true );
+define_pd_global(intx,   OnStackReplacePercentage,     933  );
+define_pd_global(intx,   FreqInlineSize,               325  );
+define_pd_global(size_t, NewSizeThreadIncrease,        4*K  );
+define_pd_global(intx, InitialCodeCacheSize,           160*K);
+define_pd_global(intx, ReservedCodeCacheSize,          32*M );
+define_pd_global(intx, NonProfiledCodeHeapSize,        13*M );
+define_pd_global(intx, ProfiledCodeHeapSize,           14*M );
+define_pd_global(intx, NonNMethodCodeHeapSize,         5*M  );
+define_pd_global(bool,   ProfileInterpreter,           false);
+define_pd_global(intx, CodeCacheExpansionSize,         32*K );
+define_pd_global(uintx, CodeCacheMinBlockLength,       1    );
+define_pd_global(uintx, CodeCacheMinimumUseSpace,      400*K);
+define_pd_global(size_t, MetaspaceSize,                12*M );
+define_pd_global(bool,   NeverActAsServerClassMachine, true );
+define_pd_global(uint64_t, MaxRAM,                    1ULL*G);
+define_pd_global(bool,   CICompileOSR,                 true );
 #endif // !TIERED
-define_pd_global(bool, UseTypeProfile,               false);
-define_pd_global(bool, RoundFPResults,               true );
+define_pd_global(bool, UseTypeProfile,                 false);
+define_pd_global(bool, RoundFPResults,                 true );
 
-define_pd_global(bool, LIRFillDelaySlots,            false);
-define_pd_global(bool, OptimizeSinglePrecision,      true );
-define_pd_global(bool, CSEArrayLength,               false);
-define_pd_global(bool, TwoOperandLIRForm,            true );
+define_pd_global(bool, LIRFillDelaySlots,              false);
+define_pd_global(bool, OptimizeSinglePrecision,        true );
+define_pd_global(bool, CSEArrayLength,                 false);
+define_pd_global(bool, TwoOperandLIRForm,              true );
 
 #endif // CPU_X86_VM_C1_GLOBALS_X86_HPP
--- a/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, 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,25 +54,25 @@
 #ifdef AMD64
 define_pd_global(intx, INTPRESSURE,                  13);
 define_pd_global(intx, InteriorEntryAlignment,       16);
-define_pd_global(intx, NewSizeThreadIncrease, ScaleForWordSize(4*K));
+define_pd_global(size_t, NewSizeThreadIncrease,      ScaleForWordSize(4*K));
 define_pd_global(intx, LoopUnrollLimit,              60);
 // InitialCodeCacheSize derived from specjbb2000 run.
 define_pd_global(intx, InitialCodeCacheSize,         2496*K); // Integral multiple of CodeCacheExpansionSize
 define_pd_global(intx, CodeCacheExpansionSize,       64*K);
 
 // Ergonomics related flags
-define_pd_global(uint64_t,MaxRAM,                    128ULL*G);
+define_pd_global(uint64_t, MaxRAM,                   128ULL*G);
 #else
 define_pd_global(intx, INTPRESSURE,                  6);
 define_pd_global(intx, InteriorEntryAlignment,       4);
-define_pd_global(intx, NewSizeThreadIncrease,        4*K);
+define_pd_global(size_t, NewSizeThreadIncrease,      4*K);
 define_pd_global(intx, LoopUnrollLimit,              50);     // Design center runs on 1.3.1
 // InitialCodeCacheSize derived from specjbb2000 run.
 define_pd_global(intx, InitialCodeCacheSize,         2304*K); // Integral multiple of CodeCacheExpansionSize
 define_pd_global(intx, CodeCacheExpansionSize,       32*K);
 
 // Ergonomics related flags
-define_pd_global(uint64_t,MaxRAM,                    4ULL*G);
+define_pd_global(uint64_t, MaxRAM,                   4ULL*G);
 #endif // AMD64
 define_pd_global(intx, RegisterCostAreaRatio,        16000);
 
@@ -93,7 +93,7 @@
 define_pd_global(bool,  TrapBasedRangeChecks,        false); // Not needed on x86.
 
 // Heap related flags
-define_pd_global(uintx,MetaspaceSize,    ScaleForWordSize(16*M));
+define_pd_global(size_t, MetaspaceSize,              ScaleForWordSize(16*M));
 
 // Ergonomics related flags
 define_pd_global(bool, NeverActAsServerClassMachine, false);
--- a/hotspot/src/cpu/x86/vm/globals_x86.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/cpu/x86/vm/globals_x86.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -78,7 +78,7 @@
 #endif
 
 // GC Ergo Flags
-define_pd_global(uintx, CMSYoungGenPerWorker, 64*M);  // default max size of CMS young gen, per GC worker thread
+define_pd_global(size_t, CMSYoungGenPerWorker, 64*M);  // default max size of CMS young gen, per GC worker thread
 
 define_pd_global(uintx, TypeProfileLevel, 111);
 
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -706,7 +706,6 @@
     assert_different_registers(start, count);
     BarrierSet* bs = Universe::heap()->barrier_set();
     switch (bs->kind()) {
-      case BarrierSet::G1SATBCT:
       case BarrierSet::G1SATBCTLogging:
         // With G1, don't generate the call if we statically know that the target in uninitialized
         if (!uninitialized_target) {
@@ -739,7 +738,6 @@
     BarrierSet* bs = Universe::heap()->barrier_set();
     assert_different_registers(start, count);
     switch (bs->kind()) {
-      case BarrierSet::G1SATBCT:
       case BarrierSet::G1SATBCTLogging:
         {
           __ pusha();                      // push registers
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1207,7 +1207,6 @@
   void  gen_write_ref_array_pre_barrier(Register addr, Register count, bool dest_uninitialized) {
     BarrierSet* bs = Universe::heap()->barrier_set();
     switch (bs->kind()) {
-      case BarrierSet::G1SATBCT:
       case BarrierSet::G1SATBCTLogging:
         // With G1, don't generate the call if we statically know that the target in uninitialized
         if (!dest_uninitialized) {
@@ -1252,7 +1251,6 @@
     assert_different_registers(start, count, scratch);
     BarrierSet* bs = Universe::heap()->barrier_set();
     switch (bs->kind()) {
-      case BarrierSet::G1SATBCT:
       case BarrierSet::G1SATBCTLogging:
         {
           __ pusha();             // push registers (overkill)
--- a/hotspot/src/cpu/x86/vm/templateTable_x86.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -156,7 +156,6 @@
   assert(val == noreg || val == rax, "parameter is just for looks");
   switch (barrier) {
 #if INCLUDE_ALL_GCS
-    case BarrierSet::G1SATBCT:
     case BarrierSet::G1SATBCTLogging:
       {
         // flatten object address if needed
--- a/hotspot/src/cpu/zero/vm/globals_zero.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/cpu/zero/vm/globals_zero.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -57,7 +57,7 @@
 define_pd_global(bool,  UseMembar,            true);
 
 // GC Ergo Flags
-define_pd_global(uintx, CMSYoungGenPerWorker, 16*M);  // default max size of CMS young gen, per GC worker thread
+define_pd_global(size_t, CMSYoungGenPerWorker, 16*M);  // default max size of CMS young gen, per GC worker thread
 
 define_pd_global(uintx, TypeProfileLevel, 0);
 
--- a/hotspot/src/cpu/zero/vm/shark_globals_zero.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/cpu/zero/vm/shark_globals_zero.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2008, 2009, 2010 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -50,7 +50,7 @@
 define_pd_global(intx,     OnStackReplacePercentage,     933  );
 define_pd_global(intx,     FreqInlineSize,               325  );
 define_pd_global(uintx,    NewRatio,                     12   );
-define_pd_global(intx,     NewSizeThreadIncrease,        4*K  );
+define_pd_global(size_t,   NewSizeThreadIncrease,        4*K  );
 define_pd_global(intx,     InitialCodeCacheSize,         160*K);
 define_pd_global(intx,     ReservedCodeCacheSize,        32*M );
 define_pd_global(intx,     NonProfiledCodeHeapSize,      13*M );
@@ -61,7 +61,7 @@
 define_pd_global(uintx,    CodeCacheMinBlockLength,      1    );
 define_pd_global(uintx,    CodeCacheMinimumUseSpace,     200*K);
 
-define_pd_global(uintx,    MetaspaceSize,                12*M );
+define_pd_global(size_t,   MetaspaceSize,                12*M );
 define_pd_global(bool,     NeverActAsServerClassMachine, true );
 define_pd_global(uint64_t, MaxRAM,                       1ULL*G);
 define_pd_global(bool,     CICompileOSR,                 true );
--- a/hotspot/src/os/aix/vm/attachListener_aix.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/os/aix/vm/attachListener_aix.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2013 SAP AG. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2012, 2015 SAP AG. 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
@@ -144,6 +144,10 @@
   }
   char* next() {
     if (*_pos == '\0') {
+      if (_pos < _end) {
+        _pos += 1;
+      }
+
       return NULL;
     }
     char* res = _pos;
@@ -214,6 +218,7 @@
 
   // bind socket
   struct sockaddr_un addr;
+  memset((void *)&addr, 0, sizeof(addr));
   addr.sun_family = AF_UNIX;
   strcpy(addr.sun_path, initial_path);
   ::unlink(initial_path);
--- a/hotspot/src/os/aix/vm/globals_aix.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/os/aix/vm/globals_aix.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2013 SAP AG. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2012, 2015 SAP AG. 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
@@ -31,6 +31,10 @@
 //
 #define RUNTIME_OS_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct) \
                                                                                     \
+  /* Use 64K pages for virtual memory (shmat). */                                   \
+  product(bool, Use64KPages, true,                                                  \
+          "Use 64K pages if available.")                                            \
+                                                                                    \
   /* If UseLargePages == true allow or deny usage of 16M pages. 16M pages are  */   \
   /* a scarce resource and there may be situations where we do not want the VM */   \
   /* to run with 16M pages. (Will fall back to 64K pages).                     */   \
@@ -55,7 +59,7 @@
 // Defines Aix-specific default values. The flags are available on all
 // platforms, but they may have different default values on other platforms.
 //
-define_pd_global(bool, UseLargePages, true);
+define_pd_global(bool, UseLargePages, false);
 define_pd_global(bool, UseLargePagesIndividualAllocation, false);
 define_pd_global(bool, UseOSErrorReporting, false);
 define_pd_global(bool, UseThreadPriorities, true) ;
--- a/hotspot/src/os/aix/vm/interfaceSupport_aix.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/os/aix/vm/interfaceSupport_aix.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2013 SAP AG. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2012, 2015 SAP AG. 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
@@ -23,8 +23,8 @@
  *
  */
 
-#ifndef OS_LINUX_VM_INTERFACESUPPORT_LINUX_HPP
-#define OS_LINUX_VM_INTERFACESUPPORT_LINUX_HPP
+#ifndef OS_AIX_VM_INTERFACESUPPORT_AIX_HPP
+#define OS_AIX_VM_INTERFACESUPPORT_AIX_HPP
 
 // Contains inlined functions for class InterfaceSupport
 
@@ -32,4 +32,4 @@
   os::write_memory_serialize_page(thread);
 }
 
-#endif // OS_LINUX_VM_INTERFACESUPPORT_LINUX_HPP
+#endif // OS_AIX_VM_INTERFACESUPPORT_AIX_HPP
--- a/hotspot/src/os/aix/vm/osThread_aix.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/os/aix/vm/osThread_aix.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2013 SAP AG. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2012, 2015 SAP AG. 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
@@ -47,7 +47,7 @@
 
   _startThread_lock = new Monitor(Mutex::event, "startThread_lock", true,
                                   Monitor::_safepoint_check_never);
-  assert(_startThread_lock !=NULL, "check");
+  assert(_startThread_lock != NULL, "check");
 }
 
 void OSThread::pd_destroy() {
--- a/hotspot/src/os/aix/vm/os_aix.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/os/aix/vm/os_aix.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2014 SAP AG. All rights reserved.
+ * Copyright 2012, 2015 SAP AG. 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
@@ -113,6 +113,10 @@
 #define RUSAGE_THREAD   (1)               /* only the calling thread */
 #endif
 
+// PPC port
+static const uintx Use64KPagesThreshold       = 1*M;
+static const uintx MaxExpectedDataSegmentSize = SIZE_4G*2;
+
 // Add missing declarations (should be in procinfo.h but isn't until AIX 6.1).
 #if !defined(_AIXVERSION_610)
 extern "C" {
@@ -168,8 +172,8 @@
     return -1; \
 }
 
-// query dimensions of the stack of the calling thread
-static void query_stack_dimensions(address* p_stack_base, size_t* p_stack_size);
+// Query dimensions of the stack of the calling thread.
+static bool query_stack_dimensions(address* p_stack_base, size_t* p_stack_size);
 
 // function to check a given stack pointer against given stack limits
 inline bool is_valid_stackpointer(stackptr_t sp, stackptr_t stack_base, size_t stack_size) {
@@ -220,9 +224,6 @@
 int       os::Aix::_on_pase = -1;
 int       os::Aix::_os_version = -1;
 int       os::Aix::_stack_page_size = -1;
-size_t    os::Aix::_shm_default_page_size = -1;
-int       os::Aix::_can_use_64K_pages = -1;
-int       os::Aix::_can_use_16M_pages = -1;
 int       os::Aix::_xpg_sus_mode = -1;
 int       os::Aix::_extshm = -1;
 int       os::Aix::_logical_cpus = -1;
@@ -240,6 +241,63 @@
 static sigset_t SR_sigset;
 static pthread_mutex_t dl_mutex;              // Used to protect dlsym() calls.
 
+// This describes the state of multipage support of the underlying
+// OS. Note that this is of no interest to the outsize world and
+// therefore should not be defined in AIX class.
+//
+// AIX supports four different page sizes - 4K, 64K, 16MB, 16GB. The
+// latter two (16M "large" resp. 16G "huge" pages) require special
+// setup and are normally not available.
+//
+// AIX supports multiple page sizes per process, for:
+//  - Stack (of the primordial thread, so not relevant for us)
+//  - Data - data, bss, heap, for us also pthread stacks
+//  - Text - text code
+//  - shared memory
+//
+// Default page sizes can be set via linker options (-bdatapsize, -bstacksize, ...)
+// and via environment variable LDR_CNTRL (DATAPSIZE, STACKPSIZE, ...).
+//
+// For shared memory, page size can be set dynamically via
+// shmctl(). Different shared memory regions can have different page
+// sizes.
+//
+// More information can be found at AIBM info center:
+//   http://publib.boulder.ibm.com/infocenter/aix/v6r1/index.jsp?topic=/com.ibm.aix.prftungd/doc/prftungd/multiple_page_size_app_support.htm
+//
+static struct {
+  size_t pagesize;            // sysconf _SC_PAGESIZE (4K)
+  size_t datapsize;           // default data page size (LDR_CNTRL DATAPSIZE)
+  size_t shmpsize;            // default shared memory page size (LDR_CNTRL SHMPSIZE)
+  size_t pthr_stack_pagesize; // stack page size of pthread threads
+  size_t textpsize;           // default text page size (LDR_CNTRL STACKPSIZE)
+  bool can_use_64K_pages;     // True if we can alloc 64K pages dynamically with Sys V shm.
+  bool can_use_16M_pages;     // True if we can alloc 16M pages dynamically with Sys V shm.
+  int error;                  // Error describing if something went wrong at multipage init.
+} g_multipage_support = {
+  (size_t) -1,
+  (size_t) -1,
+  (size_t) -1,
+  (size_t) -1,
+  (size_t) -1,
+  false, false,
+  0
+};
+
+// We must not accidentally allocate memory close to the BRK - even if
+// that would work - because then we prevent the BRK segment from
+// growing which may result in a malloc OOM even though there is
+// enough memory. The problem only arises if we shmat() or mmap() at
+// a specific wish address, e.g. to place the heap in a
+// compressed-oops-friendly way.
+static bool is_close_to_brk(address a) {
+  address a1 = (address) sbrk(0);
+  if (a >= a1 && a < (a1 + MaxExpectedDataSegmentSize)) {
+    return true;
+  }
+  return false;
+}
+
 julong os::available_memory() {
   return Aix::available_memory();
 }
@@ -291,7 +349,7 @@
   }
 
   // Maximum size 32bit disclaim() accepts. (Theoretically 4GB, but I just do not trust that.)
-  const unsigned int maxDisclaimSize = 0x80000000;
+  const unsigned int maxDisclaimSize = 0x40000000;
 
   const unsigned int numFullDisclaimsNeeded = (size / maxDisclaimSize);
   const unsigned int lastDisclaimSize = (size % maxDisclaimSize);
@@ -368,162 +426,161 @@
     case SIZE_64K: return "64K";
     case SIZE_16M: return "16M";
     case SIZE_16G: return "16G";
+    case -1:       return "not set";
     default:
       assert(false, "surprise");
       return "??";
   }
 }
 
-// Retrieve information about multipage size support. Will initialize
-// Aix::_page_size, Aix::_stack_page_size, Aix::_can_use_64K_pages,
-// Aix::_can_use_16M_pages.
+// Probe OS for multipage support.
+// Will fill the global g_multipage_support structure.
 // Must be called before calling os::large_page_init().
-void os::Aix::query_multipage_support() {
-
-  guarantee(_page_size == -1 &&
-            _stack_page_size == -1 &&
-            _can_use_64K_pages == -1 &&
-            _can_use_16M_pages == -1 &&
-            g_multipage_error == -1,
+static void query_multipage_support() {
+
+  guarantee(g_multipage_support.pagesize == -1,
             "do not call twice");
 
-  _page_size = ::sysconf(_SC_PAGESIZE);
+  g_multipage_support.pagesize = ::sysconf(_SC_PAGESIZE);
 
   // This really would surprise me.
-  assert(_page_size == SIZE_4K, "surprise!");
-
+  assert(g_multipage_support.pagesize == SIZE_4K, "surprise!");
 
   // Query default data page size (default page size for C-Heap, pthread stacks and .bss).
-  // Default data page size is influenced either by linker options (-bdatapsize)
+  // Default data page size is defined either by linker options (-bdatapsize)
   // or by environment variable LDR_CNTRL (suboption DATAPSIZE). If none is given,
   // default should be 4K.
-  size_t data_page_size = SIZE_4K;
   {
-    void* p = os::malloc(SIZE_16M, mtInternal);
-    guarantee(p != NULL, "malloc failed");
-    data_page_size = os::Aix::query_pagesize(p);
-    os::free(p);
-  }
-
-  // query default shm page size (LDR_CNTRL SHMPSIZE)
+    void* p = ::malloc(SIZE_16M);
+    g_multipage_support.datapsize = os::Aix::query_pagesize(p);
+    ::free(p);
+  }
+
+  // Query default shm page size (LDR_CNTRL SHMPSIZE).
   {
     const int shmid = ::shmget(IPC_PRIVATE, 1, IPC_CREAT | S_IRUSR | S_IWUSR);
     guarantee(shmid != -1, "shmget failed");
     void* p = ::shmat(shmid, NULL, 0);
     ::shmctl(shmid, IPC_RMID, NULL);
     guarantee(p != (void*) -1, "shmat failed");
-    _shm_default_page_size = os::Aix::query_pagesize(p);
+    g_multipage_support.shmpsize = os::Aix::query_pagesize(p);
     ::shmdt(p);
   }
 
-  // before querying the stack page size, make sure we are not running as primordial
+  // Before querying the stack page size, make sure we are not running as primordial
   // thread (because primordial thread's stack may have different page size than
   // pthread thread stacks). Running a VM on the primordial thread won't work for a
-  // number of reasons so we may just as well guarantee it here
-  guarantee(!os::Aix::is_primordial_thread(), "Must not be called for primordial thread");
-
-  // query stack page size
+  // number of reasons so we may just as well guarantee it here.
+  guarantee0(!os::Aix::is_primordial_thread());
+
+  // Query pthread stack page size.
   {
     int dummy = 0;
-    _stack_page_size = os::Aix::query_pagesize(&dummy);
-    // everything else would surprise me and should be looked into
-    guarantee(_stack_page_size == SIZE_4K || _stack_page_size == SIZE_64K, "Wrong page size");
-    // also, just for completeness: pthread stacks are allocated from C heap, so
-    // stack page size should be the same as data page size
-    guarantee(_stack_page_size == data_page_size, "stack page size should be the same as data page size");
-  }
-
-  // EXTSHM is bad: among other things, it prevents setting pagesize dynamically
-  // for system V shm.
-  if (Aix::extshm()) {
-    if (Verbose) {
-      fprintf(stderr, "EXTSHM is active - will disable large page support.\n"
-                      "Please make sure EXTSHM is OFF for large page support.\n");
-    }
-    g_multipage_error = ERROR_MP_EXTSHM_ACTIVE;
-    _can_use_64K_pages = _can_use_16M_pages = 0;
+    g_multipage_support.pthr_stack_pagesize = os::Aix::query_pagesize(&dummy);
+  }
+
+  // Query default text page size (LDR_CNTRL TEXTPSIZE).
+  /* PPC port: so far unused.
+  {
+    address any_function =
+      (address) resolve_function_descriptor_to_code_pointer((address)describe_pagesize);
+    g_multipage_support.textpsize = os::Aix::query_pagesize(any_function);
+  }
+  */
+
+  // Now probe for support of 64K pages and 16M pages.
+
+  // Before OS/400 V6R1, there is no support for pages other than 4K.
+  if (os::Aix::on_pase_V5R4_or_older()) {
+    Unimplemented();
     goto query_multipage_support_end;
   }
 
-  // now check which page sizes the OS claims it supports, and of those, which actually can be used.
+  // Now check which page sizes the OS claims it supports, and of those, which actually can be used.
   {
     const int MAX_PAGE_SIZES = 4;
     psize_t sizes[MAX_PAGE_SIZES];
     const int num_psizes = ::vmgetinfo(sizes, VMINFO_GETPSIZES, MAX_PAGE_SIZES);
     if (num_psizes == -1) {
-      if (Verbose) {
-        fprintf(stderr, "vmgetinfo(VMINFO_GETPSIZES) failed (errno: %d)\n", errno);
-        fprintf(stderr, "disabling multipage support.\n");
-      }
-      g_multipage_error = ERROR_MP_VMGETINFO_FAILED;
-      _can_use_64K_pages = _can_use_16M_pages = 0;
+      trc("vmgetinfo(VMINFO_GETPSIZES) failed (errno: %d)\n", errno);
+      trc("disabling multipage support.\n");
+      g_multipage_support.error = ERROR_MP_VMGETINFO_FAILED;
       goto query_multipage_support_end;
     }
     guarantee(num_psizes > 0, "vmgetinfo(.., VMINFO_GETPSIZES, ...) failed.");
     assert(num_psizes <= MAX_PAGE_SIZES, "Surprise! more than 4 page sizes?");
-    if (Verbose) {
-      fprintf(stderr, "vmgetinfo(.., VMINFO_GETPSIZES, ...) returns %d supported page sizes: ", num_psizes);
-      for (int i = 0; i < num_psizes; i ++) {
-        fprintf(stderr, " %s ", describe_pagesize(sizes[i]));
+    trcVerbose("vmgetinfo(.., VMINFO_GETPSIZES, ...) returns %d supported page sizes: ", num_psizes);
+    for (int i = 0; i < num_psizes; i ++) {
+      trcVerbose(" %s ", describe_pagesize(sizes[i]));
+    }
+
+    // Can we use 64K, 16M pages?
+    for (int i = 0; i < num_psizes; i ++) {
+      const size_t pagesize = sizes[i];
+      if (pagesize != SIZE_64K && pagesize != SIZE_16M) {
+        continue;
       }
-      fprintf(stderr, " .\n");
-    }
-
-    // Can we use 64K, 16M pages?
-    _can_use_64K_pages = 0;
-    _can_use_16M_pages = 0;
-    for (int i = 0; i < num_psizes; i ++) {
-      if (sizes[i] == SIZE_64K) {
-        _can_use_64K_pages = 1;
-      } else if (sizes[i] == SIZE_16M) {
-        _can_use_16M_pages = 1;
+      bool can_use = false;
+      trcVerbose("Probing support for %s pages...", describe_pagesize(pagesize));
+      const int shmid = ::shmget(IPC_PRIVATE, pagesize,
+        IPC_CREAT | S_IRUSR | S_IWUSR);
+      guarantee0(shmid != -1); // Should always work.
+      // Try to set pagesize.
+      struct shmid_ds shm_buf = { 0 };
+      shm_buf.shm_pagesize = pagesize;
+      if (::shmctl(shmid, SHM_PAGESIZE, &shm_buf) != 0) {
+        const int en = errno;
+        ::shmctl(shmid, IPC_RMID, NULL); // As early as possible!
+        // PPC port trcVerbose("shmctl(SHM_PAGESIZE) failed with %s",
+        // PPC port  MiscUtils::describe_errno(en));
+      } else {
+        // Attach and double check pageisze.
+        void* p = ::shmat(shmid, NULL, 0);
+        ::shmctl(shmid, IPC_RMID, NULL); // As early as possible!
+        guarantee0(p != (void*) -1); // Should always work.
+        const size_t real_pagesize = os::Aix::query_pagesize(p);
+        if (real_pagesize != pagesize) {
+          trcVerbose("real page size (0x%llX) differs.", real_pagesize);
+        } else {
+          can_use = true;
+        }
+        ::shmdt(p);
+      }
+      trcVerbose("Can use: %s", (can_use ? "yes" : "no"));
+      if (pagesize == SIZE_64K) {
+        g_multipage_support.can_use_64K_pages = can_use;
+      } else if (pagesize == SIZE_16M) {
+        g_multipage_support.can_use_16M_pages = can_use;
       }
     }
 
-    if (!_can_use_64K_pages) {
-      g_multipage_error = ERROR_MP_VMGETINFO_CLAIMS_NO_SUPPORT_FOR_64K;
-    }
-
-    // Double-check for 16M pages: Even if AIX claims to be able to use 16M pages,
-    // there must be an actual 16M page pool, and we must run with enough rights.
-    if (_can_use_16M_pages) {
-      const int shmid = ::shmget(IPC_PRIVATE, SIZE_16M, IPC_CREAT | S_IRUSR | S_IWUSR);
-      guarantee(shmid != -1, "shmget failed");
-      struct shmid_ds shm_buf = { 0 };
-      shm_buf.shm_pagesize = SIZE_16M;
-      const bool can_set_pagesize = ::shmctl(shmid, SHM_PAGESIZE, &shm_buf) == 0 ? true : false;
-      const int en = errno;
-      ::shmctl(shmid, IPC_RMID, NULL);
-      if (!can_set_pagesize) {
-        if (Verbose) {
-          fprintf(stderr, "Failed to allocate even one misely 16M page. shmctl failed with %d (%s).\n"
-                          "Will deactivate 16M support.\n", en, strerror(en));
-        }
-        _can_use_16M_pages = 0;
-      }
-    }
-
   } // end: check which pages can be used for shared memory
 
 query_multipage_support_end:
 
-  guarantee(_page_size != -1 &&
-            _stack_page_size != -1 &&
-            _can_use_64K_pages != -1 &&
-            _can_use_16M_pages != -1, "Page sizes not properly initialized");
-
-  if (_can_use_64K_pages) {
-    g_multipage_error = 0;
-  }
-
-  if (Verbose) {
-    fprintf(stderr, "Data page size (C-Heap, bss, etc): %s\n", describe_pagesize(data_page_size));
-    fprintf(stderr, "Thread stack page size (pthread): %s\n", describe_pagesize(_stack_page_size));
-    fprintf(stderr, "Default shared memory page size: %s\n", describe_pagesize(_shm_default_page_size));
-    fprintf(stderr, "Can use 64K pages dynamically with shared meory: %s\n", (_can_use_64K_pages ? "yes" :"no"));
-    fprintf(stderr, "Can use 16M pages dynamically with shared memory: %s\n", (_can_use_16M_pages ? "yes" :"no"));
-    fprintf(stderr, "Multipage error details: %d\n", g_multipage_error);
-  }
+  trcVerbose("base page size (sysconf _SC_PAGESIZE): %s\n",
+      describe_pagesize(g_multipage_support.pagesize));
+  trcVerbose("Data page size (C-Heap, bss, etc): %s\n",
+      describe_pagesize(g_multipage_support.datapsize));
+  trcVerbose("Text page size: %s\n",
+      describe_pagesize(g_multipage_support.textpsize));
+  trcVerbose("Thread stack page size (pthread): %s\n",
+      describe_pagesize(g_multipage_support.pthr_stack_pagesize));
+  trcVerbose("Default shared memory page size: %s\n",
+      describe_pagesize(g_multipage_support.shmpsize));
+  trcVerbose("Can use 64K pages dynamically with shared meory: %s\n",
+      (g_multipage_support.can_use_64K_pages ? "yes" :"no"));
+  trcVerbose("Can use 16M pages dynamically with shared memory: %s\n",
+      (g_multipage_support.can_use_16M_pages ? "yes" :"no"));
+  trcVerbose("Multipage error details: %d\n",
+      g_multipage_support.error);
+
+  // sanity checks
+  assert0(g_multipage_support.pagesize == SIZE_4K);
+  assert0(g_multipage_support.datapsize == SIZE_4K || g_multipage_support.datapsize == SIZE_64K);
+  // PPC port: so far unused.assert0(g_multipage_support.textpsize == SIZE_4K || g_multipage_support.textpsize == SIZE_64K);
+  assert0(g_multipage_support.pthr_stack_pagesize == g_multipage_support.datapsize);
+  assert0(g_multipage_support.shmpsize == SIZE_4K || g_multipage_support.shmpsize == SIZE_64K);
 
 } // end os::Aix::query_multipage_support()
 
@@ -1572,9 +1629,12 @@
 
   st->print_cr("  default page size: %s", describe_pagesize(os::vm_page_size()));
   st->print_cr("  default stack page size: %s", describe_pagesize(os::vm_page_size()));
-  st->print_cr("  default shm page size: %s", describe_pagesize(os::Aix::shm_default_page_size()));
-  st->print_cr("  can use 64K pages dynamically: %s", (os::Aix::can_use_64K_pages() ? "yes" :"no"));
-  st->print_cr("  can use 16M pages dynamically: %s", (os::Aix::can_use_16M_pages() ? "yes" :"no"));
+  st->print_cr("  Default shared memory page size:        %s",
+    describe_pagesize(g_multipage_support.shmpsize));
+  st->print_cr("  Can use 64K pages dynamically with shared meory:  %s",
+    (g_multipage_support.can_use_64K_pages ? "yes" :"no"));
+  st->print_cr("  Can use 16M pages dynamically with shared memory: %s",
+    (g_multipage_support.can_use_16M_pages ? "yes" :"no"));
   if (g_multipage_error != 0) {
     st->print_cr("  multipage error: %d", g_multipage_error);
   }
@@ -1585,6 +1645,9 @@
 
   const char* const extshm = ::getenv("EXTSHM");
   st->print_cr("  EXTSHM=%s.", extshm ? extshm : "<unset>");
+  if ( (strcmp(extshm, "on") == 0) || (strcmp(extshm, "ON") == 0) ) {
+    st->print_cr("  *** Unsupported! Please remove EXTSHM from your environment! ***");
+  }
 
   // Call os::Aix::get_meminfo() to retrieve memory statistics.
   os::Aix::meminfo_t mi;
@@ -1827,315 +1890,386 @@
 ////////////////////////////////////////////////////////////////////////////////
 // Virtual Memory
 
-// AddrRange describes an immutable address range
-//
-// This is a helper class for the 'shared memory bookkeeping' below.
-class AddrRange {
-  friend class ShmBkBlock;
-
-  char* _start;
-  size_t _size;
-
-public:
-
-  AddrRange(char* start, size_t size)
-    : _start(start), _size(size)
-  {}
-
-  AddrRange(const AddrRange& r)
-    : _start(r.start()), _size(r.size())
-  {}
-
-  char* start() const { return _start; }
-  size_t size() const { return _size; }
-  char* end() const { return _start + _size; }
-  bool is_empty() const { return _size == 0 ? true : false; }
-
-  static AddrRange empty_range() { return AddrRange(NULL, 0); }
-
-  bool contains(const char* p) const {
-    return start() <= p && end() > p;
-  }
-
-  bool contains(const AddrRange& range) const {
-    return start() <= range.start() && end() >= range.end();
-  }
-
-  bool intersects(const AddrRange& range) const {
-    return (range.start() <= start() && range.end() > start()) ||
-           (range.start() < end() && range.end() >= end()) ||
-           contains(range);
-  }
-
-  bool is_same_range(const AddrRange& range) const {
-    return start() == range.start() && size() == range.size();
-  }
-
-  // return the closest inside range consisting of whole pages
-  AddrRange find_closest_aligned_range(size_t pagesize) const {
-    if (pagesize == 0 || is_empty()) {
-      return empty_range();
+// We need to keep small simple bookkeeping for os::reserve_memory and friends.
+
+#define VMEM_MAPPED  1
+#define VMEM_SHMATED 2
+
+struct vmembk_t {
+  int type;         // 1 - mmap, 2 - shmat
+  char* addr;
+  size_t size;      // Real size, may be larger than usersize.
+  size_t pagesize;  // page size of area
+  vmembk_t* next;
+
+  bool contains_addr(char* p) const {
+    return p >= addr && p < (addr + size);
+  }
+
+  bool contains_range(char* p, size_t s) const {
+    return contains_addr(p) && contains_addr(p + s - 1);
+  }
+
+  void print_on(outputStream* os) const {
+    os->print("[" PTR_FORMAT " - " PTR_FORMAT "] (" UINTX_FORMAT
+      " bytes, %d %s pages), %s",
+      addr, addr + size - 1, size, size / pagesize, describe_pagesize(pagesize),
+      (type == VMEM_SHMATED ? "shmat" : "mmap")
+    );
+  }
+
+  // Check that range is a sub range of memory block (or equal to memory block);
+  // also check that range is fully page aligned to the page size if the block.
+  void assert_is_valid_subrange(char* p, size_t s) const {
+    if (!contains_range(p, s)) {
+      fprintf(stderr, "[" PTR_FORMAT " - " PTR_FORMAT "] is not a sub "
+              "range of [" PTR_FORMAT " - " PTR_FORMAT "].\n",
+              p, p + s - 1, addr, addr + size - 1);
+      guarantee0(false);
     }
-    char* const from = (char*)align_size_up((intptr_t)_start, pagesize);
-    char* const to = (char*)align_size_down((intptr_t)end(), pagesize);
-    if (from > to) {
-      return empty_range();
+    if (!is_aligned_to(p, pagesize) || !is_aligned_to(p + s, pagesize)) {
+      fprintf(stderr, "range [" PTR_FORMAT " - " PTR_FORMAT "] is not"
+              " aligned to pagesize (%s)\n", p, p + s);
+      guarantee0(false);
     }
-    return AddrRange(from, to - from);
   }
 };
 
-////////////////////////////////////////////////////////////////////////////
-// shared memory bookkeeping
-//
-// the os::reserve_memory() API and friends hand out different kind of memory, depending
-// on need and circumstances. Memory may be allocated with mmap() or with shmget/shmat.
-//
-// But these memory types have to be treated differently. For example, to uncommit
-// mmap-based memory, msync(MS_INVALIDATE) is needed, to uncommit shmat-based memory,
-// disclaim64() is needed.
-//
-// Therefore we need to keep track of the allocated memory segments and their
-// properties.
-
-// ShmBkBlock: base class for all blocks in the shared memory bookkeeping
-class ShmBkBlock : public CHeapObj<mtInternal> {
-
-  ShmBkBlock* _next;
-
-protected:
-
-  AddrRange _range;
-  const size_t _pagesize;
-  const bool _pinned;
-
-public:
-
-  ShmBkBlock(AddrRange range, size_t pagesize, bool pinned)
-    : _range(range), _pagesize(pagesize), _pinned(pinned) , _next(NULL) {
-
-    assert(_pagesize == SIZE_4K || _pagesize == SIZE_64K || _pagesize == SIZE_16M, "invalid page size");
-    assert(!_range.is_empty(), "invalid range");
-  }
-
-  virtual void print(outputStream* st) const {
-    st->print("0x%p ... 0x%p (%llu) - %d %s pages - %s",
-              _range.start(), _range.end(), _range.size(),
-              _range.size() / _pagesize, describe_pagesize(_pagesize),
-              _pinned ? "pinned" : "");
-  }
-
-  enum Type { MMAP, SHMAT };
-  virtual Type getType() = 0;
-
-  char* base() const { return _range.start(); }
-  size_t size() const { return _range.size(); }
-
-  void setAddrRange(AddrRange range) {
-    _range = range;
-  }
-
-  bool containsAddress(const char* p) const {
-    return _range.contains(p);
-  }
-
-  bool containsRange(const char* p, size_t size) const {
-    return _range.contains(AddrRange((char*)p, size));
-  }
-
-  bool isSameRange(const char* p, size_t size) const {
-    return _range.is_same_range(AddrRange((char*)p, size));
-  }
-
-  virtual bool disclaim(char* p, size_t size) = 0;
-  virtual bool release() = 0;
-
-  // blocks live in a list.
-  ShmBkBlock* next() const { return _next; }
-  void set_next(ShmBkBlock* blk) { _next = blk; }
-
-}; // end: ShmBkBlock
-
-
-// ShmBkMappedBlock: describes an block allocated with mmap()
-class ShmBkMappedBlock : public ShmBkBlock {
-public:
-
-  ShmBkMappedBlock(AddrRange range)
-    : ShmBkBlock(range, SIZE_4K, false) {} // mmap: always 4K, never pinned
-
-  void print(outputStream* st) const {
-    ShmBkBlock::print(st);
-    st->print_cr(" - mmap'ed");
-  }
-
-  Type getType() {
-    return MMAP;
-  }
-
-  bool disclaim(char* p, size_t size) {
-
-    AddrRange r(p, size);
-
-    guarantee(_range.contains(r), "invalid disclaim");
-
-    // only disclaim whole ranges.
-    const AddrRange r2 = r.find_closest_aligned_range(_pagesize);
-    if (r2.is_empty()) {
-      return true;
+static struct {
+  vmembk_t* first;
+  MiscUtils::CritSect cs;
+} vmem;
+
+static void vmembk_add(char* addr, size_t size, size_t pagesize, int type) {
+  vmembk_t* p = (vmembk_t*) ::malloc(sizeof(vmembk_t));
+  assert0(p);
+  if (p) {
+    MiscUtils::AutoCritSect lck(&vmem.cs);
+    p->addr = addr; p->size = size;
+    p->pagesize = pagesize;
+    p->type = type;
+    p->next = vmem.first;
+    vmem.first = p;
+  }
+}
+
+static vmembk_t* vmembk_find(char* addr) {
+  MiscUtils::AutoCritSect lck(&vmem.cs);
+  for (vmembk_t* p = vmem.first; p; p = p->next) {
+    if (p->addr <= addr && (p->addr + p->size) > addr) {
+      return p;
     }
-
-    const int rc = ::msync(r2.start(), r2.size(), MS_INVALIDATE);
-
-    if (rc != 0) {
-      warning("msync(0x%p, %llu, MS_INVALIDATE) failed (%d)\n", r2.start(), r2.size(), errno);
-    }
-
-    return rc == 0 ? true : false;
-  }
-
-  bool release() {
-    // mmap'ed blocks are released using munmap
-    if (::munmap(_range.start(), _range.size()) != 0) {
-      warning("munmap(0x%p, %llu) failed (%d)\n", _range.start(), _range.size(), errno);
-      return false;
-    }
-    return true;
-  }
-}; // end: ShmBkMappedBlock
-
-// ShmBkShmatedBlock: describes an block allocated with shmget/shmat()
-class ShmBkShmatedBlock : public ShmBkBlock {
-public:
-
-  ShmBkShmatedBlock(AddrRange range, size_t pagesize, bool pinned)
-    : ShmBkBlock(range, pagesize, pinned) {}
-
-  void print(outputStream* st) const {
-    ShmBkBlock::print(st);
-    st->print_cr(" - shmat'ed");
-  }
-
-  Type getType() {
-    return SHMAT;
-  }
-
-  bool disclaim(char* p, size_t size) {
-
-    AddrRange r(p, size);
-
-    if (_pinned) {
-      return true;
-    }
-
-    // shmat'ed blocks are disclaimed using disclaim64
-    guarantee(_range.contains(r), "invalid disclaim");
-
-    // only disclaim whole ranges.
-    const AddrRange r2 = r.find_closest_aligned_range(_pagesize);
-    if (r2.is_empty()) {
-      return true;
-    }
-
-    const bool rc = my_disclaim64(r2.start(), r2.size());
-
-    if (Verbose && !rc) {
-      warning("failed to disclaim shm %p-%p\n", r2.start(), r2.end());
-    }
-
-    return rc;
-  }
-
-  bool release() {
-    bool rc = false;
-    if (::shmdt(_range.start()) != 0) {
-      warning("shmdt(0x%p) failed (%d)\n", _range.start(), errno);
-    } else {
-      rc = true;
-    }
-    return rc;
-  }
-
-}; // end: ShmBkShmatedBlock
-
-static ShmBkBlock* g_shmbk_list = NULL;
-static volatile jint g_shmbk_table_lock = 0;
-
-// keep some usage statistics
-static struct {
-  int nodes;    // number of nodes in list
-  size_t bytes; // reserved - not committed - bytes.
-  int reserves; // how often reserve was called
-  int lookups;  // how often a lookup was made
-} g_shmbk_stats = { 0, 0, 0, 0 };
-
-// add information about a shared memory segment to the bookkeeping
-static void shmbk_register(ShmBkBlock* p_block) {
-  guarantee(p_block, "logic error");
-  p_block->set_next(g_shmbk_list);
-  g_shmbk_list = p_block;
-  g_shmbk_stats.reserves ++;
-  g_shmbk_stats.bytes += p_block->size();
-  g_shmbk_stats.nodes ++;
-}
-
-// remove information about a shared memory segment by its starting address
-static void shmbk_unregister(ShmBkBlock* p_block) {
-  ShmBkBlock* p = g_shmbk_list;
-  ShmBkBlock* prev = NULL;
-  while (p) {
-    if (p == p_block) {
-      if (prev) {
-        prev->set_next(p->next());
-      } else {
-        g_shmbk_list = p->next();
-      }
-      g_shmbk_stats.nodes --;
-      g_shmbk_stats.bytes -= p->size();
+  }
+  return NULL;
+}
+
+static void vmembk_remove(vmembk_t* p0) {
+  MiscUtils::AutoCritSect lck(&vmem.cs);
+  assert0(p0);
+  assert0(vmem.first); // List should not be empty.
+  for (vmembk_t** pp = &(vmem.first); *pp; pp = &((*pp)->next)) {
+    if (*pp == p0) {
+      *pp = p0->next;
+      ::free(p0);
       return;
     }
-    prev = p;
-    p = p->next();
-  }
-  assert(false, "should not happen");
-}
-
-// given a pointer, return shared memory bookkeeping record for the segment it points into
-// using the returned block info must happen under lock protection
-static ShmBkBlock* shmbk_find_by_containing_address(const char* addr) {
-  g_shmbk_stats.lookups ++;
-  ShmBkBlock* p = g_shmbk_list;
-  while (p) {
-    if (p->containsAddress(addr)) {
-      return p;
+  }
+  assert0(false); // Not found?
+}
+
+static void vmembk_print_on(outputStream* os) {
+  MiscUtils::AutoCritSect lck(&vmem.cs);
+  for (vmembk_t* vmi = vmem.first; vmi; vmi = vmi->next) {
+    vmi->print_on(os);
+    os->cr();
+  }
+}
+
+// Reserve and attach a section of System V memory.
+// If <requested_addr> is not NULL, function will attempt to attach the memory at the given
+// address. Failing that, it will attach the memory anywhere.
+// If <requested_addr> is NULL, function will attach the memory anywhere.
+//
+// <alignment_hint> is being ignored by this function. It is very probable however that the
+// alignment requirements are met anyway, because shmat() attaches at 256M boundaries.
+// Should this be not enogh, we can put more work into it.
+static char* reserve_shmated_memory (
+  size_t bytes,
+  char* requested_addr,
+  size_t alignment_hint) {
+
+  trcVerbose("reserve_shmated_memory " UINTX_FORMAT " bytes, wishaddress "
+    PTR_FORMAT ", alignment_hint " UINTX_FORMAT "...",
+    bytes, requested_addr, alignment_hint);
+
+  // Either give me wish address or wish alignment but not both.
+  assert0(!(requested_addr != NULL && alignment_hint != 0));
+
+  // We must prevent anyone from attaching too close to the
+  // BRK because that may cause malloc OOM.
+  if (requested_addr != NULL && is_close_to_brk((address)requested_addr)) {
+    trcVerbose("Wish address " PTR_FORMAT " is too close to the BRK segment. "
+      "Will attach anywhere.", requested_addr);
+    // Act like the OS refused to attach there.
+    requested_addr = NULL;
+  }
+
+  // For old AS/400's (V5R4 and older) we should not even be here - System V shared memory is not
+  // really supported (max size 4GB), so reserve_mmapped_memory should have been used instead.
+  if (os::Aix::on_pase_V5R4_or_older()) {
+    ShouldNotReachHere();
+  }
+
+  // Align size of shm up to 64K to avoid errors if we later try to change the page size.
+  const size_t size = align_size_up(bytes, SIZE_64K);
+
+  // Reserve the shared segment.
+  int shmid = shmget(IPC_PRIVATE, size, IPC_CREAT | S_IRUSR | S_IWUSR);
+  if (shmid == -1) {
+    trc("shmget(.., " UINTX_FORMAT ", ..) failed (errno: %d).", size, errno);
+    return NULL;
+  }
+
+  // Important note:
+  // It is very important that we, upon leaving this function, do not leave a shm segment alive.
+  // We must right after attaching it remove it from the system. System V shm segments are global and
+  // survive the process.
+  // So, from here on: Do not assert, do not return, until we have called shmctl(IPC_RMID) (A).
+
+  struct shmid_ds shmbuf;
+  memset(&shmbuf, 0, sizeof(shmbuf));
+  shmbuf.shm_pagesize = SIZE_64K;
+  if (shmctl(shmid, SHM_PAGESIZE, &shmbuf) != 0) {
+    trcVerbose("Failed to set page size (need " UINTX_FORMAT " 64K pages) - shmctl failed with %d.",
+               size / SIZE_64K, errno);
+    // I want to know if this ever happens.
+    assert(false, "failed to set page size for shmat");
+  }
+
+  // Now attach the shared segment.
+  // Note that I attach with SHM_RND - which means that the requested address is rounded down, if
+  // needed, to the next lowest segment boundary. Otherwise the attach would fail if the address
+  // were not a segment boundary.
+  char* const addr = (char*) shmat(shmid, requested_addr, SHM_RND);
+  const int errno_shmat = errno;
+
+  // (A) Right after shmat and before handing shmat errors delete the shm segment.
+  if (::shmctl(shmid, IPC_RMID, NULL) == -1) {
+    trc("shmctl(%u, IPC_RMID) failed (%d)\n", shmid, errno);
+    assert(false, "failed to remove shared memory segment!");
+  }
+
+  // Handle shmat error. If we failed to attach, just return.
+  if (addr == (char*)-1) {
+    trcVerbose("Failed to attach segment at " PTR_FORMAT " (%d).", requested_addr, errno_shmat);
+    return NULL;
+  }
+
+  // Just for info: query the real page size. In case setting the page size did not
+  // work (see above), the system may have given us something other then 4K (LDR_CNTRL).
+  const size_t real_pagesize = os::Aix::query_pagesize(addr);
+  if (real_pagesize != shmbuf.shm_pagesize) {
+    trcVerbose("pagesize is, surprisingly, %h.", real_pagesize);
+  }
+
+  if (addr) {
+    trcVerbose("shm-allocated " PTR_FORMAT " .. " PTR_FORMAT " (" UINTX_FORMAT " bytes, " UINTX_FORMAT " %s pages)",
+      addr, addr + size - 1, size, size/real_pagesize, describe_pagesize(real_pagesize));
+  } else {
+    if (requested_addr != NULL) {
+      trcVerbose("failed to shm-allocate " UINTX_FORMAT " bytes at with address " PTR_FORMAT ".", size, requested_addr);
+    } else {
+      trcVerbose("failed to shm-allocate " UINTX_FORMAT " bytes at any address.", size);
     }
-    p = p->next();
-  }
-  return NULL;
-}
-
-// dump all information about all memory segments allocated with os::reserve_memory()
-void shmbk_dump_info() {
-  tty->print_cr("-- shared mem bookkeeping (alive: %d segments, %llu bytes, "
-    "total reserves: %d total lookups: %d)",
-    g_shmbk_stats.nodes, g_shmbk_stats.bytes, g_shmbk_stats.reserves, g_shmbk_stats.lookups);
-  const ShmBkBlock* p = g_shmbk_list;
-  int i = 0;
-  while (p) {
-    p->print(tty);
-    p = p->next();
-    i ++;
-  }
-}
-
-#define LOCK_SHMBK     { ThreadCritical _LOCK_SHMBK;
-#define UNLOCK_SHMBK   }
+  }
+
+  // book-keeping
+  vmembk_add(addr, size, real_pagesize, VMEM_SHMATED);
+  assert0(is_aligned_to(addr, os::vm_page_size()));
+
+  return addr;
+}
+
+static bool release_shmated_memory(char* addr, size_t size) {
+
+  trcVerbose("release_shmated_memory [" PTR_FORMAT " - " PTR_FORMAT "].",
+    addr, addr + size - 1);
+
+  bool rc = false;
+
+  // TODO: is there a way to verify shm size without doing bookkeeping?
+  if (::shmdt(addr) != 0) {
+    trcVerbose("error (%d).", errno);
+  } else {
+    trcVerbose("ok.");
+    rc = true;
+  }
+  return rc;
+}
+
+static bool uncommit_shmated_memory(char* addr, size_t size) {
+  trcVerbose("uncommit_shmated_memory [" PTR_FORMAT " - " PTR_FORMAT "].",
+    addr, addr + size - 1);
+
+  const bool rc = my_disclaim64(addr, size);
+
+  if (!rc) {
+    trcVerbose("my_disclaim64(" PTR_FORMAT ", " UINTX_FORMAT ") failed.\n", addr, size);
+    return false;
+  }
+  return true;
+}
+
+// Reserve memory via mmap.
+// If <requested_addr> is given, an attempt is made to attach at the given address.
+// Failing that, memory is allocated at any address.
+// If <alignment_hint> is given and <requested_addr> is NULL, an attempt is made to
+// allocate at an address aligned with the given alignment. Failing that, memory
+// is aligned anywhere.
+static char* reserve_mmaped_memory(size_t bytes, char* requested_addr, size_t alignment_hint) {
+  trcVerbose("reserve_mmaped_memory " UINTX_FORMAT " bytes, wishaddress " PTR_FORMAT ", "
+    "alignment_hint " UINTX_FORMAT "...",
+    bytes, requested_addr, alignment_hint);
+
+  // If a wish address is given, but not aligned to 4K page boundary, mmap will fail.
+  if (requested_addr && !is_aligned_to(requested_addr, os::vm_page_size()) != 0) {
+    trcVerbose("Wish address " PTR_FORMAT " not aligned to page boundary.", requested_addr);
+    return NULL;
+  }
+
+  // We must prevent anyone from attaching too close to the
+  // BRK because that may cause malloc OOM.
+  if (requested_addr != NULL && is_close_to_brk((address)requested_addr)) {
+    trcVerbose("Wish address " PTR_FORMAT " is too close to the BRK segment. "
+      "Will attach anywhere.", requested_addr);
+    // Act like the OS refused to attach there.
+    requested_addr = NULL;
+  }
+
+  // Specify one or the other but not both.
+  assert0(!(requested_addr != NULL && alignment_hint > 0));
+
+  // In 64K mode, we claim the global page size (os::vm_page_size())
+  // is 64K. This is one of the few points where that illusion may
+  // break, because mmap() will always return memory aligned to 4K. So
+  // we must ensure we only ever return memory aligned to 64k.
+  if (alignment_hint) {
+    alignment_hint = lcm(alignment_hint, os::vm_page_size());
+  } else {
+    alignment_hint = os::vm_page_size();
+  }
+
+  // Size shall always be a multiple of os::vm_page_size (esp. in 64K mode).
+  const size_t size = align_size_up(bytes, os::vm_page_size());
+
+  // alignment: Allocate memory large enough to include an aligned range of the right size and
+  // cut off the leading and trailing waste pages.
+  assert0(alignment_hint != 0 && is_aligned_to(alignment_hint, os::vm_page_size())); // see above
+  const size_t extra_size = size + alignment_hint;
+
+  // Note: MAP_SHARED (instead of MAP_PRIVATE) needed to be able to
+  // later use msync(MS_INVALIDATE) (see os::uncommit_memory).
+  int flags = MAP_ANONYMOUS | MAP_SHARED;
+
+  // MAP_FIXED is needed to enforce requested_addr - manpage is vague about what
+  // it means if wishaddress is given but MAP_FIXED is not set.
+  //
+  // Important! Behaviour differs depending on whether SPEC1170 mode is active or not.
+  // SPEC1170 mode active: behaviour like POSIX, MAP_FIXED will clobber existing mappings.
+  // SPEC1170 mode not active: behaviour, unlike POSIX, is that no existing mappings will
+  // get clobbered.
+  if (requested_addr != NULL) {
+    if (!os::Aix::xpg_sus_mode()) {  // not SPEC1170 Behaviour
+      flags |= MAP_FIXED;
+    }
+  }
+
+  char* addr = (char*)::mmap(requested_addr, extra_size,
+      PROT_READ|PROT_WRITE|PROT_EXEC, flags, -1, 0);
+
+  if (addr == MAP_FAILED) {
+    trcVerbose("mmap(" PTR_FORMAT ", " UINTX_FORMAT ", ..) failed (%d)", requested_addr, size, errno);
+    return NULL;
+  }
+
+  // Handle alignment.
+  char* const addr_aligned = (char *)align_ptr_up(addr, alignment_hint);
+  const size_t waste_pre = addr_aligned - addr;
+  char* const addr_aligned_end = addr_aligned + size;
+  const size_t waste_post = extra_size - waste_pre - size;
+  if (waste_pre > 0) {
+    ::munmap(addr, waste_pre);
+  }
+  if (waste_post > 0) {
+    ::munmap(addr_aligned_end, waste_post);
+  }
+  addr = addr_aligned;
+
+  if (addr) {
+    trcVerbose("mmap-allocated " PTR_FORMAT " .. " PTR_FORMAT " (" UINTX_FORMAT " bytes)",
+      addr, addr + bytes, bytes);
+  } else {
+    if (requested_addr != NULL) {
+      trcVerbose("failed to mmap-allocate " UINTX_FORMAT " bytes at wish address " PTR_FORMAT ".", bytes, requested_addr);
+    } else {
+      trcVerbose("failed to mmap-allocate " UINTX_FORMAT " bytes at any address.", bytes);
+    }
+  }
+
+  // bookkeeping
+  vmembk_add(addr, size, SIZE_4K, VMEM_MAPPED);
+
+  // Test alignment, see above.
+  assert0(is_aligned_to(addr, os::vm_page_size()));
+
+  return addr;
+}
+
+static bool release_mmaped_memory(char* addr, size_t size) {
+  assert0(is_aligned_to(addr, os::vm_page_size()));
+  assert0(is_aligned_to(size, os::vm_page_size()));
+
+  trcVerbose("release_mmaped_memory [" PTR_FORMAT " - " PTR_FORMAT "].",
+    addr, addr + size - 1);
+  bool rc = false;
+
+  if (::munmap(addr, size) != 0) {
+    trcVerbose("failed (%d)\n", errno);
+    rc = false;
+  } else {
+    trcVerbose("ok.");
+    rc = true;
+  }
+
+  return rc;
+}
+
+static bool uncommit_mmaped_memory(char* addr, size_t size) {
+
+  assert0(is_aligned_to(addr, os::vm_page_size()));
+  assert0(is_aligned_to(size, os::vm_page_size()));
+
+  trcVerbose("uncommit_mmaped_memory [" PTR_FORMAT " - " PTR_FORMAT "].",
+    addr, addr + size - 1);
+  bool rc = false;
+
+  // Uncommit mmap memory with msync MS_INVALIDATE.
+  if (::msync(addr, size, MS_INVALIDATE) != 0) {
+    trcVerbose("failed (%d)\n", errno);
+    rc = false;
+  } else {
+    trcVerbose("ok.");
+    rc = true;
+  }
+
+  return rc;
+}
 
 // End: shared memory bookkeeping
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 
 int os::vm_page_size() {
-  // Seems redundant as all get out
+  // Seems redundant as all get out.
   assert(os::Aix::page_size() != -1, "must call os::init");
   return os::Aix::page_size();
 }
@@ -2146,91 +2280,76 @@
   return os::Aix::page_size();
 }
 
-int os::Aix::commit_memory_impl(char* addr, size_t size, bool exec) {
-
-  // Commit is a noop. There is no explicit commit
-  // needed on AIX. Memory is committed when touched.
-  //
-  // Debug : check address range for validity
-#ifdef ASSERT
-  LOCK_SHMBK
-    ShmBkBlock* const block = shmbk_find_by_containing_address(addr);
-    if (!block) {
-      fprintf(stderr, "invalid pointer: " INTPTR_FORMAT "\n", addr);
-      shmbk_dump_info();
-      assert(false, "invalid pointer");
-      return false;
-    } else if (!block->containsRange(addr, size)) {
-      fprintf(stderr, "invalid range: " INTPTR_FORMAT " .. " INTPTR_FORMAT "\n", addr, addr + size);
-      shmbk_dump_info();
-      assert(false, "invalid range");
-      return false;
-    }
-  UNLOCK_SHMBK
-#endif // ASSERT
-
-  return 0;
-}
-
-bool os::pd_commit_memory(char* addr, size_t size, bool exec) {
-  return os::Aix::commit_memory_impl(addr, size, exec) == 0;
-}
+#ifdef PRODUCT
+static void warn_fail_commit_memory(char* addr, size_t size, bool exec,
+                                    int err) {
+  warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
+          ", %d) failed; error='%s' (errno=%d)", addr, size, exec,
+          strerror(err), err);
+}
+#endif
 
 void os::pd_commit_memory_or_exit(char* addr, size_t size, bool exec,
                                   const char* mesg) {
   assert(mesg != NULL, "mesg must be specified");
-  os::Aix::commit_memory_impl(addr, size, exec);
-}
-
-int os::Aix::commit_memory_impl(char* addr, size_t size,
-                                size_t alignment_hint, bool exec) {
-  return os::Aix::commit_memory_impl(addr, size, exec);
-}
-
-bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint,
-                          bool exec) {
-  return os::Aix::commit_memory_impl(addr, size, alignment_hint, exec) == 0;
+  if (!pd_commit_memory(addr, size, exec)) {
+    // Add extra info in product mode for vm_exit_out_of_memory():
+    PRODUCT_ONLY(warn_fail_commit_memory(addr, size, exec, errno);)
+    vm_exit_out_of_memory(size, OOM_MMAP_ERROR, mesg);
+  }
+}
+
+bool os::pd_commit_memory(char* addr, size_t size, bool exec) {
+
+  assert0(is_aligned_to(addr, os::vm_page_size()));
+  assert0(is_aligned_to(size, os::vm_page_size()));
+
+  vmembk_t* const vmi = vmembk_find(addr);
+  assert0(vmi);
+  vmi->assert_is_valid_subrange(addr, size);
+
+  trcVerbose("commit_memory [" PTR_FORMAT " - " PTR_FORMAT "].", addr, addr + size - 1);
+
+  return true;
+}
+
+bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint, bool exec) {
+  return pd_commit_memory(addr, size, exec);
 }
 
 void os::pd_commit_memory_or_exit(char* addr, size_t size,
                                   size_t alignment_hint, bool exec,
                                   const char* mesg) {
-  os::Aix::commit_memory_impl(addr, size, alignment_hint, exec);
+  // Alignment_hint is ignored on this OS.
+  pd_commit_memory_or_exit(addr, size, exec, mesg);
 }
 
 bool os::pd_uncommit_memory(char* addr, size_t size) {
-
-  // Delegate to ShmBkBlock class which knows how to uncommit its memory.
-
-  bool rc = false;
-  LOCK_SHMBK
-    ShmBkBlock* const block = shmbk_find_by_containing_address(addr);
-    if (!block) {
-      fprintf(stderr, "invalid pointer: 0x%p.\n", addr);
-      shmbk_dump_info();
-      assert(false, "invalid pointer");
-      return false;
-    } else if (!block->containsRange(addr, size)) {
-      fprintf(stderr, "invalid range: 0x%p .. 0x%p.\n", addr, addr + size);
-      shmbk_dump_info();
-      assert(false, "invalid range");
-      return false;
-    }
-    rc = block->disclaim(addr, size);
-  UNLOCK_SHMBK
-
-  if (Verbose && !rc) {
-    warning("failed to disclaim 0x%p .. 0x%p (0x%llX bytes).", addr, addr + size, size);
-  }
-  return rc;
+  assert0(is_aligned_to(addr, os::vm_page_size()));
+  assert0(is_aligned_to(size, os::vm_page_size()));
+
+  // Dynamically do different things for mmap/shmat.
+  const vmembk_t* const vmi = vmembk_find(addr);
+  assert0(vmi);
+  vmi->assert_is_valid_subrange(addr, size);
+
+  if (vmi->type == VMEM_SHMATED) {
+    return uncommit_shmated_memory(addr, size);
+  } else {
+    return uncommit_mmaped_memory(addr, size);
+  }
 }
 
 bool os::pd_create_stack_guard_pages(char* addr, size_t size) {
-  return os::guard_memory(addr, size);
+  // Do not call this; no need to commit stack pages on AIX.
+  ShouldNotReachHere();
+  return true;
 }
 
 bool os::remove_stack_guard_pages(char* addr, size_t size) {
-  return os::unguard_memory(addr, size);
+  // Do not call this; no need to commit stack pages on AIX.
+  ShouldNotReachHere();
+  return true;
 }
 
 void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
@@ -2273,355 +2392,75 @@
   return end;
 }
 
-// Flags for reserve_shmatted_memory:
-#define RESSHM_WISHADDR_OR_FAIL                     1
-#define RESSHM_TRY_16M_PAGES                        2
-#define RESSHM_16M_PAGES_OR_FAIL                    4
-
-// Result of reserve_shmatted_memory:
-struct shmatted_memory_info_t {
-  char* addr;
-  size_t pagesize;
-  bool pinned;
-};
-
-// Reserve a section of shmatted memory.
-// params:
-// bytes [in]: size of memory, in bytes
-// requested_addr [in]: wish address.
-//                      NULL = no wish.
-//                      If RESSHM_WISHADDR_OR_FAIL is set in flags and wish address cannot
-//                      be obtained, function will fail. Otherwise wish address is treated as hint and
-//                      another pointer is returned.
-// flags [in]:          some flags. Valid flags are:
-//                      RESSHM_WISHADDR_OR_FAIL - fail if wish address is given and cannot be obtained.
-//                      RESSHM_TRY_16M_PAGES - try to allocate from 16M page pool
-//                          (requires UseLargePages and Use16MPages)
-//                      RESSHM_16M_PAGES_OR_FAIL - if you cannot allocate from 16M page pool, fail.
-//                          Otherwise any other page size will do.
-// p_info [out] :       holds information about the created shared memory segment.
-static bool reserve_shmatted_memory(size_t bytes, char* requested_addr, int flags, shmatted_memory_info_t* p_info) {
-
-  assert(p_info, "parameter error");
-
-  // init output struct.
-  p_info->addr = NULL;
-
-  // neither should we be here for EXTSHM=ON.
-  if (os::Aix::extshm()) {
-    ShouldNotReachHere();
-  }
-
-  // extract flags. sanity checks.
-  const bool wishaddr_or_fail =
-    flags & RESSHM_WISHADDR_OR_FAIL;
-  const bool try_16M_pages =
-    flags & RESSHM_TRY_16M_PAGES;
-  const bool f16M_pages_or_fail =
-    flags & RESSHM_16M_PAGES_OR_FAIL;
-
-  // first check: if a wish address is given and it is mandatory, but not aligned to segment boundary,
-  // shmat will fail anyway, so save some cycles by failing right away
-  if (requested_addr && ((uintptr_t)requested_addr % SIZE_256M == 0)) {
-    if (wishaddr_or_fail) {
-      return false;
-    } else {
-      requested_addr = NULL;
-    }
-  }
-
-  char* addr = NULL;
-
-  // Align size of shm up to the largest possible page size, to avoid errors later on when we try to change
-  // pagesize dynamically.
-  const size_t size = align_size_up(bytes, SIZE_16M);
-
-  // reserve the shared segment
-  int shmid = shmget(IPC_PRIVATE, size, IPC_CREAT | S_IRUSR | S_IWUSR);
-  if (shmid == -1) {
-    warning("shmget(.., %lld, ..) failed (errno: %d).", size, errno);
-    return false;
-  }
-
-  // Important note:
-  // It is very important that we, upon leaving this function, do not leave a shm segment alive.
-  // We must right after attaching it remove it from the system. System V shm segments are global and
-  // survive the process.
-  // So, from here on: Do not assert. Do not return. Always do a "goto cleanup_shm".
-
-  // try forcing the page size
-  size_t pagesize = -1; // unknown so far
-
-  if (UseLargePages) {
-
-    struct shmid_ds shmbuf;
-    memset(&shmbuf, 0, sizeof(shmbuf));
-
-    // First, try to take from 16M page pool if...
-    if (os::Aix::can_use_16M_pages()  // we can ...
-        && Use16MPages                // we are not explicitly forbidden to do so (-XX:-Use16MPages)..
-        && try_16M_pages) {           // caller wants us to.
-      shmbuf.shm_pagesize = SIZE_16M;
-      if (shmctl(shmid, SHM_PAGESIZE, &shmbuf) == 0) {
-        pagesize = SIZE_16M;
-      } else {
-        warning("Failed to allocate %d 16M pages. 16M page pool might be exhausted. (shmctl failed with %d)",
-                size / SIZE_16M, errno);
-        if (f16M_pages_or_fail) {
-          goto cleanup_shm;
-        }
-      }
-    }
-
-    // Nothing yet? Try setting 64K pages. Note that I never saw this fail, but in theory it might,
-    // because the 64K page pool may also be exhausted.
-    if (pagesize == -1) {
-      shmbuf.shm_pagesize = SIZE_64K;
-      if (shmctl(shmid, SHM_PAGESIZE, &shmbuf) == 0) {
-        pagesize = SIZE_64K;
-      } else {
-        warning("Failed to allocate %d 64K pages. (shmctl failed with %d)",
-                size / SIZE_64K, errno);
-        // here I give up. leave page_size -1 - later, after attaching, we will query the
-        // real page size of the attached memory. (in theory, it may be something different
-        // from 4K if LDR_CNTRL SHM_PSIZE is set)
-      }
-    }
-  }
-
-  // sanity point
-  assert(pagesize == -1 || pagesize == SIZE_16M || pagesize == SIZE_64K, "wrong page size");
-
-  // Now attach the shared segment.
-  addr = (char*) shmat(shmid, requested_addr, 0);
-  if (addr == (char*)-1) {
-    // How to handle attach failure:
-    // If it failed for a specific wish address, tolerate this: in that case, if wish address was
-    // mandatory, fail, if not, retry anywhere.
-    // If it failed for any other reason, treat that as fatal error.
-    addr = NULL;
-    if (requested_addr) {
-      if (wishaddr_or_fail) {
-        goto cleanup_shm;
-      } else {
-        addr = (char*) shmat(shmid, NULL, 0);
-        if (addr == (char*)-1) { // fatal
-          addr = NULL;
-          warning("shmat failed (errno: %d)", errno);
-          goto cleanup_shm;
-        }
-      }
-    } else { // fatal
-      addr = NULL;
-      warning("shmat failed (errno: %d)", errno);
-      goto cleanup_shm;
-    }
-  }
-
-  // sanity point
-  assert(addr && addr != (char*) -1, "wrong address");
-
-  // after successful Attach remove the segment - right away.
-  if (::shmctl(shmid, IPC_RMID, NULL) == -1) {
-    warning("shmctl(%u, IPC_RMID) failed (%d)\n", shmid, errno);
-    guarantee(false, "failed to remove shared memory segment!");
-  }
-  shmid = -1;
-
-  // query the real page size. In case setting the page size did not work (see above), the system
-  // may have given us something other then 4K (LDR_CNTRL)
-  {
-    const size_t real_pagesize = os::Aix::query_pagesize(addr);
-    if (pagesize != -1) {
-      assert(pagesize == real_pagesize, "unexpected pagesize after shmat");
-    } else {
-      pagesize = real_pagesize;
-    }
-  }
-
-  // Now register the reserved block with internal book keeping.
-  LOCK_SHMBK
-    const bool pinned = pagesize >= SIZE_16M ? true : false;
-    ShmBkShmatedBlock* const p_block = new ShmBkShmatedBlock(AddrRange(addr, size), pagesize, pinned);
-    assert(p_block, "");
-    shmbk_register(p_block);
-  UNLOCK_SHMBK
-
-cleanup_shm:
-
-  // if we have not done so yet, remove the shared memory segment. This is very important.
-  if (shmid != -1) {
-    if (::shmctl(shmid, IPC_RMID, NULL) == -1) {
-      warning("shmctl(%u, IPC_RMID) failed (%d)\n", shmid, errno);
-      guarantee(false, "failed to remove shared memory segment!");
-    }
-    shmid = -1;
-  }
-
-  // trace
-  if (Verbose && !addr) {
-    if (requested_addr != NULL) {
-      warning("failed to shm-allocate 0x%llX bytes at wish address 0x%p.", size, requested_addr);
-    } else {
-      warning("failed to shm-allocate 0x%llX bytes at any address.", size);
-    }
-  }
-
-  // hand info to caller
-  if (addr) {
-    p_info->addr = addr;
-    p_info->pagesize = pagesize;
-    p_info->pinned = pagesize == SIZE_16M ? true : false;
-  }
-
-  // sanity test:
-  if (requested_addr && addr && wishaddr_or_fail) {
-    guarantee(addr == requested_addr, "shmat error");
-  }
-
-  // just one more test to really make sure we have no dangling shm segments.
-  guarantee(shmid == -1, "dangling shm segments");
-
-  return addr ? true : false;
-
-} // end: reserve_shmatted_memory
-
-// Reserve memory using mmap. Behaves the same as reserve_shmatted_memory():
-// will return NULL in case of an error.
-static char* reserve_mmaped_memory(size_t bytes, char* requested_addr) {
-
-  // if a wish address is given, but not aligned to 4K page boundary, mmap will fail.
-  if (requested_addr && ((uintptr_t)requested_addr % os::vm_page_size() != 0)) {
-    warning("Wish address 0x%p not aligned to page boundary.", requested_addr);
-    return NULL;
-  }
-
-  const size_t size = align_size_up(bytes, SIZE_4K);
-
-  // Note: MAP_SHARED (instead of MAP_PRIVATE) needed to be able to
-  // msync(MS_INVALIDATE) (see os::uncommit_memory)
-  int flags = MAP_ANONYMOUS | MAP_SHARED;
-
-  // MAP_FIXED is needed to enforce requested_addr - manpage is vague about what
-  // it means if wishaddress is given but MAP_FIXED is not set.
-  //
-  // Note however that this changes semantics in SPEC1170 mode insofar as MAP_FIXED
-  // clobbers the address range, which is probably not what the caller wants. That's
-  // why I assert here (again) that the SPEC1170 compat mode is off.
-  // If we want to be able to run under SPEC1170, we have to do some porting and
-  // testing.
-  if (requested_addr != NULL) {
-    assert(!os::Aix::xpg_sus_mode(), "SPEC1170 mode not allowed.");
-    flags |= MAP_FIXED;
-  }
-
-  char* addr = (char*)::mmap(requested_addr, size, PROT_READ|PROT_WRITE|PROT_EXEC, flags, -1, 0);
-
-  if (addr == MAP_FAILED) {
-    // attach failed: tolerate for specific wish addresses. Not being able to attach
-    // anywhere is a fatal error.
-    if (requested_addr == NULL) {
-      // It's ok to fail here if the machine has not enough memory.
-      warning("mmap(NULL, 0x%llX, ..) failed (%d)", size, errno);
-    }
-    addr = NULL;
-    goto cleanup_mmap;
-  }
-
-  // If we did request a specific address and that address was not available, fail.
-  if (addr && requested_addr) {
-    guarantee(addr == requested_addr, "unexpected");
-  }
-
-  // register this mmap'ed segment with book keeping
-  LOCK_SHMBK
-    ShmBkMappedBlock* const p_block = new ShmBkMappedBlock(AddrRange(addr, size));
-    assert(p_block, "");
-    shmbk_register(p_block);
-  UNLOCK_SHMBK
-
-cleanup_mmap:
-
-  // trace
-  if (Verbose) {
-    if (addr) {
-      fprintf(stderr, "mmap-allocated 0x%p .. 0x%p (0x%llX bytes)\n", addr, addr + bytes, bytes);
-    }
-    else {
-      if (requested_addr != NULL) {
-        warning("failed to mmap-allocate 0x%llX bytes at wish address 0x%p.", bytes, requested_addr);
-      } else {
-        warning("failed to mmap-allocate 0x%llX bytes at any address.", bytes);
-      }
-    }
-  }
-
-  return addr;
-
-} // end: reserve_mmaped_memory
-
 // Reserves and attaches a shared memory segment.
 // Will assert if a wish address is given and could not be obtained.
 char* os::pd_reserve_memory(size_t bytes, char* requested_addr, size_t alignment_hint) {
-  return os::attempt_reserve_memory_at(bytes, requested_addr);
+
+  // All other Unices do a mmap(MAP_FIXED) if the addr is given,
+  // thereby clobbering old mappings at that place. That is probably
+  // not intended, never used and almost certainly an error were it
+  // ever be used this way (to try attaching at a specified address
+  // without clobbering old mappings an alternate API exists,
+  // os::attempt_reserve_memory_at()).
+  // Instead of mimicking the dangerous coding of the other platforms, here I
+  // just ignore the request address (release) or assert(debug).
+  assert0(requested_addr == NULL);
+
+  // Always round to os::vm_page_size(), which may be larger than 4K.
+  bytes = align_size_up(bytes, os::vm_page_size());
+  const size_t alignment_hint0 =
+    alignment_hint ? align_size_up(alignment_hint, os::vm_page_size()) : 0;
+
+  // In 4K mode always use mmap.
+  // In 64K mode allocate small sizes with mmap, large ones with 64K shmatted.
+  if (os::vm_page_size() == SIZE_4K) {
+    return reserve_mmaped_memory(bytes, requested_addr, alignment_hint);
+  } else {
+    if (bytes >= Use64KPagesThreshold) {
+      return reserve_shmated_memory(bytes, requested_addr, alignment_hint);
+    } else {
+      return reserve_mmaped_memory(bytes, requested_addr, alignment_hint);
+    }
+  }
 }
 
 bool os::pd_release_memory(char* addr, size_t size) {
 
-  // delegate to ShmBkBlock class which knows how to uncommit its memory.
+  // Dynamically do different things for mmap/shmat.
+  vmembk_t* const vmi = vmembk_find(addr);
+  assert0(vmi);
+
+  // Always round to os::vm_page_size(), which may be larger than 4K.
+  size = align_size_up(size, os::vm_page_size());
+  addr = (char *)align_ptr_up(addr, os::vm_page_size());
 
   bool rc = false;
-  LOCK_SHMBK
-    ShmBkBlock* const block = shmbk_find_by_containing_address(addr);
-    if (!block) {
-      fprintf(stderr, "invalid pointer: 0x%p.\n", addr);
-      shmbk_dump_info();
-      assert(false, "invalid pointer");
-      return false;
+  bool remove_bookkeeping = false;
+  if (vmi->type == VMEM_SHMATED) {
+    // For shmatted memory, we do:
+    // - If user wants to release the whole range, release the memory (shmdt).
+    // - If user only wants to release a partial range, uncommit (disclaim) that
+    //   range. That way, at least, we do not use memory anymore (bust still page
+    //   table space).
+    vmi->assert_is_valid_subrange(addr, size);
+    if (addr == vmi->addr && size == vmi->size) {
+      rc = release_shmated_memory(addr, size);
+      remove_bookkeeping = true;
+    } else {
+      rc = uncommit_shmated_memory(addr, size);
     }
-    else if (!block->isSameRange(addr, size)) {
-      if (block->getType() == ShmBkBlock::MMAP) {
-        // Release only the same range or a the beginning or the end of a range.
-        if (block->base() == addr && size < block->size()) {
-          ShmBkMappedBlock* const b = new ShmBkMappedBlock(AddrRange(block->base() + size, block->size() - size));
-          assert(b, "");
-          shmbk_register(b);
-          block->setAddrRange(AddrRange(addr, size));
-        }
-        else if (addr > block->base() && addr + size == block->base() + block->size()) {
-          ShmBkMappedBlock* const b = new ShmBkMappedBlock(AddrRange(block->base(), block->size() - size));
-          assert(b, "");
-          shmbk_register(b);
-          block->setAddrRange(AddrRange(addr, size));
-        }
-        else {
-          fprintf(stderr, "invalid mmap range: 0x%p .. 0x%p.\n", addr, addr + size);
-          shmbk_dump_info();
-          assert(false, "invalid mmap range");
-          return false;
-        }
-      }
-      else {
-        // Release only the same range. No partial release allowed.
-        // Soften the requirement a bit, because the user may think he owns a smaller size
-        // than the block is due to alignment etc.
-        if (block->base() != addr || block->size() < size) {
-          fprintf(stderr, "invalid shmget range: 0x%p .. 0x%p.\n", addr, addr + size);
-          shmbk_dump_info();
-          assert(false, "invalid shmget range");
-          return false;
-        }
-      }
-    }
-    rc = block->release();
-    assert(rc, "release failed");
-    // remove block from bookkeeping
-    shmbk_unregister(block);
-    delete block;
-  UNLOCK_SHMBK
-
-  if (!rc) {
-    warning("failed to released %lu bytes at 0x%p", size, addr);
+  } else {
+    // User may unmap partial regions but region has to be fully contained.
+#ifdef ASSERT
+    vmi->assert_is_valid_subrange(addr, size);
+#endif
+    rc = release_mmaped_memory(addr, size);
+    remove_bookkeeping = true;
+  }
+
+  // update bookkeeping
+  if (rc && remove_bookkeeping) {
+    vmembk_remove(vmi);
   }
 
   return rc;
@@ -2702,46 +2541,8 @@
 
 // Enable large page support if OS allows that.
 void os::large_page_init() {
-
-  // Note: os::Aix::query_multipage_support must run first.
-
-  if (!UseLargePages) {
-    return;
-  }
-
-  if (!Aix::can_use_64K_pages()) {
-    assert(!Aix::can_use_16M_pages(), "64K is a precondition for 16M.");
-    UseLargePages = false;
-    return;
-  }
-
-  if (!Aix::can_use_16M_pages() && Use16MPages) {
-    fprintf(stderr, "Cannot use 16M pages. Please ensure that there is a 16M page pool "
-            " and that the VM runs with CAP_BYPASS_RAC_VMM and CAP_PROPAGATE capabilities.\n");
-  }
-
-  // Do not report 16M page alignment as part of os::_page_sizes if we are
-  // explicitly forbidden from using 16M pages. Doing so would increase the
-  // alignment the garbage collector calculates with, slightly increasing
-  // heap usage. We should only pay for 16M alignment if we really want to
-  // use 16M pages.
-  if (Use16MPages && Aix::can_use_16M_pages()) {
-    _large_page_size = SIZE_16M;
-    _page_sizes[0] = SIZE_16M;
-    _page_sizes[1] = SIZE_64K;
-    _page_sizes[2] = SIZE_4K;
-    _page_sizes[3] = 0;
-  } else if (Aix::can_use_64K_pages()) {
-    _large_page_size = SIZE_64K;
-    _page_sizes[0] = SIZE_64K;
-    _page_sizes[1] = SIZE_4K;
-    _page_sizes[2] = 0;
-  }
-
-  if (Verbose) {
-    ("Default large page size is 0x%llX.", _large_page_size);
-  }
-} // end: os::large_page_init()
+  return; // Nothing to do. See query_multipage_support and friends.
+}
 
 char* os::reserve_memory_special(size_t bytes, size_t alignment, char* req_addr, bool exec) {
   // "exec" is passed in but not used. Creating the shared image for
@@ -2751,7 +2552,7 @@
 }
 
 bool os::release_memory_special(char* base, size_t bytes) {
-  // detaching the SHM segment will also delete it, see reserve_memory_special()
+  // Detaching the SHM segment will also delete it, see reserve_memory_special().
   Unimplemented();
   return false;
 }
@@ -2761,40 +2562,32 @@
 }
 
 bool os::can_commit_large_page_memory() {
-  // Well, sadly we cannot commit anything at all (see comment in
-  // os::commit_memory) but we claim to so we can make use of large pages
-  return true;
+  // Does not matter, we do not support huge pages.
+  return false;
 }
 
 bool os::can_execute_large_page_memory() {
-  // We can do that
-  return true;
+  // Does not matter, we do not support huge pages.
+  return false;
 }
 
 // Reserve memory at an arbitrary address, only if that area is
 // available (and not reserved for something else).
 char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr) {
-
-  bool use_mmap = false;
-
-  // mmap: smaller graining, no large page support
-  // shm: large graining (256M), large page support, limited number of shm segments
-  //
-  // Prefer mmap wherever we either do not need large page support or have OS limits
-
-  if (!UseLargePages || bytes < SIZE_16M) {
-    use_mmap = true;
-  }
-
   char* addr = NULL;
-  if (use_mmap) {
-    addr = reserve_mmaped_memory(bytes, requested_addr);
+
+  // Always round to os::vm_page_size(), which may be larger than 4K.
+  bytes = align_size_up(bytes, os::vm_page_size());
+
+  // In 4K mode always use mmap.
+  // In 64K mode allocate small sizes with mmap, large ones with 64K shmatted.
+  if (os::vm_page_size() == SIZE_4K) {
+    return reserve_mmaped_memory(bytes, requested_addr, 0);
   } else {
-    // shmat: wish address is mandatory, and do not try 16M pages here.
-    shmatted_memory_info_t info;
-    const int flags = RESSHM_WISHADDR_OR_FAIL;
-    if (reserve_shmatted_memory(bytes, requested_addr, flags, &info)) {
-      addr = info.addr;
+    if (bytes >= Use64KPagesThreshold) {
+      return reserve_shmated_memory(bytes, requested_addr, 0);
+    } else {
+      return reserve_mmaped_memory(bytes, requested_addr, 0);
     }
   }
 
@@ -3629,18 +3422,89 @@
 // This is called _before_ the most of global arguments have been parsed.
 void os::init(void) {
   // This is basic, we want to know if that ever changes.
-  // (shared memory boundary is supposed to be a 256M aligned)
+  // (Shared memory boundary is supposed to be a 256M aligned.)
   assert(SHMLBA == ((uint64_t)0x10000000ULL)/*256M*/, "unexpected");
 
   // First off, we need to know whether we run on AIX or PASE, and
   // the OS level we run on.
   os::Aix::initialize_os_info();
 
-  // Scan environment (SPEC1170 behaviour, etc)
+  // Scan environment (SPEC1170 behaviour, etc).
   os::Aix::scan_environment();
 
   // Check which pages are supported by AIX.
-  os::Aix::query_multipage_support();
+  query_multipage_support();
+
+  // Act like we only have one page size by eliminating corner cases which
+  // we did not support very well anyway.
+  // We have two input conditions:
+  // 1) Data segment page size. This is controlled by linker setting (datapsize) on the
+  //    launcher, and/or by LDR_CNTRL environment variable. The latter overrules the linker
+  //    setting.
+  //    Data segment page size is important for us because it defines the thread stack page
+  //    size, which is needed for guard page handling, stack banging etc.
+  // 2) The ability to allocate 64k pages dynamically. If this is a given, java heap can
+  //    and should be allocated with 64k pages.
+  //
+  // So, we do the following:
+  // LDR_CNTRL    can_use_64K_pages_dynamically       what we do                      remarks
+  // 4K           no                                  4K                              old systems (aix 5.2, as/400 v5r4) or new systems with AME activated
+  // 4k           yes                                 64k (treat 4k stacks as 64k)    different loader than java and standard settings
+  // 64k          no              --- AIX 5.2 ? ---
+  // 64k          yes                                 64k                             new systems and standard java loader (we set datapsize=64k when linking)
+
+  // We explicitly leave no option to change page size, because only upgrading would work,
+  // not downgrading (if stack page size is 64k you cannot pretend its 4k).
+
+  if (g_multipage_support.datapsize == SIZE_4K) {
+    // datapsize = 4K. Data segment, thread stacks are 4K paged.
+    if (g_multipage_support.can_use_64K_pages) {
+      // .. but we are able to use 64K pages dynamically.
+      // This would be typical for java launchers which are not linked
+      // with datapsize=64K (like, any other launcher but our own).
+      //
+      // In this case it would be smart to allocate the java heap with 64K
+      // to get the performance benefit, and to fake 64k pages for the
+      // data segment (when dealing with thread stacks).
+      //
+      // However, leave a possibility to downgrade to 4K, using
+      // -XX:-Use64KPages.
+      if (Use64KPages) {
+        trcVerbose("64K page mode (faked for data segment)");
+        Aix::_page_size = SIZE_64K;
+      } else {
+        trcVerbose("4K page mode (Use64KPages=off)");
+        Aix::_page_size = SIZE_4K;
+      }
+    } else {
+      // .. and not able to allocate 64k pages dynamically. Here, just
+      // fall back to 4K paged mode and use mmap for everything.
+      trcVerbose("4K page mode");
+      Aix::_page_size = SIZE_4K;
+      FLAG_SET_ERGO(bool, Use64KPages, false);
+    }
+  } else {
+    // datapsize = 64k. Data segment, thread stacks are 64k paged.
+    //   This normally means that we can allocate 64k pages dynamically.
+    //   (There is one special case where this may be false: EXTSHM=on.
+    //    but we decided to not support that mode).
+    assert0(g_multipage_support.can_use_64K_pages);
+    Aix::_page_size = SIZE_64K;
+    trcVerbose("64K page mode");
+    FLAG_SET_ERGO(bool, Use64KPages, true);
+  }
+
+  // Short-wire stack page size to base page size; if that works, we just remove
+  // that stack page size altogether.
+  Aix::_stack_page_size = Aix::_page_size;
+
+  // For now UseLargePages is just ignored.
+  FLAG_SET_ERGO(bool, UseLargePages, false);
+  _page_sizes[0] = 0;
+  _large_page_size = -1;
+
+  // debug trace
+  trcVerbose("os::vm_page_size %s\n", describe_pagesize(os::vm_page_size()));
 
   // Next, we need to initialize libo4 and libperfstat libraries.
   if (os::Aix::on_pase()) {
@@ -3658,34 +3522,6 @@
   // need libperfstat etc.
   os::Aix::initialize_system_info();
 
-  // Initialize large page support.
-  if (UseLargePages) {
-    os::large_page_init();
-    if (!UseLargePages) {
-      // initialize os::_page_sizes
-      _page_sizes[0] = Aix::page_size();
-      _page_sizes[1] = 0;
-      if (Verbose) {
-        fprintf(stderr, "Large Page initialization failed: setting UseLargePages=0.\n");
-      }
-    }
-  } else {
-    // initialize os::_page_sizes
-    _page_sizes[0] = Aix::page_size();
-    _page_sizes[1] = 0;
-  }
-
-  // debug trace
-  if (Verbose) {
-    fprintf(stderr, "os::vm_page_size 0x%llX\n", os::vm_page_size());
-    fprintf(stderr, "os::large_page_size 0x%llX\n", os::large_page_size());
-    fprintf(stderr, "os::_page_sizes = ( ");
-    for (int i = 0; _page_sizes[i]; i ++) {
-      fprintf(stderr, " %s ", describe_pagesize(_page_sizes[i]));
-    }
-    fprintf(stderr, ")\n");
-  }
-
   _initial_pid = getpid();
 
   clock_tics_per_sec = sysconf(_SC_CLK_TCK);
@@ -3699,6 +3535,15 @@
 
   initial_time_count = os::elapsed_counter();
   pthread_mutex_init(&dl_mutex, NULL);
+
+  // If the pagesize of the VM is greater than 8K determine the appropriate
+  // number of initial guard pages. The user can change this with the
+  // command line arguments, if needed.
+  if (vm_page_size() > (int)Aix::vm_default_page_size()) {
+    StackYellowPages = 1;
+    StackRedPages = 1;
+    StackShadowPages = round_to((StackShadowPages*Aix::vm_default_page_size()), vm_page_size()) / vm_page_size();
+  }
 }
 
 // This is called _after_ the global arguments have been parsed.
@@ -3717,7 +3562,7 @@
   const int prot  = PROT_READ;
   const int flags = MAP_PRIVATE|MAP_ANONYMOUS;
 
-  // use optimized addresses for the polling page,
+  // Use optimized addresses for the polling page,
   // e.g. map it to a special 32-bit address.
   if (OptimizePollingPageLocation) {
     // architecture-specific list of address wishes:
@@ -3739,7 +3584,7 @@
 
     // iterate over the list of address wishes:
     for (int i=0; i<address_wishes_length; i++) {
-      // try to map with current address wish.
+      // Try to map with current address wish.
       // AIX: AIX needs MAP_FIXED if we provide an address and mmap will
       // fail if the address is already mapped.
       map_address = (address) ::mmap(address_wishes[i] - (ssize_t)page_size,
@@ -3752,7 +3597,7 @@
       }
 
       if (map_address + (ssize_t)page_size == address_wishes[i]) {
-        // map succeeded and map_address is at wished address, exit loop.
+        // Map succeeded and map_address is at wished address, exit loop.
         break;
       }
 
@@ -3761,7 +3606,7 @@
         ::munmap(map_address, map_size);
         map_address = (address) MAP_FAILED;
       }
-      // map failed, continue loop.
+      // Map failed, continue loop.
     }
   } // end OptimizePollingPageLocation
 
@@ -3777,8 +3622,9 @@
     os::set_memory_serialize_page(mem_serialize_page);
 
 #ifndef PRODUCT
-    if (Verbose && PrintMiscellaneous)
+    if (Verbose && PrintMiscellaneous) {
       tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page);
+    }
 #endif
   }
 
@@ -3797,16 +3643,18 @@
   // Add in 2*BytesPerWord times page size to account for VM stack during
   // class initialization depending on 32 or 64 bit VM.
   os::Aix::min_stack_allowed = MAX2(os::Aix::min_stack_allowed,
-            (size_t)(StackYellowPages+StackRedPages+StackShadowPages +
-                     2*BytesPerWord COMPILER2_PRESENT(+1)) * Aix::page_size());
+            (size_t)(StackYellowPages+StackRedPages+StackShadowPages) * Aix::page_size() +
+                     (2*BytesPerWord COMPILER2_PRESENT(+1)) * Aix::vm_default_page_size());
+
+  os::Aix::min_stack_allowed = align_size_up(os::Aix::min_stack_allowed, os::Aix::page_size());
 
   size_t threadStackSizeInBytes = ThreadStackSize * K;
   if (threadStackSizeInBytes != 0 &&
       threadStackSizeInBytes < os::Aix::min_stack_allowed) {
-        tty->print_cr("\nThe stack size specified is too small, "
-                      "Specify at least %dk",
-                      os::Aix::min_stack_allowed / K);
-        return JNI_ERR;
+    tty->print_cr("\nThe stack size specified is too small, "
+                  "Specify at least %dk",
+                  os::Aix::min_stack_allowed / K);
+    return JNI_ERR;
   }
 
   // Make the stack size a multiple of the page size so that
@@ -3817,7 +3665,7 @@
   Aix::libpthread_init();
 
   if (MaxFDLimit) {
-    // set the number of file descriptors to max. print out error
+    // Set the number of file descriptors to max. print out error
     // if getrlimit/setrlimit fails but continue regardless.
     struct rlimit nbr_files;
     int status = getrlimit(RLIMIT_NOFILE, &nbr_files);
@@ -3835,12 +3683,12 @@
   }
 
   if (PerfAllowAtExitRegistration) {
-    // only register atexit functions if PerfAllowAtExitRegistration is set.
-    // atexit functions can be delayed until process exit time, which
+    // Only register atexit functions if PerfAllowAtExitRegistration is set.
+    // Atexit functions can be delayed until process exit time, which
     // can be problematic for embedded VM situations. Embedded VMs should
     // call DestroyJavaVM() to assure that VM resources are released.
 
-    // note: perfMemory_exit_helper atexit function may be removed in
+    // Note: perfMemory_exit_helper atexit function may be removed in
     // the future if the appropriate cleanup code can be added to the
     // VM_Exit VMOperation's doit method.
     if (atexit(perfMemory_exit_helper) != 0) {
@@ -4162,8 +4010,10 @@
 
   if (read_only) {
     prot = PROT_READ;
+    flags = MAP_SHARED;
   } else {
     prot = PROT_READ | PROT_WRITE;
+    flags = MAP_PRIVATE;
   }
 
   if (allow_exec) {
@@ -4174,7 +4024,12 @@
     flags |= MAP_FIXED;
   }
 
-  char* mapped_address = (char*)mmap(addr, (size_t)bytes, prot, flags,
+  // Allow anonymous mappings if 'fd' is -1.
+  if (fd == -1) {
+    flags |= MAP_ANONYMOUS;
+  }
+
+  char* mapped_address = (char*)::mmap(addr, (size_t)bytes, prot, flags,
                                      fd, file_offset);
   if (mapped_address == MAP_FAILED) {
     return NULL;
@@ -4432,7 +4287,7 @@
   if (Verbose) {
     fprintf(stderr, "EXTSHM=%s.\n", p ? p : "<unset>");
   }
-  if (p && strcmp(p, "ON") == 0) {
+  if (p && strcasecmp(p, "ON") == 0) {
     fprintf(stderr, "Unsupported setting: EXTSHM=ON. Large Page support will be disabled.\n");
     _extshm = 1;
   } else {
@@ -4493,16 +4348,13 @@
 /////////////////////////////////////////////////////////////////////////////
 // thread stack
 
-// function to query the current stack size using pthread_getthrds_np
-//
-// ! do not change anything here unless you know what you are doing !
-static void query_stack_dimensions(address* p_stack_base, size_t* p_stack_size) {
-
+// Function to query the current stack size using pthread_getthrds_np.
+static bool query_stack_dimensions(address* p_stack_base, size_t* p_stack_size) {
   // This only works when invoked on a pthread. As we agreed not to use
-  // primordial threads anyway, I assert here
+  // primordial threads anyway, I assert here.
   guarantee(!os::Aix::is_primordial_thread(), "not allowed on the primordial thread");
 
-  // information about this api can be found (a) in the pthread.h header and
+  // Information about this api can be found (a) in the pthread.h header and
   // (b) in http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.basetechref/doc/basetrf1/pthread_getthrds_np.htm
   //
   // The use of this API to find out the current stack is kind of undefined.
@@ -4513,57 +4365,72 @@
 
   pthread_t tid = pthread_self();
   struct __pthrdsinfo pinfo;
-  char dummy[1]; // we only need this to satisfy the api and to not get E
+  char dummy[1]; // We only need this to satisfy the api and to not get E.
   int dummy_size = sizeof(dummy);
 
   memset(&pinfo, 0, sizeof(pinfo));
 
-  const int rc = pthread_getthrds_np (&tid, PTHRDSINFO_QUERY_ALL, &pinfo,
-                                      sizeof(pinfo), dummy, &dummy_size);
+  const int rc = pthread_getthrds_np(&tid, PTHRDSINFO_QUERY_ALL, &pinfo,
+                                     sizeof(pinfo), dummy, &dummy_size);
 
   if (rc != 0) {
-    fprintf(stderr, "pthread_getthrds_np failed (%d)\n", rc);
-    guarantee(0, "pthread_getthrds_np failed");
-  }
-
-  guarantee(pinfo.__pi_stackend, "returned stack base invalid");
-
-  // the following can happen when invoking pthread_getthrds_np on a pthread running on a user provided stack
-  // (when handing down a stack to pthread create, see pthread_attr_setstackaddr).
+    assert0(false);
+    trcVerbose("pthread_getthrds_np failed (%d)", rc);
+    return false;
+  }
+  guarantee0(pinfo.__pi_stackend);
+
+  // The following can happen when invoking pthread_getthrds_np on a pthread running
+  // on a user provided stack (when handing down a stack to pthread create, see
+  // pthread_attr_setstackaddr).
   // Not sure what to do here - I feel inclined to forbid this use case completely.
-  guarantee(pinfo.__pi_stacksize, "returned stack size invalid");
-
-  // On AIX, stacks are not necessarily page aligned so round the base and size accordingly
+  guarantee0(pinfo.__pi_stacksize);
+
+  // Note: the pthread stack on AIX seems to look like this:
+  //
+  // ---------------------   real base ? at page border ?
+  //
+  //     pthread internal data, like ~2K, see also
+  //     http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.prftungd/doc/prftungd/thread_supp_tun_params.htm
+  //
+  // ---------------------   __pi_stackend - not page aligned, (xxxxF890)
+  //
+  //     stack
+  //      ....
+  //
+  //     stack
+  //
+  // ---------------------   __pi_stackend  - __pi_stacksize
+  //
+  //     padding due to AIX guard pages (?) see AIXTHREAD_GUARDPAGES
+  // ---------------------   __pi_stackaddr  (page aligned if AIXTHREAD_GUARDPAGES > 0)
+  //
+  //   AIX guard pages (?)
+  //
+
+  // So, the safe thing to do is to use the area from __pi_stackend to __pi_stackaddr;
+  // __pi_stackend however is almost never page aligned.
+  //
+
   if (p_stack_base) {
-    (*p_stack_base) = (address) align_size_up((intptr_t)pinfo.__pi_stackend, os::Aix::stack_page_size());
+    (*p_stack_base) = (address) (pinfo.__pi_stackend);
   }
 
   if (p_stack_size) {
-    (*p_stack_size) = pinfo.__pi_stacksize - os::Aix::stack_page_size();
-  }
-
-#ifndef PRODUCT
-  if (Verbose) {
-    fprintf(stderr,
-            "query_stack_dimensions() -> real stack_base=" INTPTR_FORMAT ", real stack_addr=" INTPTR_FORMAT
-            ", real stack_size=" INTPTR_FORMAT
-            ", stack_base=" INTPTR_FORMAT ", stack_size=" INTPTR_FORMAT "\n",
-            (intptr_t)pinfo.__pi_stackend, (intptr_t)pinfo.__pi_stackaddr, pinfo.__pi_stacksize,
-            (intptr_t)align_size_up((intptr_t)pinfo.__pi_stackend, os::Aix::stack_page_size()),
-            pinfo.__pi_stacksize - os::Aix::stack_page_size());
-  }
-#endif
-
-} // end query_stack_dimensions
-
-// get the current stack base from the OS (actually, the pthread library)
+    (*p_stack_size) = pinfo.__pi_stackend - pinfo.__pi_stackaddr;
+  }
+
+  return true;
+}
+
+// Get the current stack base from the OS (actually, the pthread library).
 address os::current_stack_base() {
   address p;
   query_stack_dimensions(&p, 0);
   return p;
 }
 
-// get the current stack size from the OS (actually, the pthread library)
+// Get the current stack size from the OS (actually, the pthread library).
 size_t os::current_stack_size() {
   size_t s;
   query_stack_dimensions(0, &s);
--- a/hotspot/src/os/aix/vm/os_aix.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/os/aix/vm/os_aix.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2013 SAP AG. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2013, 2015 SAP AG. 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
@@ -35,9 +35,9 @@
   friend class os;
 
   // For signal-chaining
-  // highest so far (AIX 5.2) is SIGSAK (63)
+  // highest so far (AIX 5.2 - 6.1) is SIGSAK (63)
 #define MAXSIGNUM 63
-  // length of strings included in the libperfstat structures
+  // Length of strings included in the libperfstat structures.
 #define IDENTIFIER_LENGTH 64
 
   static struct sigaction sigact[MAXSIGNUM]; // saved preinstalled sigactions
@@ -111,22 +111,6 @@
   // (should be LDR_CNTRL DATAPSIZE because stack is allocated on heap by pthread lib)
   static int _stack_page_size;
 
-  // Default shm page size. Read: what page size shared memory will be backed
-  // with if no page size was set explicitly using shmctl(SHM_PAGESIZE).
-  // Should be LDR_CNTRL SHMPSIZE.
-  static size_t _shm_default_page_size;
-
-  // True if sys V shm can be used with 64K pages dynamically.
-  // (via shmctl(.. SHM_PAGESIZE..). Should be true for AIX 53 and
-  // newer / PASE V6R1 and newer. (0 or 1, -1 if not initialized)
-  static int _can_use_64K_pages;
-
-  // True if sys V shm can be used with 16M pages dynamically.
-  // (via shmctl(.. SHM_PAGESIZE..). Only true on AIX 5.3 and
-  // newer, if the system was set up to use 16M pages and the
-  // jvm has enough user rights. (0 or 1, -1 if not initialized)
-  static int _can_use_16M_pages;
-
   static julong available_memory();
   static julong physical_memory() { return _physical_memory; }
   static void initialize_system_info();
@@ -135,10 +119,6 @@
   // one of Aix::on_pase(), Aix::os_version().
   static void initialize_os_info();
 
-  static int commit_memory_impl(char* addr, size_t bytes, bool exec);
-  static int commit_memory_impl(char* addr, size_t bytes,
-                                size_t alignment_hint, bool exec);
-
   // Scan environment for important settings which might effect the
   // VM. Trace out settings. Warn about invalid settings and/or
   // correct them.
@@ -146,10 +126,6 @@
   // Must run after os::Aix::initialue_os_info().
   static void scan_environment();
 
-  // Retrieve information about multipage size support. Will initialize
-  // _page_size, _stack_page_size, _can_use_64K_pages/_can_use_16M_pages
-  static void query_multipage_support();
-
   // Initialize libo4 (on PASE) and libperfstat (on AIX). Call this
   // before relying on functions from either lib, e.g. Aix::get_meminfo().
   static void initialize_libo4();
@@ -187,27 +163,8 @@
     return _stack_page_size;
   }
 
-  // default shm page size. Read: what page size shared memory
-  // will be backed with if no page size was set explicitly using shmctl(SHM_PAGESIZE).
-  // Should be LDR_CNTRL SHMPSIZE.
-  static int shm_default_page_size(void) {
-    assert(_shm_default_page_size != -1, "not initialized");
-    return _shm_default_page_size;
-  }
-
-  // Return true if sys V shm can be used with 64K pages dynamically
-  // (via shmctl(.. SHM_PAGESIZE..).
-  static bool can_use_64K_pages () {
-    assert(_can_use_64K_pages != -1,  "not initialized");
-    return _can_use_64K_pages == 1 ? true : false;
-  }
-
-  // Return true if sys V shm can be used with 16M pages dynamically.
-  // (via shmctl(.. SHM_PAGESIZE..).
-  static bool can_use_16M_pages () {
-    assert(_can_use_16M_pages != -1,  "not initialized");
-    return _can_use_16M_pages == 1 ? true : false;
-  }
+  // This is used to scale stack space (guard pages etc.). The name is somehow misleading.
+  static int vm_default_page_size(void ) { return 8*K; }
 
   static address   ucontext_get_pc(const ucontext_t* uc);
   static intptr_t* ucontext_get_sp(ucontext_t* uc);
@@ -269,6 +226,11 @@
     return _os_version;
   }
 
+  // Convenience method: returns true if running on PASE V5R4 or older.
+  static bool on_pase_V5R4_or_older() {
+    return on_pase() && os_version() <= 0x0504;
+  }
+
   // Convenience method: returns true if running on AIX 5.3 or older.
   static bool on_aix_53_or_older() {
     return on_aix() && os_version() <= 0x0503;
--- a/hotspot/src/os/aix/vm/os_aix.inline.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/os/aix/vm/os_aix.inline.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2013 SAP AG. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2012, 2015 SAP AG. 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
@@ -40,7 +40,7 @@
   return pthread_getspecific((pthread_key_t)index);
 }
 
-// File names are case-sensitive on windows only
+// File names are case-sensitive on windows only.
 inline int os::file_name_strcmp(const char* s1, const char* s2) {
   return strcmp(s1, s2);
 }
@@ -53,18 +53,19 @@
   return true;
 }
 
+// Whether or not calling code should/can commit/uncommit stack pages
+// before guarding them. Answer for AIX is definitly no, because memory
+// is automatically committed on touch.
 inline bool os::allocate_stack_guard_pages() {
   assert(uses_stack_guard_pages(), "sanity check");
-  return true;
+  return false;
 }
 
-
 // On Aix, reservations are made on a page by page basis, nothing to do.
 inline void os::pd_split_reserved_memory(char *base, size_t size,
                                          size_t split, bool realloc) {
 }
 
-
 // Bang the shadow pages if they need to be touched to be mapped.
 inline void os::bang_stack_shadow_pages() {
 }
@@ -75,15 +76,13 @@
 
 inline const int os::default_file_open_flags() { return 0;}
 
-inline DIR* os::opendir(const char* dirname)
-{
+inline DIR* os::opendir(const char* dirname) {
   assert(dirname != NULL, "just checking");
   return ::opendir(dirname);
 }
 
-inline int os::readdir_buf_size(const char *path)
-{
-  // according to aix sys/limits, NAME_MAX must be retrieved at runtime. */
+inline int os::readdir_buf_size(const char *path) {
+  // According to aix sys/limits, NAME_MAX must be retrieved at runtime.
   const long my_NAME_MAX = pathconf(path, _PC_NAME_MAX);
   return my_NAME_MAX + sizeof(dirent) + 1;
 }
@@ -104,8 +103,7 @@
   return ::ftruncate64(fd, length);
 }
 
-inline struct dirent* os::readdir(DIR* dirp, dirent *dbuf)
-{
+inline struct dirent* os::readdir(DIR* dirp, dirent *dbuf) {
   dirent* p;
   int status;
   assert(dirp != NULL, "just checking");
@@ -174,11 +172,11 @@
   RESTARTABLE_RETURN_INT(::send(fd, buf, nBytes, flags));
 }
 
-inline int os::raw_send(int fd, char* buf, size_t nBytes, uint flags) {
+inline int os::raw_send(int fd, char *buf, size_t nBytes, uint flags) {
   return os::send(fd, buf, nBytes, flags);
 }
 
-inline int os::connect(int fd, struct sockaddr* him, socklen_t len) {
+inline int os::connect(int fd, struct sockaddr *him, socklen_t len) {
   RESTARTABLE_RETURN_INT(::connect(fd, him, len));
 }
 
--- a/hotspot/src/os/aix/vm/perfMemory_aix.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/os/aix/vm/perfMemory_aix.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -797,7 +797,7 @@
   // Close the directory and reset the current working directory.
   close_directory_secure_cwd(dirp, saved_cwd_fd);
 
-  FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
+  FREE_C_HEAP_ARRAY(char, dbuf);
 }
 
 // Make the user specific temporary directory. Returns true if
@@ -1164,9 +1164,9 @@
   // store file, we don't follow them when attaching either.
   //
   if (!is_directory_secure(dirname)) {
-    FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
+    FREE_C_HEAP_ARRAY(char, dirname);
     if (luser != user) {
-      FREE_C_HEAP_ARRAY(char, luser, mtInternal);
+      FREE_C_HEAP_ARRAY(char, luser);
     }
     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
               "Process not found");
--- a/hotspot/src/os/aix/vm/porting_aix.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/os/aix/vm/porting_aix.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012, 2013 SAP AG. All rights reserved.
+ * Copyright 2012, 2015 SAP AG. 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
@@ -22,8 +22,18 @@
  *
  */
 
+#ifndef OS_AIX_VM_PORTING_AIX_HPP
+#define OS_AIX_VM_PORTING_AIX_HPP
+
 #include <stddef.h>
 
+// PPC port only:
+#define assert0(b) assert( (b), "" )
+#define guarantee0(b) assert( (b), "" )
+template <class T1, class T2> bool is_aligned_to(T1 what, T2 alignment) {
+  return  ( ((uintx)(what)) & (((uintx)(alignment)) - 1) ) == 0 ? true : false;
+}
+
 // Header file to contain porting-relevant code which does not have a
 // home anywhere else and which can not go into os_<platform>.h because
 // that header is included inside the os class definition, hence all
@@ -79,3 +89,62 @@
       const struct tbtable** p_tb,     // [out] optional: ptr to traceback table to get further information
       char* p_errmsg, size_t errmsglen // [out] optional: user provided buffer for error messages
     );
+
+// -------------------------------------------------------------------------
+
+// A simple critical section which shall be based upon OS critical
+// sections (CRITICAL_SECTION resp. Posix Mutex) and nothing else.
+
+#include <pthread.h>
+
+namespace MiscUtils {
+  typedef pthread_mutex_t critsect_t;
+
+  inline void init_critsect(MiscUtils::critsect_t* cs) {
+    pthread_mutex_init(cs, NULL);
+  }
+  inline void free_critsect(MiscUtils::critsect_t* cs) {
+    pthread_mutex_destroy(cs);
+  }
+  inline void enter_critsect(MiscUtils::critsect_t* cs) {
+    pthread_mutex_lock(cs);
+  }
+  inline void leave_critsect(MiscUtils::critsect_t* cs) {
+    pthread_mutex_unlock(cs);
+  }
+
+  // Need to wrap this in an object because we need to dynamically initialize
+  // critical section (because of windows, where there is no way to initialize
+  // a CRITICAL_SECTION statically. On Unix, we could use
+  // PTHREAD_MUTEX_INITIALIZER)
+
+  // Note: The critical section does NOT get cleaned up in the destructor. That is
+  // by design: the CritSect class is only ever used as global objects whose
+  // lifetime spans the whole VM life; in that context we don't want the lock to
+  // be cleaned up when global C++ objects are destroyed, but to continue to work
+  // correctly right to the very end of the process life.
+  class CritSect {
+    critsect_t _cs;
+  public:
+    CritSect()        { init_critsect(&_cs); }
+    //~CritSect()       { free_critsect(&_cs); }
+    void enter()      { enter_critsect(&_cs); }
+    void leave()      { leave_critsect(&_cs); }
+  };
+
+  class AutoCritSect {
+    CritSect* const _pcsobj;
+  public:
+    AutoCritSect(CritSect* pcsobj)
+      : _pcsobj(pcsobj)
+    {
+      _pcsobj->enter();
+    }
+    ~AutoCritSect() {
+      _pcsobj->leave();
+    }
+  };
+
+}
+
+#endif // OS_AIX_VM_PORTING_AIX_HPP
--- a/hotspot/src/os_cpu/aix_ppc/vm/globals_aix_ppc.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/os_cpu/aix_ppc/vm/globals_aix_ppc.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -40,13 +40,13 @@
 define_pd_global(intx, CompilerThreadStackSize,  4096);
 
 // Allow extra space in DEBUG builds for asserts.
-define_pd_global(uintx,JVMInvokeMethodSlack,     8192);
+define_pd_global(size_t, JVMInvokeMethodSlack,   8192);
 
 define_pd_global(intx, StackYellowPages,         6);
 define_pd_global(intx, StackRedPages,            1);
 define_pd_global(intx, StackShadowPages,         6 DEBUG_ONLY(+2));
 
 // Only used on 64 bit platforms
-define_pd_global(uintx,HeapBaseMinAddress,       2*G);
+define_pd_global(size_t, HeapBaseMinAddress,     2*G);
 
 #endif // OS_CPU_AIX_OJDKPPC_VM_GLOBALS_AIX_PPC_HPP
--- a/hotspot/src/os_cpu/bsd_x86/vm/globals_bsd_x86.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/os_cpu/bsd_x86/vm/globals_bsd_x86.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, 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,9 +43,9 @@
 
 define_pd_global(intx, CompilerThreadStackSize,  0);
 
-define_pd_global(uintx, JVMInvokeMethodSlack,    8192);
+define_pd_global(size_t, JVMInvokeMethodSlack,   8192);
 
 // Used on 64 bit platforms for UseCompressedOops base address
-define_pd_global(uintx, HeapBaseMinAddress,      2*G);
+define_pd_global(size_t, HeapBaseMinAddress,     2*G);
 
 #endif // OS_CPU_BSD_X86_VM_GLOBALS_BSD_X86_HPP
--- a/hotspot/src/os_cpu/bsd_zero/vm/globals_bsd_zero.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/os_cpu/bsd_zero/vm/globals_bsd_zero.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2007, 2008, 2010 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -39,9 +39,9 @@
 define_pd_global(intx,  VMThreadStackSize,       512);
 #endif // _LP64
 define_pd_global(intx,  CompilerThreadStackSize, 0);
-define_pd_global(uintx, JVMInvokeMethodSlack,    8192);
+define_pd_global(size_t, JVMInvokeMethodSlack,   8192);
 
 // Used on 64 bit platforms for UseCompressedOops base address
-define_pd_global(uintx, HeapBaseMinAddress,      2*G);
+define_pd_global(size_t, HeapBaseMinAddress,     2*G);
 
 #endif // OS_CPU_BSD_ZERO_VM_GLOBALS_BSD_ZERO_HPP
--- a/hotspot/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -116,6 +116,14 @@
 #endif
 }
 
+void os::Linux::ucontext_set_pc(ucontext_t * uc, address pc) {
+#ifdef BUILTIN_SIM
+  uc->uc_mcontext.gregs[REG_PC] = (intptr_t)pc;
+#else
+  uc->uc_mcontext.pc = (intptr_t)pc;
+#endif
+}
+
 intptr_t* os::Linux::ucontext_get_sp(ucontext_t * uc) {
 #ifdef BUILTIN_SIM
   return (intptr_t*)uc->uc_mcontext.gregs[REG_SP];
@@ -311,7 +319,7 @@
     }
 #else
     if (StubRoutines::is_safefetch_fault(pc)) {
-      uc->uc_mcontext.pc = intptr_t(StubRoutines::continuation_for_safefetch_fault(pc));
+      os::Linux::ucontext_set_pc(uc, StubRoutines::continuation_for_safefetch_fault(pc));
       return 1;
     }
 #endif
@@ -432,11 +440,7 @@
     // save all thread context in case we need to restore it
     if (thread != NULL) thread->set_saved_exception_pc(pc);
 
-#ifdef BUILTIN_SIM
-    uc->uc_mcontext.gregs[REG_PC] = (greg_t)stub;
-#else
-    uc->uc_mcontext.pc = (__u64)stub;
-#endif
+    os::Linux::ucontext_set_pc(uc, stub);
     return true;
   }
 
--- a/hotspot/src/os_cpu/linux_ppc/vm/globals_linux_ppc.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/os_cpu/linux_ppc/vm/globals_linux_ppc.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -40,13 +40,13 @@
 define_pd_global(intx, CompilerThreadStackSize,  4096);
 
 // Allow extra space in DEBUG builds for asserts.
-define_pd_global(uintx,JVMInvokeMethodSlack,     8192);
+define_pd_global(size_t, JVMInvokeMethodSlack,   8192);
 
 define_pd_global(intx, StackYellowPages,         6);
 define_pd_global(intx, StackRedPages,            1);
 define_pd_global(intx, StackShadowPages,         6 DEBUG_ONLY(+2));
 
 // Only used on 64 bit platforms
-define_pd_global(uintx,HeapBaseMinAddress,       2*G);
+define_pd_global(size_t, HeapBaseMinAddress,     2*G);
 
 #endif // OS_CPU_LINUX_PPC_VM_GLOBALS_LINUX_PPC_HPP
--- a/hotspot/src/os_cpu/linux_sparc/vm/globals_linux_sparc.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/os_cpu/linux_sparc/vm/globals_linux_sparc.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, 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
@@ -30,10 +30,10 @@
 // runtime system.  (see globals.hpp)
 //
 
-define_pd_global(uintx, JVMInvokeMethodSlack,    12288);
+define_pd_global(size_t, JVMInvokeMethodSlack,   12288);
 define_pd_global(intx, CompilerThreadStackSize,  0);
 
 // Used on 64 bit platforms for UseCompressedOops base address
-define_pd_global(uintx, HeapBaseMinAddress,      CONST64(4)*G);
+define_pd_global(size_t, HeapBaseMinAddress,     CONST64(4)*G);
 
 #endif // OS_CPU_LINUX_SPARC_VM_GLOBALS_LINUX_SPARC_HPP
--- a/hotspot/src/os_cpu/linux_x86/vm/globals_linux_x86.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/os_cpu/linux_x86/vm/globals_linux_x86.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, 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,9 +42,9 @@
 
 define_pd_global(intx, CompilerThreadStackSize,  0);
 
-define_pd_global(uintx,JVMInvokeMethodSlack,     8192);
+define_pd_global(size_t, JVMInvokeMethodSlack,   8192);
 
 // Used on 64 bit platforms for UseCompressedOops base address
-define_pd_global(uintx,HeapBaseMinAddress,       2*G);
+define_pd_global(size_t, HeapBaseMinAddress,     2*G);
 
 #endif // OS_CPU_LINUX_X86_VM_GLOBALS_LINUX_X86_HPP
--- a/hotspot/src/os_cpu/linux_zero/vm/globals_linux_zero.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/os_cpu/linux_zero/vm/globals_linux_zero.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2007, 2008, 2010 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -39,9 +39,9 @@
 define_pd_global(intx,  VMThreadStackSize,       512);
 #endif // _LP64
 define_pd_global(intx,  CompilerThreadStackSize, 0);
-define_pd_global(uintx, JVMInvokeMethodSlack,    8192);
+define_pd_global(size_t, JVMInvokeMethodSlack,   8192);
 
 // Used on 64 bit platforms for UseCompressedOops base address
-define_pd_global(uintx, HeapBaseMinAddress,      2*G);
+define_pd_global(size_t, HeapBaseMinAddress,     2*G);
 
 #endif // OS_CPU_LINUX_ZERO_VM_GLOBALS_LINUX_ZERO_HPP
--- a/hotspot/src/os_cpu/solaris_sparc/vm/globals_solaris_sparc.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/globals_solaris_sparc.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, 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
@@ -30,16 +30,16 @@
 // (see globals.hpp)
 //
 
-define_pd_global(uintx, JVMInvokeMethodSlack,    12288);
+define_pd_global(size_t, JVMInvokeMethodSlack,   12288);
 define_pd_global(intx, CompilerThreadStackSize,  0);
 
 // Used on 64 bit platforms for UseCompressedOops base address
 #ifdef _LP64
 // use 6G as default base address because by default the OS maps the application
 // to 4G on Solaris-Sparc. This leaves at least 2G for the native heap.
-define_pd_global(uintx, HeapBaseMinAddress,      CONST64(6)*G);
+define_pd_global(size_t, HeapBaseMinAddress,     CONST64(6)*G);
 #else
-define_pd_global(uintx, HeapBaseMinAddress,      2*G);
+define_pd_global(size_t, HeapBaseMinAddress,     2*G);
 #endif
 
 
--- a/hotspot/src/os_cpu/solaris_x86/vm/globals_solaris_x86.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/os_cpu/solaris_x86/vm/globals_solaris_x86.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, 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,18 +32,18 @@
 #ifdef AMD64
 define_pd_global(intx, ThreadStackSize,          1024); // 0 => use system default
 define_pd_global(intx, VMThreadStackSize,        1024);
-define_pd_global(uintx,JVMInvokeMethodSlack,     8*K);
+define_pd_global(size_t, JVMInvokeMethodSlack,   8*K);
 #else
 // ThreadStackSize 320 allows a couple of test cases to run while
 // keeping the number of threads that can be created high.
 define_pd_global(intx, ThreadStackSize,          320);
 define_pd_global(intx, VMThreadStackSize,        512);
-define_pd_global(uintx,JVMInvokeMethodSlack,     10*K);
+define_pd_global(size_t, JVMInvokeMethodSlack,   10*K);
 #endif // AMD64
 
 define_pd_global(intx, CompilerThreadStackSize,  0);
 
 // Used on 64 bit platforms for UseCompressedOops base address
-define_pd_global(uintx,HeapBaseMinAddress,       2*G);
+define_pd_global(size_t, HeapBaseMinAddress,     2*G);
 
 #endif // OS_CPU_SOLARIS_X86_VM_GLOBALS_SOLARIS_X86_HPP
--- a/hotspot/src/os_cpu/windows_x86/vm/globals_windows_x86.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/os_cpu/windows_x86/vm/globals_windows_x86.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, 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,9 +43,9 @@
 define_pd_global(intx, CompilerThreadStackSize,  0);
 #endif
 
-define_pd_global(uintx, JVMInvokeMethodSlack,    8192);
+define_pd_global(size_t, JVMInvokeMethodSlack,   8192);
 
 // Used on 64 bit platforms for UseCompressedOops base address
-define_pd_global(uintx, HeapBaseMinAddress,      2*G);
+define_pd_global(size_t, HeapBaseMinAddress,     2*G);
 
 #endif // OS_CPU_WINDOWS_X86_VM_GLOBALS_WINDOWS_X86_HPP
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1421,7 +1421,6 @@
   // Do the pre-write barrier, if any.
   switch (_bs->kind()) {
 #if INCLUDE_ALL_GCS
-    case BarrierSet::G1SATBCT:
     case BarrierSet::G1SATBCTLogging:
       G1SATBCardTableModRef_pre_barrier(addr_opr, pre_val, do_load, patch, info);
       break;
@@ -1442,7 +1441,6 @@
 void LIRGenerator::post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val) {
   switch (_bs->kind()) {
 #if INCLUDE_ALL_GCS
-    case BarrierSet::G1SATBCT:
     case BarrierSet::G1SATBCTLogging:
       G1SATBCardTableModRef_post_barrier(addr,  new_val);
       break;
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, 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
@@ -186,7 +186,7 @@
       cp->space->set_compaction_top(compact_top);
       cp->space = cp->space->next_compaction_space();
       if (cp->space == NULL) {
-        cp->gen = GenCollectedHeap::heap()->prev_gen(cp->gen);
+        cp->gen = GenCollectedHeap::heap()->young_gen();
         assert(cp->gen != NULL, "compaction must succeed");
         cp->space = cp->gen->first_compaction_space();
         assert(cp->space != NULL, "generation must have a first compaction space");
@@ -900,7 +900,6 @@
   }
 }
 
-
 // Callers of this iterator beware: The closure application should
 // be robust in the face of uninitialized objects and should (always)
 // return a correct size so that the next addr + size below gives us a
@@ -2663,8 +2662,8 @@
       // Need to smooth wrt historical average
       if (ResizeOldPLAB) {
         _blocks_to_claim[i].sample(
-          MAX2((size_t)CMSOldPLABMin,
-          MIN2((size_t)CMSOldPLABMax,
+          MAX2(CMSOldPLABMin,
+          MIN2(CMSOldPLABMax,
                _global_num_blocks[i]/(_global_num_workers[i]*CMSOldPLABNumRefills))));
       }
       // Reset counters for next round
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, 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
@@ -36,7 +36,9 @@
 // space, in this case a CompactibleFreeListSpace.
 
 // Forward declarations
+class CMSCollector;
 class CompactibleFreeListSpace;
+class ConcurrentMarkSweepGeneration;
 class BlkClosure;
 class BlkClosureCareful;
 class FreeChunk;
@@ -396,6 +398,10 @@
   // Resizing support
   void set_end(HeapWord* value);  // override
 
+  // Never mangle CompactibleFreeListSpace
+  void mangle_unused_area() {}
+  void mangle_unused_area_complete() {}
+
   // Mutual exclusion support
   Mutex* freelistLock() const { return &_freelistLock; }
 
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -369,7 +369,7 @@
 double CMSStats::time_until_cms_gen_full() const {
   size_t cms_free = _cms_gen->cmsSpace()->free();
   GenCollectedHeap* gch = GenCollectedHeap::heap();
-  size_t expected_promotion = MIN2(gch->get_gen(0)->capacity(),
+  size_t expected_promotion = MIN2(gch->young_gen()->capacity(),
                                    (size_t) _cms_gen->gc_stats()->avg_promoted()->padded_average());
   if (cms_free > expected_promotion) {
     // Start a cms collection if there isn't enough space to promote
@@ -506,7 +506,7 @@
   _collector_policy(cp),
   _should_unload_classes(CMSClassUnloadingEnabled),
   _concurrent_cycles_since_last_unload(0),
-  _roots_scanning_options(SharedHeap::SO_None),
+  _roots_scanning_options(GenCollectedHeap::SO_None),
   _inter_sweep_estimate(CMS_SweepWeight, CMS_SweepPadding),
   _intra_sweep_estimate(CMS_SweepWeight, CMS_SweepPadding),
   _gc_tracer_cm(new (ResourceObj::C_HEAP, mtGC) CMSTracer()),
@@ -626,8 +626,8 @@
 
   // Support for parallelizing young gen rescan
   GenCollectedHeap* gch = GenCollectedHeap::heap();
-  assert(gch->prev_gen(_cmsGen)->kind() == Generation::ParNew, "CMS can only be used with ParNew");
-  _young_gen = (ParNewGeneration*)gch->prev_gen(_cmsGen);
+  assert(gch->young_gen()->kind() == Generation::ParNew, "CMS can only be used with ParNew");
+  _young_gen = (ParNewGeneration*)gch->young_gen();
   if (gch->supports_inline_contig_alloc()) {
     _top_addr = gch->top_addr();
     _end_addr = gch->end_addr();
@@ -869,7 +869,7 @@
       if (prev_level >= 0) {
         size_t prev_size = 0;
         GenCollectedHeap* gch = GenCollectedHeap::heap();
-        Generation* prev_gen = gch->get_gen(prev_level);
+        Generation* prev_gen = gch->young_gen();
         prev_size = prev_gen->capacity();
           gclog_or_tty->print_cr("  Younger gen size "SIZE_FORMAT,
                                  prev_size/1000);
@@ -1049,11 +1049,8 @@
     // expand and retry
     size_t s = _cmsSpace->expansionSpaceRequired(obj_size);  // HeapWords
     expand_for_gc_cause(s*HeapWordSize, MinHeapDeltaBytes, CMSExpansionCause::_satisfy_promotion);
-    // Since there's currently no next generation, we don't try to promote
+    // Since this is the old generation, we don't try to promote
     // into a more senior generation.
-    assert(next_gen() == NULL, "assumption, based upon which no attempt "
-                               "is made to pass on a possibly failing "
-                               "promotion to next generation");
     res = _cmsSpace->promote(obj, obj_size);
   }
   if (res != NULL) {
@@ -2499,7 +2496,7 @@
   gch->gen_process_roots(_cmsGen->level(),
                          true,   // younger gens are roots
                          true,   // activate StrongRootsScope
-                         SharedHeap::ScanningOption(roots_scanning_options()),
+                         GenCollectedHeap::ScanningOption(roots_scanning_options()),
                          should_unload_classes(),
                          &notOlder,
                          NULL,
@@ -2567,7 +2564,7 @@
   gch->gen_process_roots(_cmsGen->level(),
                          true,   // younger gens are roots
                          true,   // activate StrongRootsScope
-                         SharedHeap::ScanningOption(roots_scanning_options()),
+                         GenCollectedHeap::ScanningOption(roots_scanning_options()),
                          should_unload_classes(),
                          &notOlder,
                          NULL,
@@ -2751,7 +2748,7 @@
 void CMSCollector::setup_cms_unloading_and_verification_state() {
   const  bool should_verify =   VerifyBeforeGC || VerifyAfterGC || VerifyDuringGC
                              || VerifyBeforeExit;
-  const  int  rso           =   SharedHeap::SO_AllCodeCache;
+  const  int  rso           =   GenCollectedHeap::SO_AllCodeCache;
 
   // We set the proper root for this CMS cycle here.
   if (should_unload_classes()) {   // Should unload classes this cycle
@@ -3000,7 +2997,6 @@
   report_heap_summary(GCWhen::BeforeGC);
 
   ReferenceProcessor* rp = ref_processor();
-  SpecializationStats::clear();
   assert(_restart_addr == NULL, "Control point invariant");
   {
     // acquire locks for subsequent manipulations
@@ -3011,7 +3007,6 @@
     rp->enable_discovery();
     _collectorState = Marking;
   }
-  SpecializationStats::print();
 }
 
 void CMSCollector::checkpointRootsInitialWork() {
@@ -3092,7 +3087,7 @@
       gch->gen_process_roots(_cmsGen->level(),
                              true,   // younger gens are roots
                              true,   // activate StrongRootsScope
-                             SharedHeap::ScanningOption(roots_scanning_options()),
+                             GenCollectedHeap::ScanningOption(roots_scanning_options()),
                              should_unload_classes(),
                              &notOlder,
                              NULL,
@@ -4329,7 +4324,6 @@
   verify_work_stacks_empty();
   verify_overflow_empty();
 
-  SpecializationStats::clear();
   if (PrintGCDetails) {
     gclog_or_tty->print("[YG occupancy: "SIZE_FORMAT" K ("SIZE_FORMAT" K)]",
                         _young_gen->used() / K,
@@ -4360,7 +4354,6 @@
   }
   verify_work_stacks_empty();
   verify_overflow_empty();
-  SpecializationStats::print();
 }
 
 void CMSCollector::checkpointRootsFinalWork() {
@@ -4528,13 +4521,13 @@
   gch->gen_process_roots(_collector->_cmsGen->level(),
                          false,     // yg was scanned above
                          false,     // this is parallel code
-                         SharedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()),
+                         GenCollectedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()),
                          _collector->should_unload_classes(),
                          &par_mri_cl,
                          NULL,
                          &cld_closure);
   assert(_collector->should_unload_classes()
-         || (_collector->CMSCollector::roots_scanning_options() & SharedHeap::SO_AllCodeCache),
+         || (_collector->CMSCollector::roots_scanning_options() & GenCollectedHeap::SO_AllCodeCache),
          "if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops");
   _timer.stop();
   if (PrintCMSStatistics != 0) {
@@ -4664,14 +4657,14 @@
   gch->gen_process_roots(_collector->_cmsGen->level(),
                          false,     // yg was scanned above
                          false,     // this is parallel code
-                         SharedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()),
+                         GenCollectedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()),
                          _collector->should_unload_classes(),
                          &par_mrias_cl,
                          NULL,
                          NULL);     // The dirty klasses will be handled below
 
   assert(_collector->should_unload_classes()
-         || (_collector->CMSCollector::roots_scanning_options() & SharedHeap::SO_AllCodeCache),
+         || (_collector->CMSCollector::roots_scanning_options() & GenCollectedHeap::SO_AllCodeCache),
          "if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops");
   _timer.stop();
   if (PrintCMSStatistics != 0) {
@@ -5255,14 +5248,14 @@
     gch->gen_process_roots(_cmsGen->level(),
                            true,  // younger gens as roots
                            false, // use the local StrongRootsScope
-                           SharedHeap::ScanningOption(roots_scanning_options()),
+                           GenCollectedHeap::ScanningOption(roots_scanning_options()),
                            should_unload_classes(),
                            &mrias_cl,
                            NULL,
                            NULL); // The dirty klasses will be handled below
 
     assert(should_unload_classes()
-           || (roots_scanning_options() & SharedHeap::SO_AllCodeCache),
+           || (roots_scanning_options() & GenCollectedHeap::SO_AllCodeCache),
            "if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops");
   }
 
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, 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,6 +25,7 @@
 #ifndef SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_CONCURRENTMARKSWEEPGENERATION_HPP
 #define SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_CONCURRENTMARKSWEEPGENERATION_HPP
 
+#include "gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp"
 #include "gc_implementation/shared/gcHeapSummary.hpp"
 #include "gc_implementation/shared/gSpaceCounters.hpp"
 #include "gc_implementation/shared/gcStats.hpp"
@@ -55,6 +56,7 @@
 // means of a sliding mark-compact.
 
 class AdaptiveSizePolicy;
+class CMSCollector;
 class CMSConcMarkingTask;
 class CMSGCAdaptivePolicyCounters;
 class CMSTracer;
@@ -64,6 +66,7 @@
 class ConcurrentMarkSweepThread;
 class CompactibleFreeListSpace;
 class FreeChunk;
+class ParNewGeneration;
 class PromotionInfo;
 class ScanMarkedObjectsAgainCarefullyClosure;
 class TenuredGeneration;
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -696,32 +696,32 @@
   }
 
   if (FLAG_IS_DEFAULT(MarkStackSize)) {
-    uintx mark_stack_size =
+    size_t mark_stack_size =
       MIN2(MarkStackSizeMax,
-          MAX2(MarkStackSize, (uintx) (parallel_marking_threads() * TASKQUEUE_SIZE)));
+          MAX2(MarkStackSize, (size_t) (parallel_marking_threads() * TASKQUEUE_SIZE)));
     // Verify that the calculated value for MarkStackSize is in range.
     // It would be nice to use the private utility routine from Arguments.
     if (!(mark_stack_size >= 1 && mark_stack_size <= MarkStackSizeMax)) {
-      warning("Invalid value calculated for MarkStackSize (" UINTX_FORMAT "): "
-              "must be between " UINTX_FORMAT " and " UINTX_FORMAT,
-              mark_stack_size, (uintx) 1, MarkStackSizeMax);
+      warning("Invalid value calculated for MarkStackSize (" SIZE_FORMAT "): "
+              "must be between 1 and " SIZE_FORMAT,
+              mark_stack_size, MarkStackSizeMax);
       return;
     }
-    FLAG_SET_ERGO(uintx, MarkStackSize, mark_stack_size);
+    FLAG_SET_ERGO(size_t, MarkStackSize, mark_stack_size);
   } else {
     // Verify MarkStackSize is in range.
     if (FLAG_IS_CMDLINE(MarkStackSize)) {
       if (FLAG_IS_DEFAULT(MarkStackSizeMax)) {
         if (!(MarkStackSize >= 1 && MarkStackSize <= MarkStackSizeMax)) {
-          warning("Invalid value specified for MarkStackSize (" UINTX_FORMAT "): "
-                  "must be between " UINTX_FORMAT " and " UINTX_FORMAT,
-                  MarkStackSize, (uintx) 1, MarkStackSizeMax);
+          warning("Invalid value specified for MarkStackSize (" SIZE_FORMAT "): "
+                  "must be between 1 and " SIZE_FORMAT,
+                  MarkStackSize, MarkStackSizeMax);
           return;
         }
       } else if (FLAG_IS_CMDLINE(MarkStackSizeMax)) {
         if (!(MarkStackSize >= 1 && MarkStackSize <= MarkStackSizeMax)) {
-          warning("Invalid value specified for MarkStackSize (" UINTX_FORMAT ")"
-                  " or for MarkStackSizeMax (" UINTX_FORMAT ")",
+          warning("Invalid value specified for MarkStackSize (" SIZE_FORMAT ")"
+                  " or for MarkStackSizeMax (" SIZE_FORMAT ")",
                   MarkStackSize, MarkStackSizeMax);
           return;
         }
@@ -745,7 +745,7 @@
   // so that the assertion in MarkingTaskQueue::task_queue doesn't fail
   _active_tasks = _max_worker_id;
 
-  size_t max_regions = (size_t) _g1h->max_regions();
+  uint max_regions = _g1h->max_regions();
   for (uint i = 0; i < _max_worker_id; ++i) {
     CMTaskQueue* task_queue = new CMTaskQueue();
     task_queue->initialize();
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -34,6 +34,7 @@
 class G1CollectedHeap;
 class CMBitMap;
 class CMTask;
+class ConcurrentMark;
 typedef GenericTaskQueue<oop, mtGC>            CMTaskQueue;
 typedef GenericTaskQueueSet<CMTaskQueue, mtGC> CMTaskQueueSet;
 
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -48,6 +48,7 @@
 #include "gc_implementation/g1/g1ParScanThreadState.inline.hpp"
 #include "gc_implementation/g1/g1RegionToSpaceMapper.hpp"
 #include "gc_implementation/g1/g1RemSet.inline.hpp"
+#include "gc_implementation/g1/g1RootProcessor.hpp"
 #include "gc_implementation/g1/g1StringDedup.hpp"
 #include "gc_implementation/g1/g1YCTypes.hpp"
 #include "gc_implementation/g1/heapRegion.inline.hpp"
@@ -89,18 +90,6 @@
 // apply to TLAB allocation, which is not part of this interface: it
 // is done by clients of this interface.)
 
-// Notes on implementation of parallelism in different tasks.
-//
-// G1ParVerifyTask uses heap_region_par_iterate() for parallelism.
-// The number of GC workers is passed to heap_region_par_iterate().
-// It does use run_task() which sets _n_workers in the task.
-// G1ParTask executes g1_process_roots() ->
-// SharedHeap::process_roots() which calls eventually to
-// CardTableModRefBS::par_non_clean_card_iterate_work() which uses
-// SequentialSubTasksDone.  SharedHeap::process_roots() also
-// directly uses SubTasksDone (_process_strong_tasks field in SharedHeap).
-//
-
 // Local to this file.
 
 class RefineCardTableEntryClosure: public CardTableEntryClosure {
@@ -1767,7 +1756,6 @@
   _is_alive_closure_stw(this),
   _ref_processor_cm(NULL),
   _ref_processor_stw(NULL),
-  _process_strong_tasks(new SubTasksDone(G1H_PS_NumElements)),
   _bot_shared(NULL),
   _evac_failure_scan_stack(NULL),
   _mark_in_progress(false),
@@ -1801,9 +1789,6 @@
   _gc_tracer_cm(new (ResourceObj::C_HEAP, mtGC) G1OldTracer()) {
 
   _g1h = this;
-  if (_process_strong_tasks == NULL || !_process_strong_tasks->valid()) {
-    vm_exit_during_initialization("Failed necessary allocation.");
-  }
 
   _allocator = G1Allocator::create_allocator(_g1h);
   _humongous_object_threshold_in_words = HeapRegion::GrainWords / 2;
@@ -2026,10 +2011,6 @@
                                              Shared_DirtyCardQ_lock,
                                              &JavaThread::dirty_card_queue_set());
 
-  // In case we're keeping closure specialization stats, initialize those
-  // counts and that mechanism.
-  SpecializationStats::clear();
-
   // Here we allocate the dummy HeapRegion that is required by the
   // G1AllocRegion class.
   HeapRegion* dummy_region = _hrm.get_dummy_region();
@@ -2206,11 +2187,11 @@
   hot_card_cache->drain(worker_i, g1_rem_set(), into_cset_dcq);
 
   DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
-  int n_completed_buffers = 0;
+  size_t n_completed_buffers = 0;
   while (dcqs.apply_closure_to_completed_buffer(cl, worker_i, 0, true)) {
     n_completed_buffers++;
   }
-  g1_policy()->phase_times()->record_update_rs_processed_buffers(worker_i, n_completed_buffers);
+  g1_policy()->phase_times()->record_thread_work_item(G1GCPhaseTimes::UpdateRS, worker_i, n_completed_buffers);
   dcqs.clear_n_completed_buffers();
   assert(!dcqs.completed_buffers_exist_dirty(), "Completed buffers exist!");
 }
@@ -3111,11 +3092,12 @@
     G1VerifyCodeRootOopClosure codeRootsCl(this, &rootsCl, vo);
     G1VerifyCodeRootBlobClosure blobsCl(&codeRootsCl);
 
-    process_all_roots(true,            // activate StrongRootsScope
-                      SO_AllCodeCache, // roots scanning options
-                      &rootsCl,
-                      &cldCl,
-                      &blobsCl);
+    {
+      G1RootProcessor root_processor(this);
+      root_processor.process_all_roots(&rootsCl,
+                                       &cldCl,
+                                       &blobsCl);
+    }
 
     bool failures = rootsCl.failures() || codeRootsCl.failures();
 
@@ -3321,7 +3303,6 @@
     concurrent_mark()->print_summary_info();
   }
   g1_policy()->print_yg_surv_rate_info();
-  SpecializationStats::print();
 }
 
 #ifndef PRODUCT
@@ -3751,9 +3732,9 @@
 
     TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty);
 
-    int active_workers = workers()->active_workers();
+    uint active_workers = workers()->active_workers();
     double pause_start_sec = os::elapsedTime();
-    g1_policy()->phase_times()->note_gc_start(active_workers);
+    g1_policy()->phase_times()->note_gc_start(active_workers, mark_in_progress());
     log_gc_header();
 
     TraceCollectorStats tcs(g1mm()->incremental_collection_counters());
@@ -4365,60 +4346,11 @@
   }
 };
 
-class G1CodeBlobClosure : public CodeBlobClosure {
-  class HeapRegionGatheringOopClosure : public OopClosure {
-    G1CollectedHeap* _g1h;
-    OopClosure* _work;
-    nmethod* _nm;
-
-    template <typename T>
-    void do_oop_work(T* p) {
-      _work->do_oop(p);
-      T oop_or_narrowoop = oopDesc::load_heap_oop(p);
-      if (!oopDesc::is_null(oop_or_narrowoop)) {
-        oop o = oopDesc::decode_heap_oop_not_null(oop_or_narrowoop);
-        HeapRegion* hr = _g1h->heap_region_containing_raw(o);
-        assert(!_g1h->obj_in_cs(o) || hr->rem_set()->strong_code_roots_list_contains(_nm), "if o still in CS then evacuation failed and nm must already be in the remset");
-        hr->add_strong_code_root(_nm);
-      }
-    }
-
-  public:
-    HeapRegionGatheringOopClosure(OopClosure* oc) : _g1h(G1CollectedHeap::heap()), _work(oc), _nm(NULL) {}
-
-    void do_oop(oop* o) {
-      do_oop_work(o);
-    }
-
-    void do_oop(narrowOop* o) {
-      do_oop_work(o);
-    }
-
-    void set_nm(nmethod* nm) {
-      _nm = nm;
-    }
-  };
-
-  HeapRegionGatheringOopClosure _oc;
-public:
-  G1CodeBlobClosure(OopClosure* oc) : _oc(oc) {}
-
-  void do_code_blob(CodeBlob* cb) {
-    nmethod* nm = cb->as_nmethod_or_null();
-    if (nm != NULL) {
-      if (!nm->test_set_oops_do_mark()) {
-        _oc.set_nm(nm);
-        nm->oops_do(&_oc);
-        nm->fix_oop_relocations();
-      }
-    }
-  }
-};
-
 class G1ParTask : public AbstractGangTask {
 protected:
   G1CollectedHeap*       _g1h;
   RefToScanQueueSet      *_queues;
+  G1RootProcessor*       _root_processor;
   ParallelTaskTerminator _terminator;
   uint _n_workers;
 
@@ -4426,10 +4358,11 @@
   Mutex* stats_lock() { return &_stats_lock; }
 
 public:
-  G1ParTask(G1CollectedHeap* g1h, RefToScanQueueSet *task_queues)
+  G1ParTask(G1CollectedHeap* g1h, RefToScanQueueSet *task_queues, G1RootProcessor* root_processor)
     : AbstractGangTask("G1 collection"),
       _g1h(g1h),
       _queues(task_queues),
+      _root_processor(root_processor),
       _terminator(0, _queues),
       _stats_lock(Mutex::leaf, "parallel G1 stats lock", true)
   {}
@@ -4443,13 +4376,7 @@
   ParallelTaskTerminator* terminator() { return &_terminator; }
 
   virtual void set_for_termination(int active_workers) {
-    // This task calls set_n_termination() in par_non_clean_card_iterate_work()
-    // in the young space (_par_seq_tasks) in the G1 heap
-    // for SequentialSubTasksDone.
-    // This task also uses SubTasksDone in SharedHeap and G1CollectedHeap
-    // both of which need setting by set_n_termination().
-    _g1h->SharedHeap::set_n_termination(active_workers);
-    _g1h->set_n_termination(active_workers);
+    _root_processor->set_num_workers(active_workers);
     terminator()->reset_for_reuse(active_workers);
     _n_workers = active_workers;
   }
@@ -4486,8 +4413,7 @@
   void work(uint worker_id) {
     if (worker_id >= _n_workers) return;  // no work needed this round
 
-    double start_time_ms = os::elapsedTime() * 1000.0;
-    _g1h->g1_policy()->phase_times()->record_gc_worker_start_time(worker_id, start_time_ms);
+    _g1h->g1_policy()->phase_times()->record_time_secs(G1GCPhaseTimes::GCWorkerStart, worker_id, os::elapsedTime());
 
     {
       ResourceMark rm;
@@ -4519,24 +4445,21 @@
                                                                                     false, // Process all klasses.
                                                                                     true); // Need to claim CLDs.
 
-      G1CodeBlobClosure scan_only_code_cl(&scan_only_root_cl);
-      G1CodeBlobClosure scan_mark_code_cl(&scan_mark_root_cl);
-      // IM Weak code roots are handled later.
-
       OopClosure* strong_root_cl;
       OopClosure* weak_root_cl;
       CLDClosure* strong_cld_cl;
       CLDClosure* weak_cld_cl;
-      CodeBlobClosure* strong_code_cl;
+
+      bool trace_metadata = false;
 
       if (_g1h->g1_policy()->during_initial_mark_pause()) {
         // We also need to mark copied objects.
         strong_root_cl = &scan_mark_root_cl;
         strong_cld_cl  = &scan_mark_cld_cl;
-        strong_code_cl = &scan_mark_code_cl;
         if (ClassUnloadingWithConcurrentMark) {
           weak_root_cl = &scan_mark_weak_root_cl;
           weak_cld_cl  = &scan_mark_weak_cld_cl;
+          trace_metadata = true;
         } else {
           weak_root_cl = &scan_mark_root_cl;
           weak_cld_cl  = &scan_mark_cld_cl;
@@ -4546,31 +4469,32 @@
         weak_root_cl   = &scan_only_root_cl;
         strong_cld_cl  = &scan_only_cld_cl;
         weak_cld_cl    = &scan_only_cld_cl;
-        strong_code_cl = &scan_only_code_cl;
       }
 
-
-      G1ParPushHeapRSClosure  push_heap_rs_cl(_g1h, &pss);
-
       pss.start_strong_roots();
-      _g1h->g1_process_roots(strong_root_cl,
-                             weak_root_cl,
-                             &push_heap_rs_cl,
-                             strong_cld_cl,
-                             weak_cld_cl,
-                             strong_code_cl,
-                             worker_id);
-
+
+      _root_processor->evacuate_roots(strong_root_cl,
+                                      weak_root_cl,
+                                      strong_cld_cl,
+                                      weak_cld_cl,
+                                      trace_metadata,
+                                      worker_id);
+
+      G1ParPushHeapRSClosure push_heap_rs_cl(_g1h, &pss);
+      _root_processor->scan_remembered_sets(&push_heap_rs_cl,
+                                            weak_root_cl,
+                                            worker_id);
       pss.end_strong_roots();
 
       {
         double start = os::elapsedTime();
         G1ParEvacuateFollowersClosure evac(_g1h, &pss, _queues, &_terminator);
         evac.do_void();
-        double elapsed_ms = (os::elapsedTime()-start)*1000.0;
-        double term_ms = pss.term_time()*1000.0;
-        _g1h->g1_policy()->phase_times()->add_obj_copy_time(worker_id, elapsed_ms-term_ms);
-        _g1h->g1_policy()->phase_times()->record_termination(worker_id, term_ms, pss.term_attempts());
+        double elapsed_sec = os::elapsedTime() - start;
+        double term_sec = pss.term_time();
+        _g1h->g1_policy()->phase_times()->add_time_secs(G1GCPhaseTimes::ObjCopy, worker_id, elapsed_sec - term_sec);
+        _g1h->g1_policy()->phase_times()->record_time_secs(G1GCPhaseTimes::Termination, worker_id, term_sec);
+        _g1h->g1_policy()->phase_times()->record_thread_work_item(G1GCPhaseTimes::Termination, worker_id, pss.term_attempts());
       }
       _g1h->g1_policy()->record_thread_age_table(pss.age_table());
       _g1h->update_surviving_young_words(pss.surviving_young_words()+1);
@@ -4586,100 +4510,10 @@
       // destructors are executed here and are included as part of the
       // "GC Worker Time".
     }
-
-    double end_time_ms = os::elapsedTime() * 1000.0;
-    _g1h->g1_policy()->phase_times()->record_gc_worker_end_time(worker_id, end_time_ms);
+    _g1h->g1_policy()->phase_times()->record_time_secs(G1GCPhaseTimes::GCWorkerEnd, worker_id, os::elapsedTime());
   }
 };
 
-// *** Common G1 Evacuation Stuff
-
-// This method is run in a GC worker.
-
-void
-G1CollectedHeap::
-g1_process_roots(OopClosure* scan_non_heap_roots,
-                 OopClosure* scan_non_heap_weak_roots,
-                 G1ParPushHeapRSClosure* scan_rs,
-                 CLDClosure* scan_strong_clds,
-                 CLDClosure* scan_weak_clds,
-                 CodeBlobClosure* scan_strong_code,
-                 uint worker_i) {
-
-  // First scan the shared roots.
-  double ext_roots_start = os::elapsedTime();
-  double closure_app_time_sec = 0.0;
-
-  bool during_im = _g1h->g1_policy()->during_initial_mark_pause();
-  bool trace_metadata = during_im && ClassUnloadingWithConcurrentMark;
-
-  BufferingOopClosure buf_scan_non_heap_roots(scan_non_heap_roots);
-  BufferingOopClosure buf_scan_non_heap_weak_roots(scan_non_heap_weak_roots);
-
-  process_roots(false, // no scoping; this is parallel code
-                SharedHeap::SO_None,
-                &buf_scan_non_heap_roots,
-                &buf_scan_non_heap_weak_roots,
-                scan_strong_clds,
-                // Unloading Initial Marks handle the weak CLDs separately.
-                (trace_metadata ? NULL : scan_weak_clds),
-                scan_strong_code);
-
-  // Now the CM ref_processor roots.
-  if (!_process_strong_tasks->is_task_claimed(G1H_PS_refProcessor_oops_do)) {
-    // We need to treat the discovered reference lists of the
-    // concurrent mark ref processor as roots and keep entries
-    // (which are added by the marking threads) on them live
-    // until they can be processed at the end of marking.
-    ref_processor_cm()->weak_oops_do(&buf_scan_non_heap_roots);
-  }
-
-  if (trace_metadata) {
-    // Barrier to make sure all workers passed
-    // the strong CLD and strong nmethods phases.
-    active_strong_roots_scope()->wait_until_all_workers_done_with_threads(n_par_threads());
-
-    // Now take the complement of the strong CLDs.
-    ClassLoaderDataGraph::roots_cld_do(NULL, scan_weak_clds);
-  }
-
-  // Finish up any enqueued closure apps (attributed as object copy time).
-  buf_scan_non_heap_roots.done();
-  buf_scan_non_heap_weak_roots.done();
-
-  double obj_copy_time_sec = buf_scan_non_heap_roots.closure_app_seconds()
-      + buf_scan_non_heap_weak_roots.closure_app_seconds();
-
-  g1_policy()->phase_times()->record_obj_copy_time(worker_i, obj_copy_time_sec * 1000.0);
-
-  double ext_root_time_ms =
-    ((os::elapsedTime() - ext_roots_start) - obj_copy_time_sec) * 1000.0;
-
-  g1_policy()->phase_times()->record_ext_root_scan_time(worker_i, ext_root_time_ms);
-
-  // During conc marking we have to filter the per-thread SATB buffers
-  // to make sure we remove any oops into the CSet (which will show up
-  // as implicitly live).
-  double satb_filtering_ms = 0.0;
-  if (!_process_strong_tasks->is_task_claimed(G1H_PS_filter_satb_buffers)) {
-    if (mark_in_progress()) {
-      double satb_filter_start = os::elapsedTime();
-
-      JavaThread::satb_mark_queue_set().filter_thread_buffers();
-
-      satb_filtering_ms = (os::elapsedTime() - satb_filter_start) * 1000.0;
-    }
-  }
-  g1_policy()->phase_times()->record_satb_filtering_time(worker_i, satb_filtering_ms);
-
-  // Now scan the complement of the collection set.
-  G1CodeBlobClosure scavenge_cs_nmethods(scan_non_heap_weak_roots);
-
-  g1_rem_set()->oops_into_collection_set_do(scan_rs, &scavenge_cs_nmethods, worker_i);
-
-  _process_strong_tasks->all_tasks_completed();
-}
-
 class G1StringSymbolTableUnlinkTask : public AbstractGangTask {
 private:
   BoolObjectClosure* _is_alive;
@@ -5054,14 +4888,13 @@
   G1RedirtyLoggedCardsTask(DirtyCardQueueSet* queue) : AbstractGangTask("Redirty Cards"), _queue(queue) { }
 
   virtual void work(uint worker_id) {
-    double start_time = os::elapsedTime();
+    G1GCPhaseTimes* phase_times = G1CollectedHeap::heap()->g1_policy()->phase_times();
+    G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::RedirtyCards, worker_id);
 
     RedirtyLoggedCardTableEntryClosure cl;
     _queue->par_apply_closure_to_all_completed_buffers(&cl);
 
-    G1GCPhaseTimes* timer = G1CollectedHeap::heap()->g1_policy()->phase_times();
-    timer->record_redirty_logged_cards_time_ms(worker_id, (os::elapsedTime() - start_time) * 1000.0);
-    timer->record_redirty_logged_cards_processed_cards(worker_id, cl.num_processed());
+    phase_times->record_thread_work_item(G1GCPhaseTimes::RedirtyCards, worker_id, cl.num_processed());
   }
 };
 
@@ -5608,7 +5441,6 @@
   workers()->set_active_workers(n_workers);
   set_par_threads(n_workers);
 
-  G1ParTask g1_par_task(this, _task_queues);
 
   init_for_evac_failure(NULL);
 
@@ -5617,7 +5449,8 @@
   double end_par_time_sec;
 
   {
-    StrongRootsScope srs(this);
+    G1RootProcessor root_processor(this);
+    G1ParTask g1_par_task(this, _task_queues, &root_processor);
     // InitialMark needs claim bits to keep track of the marked-through CLDs.
     if (g1_policy()->during_initial_mark_pause()) {
       ClassLoaderDataGraph::clear_claimed_marks();
@@ -5633,18 +5466,20 @@
     end_par_time_sec = os::elapsedTime();
 
     // Closing the inner scope will execute the destructor
-    // for the StrongRootsScope object. We record the current
+    // for the G1RootProcessor object. We record the current
     // elapsed time before closing the scope so that time
-    // taken for the SRS destructor is NOT included in the
+    // taken for the destructor is NOT included in the
     // reported parallel time.
   }
 
+  G1GCPhaseTimes* phase_times = g1_policy()->phase_times();
+
   double par_time_ms = (end_par_time_sec - start_par_time_sec) * 1000.0;
-  g1_policy()->phase_times()->record_par_time(par_time_ms);
+  phase_times->record_par_time(par_time_ms);
 
   double code_root_fixup_time_ms =
         (os::elapsedTime() - end_par_time_sec) * 1000.0;
-  g1_policy()->phase_times()->record_code_root_fixup_time(code_root_fixup_time_ms);
+  phase_times->record_code_root_fixup_time(code_root_fixup_time_ms);
 
   set_par_threads(0);
 
@@ -5656,9 +5491,14 @@
   process_discovered_references(n_workers);
 
   if (G1StringDedup::is_enabled()) {
+    double fixup_start = os::elapsedTime();
+
     G1STWIsAliveClosure is_alive(this);
     G1KeepAliveClosure keep_alive(this);
-    G1StringDedup::unlink_or_oops_do(&is_alive, &keep_alive);
+    G1StringDedup::unlink_or_oops_do(&is_alive, &keep_alive, true, phase_times);
+
+    double fixup_time_ms = (os::elapsedTime() - fixup_start) * 1000.0;
+    phase_times->record_string_dedup_fixup_time(fixup_time_ms);
   }
 
   _allocator->release_gc_alloc_regions(n_workers, evacuation_info);
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -56,6 +56,7 @@
 class GenerationSpec;
 class OopsInHeapRegionClosure;
 class G1KlassScanClosure;
+class G1ParScanThreadState;
 class ObjectClosure;
 class SpaceClosure;
 class CompactibleSpaceClosure;
@@ -780,22 +781,6 @@
   // statistics or updating free lists.
   void abandon_collection_set(HeapRegion* cs_head);
 
-  // Applies "scan_non_heap_roots" to roots outside the heap,
-  // "scan_rs" to roots inside the heap (having done "set_region" to
-  // indicate the region in which the root resides),
-  // and does "scan_metadata" If "scan_rs" is
-  // NULL, then this step is skipped.  The "worker_i"
-  // param is for use with parallel roots processing, and should be
-  // the "i" of the calling parallel worker thread's work(i) function.
-  // In the sequential case this param will be ignored.
-  void g1_process_roots(OopClosure* scan_non_heap_roots,
-                        OopClosure* scan_non_heap_weak_roots,
-                        G1ParPushHeapRSClosure* scan_rs,
-                        CLDClosure* scan_strong_clds,
-                        CLDClosure* scan_weak_clds,
-                        CodeBlobClosure* scan_strong_code,
-                        uint worker_i);
-
   // The concurrent marker (and the thread it runs in.)
   ConcurrentMark* _cm;
   ConcurrentMarkThread* _cmThread;
@@ -982,21 +967,10 @@
   // of G1CollectedHeap::_gc_time_stamp.
   uint* _worker_cset_start_region_time_stamp;
 
-  enum G1H_process_roots_tasks {
-    G1H_PS_filter_satb_buffers,
-    G1H_PS_refProcessor_oops_do,
-    // Leave this one last.
-    G1H_PS_NumElements
-  };
-
-  SubTasksDone* _process_strong_tasks;
-
   volatile bool _free_regions_coming;
 
 public:
 
-  SubTasksDone* process_strong_tasks() { return _process_strong_tasks; }
-
   void set_refine_cte_cl_concurrency(bool concurrent);
 
   RefToScanQueue *task_queue(int i) const;
@@ -1029,21 +1003,11 @@
   // Initialize weak reference processing.
   virtual void ref_processing_init();
 
-  void set_par_threads(uint t) {
-    SharedHeap::set_par_threads(t);
-    // Done in SharedHeap but oddly there are
-    // two _process_strong_tasks's in a G1CollectedHeap
-    // so do it here too.
-    _process_strong_tasks->set_n_threads(t);
-  }
-
+  // Explicitly import set_par_threads into this scope
+  using SharedHeap::set_par_threads;
   // Set _n_par_threads according to a policy TBD.
   void set_par_threads();
 
-  void set_n_termination(int t) {
-    _process_strong_tasks->set_n_threads(t);
-  }
-
   virtual CollectedHeap::Name kind() const {
     return CollectedHeap::G1CollectedHeap;
   }
@@ -1118,6 +1082,10 @@
   // The number of regions that are completely free.
   uint num_free_regions() const { return _hrm.num_free_regions(); }
 
+  MemoryUsage get_auxiliary_data_memory_usage() const {
+    return _hrm.get_auxiliary_data_memory_usage();
+  }
+
   // The number of regions that are not completely free.
   uint num_used_regions() const { return num_regions() - num_free_regions(); }
 
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -321,7 +321,7 @@
 
 void G1CollectorPolicy::initialize_flags() {
   if (G1HeapRegionSize != HeapRegion::GrainBytes) {
-    FLAG_SET_ERGO(uintx, G1HeapRegionSize, HeapRegion::GrainBytes);
+    FLAG_SET_ERGO(size_t, G1HeapRegionSize, HeapRegion::GrainBytes);
   }
 
   if (SurvivorRatio < 1) {
@@ -335,7 +335,7 @@
   uintx max_regions = G1CollectedHeap::heap()->max_regions();
   size_t max_young_size = (size_t)_young_gen_sizer->max_young_length(max_regions) * HeapRegion::GrainBytes;
   if (max_young_size != MaxNewSize) {
-    FLAG_SET_ERGO(uintx, MaxNewSize, max_young_size);
+    FLAG_SET_ERGO(size_t, MaxNewSize, max_young_size);
   }
 }
 
@@ -1073,7 +1073,7 @@
   if (update_stats) {
     double cost_per_card_ms = 0.0;
     if (_pending_cards > 0) {
-      cost_per_card_ms = phase_times()->average_last_update_rs_time() / (double) _pending_cards;
+      cost_per_card_ms = phase_times()->average_time_ms(G1GCPhaseTimes::UpdateRS) / (double) _pending_cards;
       _cost_per_card_ms_seq->add(cost_per_card_ms);
     }
 
@@ -1081,7 +1081,7 @@
 
     double cost_per_entry_ms = 0.0;
     if (cards_scanned > 10) {
-      cost_per_entry_ms = phase_times()->average_last_scan_rs_time() / (double) cards_scanned;
+      cost_per_entry_ms = phase_times()->average_time_ms(G1GCPhaseTimes::ScanRS) / (double) cards_scanned;
       if (_last_gc_was_young) {
         _cost_per_entry_ms_seq->add(cost_per_entry_ms);
       } else {
@@ -1123,7 +1123,7 @@
     double cost_per_byte_ms = 0.0;
 
     if (copied_bytes > 0) {
-      cost_per_byte_ms = phase_times()->average_last_obj_copy_time() / (double) copied_bytes;
+      cost_per_byte_ms = phase_times()->average_time_ms(G1GCPhaseTimes::ObjCopy) / (double) copied_bytes;
       if (_in_marking_window) {
         _cost_per_byte_ms_during_cm_seq->add(cost_per_byte_ms);
       } else {
@@ -1132,8 +1132,8 @@
     }
 
     double all_other_time_ms = pause_time_ms -
-      (phase_times()->average_last_update_rs_time() + phase_times()->average_last_scan_rs_time()
-      + phase_times()->average_last_obj_copy_time() + phase_times()->average_last_termination_time());
+      (phase_times()->average_time_ms(G1GCPhaseTimes::UpdateRS) + phase_times()->average_time_ms(G1GCPhaseTimes::ScanRS) +
+          phase_times()->average_time_ms(G1GCPhaseTimes::ObjCopy) + phase_times()->average_time_ms(G1GCPhaseTimes::Termination));
 
     double young_other_time_ms = 0.0;
     if (young_cset_region_length() > 0) {
@@ -1174,8 +1174,8 @@
 
   // Note that _mmu_tracker->max_gc_time() returns the time in seconds.
   double update_rs_time_goal_ms = _mmu_tracker->max_gc_time() * MILLIUNITS * G1RSetUpdatingPauseTimePercent / 100.0;
-  adjust_concurrent_refinement(phase_times()->average_last_update_rs_time(),
-                               phase_times()->sum_last_update_rs_processed_buffers(), update_rs_time_goal_ms);
+  adjust_concurrent_refinement(phase_times()->average_time_ms(G1GCPhaseTimes::UpdateRS),
+                               phase_times()->sum_thread_work_items(G1GCPhaseTimes::UpdateRS), update_rs_time_goal_ms);
 
   _collectionSetChooser->verify();
 }
@@ -2114,19 +2114,19 @@
     _other.add(pause_time_ms - phase_times->accounted_time_ms());
     _root_region_scan_wait.add(phase_times->root_region_scan_wait_time_ms());
     _parallel.add(phase_times->cur_collection_par_time_ms());
-    _ext_root_scan.add(phase_times->average_last_ext_root_scan_time());
-    _satb_filtering.add(phase_times->average_last_satb_filtering_times_ms());
-    _update_rs.add(phase_times->average_last_update_rs_time());
-    _scan_rs.add(phase_times->average_last_scan_rs_time());
-    _obj_copy.add(phase_times->average_last_obj_copy_time());
-    _termination.add(phase_times->average_last_termination_time());
+    _ext_root_scan.add(phase_times->average_time_ms(G1GCPhaseTimes::ExtRootScan));
+    _satb_filtering.add(phase_times->average_time_ms(G1GCPhaseTimes::SATBFiltering));
+    _update_rs.add(phase_times->average_time_ms(G1GCPhaseTimes::UpdateRS));
+    _scan_rs.add(phase_times->average_time_ms(G1GCPhaseTimes::ScanRS));
+    _obj_copy.add(phase_times->average_time_ms(G1GCPhaseTimes::ObjCopy));
+    _termination.add(phase_times->average_time_ms(G1GCPhaseTimes::Termination));
 
-    double parallel_known_time = phase_times->average_last_ext_root_scan_time() +
-      phase_times->average_last_satb_filtering_times_ms() +
-      phase_times->average_last_update_rs_time() +
-      phase_times->average_last_scan_rs_time() +
-      phase_times->average_last_obj_copy_time() +
-      + phase_times->average_last_termination_time();
+    double parallel_known_time = phase_times->average_time_ms(G1GCPhaseTimes::ExtRootScan) +
+      phase_times->average_time_ms(G1GCPhaseTimes::SATBFiltering) +
+      phase_times->average_time_ms(G1GCPhaseTimes::UpdateRS) +
+      phase_times->average_time_ms(G1GCPhaseTimes::ScanRS) +
+      phase_times->average_time_ms(G1GCPhaseTimes::ObjCopy) +
+      phase_times->average_time_ms(G1GCPhaseTimes::Termination);
 
     double parallel_other_time = phase_times->cur_collection_par_time_ms() - parallel_known_time;
     _parallel_other.add(parallel_other_time);
--- a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -22,13 +22,13 @@
  *
  */
 
-
 #include "precompiled.hpp"
 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
 #include "gc_implementation/g1/g1GCPhaseTimes.hpp"
 #include "gc_implementation/g1/g1Log.hpp"
 #include "gc_implementation/g1/g1StringDedup.hpp"
-#include "runtime/atomic.inline.hpp"
+#include "memory/allocation.hpp"
+#include "runtime/os.hpp"
 
 // Helper class for avoiding interleaved logging
 class LineBuffer: public StackObj {
@@ -71,184 +71,258 @@
     va_end(ap);
   }
 
+  void print_cr() {
+    gclog_or_tty->print_cr("%s", _buffer);
+    _cur = _indent_level * INDENT_CHARS;
+  }
+
   void append_and_print_cr(const char* format, ...)  ATTRIBUTE_PRINTF(2, 3) {
     va_list ap;
     va_start(ap, format);
     vappend(format, ap);
     va_end(ap);
-    gclog_or_tty->print_cr("%s", _buffer);
-    _cur = _indent_level * INDENT_CHARS;
+    print_cr();
   }
 };
 
-PRAGMA_DIAG_PUSH
-PRAGMA_FORMAT_NONLITERAL_IGNORED
 template <class T>
-void WorkerDataArray<T>::print(int level, const char* title) {
-  if (_length == 1) {
-    // No need for min, max, average and sum for only one worker
-    LineBuffer buf(level);
-    buf.append("[%s:  ", title);
-    buf.append(_print_format, _data[0]);
-    buf.append_and_print_cr("]");
-    return;
+class WorkerDataArray  : public CHeapObj<mtGC> {
+  friend class G1GCParPhasePrinter;
+  T*          _data;
+  uint        _length;
+  const char* _title;
+  bool        _print_sum;
+  int         _log_level;
+  uint        _indent_level;
+  bool        _enabled;
+
+  WorkerDataArray<size_t>* _thread_work_items;
+
+  NOT_PRODUCT(T uninitialized();)
+
+  // We are caching the sum and average to only have to calculate them once.
+  // This is not done in an MT-safe way. It is intended to allow single
+  // threaded code to call sum() and average() multiple times in any order
+  // without having to worry about the cost.
+  bool   _has_new_data;
+  T      _sum;
+  T      _min;
+  T      _max;
+  double _average;
+
+ public:
+  WorkerDataArray(uint length, const char* title, bool print_sum, int log_level, uint indent_level) :
+    _title(title), _length(0), _print_sum(print_sum), _log_level(log_level), _indent_level(indent_level),
+    _has_new_data(true), _thread_work_items(NULL), _enabled(true) {
+    assert(length > 0, "Must have some workers to store data for");
+    _length = length;
+    _data = NEW_C_HEAP_ARRAY(T, _length, mtGC);
   }
 
-  T min = _data[0];
-  T max = _data[0];
-  T sum = 0;
-
-  LineBuffer buf(level);
-  buf.append("[%s:", title);
-  for (uint i = 0; i < _length; ++i) {
-    T val = _data[i];
-    min = MIN2(val, min);
-    max = MAX2(val, max);
-    sum += val;
-    if (G1Log::finest()) {
-      buf.append("  ");
-      buf.append(_print_format, val);
-    }
+  ~WorkerDataArray() {
+    FREE_C_HEAP_ARRAY(T, _data);
   }
 
-  if (G1Log::finest()) {
-    buf.append_and_print_cr("%s", "");
+  void link_thread_work_items(WorkerDataArray<size_t>* thread_work_items) {
+    _thread_work_items = thread_work_items;
   }
 
-  double avg = (double)sum / (double)_length;
-  buf.append(" Min: ");
-  buf.append(_print_format, min);
-  buf.append(", Avg: ");
-  buf.append("%.1lf", avg); // Always print average as a double
-  buf.append(", Max: ");
-  buf.append(_print_format, max);
-  buf.append(", Diff: ");
-  buf.append(_print_format, max - min);
-  if (_print_sum) {
-    // for things like the start and end times the sum is not
-    // that relevant
-    buf.append(", Sum: ");
-    buf.append(_print_format, sum);
+  WorkerDataArray<size_t>* thread_work_items() { return _thread_work_items; }
+
+  void set(uint worker_i, T value) {
+    assert(worker_i < _length, err_msg("Worker %d is greater than max: %d", worker_i, _length));
+    assert(_data[worker_i] == WorkerDataArray<T>::uninitialized(), err_msg("Overwriting data for worker %d in %s", worker_i, _title));
+    _data[worker_i] = value;
+    _has_new_data = true;
   }
-  buf.append_and_print_cr("]");
-}
-PRAGMA_DIAG_POP
+
+  void set_thread_work_item(uint worker_i, size_t value) {
+    assert(_thread_work_items != NULL, "No sub count");
+    _thread_work_items->set(worker_i, value);
+  }
+
+  T get(uint worker_i) {
+    assert(worker_i < _length, err_msg("Worker %d is greater than max: %d", worker_i, _length));
+    assert(_data[worker_i] != WorkerDataArray<T>::uninitialized(), err_msg("No data added for worker %d", worker_i));
+    return _data[worker_i];
+  }
+
+  void add(uint worker_i, T value) {
+    assert(worker_i < _length, err_msg("Worker %d is greater than max: %d", worker_i, _length));
+    assert(_data[worker_i] != WorkerDataArray<T>::uninitialized(), err_msg("No data to add to for worker %d", worker_i));
+    _data[worker_i] += value;
+    _has_new_data = true;
+  }
+
+  double average(){
+    calculate_totals();
+    return _average;
+  }
+
+  T sum() {
+    calculate_totals();
+    return _sum;
+  }
+
+  T minimum() {
+    calculate_totals();
+    return _min;
+  }
+
+  T maximum() {
+    calculate_totals();
+    return _max;
+  }
+
+  void reset() PRODUCT_RETURN;
+  void verify() PRODUCT_RETURN;
+
+  void set_enabled(bool enabled) { _enabled = enabled; }
+
+  int log_level() { return _log_level;  }
+
+ private:
+
+  void calculate_totals(){
+    if (!_has_new_data) {
+      return;
+    }
+
+    _sum = (T)0;
+    _min = _data[0];
+    _max = _min;
+    for (uint i = 0; i < _length; ++i) {
+      T val = _data[i];
+      _sum += val;
+      _min = MIN2(_min, val);
+      _max = MAX2(_max, val);
+    }
+    _average = (double)_sum / (double)_length;
+    _has_new_data = false;
+  }
+};
+
 
 #ifndef PRODUCT
 
-template <> const int WorkerDataArray<int>::_uninitialized = -1;
-template <> const double WorkerDataArray<double>::_uninitialized = -1.0;
-template <> const size_t WorkerDataArray<size_t>::_uninitialized = (size_t)-1;
+template <>
+size_t WorkerDataArray<size_t>::uninitialized() {
+  return (size_t)-1;
+}
+
+template <>
+double WorkerDataArray<double>::uninitialized() {
+  return -1.0;
+}
 
 template <class T>
 void WorkerDataArray<T>::reset() {
   for (uint i = 0; i < _length; i++) {
-    _data[i] = (T)_uninitialized;
+    _data[i] = WorkerDataArray<T>::uninitialized();
+  }
+  if (_thread_work_items != NULL) {
+    _thread_work_items->reset();
   }
 }
 
 template <class T>
 void WorkerDataArray<T>::verify() {
+  if (!_enabled) {
+    return;
+  }
+
   for (uint i = 0; i < _length; i++) {
-    assert(_data[i] != _uninitialized,
-        err_msg("Invalid data for worker %u, data: %lf, uninitialized: %lf",
-            i, (double)_data[i], (double)_uninitialized));
+    assert(_data[i] != WorkerDataArray<T>::uninitialized(),
+        err_msg("Invalid data for worker %u in '%s'", i, _title));
+  }
+  if (_thread_work_items != NULL) {
+    _thread_work_items->verify();
   }
 }
 
 #endif
 
 G1GCPhaseTimes::G1GCPhaseTimes(uint max_gc_threads) :
-  _max_gc_threads(max_gc_threads),
-  _last_gc_worker_start_times_ms(_max_gc_threads, "%.1lf", false),
-  _last_ext_root_scan_times_ms(_max_gc_threads, "%.1lf"),
-  _last_satb_filtering_times_ms(_max_gc_threads, "%.1lf"),
-  _last_update_rs_times_ms(_max_gc_threads, "%.1lf"),
-  _last_update_rs_processed_buffers(_max_gc_threads, "%d"),
-  _last_scan_rs_times_ms(_max_gc_threads, "%.1lf"),
-  _last_strong_code_root_scan_times_ms(_max_gc_threads, "%.1lf"),
-  _last_obj_copy_times_ms(_max_gc_threads, "%.1lf"),
-  _last_termination_times_ms(_max_gc_threads, "%.1lf"),
-  _last_termination_attempts(_max_gc_threads, SIZE_FORMAT),
-  _last_gc_worker_end_times_ms(_max_gc_threads, "%.1lf", false),
-  _last_gc_worker_times_ms(_max_gc_threads, "%.1lf"),
-  _last_gc_worker_other_times_ms(_max_gc_threads, "%.1lf"),
-  _last_redirty_logged_cards_time_ms(_max_gc_threads, "%.1lf"),
-  _last_redirty_logged_cards_processed_cards(_max_gc_threads, SIZE_FORMAT),
-  _cur_string_dedup_queue_fixup_worker_times_ms(_max_gc_threads, "%.1lf"),
-  _cur_string_dedup_table_fixup_worker_times_ms(_max_gc_threads, "%.1lf")
+  _max_gc_threads(max_gc_threads)
 {
   assert(max_gc_threads > 0, "Must have some GC threads");
+
+  _gc_par_phases[GCWorkerStart] = new WorkerDataArray<double>(max_gc_threads, "GC Worker Start (ms)", false, G1Log::LevelFiner, 2);
+  _gc_par_phases[ExtRootScan] = new WorkerDataArray<double>(max_gc_threads, "Ext Root Scanning (ms)", true, G1Log::LevelFiner, 2);
+
+  // Root scanning phases
+  _gc_par_phases[ThreadRoots] = new WorkerDataArray<double>(max_gc_threads, "Thread Roots (ms)", true, G1Log::LevelFinest, 3);
+  _gc_par_phases[StringTableRoots] = new WorkerDataArray<double>(max_gc_threads, "StringTable Roots (ms)", true, G1Log::LevelFinest, 3);
+  _gc_par_phases[UniverseRoots] = new WorkerDataArray<double>(max_gc_threads, "Universe Roots (ms)", true, G1Log::LevelFinest, 3);
+  _gc_par_phases[JNIRoots] = new WorkerDataArray<double>(max_gc_threads, "JNI Handles Roots (ms)", true, G1Log::LevelFinest, 3);
+  _gc_par_phases[ObjectSynchronizerRoots] = new WorkerDataArray<double>(max_gc_threads, "ObjectSynchronizer Roots (ms)", true, G1Log::LevelFinest, 3);
+  _gc_par_phases[FlatProfilerRoots] = new WorkerDataArray<double>(max_gc_threads, "FlatProfiler Roots (ms)", true, G1Log::LevelFinest, 3);
+  _gc_par_phases[ManagementRoots] = new WorkerDataArray<double>(max_gc_threads, "Management Roots (ms)", true, G1Log::LevelFinest, 3);
+  _gc_par_phases[SystemDictionaryRoots] = new WorkerDataArray<double>(max_gc_threads, "SystemDictionary Roots (ms)", true, G1Log::LevelFinest, 3);
+  _gc_par_phases[CLDGRoots] = new WorkerDataArray<double>(max_gc_threads, "CLDG Roots (ms)", true, G1Log::LevelFinest, 3);
+  _gc_par_phases[JVMTIRoots] = new WorkerDataArray<double>(max_gc_threads, "JVMTI Roots (ms)", true, G1Log::LevelFinest, 3);
+  _gc_par_phases[CodeCacheRoots] = new WorkerDataArray<double>(max_gc_threads, "CodeCache Roots (ms)", true, G1Log::LevelFinest, 3);
+  _gc_par_phases[CMRefRoots] = new WorkerDataArray<double>(max_gc_threads, "CM RefProcessor Roots (ms)", true, G1Log::LevelFinest, 3);
+  _gc_par_phases[WaitForStrongCLD] = new WorkerDataArray<double>(max_gc_threads, "Wait For Strong CLD (ms)", true, G1Log::LevelFinest, 3);
+  _gc_par_phases[WeakCLDRoots] = new WorkerDataArray<double>(max_gc_threads, "Weak CLD Roots (ms)", true, G1Log::LevelFinest, 3);
+  _gc_par_phases[SATBFiltering] = new WorkerDataArray<double>(max_gc_threads, "SATB Filtering (ms)", true, G1Log::LevelFinest, 3);
+
+  _gc_par_phases[UpdateRS] = new WorkerDataArray<double>(max_gc_threads, "Update RS (ms)", true, G1Log::LevelFiner, 2);
+  _gc_par_phases[ScanRS] = new WorkerDataArray<double>(max_gc_threads, "Scan RS (ms)", true, G1Log::LevelFiner, 2);
+  _gc_par_phases[CodeRoots] = new WorkerDataArray<double>(max_gc_threads, "Code Root Scanning (ms)", true, G1Log::LevelFiner, 2);
+  _gc_par_phases[ObjCopy] = new WorkerDataArray<double>(max_gc_threads, "Object Copy (ms)", true, G1Log::LevelFiner, 2);
+  _gc_par_phases[Termination] = new WorkerDataArray<double>(max_gc_threads, "Termination (ms)", true, G1Log::LevelFiner, 2);
+  _gc_par_phases[GCWorkerTotal] = new WorkerDataArray<double>(max_gc_threads, "GC Worker Total (ms)", true, G1Log::LevelFiner, 2);
+  _gc_par_phases[GCWorkerEnd] = new WorkerDataArray<double>(max_gc_threads, "GC Worker End (ms)", false, G1Log::LevelFiner, 2);
+  _gc_par_phases[Other] = new WorkerDataArray<double>(max_gc_threads, "GC Worker Other (ms)", true, G1Log::LevelFiner, 2);
+
+  _update_rs_processed_buffers = new WorkerDataArray<size_t>(max_gc_threads, "Processed Buffers", true, G1Log::LevelFiner, 3);
+  _gc_par_phases[UpdateRS]->link_thread_work_items(_update_rs_processed_buffers);
+
+  _termination_attempts = new WorkerDataArray<size_t>(max_gc_threads, "Termination Attempts", true, G1Log::LevelFinest, 3);
+  _gc_par_phases[Termination]->link_thread_work_items(_termination_attempts);
+
+  _gc_par_phases[StringDedupQueueFixup] = new WorkerDataArray<double>(max_gc_threads, "Queue Fixup (ms)", true, G1Log::LevelFiner, 2);
+  _gc_par_phases[StringDedupTableFixup] = new WorkerDataArray<double>(max_gc_threads, "Table Fixup (ms)", true, G1Log::LevelFiner, 2);
+
+  _gc_par_phases[RedirtyCards] = new WorkerDataArray<double>(max_gc_threads, "Parallel Redirty", true, G1Log::LevelFinest, 3);
+  _redirtied_cards = new WorkerDataArray<size_t>(max_gc_threads, "Redirtied Cards", true, G1Log::LevelFinest, 3);
+  _gc_par_phases[RedirtyCards]->link_thread_work_items(_redirtied_cards);
 }
 
-void G1GCPhaseTimes::note_gc_start(uint active_gc_threads) {
+void G1GCPhaseTimes::note_gc_start(uint active_gc_threads, bool mark_in_progress) {
   assert(active_gc_threads > 0, "The number of threads must be > 0");
-  assert(active_gc_threads <= _max_gc_threads, "The number of active threads must be <= the max nubmer of threads");
+  assert(active_gc_threads <= _max_gc_threads, "The number of active threads must be <= the max number of threads");
   _active_gc_threads = active_gc_threads;
 
-  _last_gc_worker_start_times_ms.reset();
-  _last_ext_root_scan_times_ms.reset();
-  _last_satb_filtering_times_ms.reset();
-  _last_update_rs_times_ms.reset();
-  _last_update_rs_processed_buffers.reset();
-  _last_scan_rs_times_ms.reset();
-  _last_strong_code_root_scan_times_ms.reset();
-  _last_obj_copy_times_ms.reset();
-  _last_termination_times_ms.reset();
-  _last_termination_attempts.reset();
-  _last_gc_worker_end_times_ms.reset();
-  _last_gc_worker_times_ms.reset();
-  _last_gc_worker_other_times_ms.reset();
+  for (int i = 0; i < GCParPhasesSentinel; i++) {
+    _gc_par_phases[i]->reset();
+  }
 
-  _last_redirty_logged_cards_time_ms.reset();
-  _last_redirty_logged_cards_processed_cards.reset();
-
+  _gc_par_phases[StringDedupQueueFixup]->set_enabled(G1StringDedup::is_enabled());
+  _gc_par_phases[StringDedupTableFixup]->set_enabled(G1StringDedup::is_enabled());
 }
 
 void G1GCPhaseTimes::note_gc_end() {
-  _last_gc_worker_start_times_ms.verify();
-  _last_ext_root_scan_times_ms.verify();
-  _last_satb_filtering_times_ms.verify();
-  _last_update_rs_times_ms.verify();
-  _last_update_rs_processed_buffers.verify();
-  _last_scan_rs_times_ms.verify();
-  _last_strong_code_root_scan_times_ms.verify();
-  _last_obj_copy_times_ms.verify();
-  _last_termination_times_ms.verify();
-  _last_termination_attempts.verify();
-  _last_gc_worker_end_times_ms.verify();
+  for (uint i = 0; i < _active_gc_threads; i++) {
+    double worker_time = _gc_par_phases[GCWorkerEnd]->get(i) - _gc_par_phases[GCWorkerStart]->get(i);
+    record_time_secs(GCWorkerTotal, i , worker_time);
 
-  for (uint i = 0; i < _active_gc_threads; i++) {
-    double worker_time = _last_gc_worker_end_times_ms.get(i) - _last_gc_worker_start_times_ms.get(i);
-    _last_gc_worker_times_ms.set(i, worker_time);
+    double worker_known_time =
+        _gc_par_phases[ExtRootScan]->get(i) +
+        _gc_par_phases[SATBFiltering]->get(i) +
+        _gc_par_phases[UpdateRS]->get(i) +
+        _gc_par_phases[ScanRS]->get(i) +
+        _gc_par_phases[CodeRoots]->get(i) +
+        _gc_par_phases[ObjCopy]->get(i) +
+        _gc_par_phases[Termination]->get(i);
 
-    double worker_known_time = _last_ext_root_scan_times_ms.get(i) +
-                               _last_satb_filtering_times_ms.get(i) +
-                               _last_update_rs_times_ms.get(i) +
-                               _last_scan_rs_times_ms.get(i) +
-                               _last_strong_code_root_scan_times_ms.get(i) +
-                               _last_obj_copy_times_ms.get(i) +
-                               _last_termination_times_ms.get(i);
-
-    double worker_other_time = worker_time - worker_known_time;
-    _last_gc_worker_other_times_ms.set(i, worker_other_time);
+    record_time_secs(Other, i, worker_time - worker_known_time);
   }
 
-  _last_gc_worker_times_ms.verify();
-  _last_gc_worker_other_times_ms.verify();
-
-  _last_redirty_logged_cards_time_ms.verify();
-  _last_redirty_logged_cards_processed_cards.verify();
-}
-
-void G1GCPhaseTimes::note_string_dedup_fixup_start() {
-  _cur_string_dedup_queue_fixup_worker_times_ms.reset();
-  _cur_string_dedup_table_fixup_worker_times_ms.reset();
-}
-
-void G1GCPhaseTimes::note_string_dedup_fixup_end() {
-  _cur_string_dedup_queue_fixup_worker_times_ms.verify();
-  _cur_string_dedup_table_fixup_worker_times_ms.verify();
+  for (int i = 0; i < GCParPhasesSentinel; i++) {
+    _gc_par_phases[i]->verify();
+  }
 }
 
 void G1GCPhaseTimes::print_stats(int level, const char* str, double value) {
@@ -288,35 +362,172 @@
     return misc_time_ms;
 }
 
+// record the time a phase took in seconds
+void G1GCPhaseTimes::record_time_secs(GCParPhases phase, uint worker_i, double secs) {
+  _gc_par_phases[phase]->set(worker_i, secs);
+}
+
+// add a number of seconds to a phase
+void G1GCPhaseTimes::add_time_secs(GCParPhases phase, uint worker_i, double secs) {
+  _gc_par_phases[phase]->add(worker_i, secs);
+}
+
+void G1GCPhaseTimes::record_thread_work_item(GCParPhases phase, uint worker_i, size_t count) {
+  _gc_par_phases[phase]->set_thread_work_item(worker_i, count);
+}
+
+// return the average time for a phase in milliseconds
+double G1GCPhaseTimes::average_time_ms(GCParPhases phase) {
+  return _gc_par_phases[phase]->average() * 1000.0;
+}
+
+double G1GCPhaseTimes::get_time_ms(GCParPhases phase, uint worker_i) {
+  return _gc_par_phases[phase]->get(worker_i) * 1000.0;
+}
+
+double G1GCPhaseTimes::sum_time_ms(GCParPhases phase) {
+  return _gc_par_phases[phase]->sum() * 1000.0;
+}
+
+double G1GCPhaseTimes::min_time_ms(GCParPhases phase) {
+  return _gc_par_phases[phase]->minimum() * 1000.0;
+}
+
+double G1GCPhaseTimes::max_time_ms(GCParPhases phase) {
+  return _gc_par_phases[phase]->maximum() * 1000.0;
+}
+
+size_t G1GCPhaseTimes::get_thread_work_item(GCParPhases phase, uint worker_i) {
+  assert(_gc_par_phases[phase]->thread_work_items() != NULL, "No sub count");
+  return _gc_par_phases[phase]->thread_work_items()->get(worker_i);
+}
+
+size_t G1GCPhaseTimes::sum_thread_work_items(GCParPhases phase) {
+  assert(_gc_par_phases[phase]->thread_work_items() != NULL, "No sub count");
+  return _gc_par_phases[phase]->thread_work_items()->sum();
+}
+
+double G1GCPhaseTimes::average_thread_work_items(GCParPhases phase) {
+  assert(_gc_par_phases[phase]->thread_work_items() != NULL, "No sub count");
+  return _gc_par_phases[phase]->thread_work_items()->average();
+}
+
+size_t G1GCPhaseTimes::min_thread_work_items(GCParPhases phase) {
+  assert(_gc_par_phases[phase]->thread_work_items() != NULL, "No sub count");
+  return _gc_par_phases[phase]->thread_work_items()->minimum();
+}
+
+size_t G1GCPhaseTimes::max_thread_work_items(GCParPhases phase) {
+  assert(_gc_par_phases[phase]->thread_work_items() != NULL, "No sub count");
+  return _gc_par_phases[phase]->thread_work_items()->maximum();
+}
+
+class G1GCParPhasePrinter : public StackObj {
+  G1GCPhaseTimes* _phase_times;
+ public:
+  G1GCParPhasePrinter(G1GCPhaseTimes* phase_times) : _phase_times(phase_times) {}
+
+  void print(G1GCPhaseTimes::GCParPhases phase_id) {
+    WorkerDataArray<double>* phase = _phase_times->_gc_par_phases[phase_id];
+
+    if (phase->_log_level > G1Log::level() || !phase->_enabled) {
+      return;
+    }
+
+    if (phase->_length == 1) {
+      print_single_length(phase_id, phase);
+    } else {
+      print_multi_length(phase_id, phase);
+    }
+  }
+
+ private:
+
+  void print_single_length(G1GCPhaseTimes::GCParPhases phase_id, WorkerDataArray<double>* phase) {
+    // No need for min, max, average and sum for only one worker
+    LineBuffer buf(phase->_indent_level);
+    buf.append_and_print_cr("[%s:  %.1lf]", phase->_title, _phase_times->get_time_ms(phase_id, 0));
+
+    if (phase->_thread_work_items != NULL) {
+      LineBuffer buf2(phase->_thread_work_items->_indent_level);
+      buf2.append_and_print_cr("[%s:  "SIZE_FORMAT"]", phase->_thread_work_items->_title, _phase_times->sum_thread_work_items(phase_id));
+    }
+  }
+
+  void print_time_values(LineBuffer& buf, G1GCPhaseTimes::GCParPhases phase_id, WorkerDataArray<double>* phase) {
+    for (uint i = 0; i < phase->_length; ++i) {
+      buf.append("  %.1lf", _phase_times->get_time_ms(phase_id, i));
+    }
+    buf.print_cr();
+  }
+
+  void print_count_values(LineBuffer& buf, G1GCPhaseTimes::GCParPhases phase_id, WorkerDataArray<size_t>* thread_work_items) {
+    for (uint i = 0; i < thread_work_items->_length; ++i) {
+      buf.append("  " SIZE_FORMAT, _phase_times->get_thread_work_item(phase_id, i));
+    }
+    buf.print_cr();
+  }
+
+  void print_thread_work_items(G1GCPhaseTimes::GCParPhases phase_id, WorkerDataArray<size_t>* thread_work_items) {
+    LineBuffer buf(thread_work_items->_indent_level);
+    buf.append("[%s:", thread_work_items->_title);
+
+    if (G1Log::finest()) {
+      print_count_values(buf, phase_id, thread_work_items);
+    }
+
+    assert(thread_work_items->_print_sum, err_msg("%s does not have print sum true even though it is a count", thread_work_items->_title));
+
+    buf.append_and_print_cr(" Min: " SIZE_FORMAT ", Avg: %.1lf, Max: " SIZE_FORMAT ", Diff: " SIZE_FORMAT ", Sum: " SIZE_FORMAT "]",
+        _phase_times->min_thread_work_items(phase_id), _phase_times->average_thread_work_items(phase_id), _phase_times->max_thread_work_items(phase_id),
+        _phase_times->max_thread_work_items(phase_id) - _phase_times->min_thread_work_items(phase_id), _phase_times->sum_thread_work_items(phase_id));
+  }
+
+  void print_multi_length(G1GCPhaseTimes::GCParPhases phase_id, WorkerDataArray<double>* phase) {
+    LineBuffer buf(phase->_indent_level);
+    buf.append("[%s:", phase->_title);
+
+    if (G1Log::finest()) {
+      print_time_values(buf, phase_id, phase);
+    }
+
+    buf.append(" Min: %.1lf, Avg: %.1lf, Max: %.1lf, Diff: %.1lf",
+        _phase_times->min_time_ms(phase_id), _phase_times->average_time_ms(phase_id), _phase_times->max_time_ms(phase_id),
+        _phase_times->max_time_ms(phase_id) - _phase_times->min_time_ms(phase_id));
+
+    if (phase->_print_sum) {
+      // for things like the start and end times the sum is not
+      // that relevant
+      buf.append(", Sum: %.1lf", _phase_times->sum_time_ms(phase_id));
+    }
+
+    buf.append_and_print_cr("]");
+
+    if (phase->_thread_work_items != NULL) {
+      print_thread_work_items(phase_id, phase->_thread_work_items);
+    }
+  }
+};
+
 void G1GCPhaseTimes::print(double pause_time_sec) {
+  G1GCParPhasePrinter par_phase_printer(this);
+
   if (_root_region_scan_wait_time_ms > 0.0) {
     print_stats(1, "Root Region Scan Waiting", _root_region_scan_wait_time_ms);
   }
+
   print_stats(1, "Parallel Time", _cur_collection_par_time_ms, _active_gc_threads);
-  _last_gc_worker_start_times_ms.print(2, "GC Worker Start (ms)");
-  _last_ext_root_scan_times_ms.print(2, "Ext Root Scanning (ms)");
-  if (_last_satb_filtering_times_ms.sum() > 0.0) {
-    _last_satb_filtering_times_ms.print(2, "SATB Filtering (ms)");
+  for (int i = 0; i <= GCMainParPhasesLast; i++) {
+    par_phase_printer.print((GCParPhases) i);
   }
-  _last_update_rs_times_ms.print(2, "Update RS (ms)");
-    _last_update_rs_processed_buffers.print(3, "Processed Buffers");
-  _last_scan_rs_times_ms.print(2, "Scan RS (ms)");
-  _last_strong_code_root_scan_times_ms.print(2, "Code Root Scanning (ms)");
-  _last_obj_copy_times_ms.print(2, "Object Copy (ms)");
-  _last_termination_times_ms.print(2, "Termination (ms)");
-  if (G1Log::finest()) {
-    _last_termination_attempts.print(3, "Termination Attempts");
-  }
-  _last_gc_worker_other_times_ms.print(2, "GC Worker Other (ms)");
-  _last_gc_worker_times_ms.print(2, "GC Worker Total (ms)");
-  _last_gc_worker_end_times_ms.print(2, "GC Worker End (ms)");
 
   print_stats(1, "Code Root Fixup", _cur_collection_code_root_fixup_time_ms);
   print_stats(1, "Code Root Purge", _cur_strong_code_root_purge_time_ms);
   if (G1StringDedup::is_enabled()) {
     print_stats(1, "String Dedup Fixup", _cur_string_dedup_fixup_time_ms, _active_gc_threads);
-    _cur_string_dedup_queue_fixup_worker_times_ms.print(2, "Queue Fixup (ms)");
-    _cur_string_dedup_table_fixup_worker_times_ms.print(2, "Table Fixup (ms)");
+    for (int i = StringDedupPhasesFirst; i <= StringDedupPhasesLast; i++) {
+      par_phase_printer.print((GCParPhases) i);
+    }
   }
   print_stats(1, "Clear CT", _cur_clear_ct_time_ms);
   double misc_time_ms = pause_time_sec * MILLIUNITS - accounted_time_ms();
@@ -340,10 +551,7 @@
   print_stats(2, "Ref Proc", _cur_ref_proc_time_ms);
   print_stats(2, "Ref Enq", _cur_ref_enq_time_ms);
   print_stats(2, "Redirty Cards", _recorded_redirty_logged_cards_time_ms);
-  if (G1Log::finest()) {
-    _last_redirty_logged_cards_time_ms.print(3, "Parallel Redirty");
-    _last_redirty_logged_cards_processed_cards.print(3, "Redirtied Cards");
-  }
+  par_phase_printer.print(RedirtyCards);
   if (G1EagerReclaimHumongousObjects) {
     print_stats(2, "Humongous Register", _cur_fast_reclaim_humongous_register_time_ms);
     if (G1Log::finest()) {
@@ -366,3 +574,17 @@
     print_stats(2, "Verify After", _cur_verify_after_time_ms);
   }
 }
+
+G1GCParPhaseTimesTracker::G1GCParPhaseTimesTracker(G1GCPhaseTimes* phase_times, G1GCPhaseTimes::GCParPhases phase, uint worker_id) :
+    _phase_times(phase_times), _phase(phase), _worker_id(worker_id) {
+  if (_phase_times != NULL) {
+    _start_time = os::elapsedTime();
+  }
+}
+
+G1GCParPhaseTimesTracker::~G1GCParPhaseTimesTracker() {
+  if (_phase_times != NULL) {
+    _phase_times->record_time_secs(_phase, _worker_id, os::elapsedTime() - _start_time);
+  }
+}
+
--- a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -26,106 +26,60 @@
 #define SHARE_VM_GC_IMPLEMENTATION_G1_G1GCPHASETIMESLOG_HPP
 
 #include "memory/allocation.hpp"
-#include "gc_interface/gcCause.hpp"
 
-template <class T>
-class WorkerDataArray  : public CHeapObj<mtGC> {
-  T*          _data;
-  uint        _length;
-  const char* _print_format;
-  bool        _print_sum;
+class LineBuffer;
 
-  NOT_PRODUCT(static const T _uninitialized;)
-
-  // We are caching the sum and average to only have to calculate them once.
-  // This is not done in an MT-safe way. It is intended to allow single
-  // threaded code to call sum() and average() multiple times in any order
-  // without having to worry about the cost.
-  bool   _has_new_data;
-  T      _sum;
-  double _average;
-
- public:
-  WorkerDataArray(uint length, const char* print_format, bool print_sum = true) :
-  _length(length), _print_format(print_format), _print_sum(print_sum), _has_new_data(true) {
-    assert(length > 0, "Must have some workers to store data for");
-    _data = NEW_C_HEAP_ARRAY(T, _length, mtGC);
-  }
-
-  ~WorkerDataArray() {
-    FREE_C_HEAP_ARRAY(T, _data);
-  }
-
-  void set(uint worker_i, T value) {
-    assert(worker_i < _length, err_msg("Worker %d is greater than max: %d", worker_i, _length));
-    assert(_data[worker_i] == (T)-1, err_msg("Overwriting data for worker %d", worker_i));
-    _data[worker_i] = value;
-    _has_new_data = true;
-  }
-
-  T get(uint worker_i) {
-    assert(worker_i < _length, err_msg("Worker %d is greater than max: %d", worker_i, _length));
-    assert(_data[worker_i] != (T)-1, err_msg("No data to add to for worker %d", worker_i));
-    return _data[worker_i];
-  }
-
-  void add(uint worker_i, T value) {
-    assert(worker_i < _length, err_msg("Worker %d is greater than max: %d", worker_i, _length));
-    assert(_data[worker_i] != (T)-1, err_msg("No data to add to for worker %d", worker_i));
-    _data[worker_i] += value;
-    _has_new_data = true;
-  }
-
-  double average(){
-    if (_has_new_data) {
-      calculate_totals();
-    }
-    return _average;
-  }
-
-  T sum() {
-    if (_has_new_data) {
-      calculate_totals();
-    }
-    return _sum;
-  }
-
-  void print(int level, const char* title);
-
-  void reset() PRODUCT_RETURN;
-  void verify() PRODUCT_RETURN;
-
- private:
-
-  void calculate_totals(){
-    _sum = (T)0;
-    for (uint i = 0; i < _length; ++i) {
-      _sum += _data[i];
-    }
-    _average = (double)_sum / (double)_length;
-    _has_new_data = false;
-  }
-};
+template <class T> class WorkerDataArray;
 
 class G1GCPhaseTimes : public CHeapObj<mtGC> {
+  friend class G1GCParPhasePrinter;
 
- private:
   uint _active_gc_threads;
   uint _max_gc_threads;
 
-  WorkerDataArray<double> _last_gc_worker_start_times_ms;
-  WorkerDataArray<double> _last_ext_root_scan_times_ms;
-  WorkerDataArray<double> _last_satb_filtering_times_ms;
-  WorkerDataArray<double> _last_update_rs_times_ms;
-  WorkerDataArray<int>    _last_update_rs_processed_buffers;
-  WorkerDataArray<double> _last_scan_rs_times_ms;
-  WorkerDataArray<double> _last_strong_code_root_scan_times_ms;
-  WorkerDataArray<double> _last_obj_copy_times_ms;
-  WorkerDataArray<double> _last_termination_times_ms;
-  WorkerDataArray<size_t> _last_termination_attempts;
-  WorkerDataArray<double> _last_gc_worker_end_times_ms;
-  WorkerDataArray<double> _last_gc_worker_times_ms;
-  WorkerDataArray<double> _last_gc_worker_other_times_ms;
+ public:
+  enum GCParPhases {
+    GCWorkerStart,
+    ExtRootScan,
+    ThreadRoots,
+    StringTableRoots,
+    UniverseRoots,
+    JNIRoots,
+    ObjectSynchronizerRoots,
+    FlatProfilerRoots,
+    ManagementRoots,
+    SystemDictionaryRoots,
+    CLDGRoots,
+    JVMTIRoots,
+    CodeCacheRoots,
+    CMRefRoots,
+    WaitForStrongCLD,
+    WeakCLDRoots,
+    SATBFiltering,
+    UpdateRS,
+    ScanRS,
+    CodeRoots,
+    ObjCopy,
+    Termination,
+    Other,
+    GCWorkerTotal,
+    GCWorkerEnd,
+    StringDedupQueueFixup,
+    StringDedupTableFixup,
+    RedirtyCards,
+    GCParPhasesSentinel
+  };
+
+ private:
+  // Markers for grouping the phases in the GCPhases enum above
+  static const int GCMainParPhasesLast = GCWorkerEnd;
+  static const int StringDedupPhasesFirst = StringDedupQueueFixup;
+  static const int StringDedupPhasesLast = StringDedupTableFixup;
+
+  WorkerDataArray<double>* _gc_par_phases[GCParPhasesSentinel];
+  WorkerDataArray<size_t>* _update_rs_processed_buffers;
+  WorkerDataArray<size_t>* _termination_attempts;
+  WorkerDataArray<size_t>* _redirtied_cards;
 
   double _cur_collection_par_time_ms;
   double _cur_collection_code_root_fixup_time_ms;
@@ -135,9 +89,7 @@
   double _cur_evac_fail_restore_remsets;
   double _cur_evac_fail_remove_self_forwards;
 
-  double                  _cur_string_dedup_fixup_time_ms;
-  WorkerDataArray<double> _cur_string_dedup_queue_fixup_worker_times_ms;
-  WorkerDataArray<double> _cur_string_dedup_table_fixup_worker_times_ms;
+  double _cur_string_dedup_fixup_time_ms;
 
   double _cur_clear_ct_time_ms;
   double _cur_ref_proc_time_ms;
@@ -149,8 +101,6 @@
   double _recorded_young_cset_choice_time_ms;
   double _recorded_non_young_cset_choice_time_ms;
 
-  WorkerDataArray<double> _last_redirty_logged_cards_time_ms;
-  WorkerDataArray<size_t> _last_redirty_logged_cards_processed_cards;
   double _recorded_redirty_logged_cards_time_ms;
 
   double _recorded_young_free_cset_time_ms;
@@ -172,54 +122,34 @@
 
  public:
   G1GCPhaseTimes(uint max_gc_threads);
-  void note_gc_start(uint active_gc_threads);
+  void note_gc_start(uint active_gc_threads, bool mark_in_progress);
   void note_gc_end();
   void print(double pause_time_sec);
 
-  void record_gc_worker_start_time(uint worker_i, double ms) {
-    _last_gc_worker_start_times_ms.set(worker_i, ms);
-  }
+  // record the time a phase took in seconds
+  void record_time_secs(GCParPhases phase, uint worker_i, double secs);
 
-  void record_ext_root_scan_time(uint worker_i, double ms) {
-    _last_ext_root_scan_times_ms.set(worker_i, ms);
-  }
+  // add a number of seconds to a phase
+  void add_time_secs(GCParPhases phase, uint worker_i, double secs);
 
-  void record_satb_filtering_time(uint worker_i, double ms) {
-    _last_satb_filtering_times_ms.set(worker_i, ms);
-  }
+  void record_thread_work_item(GCParPhases phase, uint worker_i, size_t count);
 
-  void record_update_rs_time(uint worker_i, double ms) {
-    _last_update_rs_times_ms.set(worker_i, ms);
-  }
+  // return the average time for a phase in milliseconds
+  double average_time_ms(GCParPhases phase);
 
-  void record_update_rs_processed_buffers(uint worker_i, int processed_buffers) {
-    _last_update_rs_processed_buffers.set(worker_i, processed_buffers);
-  }
+  size_t sum_thread_work_items(GCParPhases phase);
 
-  void record_scan_rs_time(uint worker_i, double ms) {
-    _last_scan_rs_times_ms.set(worker_i, ms);
-  }
+ private:
+  double get_time_ms(GCParPhases phase, uint worker_i);
+  double sum_time_ms(GCParPhases phase);
+  double min_time_ms(GCParPhases phase);
+  double max_time_ms(GCParPhases phase);
+  size_t get_thread_work_item(GCParPhases phase, uint worker_i);
+  double average_thread_work_items(GCParPhases phase);
+  size_t min_thread_work_items(GCParPhases phase);
+  size_t max_thread_work_items(GCParPhases phase);
 
-  void record_strong_code_root_scan_time(uint worker_i, double ms) {
-    _last_strong_code_root_scan_times_ms.set(worker_i, ms);
-  }
-
-  void record_obj_copy_time(uint worker_i, double ms) {
-    _last_obj_copy_times_ms.set(worker_i, ms);
-  }
-
-  void add_obj_copy_time(uint worker_i, double ms) {
-    _last_obj_copy_times_ms.add(worker_i, ms);
-  }
-
-  void record_termination(uint worker_i, double ms, size_t attempts) {
-    _last_termination_times_ms.set(worker_i, ms);
-    _last_termination_attempts.set(worker_i, attempts);
-  }
-
-  void record_gc_worker_end_time(uint worker_i, double ms) {
-    _last_gc_worker_end_times_ms.set(worker_i, ms);
-  }
+ public:
 
   void record_clear_ct_time(double ms) {
     _cur_clear_ct_time_ms = ms;
@@ -249,21 +179,10 @@
     _cur_evac_fail_remove_self_forwards = ms;
   }
 
-  void note_string_dedup_fixup_start();
-  void note_string_dedup_fixup_end();
-
   void record_string_dedup_fixup_time(double ms) {
     _cur_string_dedup_fixup_time_ms = ms;
   }
 
-  void record_string_dedup_queue_fixup_worker_time(uint worker_id, double ms) {
-    _cur_string_dedup_queue_fixup_worker_times_ms.set(worker_id, ms);
-  }
-
-  void record_string_dedup_table_fixup_worker_time(uint worker_id, double ms) {
-    _cur_string_dedup_table_fixup_worker_times_ms.set(worker_id, ms);
-  }
-
   void record_ref_proc_time(double ms) {
     _cur_ref_proc_time_ms = ms;
   }
@@ -303,14 +222,6 @@
     _recorded_non_young_cset_choice_time_ms = time_ms;
   }
 
-  void record_redirty_logged_cards_time_ms(uint worker_i, double time_ms) {
-    _last_redirty_logged_cards_time_ms.set(worker_i, time_ms);
-  }
-
-  void record_redirty_logged_cards_processed_cards(uint worker_i, size_t processed_buffers) {
-    _last_redirty_logged_cards_processed_cards.set(worker_i, processed_buffers);
-  }
-
   void record_redirty_logged_cards_time_ms(double time_ms) {
     _recorded_redirty_logged_cards_time_ms = time_ms;
   }
@@ -364,38 +275,16 @@
   double fast_reclaim_humongous_time_ms() {
     return _cur_fast_reclaim_humongous_time_ms;
   }
+};
 
-  double average_last_update_rs_time() {
-    return _last_update_rs_times_ms.average();
-  }
-
-  int sum_last_update_rs_processed_buffers() {
-    return _last_update_rs_processed_buffers.sum();
-  }
-
-  double average_last_scan_rs_time(){
-    return _last_scan_rs_times_ms.average();
-  }
-
-  double average_last_strong_code_root_scan_time(){
-    return _last_strong_code_root_scan_times_ms.average();
-  }
-
-  double average_last_obj_copy_time() {
-    return _last_obj_copy_times_ms.average();
-  }
-
-  double average_last_termination_time() {
-    return _last_termination_times_ms.average();
-  }
-
-  double average_last_ext_root_scan_time() {
-    return _last_ext_root_scan_times_ms.average();
-  }
-
-  double average_last_satb_filtering_times_ms() {
-    return _last_satb_filtering_times_ms.average();
-  }
+class G1GCParPhaseTimesTracker : public StackObj {
+  double _start_time;
+  G1GCPhaseTimes::GCParPhases _phase;
+  G1GCPhaseTimes* _phase_times;
+  uint _worker_id;
+public:
+  G1GCParPhaseTimesTracker(G1GCPhaseTimes* phase_times, G1GCPhaseTimes::GCParPhases phase, uint worker_id);
+  ~G1GCParPhaseTimesTracker();
 };
 
 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1GCPHASETIMESLOG_HPP
--- a/hotspot/src/share/vm/gc_implementation/g1/g1Log.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1Log.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -28,6 +28,7 @@
 #include "memory/allocation.hpp"
 
 class G1Log : public AllStatic {
+ public:
   typedef enum {
     LevelNone,
     LevelFine,
@@ -35,6 +36,7 @@
     LevelFinest
   } LogLevel;
 
+ private:
   static LogLevel _level;
 
  public:
@@ -50,6 +52,10 @@
     return _level == LevelFinest;
   }
 
+  static LogLevel level() {
+    return _level;
+  }
+
   static void init();
 };
 
--- a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -31,6 +31,7 @@
 #include "code/icBuffer.hpp"
 #include "gc_implementation/g1/g1Log.hpp"
 #include "gc_implementation/g1/g1MarkSweep.hpp"
+#include "gc_implementation/g1/g1RootProcessor.hpp"
 #include "gc_implementation/g1/g1StringDedup.hpp"
 #include "gc_implementation/shared/gcHeapSummary.hpp"
 #include "gc_implementation/shared/gcTimer.hpp"
@@ -125,21 +126,22 @@
   GCTraceTime tm("phase 1", G1Log::fine() && Verbose, true, gc_timer(), gc_tracer()->gc_id());
   GenMarkSweep::trace(" 1");
 
-  SharedHeap* sh = SharedHeap::heap();
+  G1CollectedHeap* g1h = G1CollectedHeap::heap();
 
   // Need cleared claim bits for the roots processing
   ClassLoaderDataGraph::clear_claimed_marks();
 
   MarkingCodeBlobClosure follow_code_closure(&GenMarkSweep::follow_root_closure, !CodeBlobToOopClosure::FixRelocations);
-  sh->process_strong_roots(true,   // activate StrongRootsScope
-                           SharedHeap::SO_None,
-                           &GenMarkSweep::follow_root_closure,
-                           &GenMarkSweep::follow_cld_closure,
-                           &follow_code_closure);
+  {
+    G1RootProcessor root_processor(g1h);
+    root_processor.process_strong_roots(&GenMarkSweep::follow_root_closure,
+                                        &GenMarkSweep::follow_cld_closure,
+                                        &follow_code_closure);
+  }
 
   // Process reference objects found during marking
   ReferenceProcessor* rp = GenMarkSweep::ref_processor();
-  assert(rp == G1CollectedHeap::heap()->ref_processor_stw(), "Sanity");
+  assert(rp == g1h->ref_processor_stw(), "Sanity");
 
   rp->setup_policy(clear_all_softrefs);
   const ReferenceProcessorStats& stats =
@@ -225,6 +227,12 @@
   }
 };
 
+class G1AlwaysTrueClosure: public BoolObjectClosure {
+public:
+  bool do_object_b(oop p) { return true; }
+};
+static G1AlwaysTrueClosure always_true;
+
 void G1MarkSweep::mark_sweep_phase3() {
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
 
@@ -232,24 +240,23 @@
   GCTraceTime tm("phase 3", G1Log::fine() && Verbose, true, gc_timer(), gc_tracer()->gc_id());
   GenMarkSweep::trace("3");
 
-  SharedHeap* sh = SharedHeap::heap();
-
   // Need cleared claim bits for the roots processing
   ClassLoaderDataGraph::clear_claimed_marks();
 
   CodeBlobToOopClosure adjust_code_closure(&GenMarkSweep::adjust_pointer_closure, CodeBlobToOopClosure::FixRelocations);
-  sh->process_all_roots(true,  // activate StrongRootsScope
-                        SharedHeap::SO_AllCodeCache,
-                        &GenMarkSweep::adjust_pointer_closure,
-                        &GenMarkSweep::adjust_cld_closure,
-                        &adjust_code_closure);
+  {
+    G1RootProcessor root_processor(g1h);
+    root_processor.process_all_roots(&GenMarkSweep::adjust_pointer_closure,
+                                     &GenMarkSweep::adjust_cld_closure,
+                                     &adjust_code_closure);
+  }
 
   assert(GenMarkSweep::ref_processor() == g1h->ref_processor_stw(), "Sanity");
   g1h->ref_processor_stw()->weak_oops_do(&GenMarkSweep::adjust_pointer_closure);
 
   // Now adjust pointers in remaining weak roots.  (All of which should
   // have been cleared if they pointed to non-surviving objects.)
-  sh->process_weak_roots(&GenMarkSweep::adjust_pointer_closure);
+  JNIHandles::weak_oops_do(&always_true, &GenMarkSweep::adjust_pointer_closure);
 
   if (G1StringDedup::is_enabled()) {
     G1StringDedup::oops_do(&GenMarkSweep::adjust_pointer_closure);
--- a/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -109,6 +109,18 @@
   template <class T> void do_klass_barrier(T* p, oop new_obj);
 };
 
+enum G1Barrier {
+  G1BarrierNone,
+  G1BarrierEvac,
+  G1BarrierKlass
+};
+
+enum G1Mark {
+  G1MarkNone,
+  G1MarkFromRoot,
+  G1MarkPromotedFromRoot
+};
+
 template <G1Barrier barrier, G1Mark do_mark_object>
 class G1ParCopyClosure : public G1ParCopyHelper {
 private:
--- a/hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, 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
@@ -226,6 +226,8 @@
   }
 
   assert(obj_ptr != NULL, "when we get here, allocation should have succeeded");
+  assert(_g1h->is_in_reserved(obj_ptr), "Allocated memory should be in the heap");
+
 #ifndef PRODUCT
   // Should this evacuation fail?
   if (_g1h->evacuation_should_fail()) {
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RegionToSpaceMapper.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RegionToSpaceMapper.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, 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
@@ -57,6 +57,9 @@
  public:
   MemRegion reserved() { return _storage.reserved(); }
 
+  size_t reserved_size() { return _storage.reserved_size(); }
+  size_t committed_size() { return _storage.committed_size(); }
+
   void set_mapping_changed_listener(G1MappingChangedListener* listener) { _listener = listener; }
 
   virtual ~G1RegionToSpaceMapper() {
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, 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
@@ -79,7 +79,6 @@
     _cards_scanned(NULL), _total_cards_scanned(0),
     _prev_period_summary()
 {
-  _seq_task = new SubTasksDone(NumSeqTasks);
   _cset_rs_update_cl = NEW_C_HEAP_ARRAY(G1ParPushHeapRSClosure*, n_workers(), mtGC);
   for (uint i = 0; i < n_workers(); i++) {
     _cset_rs_update_cl[i] = NULL;
@@ -90,7 +89,6 @@
 }
 
 G1RemSet::~G1RemSet() {
-  delete _seq_task;
   for (uint i = 0; i < n_workers(); i++) {
     assert(_cset_rs_update_cl[i] == NULL, "it should be");
   }
@@ -109,7 +107,7 @@
 
   double _strong_code_root_scan_time_sec;
   uint   _worker_i;
-  int    _block_size;
+  size_t _block_size;
   bool   _try_claimed;
 
 public:
@@ -127,7 +125,7 @@
     _g1h = G1CollectedHeap::heap();
     _bot_shared = _g1h->bot_shared();
     _ct_bs = _g1h->g1_barrier_set();
-    _block_size = MAX2<int>(G1RSetScanBlockSize, 1);
+    _block_size = MAX2<size_t>(G1RSetScanBlockSize, 1);
   }
 
   void set_try_claimed() { _try_claimed = true; }
@@ -248,9 +246,8 @@
   assert(_cards_scanned != NULL, "invariant");
   _cards_scanned[worker_i] = scanRScl.cards_done();
 
-  _g1p->phase_times()->record_scan_rs_time(worker_i, scan_rs_time_sec * 1000.0);
-  _g1p->phase_times()->record_strong_code_root_scan_time(worker_i,
-                                                         scanRScl.strong_code_root_scan_time_sec() * 1000.0);
+  _g1p->phase_times()->record_time_secs(G1GCPhaseTimes::ScanRS, worker_i, scan_rs_time_sec);
+  _g1p->phase_times()->record_time_secs(G1GCPhaseTimes::CodeRoots, worker_i, scanRScl.strong_code_root_scan_time_sec());
 }
 
 // Closure used for updating RSets and recording references that
@@ -287,13 +284,11 @@
 };
 
 void G1RemSet::updateRS(DirtyCardQueue* into_cset_dcq, uint worker_i) {
-  double start = os::elapsedTime();
+  G1GCParPhaseTimesTracker x(_g1p->phase_times(), G1GCPhaseTimes::UpdateRS, worker_i);
   // Apply the given closure to all remaining log entries.
   RefineRecordRefsIntoCSCardTableEntryClosure into_cset_update_rs_cl(_g1, into_cset_dcq);
 
   _g1->iterate_dirty_card_closure(&into_cset_update_rs_cl, into_cset_dcq, false, worker_i);
-
-  _g1p->phase_times()->record_update_rs_time(worker_i, (os::elapsedTime() - start) * 1000.0);
 }
 
 void G1RemSet::cleanupHRRS() {
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -58,7 +58,6 @@
   };
 
   CardTableModRefBS*     _ct_bs;
-  SubTasksDone*          _seq_task;
   G1CollectorPolicy*     _g1p;
 
   ConcurrentG1Refine*    _cg1r;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RootProcessor.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -0,0 +1,337 @@
+/*
+ * Copyright (c) 2015, 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 "classfile/stringTable.hpp"
+#include "classfile/systemDictionary.hpp"
+#include "code/codeCache.hpp"
+#include "gc_implementation/g1/bufferingOopClosure.hpp"
+#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
+#include "gc_implementation/g1/g1CollectorPolicy.hpp"
+#include "gc_implementation/g1/g1GCPhaseTimes.hpp"
+#include "gc_implementation/g1/g1RemSet.inline.hpp"
+#include "gc_implementation/g1/g1RootProcessor.hpp"
+#include "memory/allocation.inline.hpp"
+#include "runtime/fprofiler.hpp"
+#include "runtime/mutex.hpp"
+#include "services/management.hpp"
+
+class G1CodeBlobClosure : public CodeBlobClosure {
+  class HeapRegionGatheringOopClosure : public OopClosure {
+    G1CollectedHeap* _g1h;
+    OopClosure* _work;
+    nmethod* _nm;
+
+    template <typename T>
+    void do_oop_work(T* p) {
+      _work->do_oop(p);
+      T oop_or_narrowoop = oopDesc::load_heap_oop(p);
+      if (!oopDesc::is_null(oop_or_narrowoop)) {
+        oop o = oopDesc::decode_heap_oop_not_null(oop_or_narrowoop);
+        HeapRegion* hr = _g1h->heap_region_containing_raw(o);
+        assert(!_g1h->obj_in_cs(o) || hr->rem_set()->strong_code_roots_list_contains(_nm), "if o still in CS then evacuation failed and nm must already be in the remset");
+        hr->add_strong_code_root(_nm);
+      }
+    }
+
+  public:
+    HeapRegionGatheringOopClosure(OopClosure* oc) : _g1h(G1CollectedHeap::heap()), _work(oc), _nm(NULL) {}
+
+    void do_oop(oop* o) {
+      do_oop_work(o);
+    }
+
+    void do_oop(narrowOop* o) {
+      do_oop_work(o);
+    }
+
+    void set_nm(nmethod* nm) {
+      _nm = nm;
+    }
+  };
+
+  HeapRegionGatheringOopClosure _oc;
+public:
+  G1CodeBlobClosure(OopClosure* oc) : _oc(oc) {}
+
+  void do_code_blob(CodeBlob* cb) {
+    nmethod* nm = cb->as_nmethod_or_null();
+    if (nm != NULL) {
+      if (!nm->test_set_oops_do_mark()) {
+        _oc.set_nm(nm);
+        nm->oops_do(&_oc);
+        nm->fix_oop_relocations();
+      }
+    }
+  }
+};
+
+
+void G1RootProcessor::worker_has_discovered_all_strong_classes() {
+  uint n_workers = _g1h->n_par_threads();
+  assert(ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading");
+
+  uint new_value = (uint)Atomic::add(1, &_n_workers_discovered_strong_classes);
+  if (new_value == n_workers) {
+    // This thread is last. Notify the others.
+    MonitorLockerEx ml(&_lock, Mutex::_no_safepoint_check_flag);
+    _lock.notify_all();
+  }
+}
+
+void G1RootProcessor::wait_until_all_strong_classes_discovered() {
+  uint n_workers = _g1h->n_par_threads();
+  assert(ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading");
+
+  if ((uint)_n_workers_discovered_strong_classes != n_workers) {
+    MonitorLockerEx ml(&_lock, Mutex::_no_safepoint_check_flag);
+    while ((uint)_n_workers_discovered_strong_classes != n_workers) {
+      _lock.wait(Mutex::_no_safepoint_check_flag, 0, false);
+    }
+  }
+}
+
+G1RootProcessor::G1RootProcessor(G1CollectedHeap* g1h) :
+    _g1h(g1h),
+    _process_strong_tasks(new SubTasksDone(G1RP_PS_NumElements)),
+    _srs(g1h),
+    _lock(Mutex::leaf, "G1 Root Scanning barrier lock", false, Monitor::_safepoint_check_never),
+    _n_workers_discovered_strong_classes(0) {}
+
+void G1RootProcessor::evacuate_roots(OopClosure* scan_non_heap_roots,
+                                     OopClosure* scan_non_heap_weak_roots,
+                                     CLDClosure* scan_strong_clds,
+                                     CLDClosure* scan_weak_clds,
+                                     bool trace_metadata,
+                                     uint worker_i) {
+  // First scan the shared roots.
+  double ext_roots_start = os::elapsedTime();
+  G1GCPhaseTimes* phase_times = _g1h->g1_policy()->phase_times();
+
+  BufferingOopClosure buf_scan_non_heap_roots(scan_non_heap_roots);
+  BufferingOopClosure buf_scan_non_heap_weak_roots(scan_non_heap_weak_roots);
+
+  OopClosure* const weak_roots = &buf_scan_non_heap_weak_roots;
+  OopClosure* const strong_roots = &buf_scan_non_heap_roots;
+
+  // CodeBlobClosures are not interoperable with BufferingOopClosures
+  G1CodeBlobClosure root_code_blobs(scan_non_heap_roots);
+
+  process_java_roots(strong_roots,
+                     trace_metadata ? scan_strong_clds : NULL,
+                     scan_strong_clds,
+                     trace_metadata ? NULL : scan_weak_clds,
+                     &root_code_blobs,
+                     phase_times,
+                     worker_i);
+
+  // This is the point where this worker thread will not find more strong CLDs/nmethods.
+  // Report this so G1 can synchronize the strong and weak CLDs/nmethods processing.
+  if (trace_metadata) {
+    worker_has_discovered_all_strong_classes();
+  }
+
+  process_vm_roots(strong_roots, weak_roots, phase_times, worker_i);
+
+  {
+    // Now the CM ref_processor roots.
+    G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::CMRefRoots, worker_i);
+    if (!_process_strong_tasks->is_task_claimed(G1RP_PS_refProcessor_oops_do)) {
+      // We need to treat the discovered reference lists of the
+      // concurrent mark ref processor as roots and keep entries
+      // (which are added by the marking threads) on them live
+      // until they can be processed at the end of marking.
+      _g1h->ref_processor_cm()->weak_oops_do(&buf_scan_non_heap_roots);
+    }
+  }
+
+  if (trace_metadata) {
+    {
+      G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::WaitForStrongCLD, worker_i);
+      // Barrier to make sure all workers passed
+      // the strong CLD and strong nmethods phases.
+      wait_until_all_strong_classes_discovered();
+    }
+
+    // Now take the complement of the strong CLDs.
+    G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::WeakCLDRoots, worker_i);
+    ClassLoaderDataGraph::roots_cld_do(NULL, scan_weak_clds);
+  } else {
+    phase_times->record_time_secs(G1GCPhaseTimes::WaitForStrongCLD, worker_i, 0.0);
+    phase_times->record_time_secs(G1GCPhaseTimes::WeakCLDRoots, worker_i, 0.0);
+  }
+
+  // Finish up any enqueued closure apps (attributed as object copy time).
+  buf_scan_non_heap_roots.done();
+  buf_scan_non_heap_weak_roots.done();
+
+  double obj_copy_time_sec = buf_scan_non_heap_roots.closure_app_seconds()
+      + buf_scan_non_heap_weak_roots.closure_app_seconds();
+
+  phase_times->record_time_secs(G1GCPhaseTimes::ObjCopy, worker_i, obj_copy_time_sec);
+
+  double ext_root_time_sec = os::elapsedTime() - ext_roots_start - obj_copy_time_sec;
+
+  phase_times->record_time_secs(G1GCPhaseTimes::ExtRootScan, worker_i, ext_root_time_sec);
+
+  // During conc marking we have to filter the per-thread SATB buffers
+  // to make sure we remove any oops into the CSet (which will show up
+  // as implicitly live).
+  {
+    G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::SATBFiltering, worker_i);
+    if (!_process_strong_tasks->is_task_claimed(G1RP_PS_filter_satb_buffers) && _g1h->mark_in_progress()) {
+      JavaThread::satb_mark_queue_set().filter_thread_buffers();
+    }
+  }
+
+  _process_strong_tasks->all_tasks_completed();
+}
+
+void G1RootProcessor::process_strong_roots(OopClosure* oops,
+                                           CLDClosure* clds,
+                                           CodeBlobClosure* blobs) {
+
+  process_java_roots(oops, clds, clds, NULL, blobs, NULL, 0);
+  process_vm_roots(oops, NULL, NULL, 0);
+
+  _process_strong_tasks->all_tasks_completed();
+}
+
+void G1RootProcessor::process_all_roots(OopClosure* oops,
+                                        CLDClosure* clds,
+                                        CodeBlobClosure* blobs) {
+
+  process_java_roots(oops, NULL, clds, clds, NULL, NULL, 0);
+  process_vm_roots(oops, oops, NULL, 0);
+
+  if (!_process_strong_tasks->is_task_claimed(G1RP_PS_CodeCache_oops_do)) {
+    CodeCache::blobs_do(blobs);
+  }
+
+  _process_strong_tasks->all_tasks_completed();
+}
+
+void G1RootProcessor::process_java_roots(OopClosure* strong_roots,
+                                         CLDClosure* thread_stack_clds,
+                                         CLDClosure* strong_clds,
+                                         CLDClosure* weak_clds,
+                                         CodeBlobClosure* strong_code,
+                                         G1GCPhaseTimes* phase_times,
+                                         uint worker_i) {
+  assert(thread_stack_clds == NULL || weak_clds == NULL, "There is overlap between those, only one may be set");
+  // Iterating over the CLDG and the Threads are done early to allow us to
+  // first process the strong CLDs and nmethods and then, after a barrier,
+  // let the thread process the weak CLDs and nmethods.
+  {
+    G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::CLDGRoots, worker_i);
+    if (!_process_strong_tasks->is_task_claimed(G1RP_PS_ClassLoaderDataGraph_oops_do)) {
+      ClassLoaderDataGraph::roots_cld_do(strong_clds, weak_clds);
+    }
+  }
+
+  {
+    G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::ThreadRoots, worker_i);
+    Threads::possibly_parallel_oops_do(strong_roots, thread_stack_clds, strong_code);
+  }
+}
+
+void G1RootProcessor::process_vm_roots(OopClosure* strong_roots,
+                                       OopClosure* weak_roots,
+                                       G1GCPhaseTimes* phase_times,
+                                       uint worker_i) {
+  {
+    G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::UniverseRoots, worker_i);
+    if (!_process_strong_tasks->is_task_claimed(G1RP_PS_Universe_oops_do)) {
+      Universe::oops_do(strong_roots);
+    }
+  }
+
+  {
+    G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::JNIRoots, worker_i);
+    if (!_process_strong_tasks->is_task_claimed(G1RP_PS_JNIHandles_oops_do)) {
+      JNIHandles::oops_do(strong_roots);
+    }
+  }
+
+  {
+    G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::ObjectSynchronizerRoots, worker_i);
+    if (!_process_strong_tasks-> is_task_claimed(G1RP_PS_ObjectSynchronizer_oops_do)) {
+      ObjectSynchronizer::oops_do(strong_roots);
+    }
+  }
+
+  {
+    G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::FlatProfilerRoots, worker_i);
+    if (!_process_strong_tasks->is_task_claimed(G1RP_PS_FlatProfiler_oops_do)) {
+      FlatProfiler::oops_do(strong_roots);
+    }
+  }
+
+  {
+    G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::ManagementRoots, worker_i);
+    if (!_process_strong_tasks->is_task_claimed(G1RP_PS_Management_oops_do)) {
+      Management::oops_do(strong_roots);
+    }
+  }
+
+  {
+    G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::JVMTIRoots, worker_i);
+    if (!_process_strong_tasks->is_task_claimed(G1RP_PS_jvmti_oops_do)) {
+      JvmtiExport::oops_do(strong_roots);
+    }
+  }
+
+  {
+    G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::SystemDictionaryRoots, worker_i);
+    if (!_process_strong_tasks->is_task_claimed(G1RP_PS_SystemDictionary_oops_do)) {
+      SystemDictionary::roots_oops_do(strong_roots, weak_roots);
+    }
+  }
+
+  {
+    G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::StringTableRoots, worker_i);
+    // All threads execute the following. A specific chunk of buckets
+    // from the StringTable are the individual tasks.
+    if (weak_roots != NULL) {
+      StringTable::possibly_parallel_oops_do(weak_roots);
+    }
+  }
+}
+
+void G1RootProcessor::scan_remembered_sets(G1ParPushHeapRSClosure* scan_rs,
+                                           OopClosure* scan_non_heap_weak_roots,
+                                           uint worker_i) {
+  G1GCPhaseTimes* phase_times = _g1h->g1_policy()->phase_times();
+  G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::CodeCacheRoots, worker_i);
+
+  // Now scan the complement of the collection set.
+  G1CodeBlobClosure scavenge_cs_nmethods(scan_non_heap_weak_roots);
+
+  _g1h->g1_rem_set()->oops_into_collection_set_do(scan_rs, &scavenge_cs_nmethods, worker_i);
+}
+
+void G1RootProcessor::set_num_workers(int active_workers) {
+  _process_strong_tasks->set_n_threads(active_workers);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RootProcessor.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2015, 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_GC_IMPLEMENTATION_G1_ROOTPROCESSOR_HPP
+#define SHARE_VM_GC_IMPLEMENTATION_G1_ROOTPROCESSOR_HPP
+
+#include "memory/allocation.hpp"
+#include "memory/sharedHeap.hpp"
+#include "runtime/mutex.hpp"
+
+class CLDClosure;
+class CodeBlobClosure;
+class G1CollectedHeap;
+class G1GCPhaseTimes;
+class G1ParPushHeapRSClosure;
+class Monitor;
+class OopClosure;
+class SubTasksDone;
+
+// Scoped object to assist in applying oop, CLD and code blob closures to
+// root locations. Handles claiming of different root scanning tasks
+// and takes care of global state for root scanning via a StrongRootsScope.
+// In the parallel case there is a shared G1RootProcessor object where all
+// worker thread call the process_roots methods.
+class G1RootProcessor : public StackObj {
+  G1CollectedHeap* _g1h;
+  SubTasksDone* _process_strong_tasks;
+  SharedHeap::StrongRootsScope _srs;
+
+  // Used to implement the Thread work barrier.
+  Monitor _lock;
+  volatile jint _n_workers_discovered_strong_classes;
+
+  enum G1H_process_roots_tasks {
+    G1RP_PS_Universe_oops_do,
+    G1RP_PS_JNIHandles_oops_do,
+    G1RP_PS_ObjectSynchronizer_oops_do,
+    G1RP_PS_FlatProfiler_oops_do,
+    G1RP_PS_Management_oops_do,
+    G1RP_PS_SystemDictionary_oops_do,
+    G1RP_PS_ClassLoaderDataGraph_oops_do,
+    G1RP_PS_jvmti_oops_do,
+    G1RP_PS_CodeCache_oops_do,
+    G1RP_PS_filter_satb_buffers,
+    G1RP_PS_refProcessor_oops_do,
+    // Leave this one last.
+    G1RP_PS_NumElements
+  };
+
+  void worker_has_discovered_all_strong_classes();
+  void wait_until_all_strong_classes_discovered();
+
+  void process_java_roots(OopClosure* scan_non_heap_roots,
+                          CLDClosure* thread_stack_clds,
+                          CLDClosure* scan_strong_clds,
+                          CLDClosure* scan_weak_clds,
+                          CodeBlobClosure* scan_strong_code,
+                          G1GCPhaseTimes* phase_times,
+                          uint worker_i);
+
+  void process_vm_roots(OopClosure* scan_non_heap_roots,
+                        OopClosure* scan_non_heap_weak_roots,
+                        G1GCPhaseTimes* phase_times,
+                        uint worker_i);
+
+public:
+  G1RootProcessor(G1CollectedHeap* g1h);
+
+  // Apply closures to the strongly and weakly reachable roots in the system
+  // in a single pass.
+  // Record and report timing measurements for sub phases using the worker_i
+  void evacuate_roots(OopClosure* scan_non_heap_roots,
+                      OopClosure* scan_non_heap_weak_roots,
+                      CLDClosure* scan_strong_clds,
+                      CLDClosure* scan_weak_clds,
+                      bool trace_metadata,
+                      uint worker_i);
+
+  // Apply oops, clds and blobs to all strongly reachable roots in the system
+  void process_strong_roots(OopClosure* oops,
+                            CLDClosure* clds,
+                            CodeBlobClosure* blobs);
+
+  // Apply oops, clds and blobs to strongly and weakly reachable roots in the system
+  void process_all_roots(OopClosure* oops,
+                         CLDClosure* clds,
+                         CodeBlobClosure* blobs);
+
+  // Apply scan_rs to all locations in the union of the remembered sets for all
+  // regions in the collection set
+  // (having done "set_region" to indicate the region in which the root resides),
+  void scan_remembered_sets(G1ParPushHeapRSClosure* scan_rs,
+                            OopClosure* scan_non_heap_weak_roots,
+                            uint worker_i);
+
+  // Inform the root processor about the number of worker threads
+  void set_num_workers(int active_workers);
+};
+
+#endif // SHARE_VM_GC_IMPLEMENTATION_G1_ROOTPROCESSOR_HPP
--- a/hotspot/src/share/vm/gc_implementation/g1/g1StringDedup.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1StringDedup.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -106,7 +106,7 @@
 
 void G1StringDedup::oops_do(OopClosure* keep_alive) {
   assert(is_enabled(), "String deduplication not enabled");
-  unlink_or_oops_do(NULL, keep_alive);
+  unlink_or_oops_do(NULL, keep_alive, true /* allow_resize_and_rehash */);
 }
 
 void G1StringDedup::unlink(BoolObjectClosure* is_alive) {
@@ -123,45 +123,39 @@
 class G1StringDedupUnlinkOrOopsDoTask : public AbstractGangTask {
 private:
   G1StringDedupUnlinkOrOopsDoClosure _cl;
+  G1GCPhaseTimes* _phase_times;
 
 public:
   G1StringDedupUnlinkOrOopsDoTask(BoolObjectClosure* is_alive,
                                   OopClosure* keep_alive,
-                                  bool allow_resize_and_rehash) :
+                                  bool allow_resize_and_rehash,
+                                  G1GCPhaseTimes* phase_times) :
     AbstractGangTask("G1StringDedupUnlinkOrOopsDoTask"),
-    _cl(is_alive, keep_alive, allow_resize_and_rehash) {
-  }
+    _cl(is_alive, keep_alive, allow_resize_and_rehash), _phase_times(phase_times) { }
 
   virtual void work(uint worker_id) {
-    double queue_fixup_start = os::elapsedTime();
-    G1StringDedupQueue::unlink_or_oops_do(&_cl);
-
-    double table_fixup_start = os::elapsedTime();
-    G1StringDedupTable::unlink_or_oops_do(&_cl, worker_id);
-
-    double queue_fixup_time_ms = (table_fixup_start - queue_fixup_start) * 1000.0;
-    double table_fixup_time_ms = (os::elapsedTime() - table_fixup_start) * 1000.0;
-    G1CollectorPolicy* g1p = G1CollectedHeap::heap()->g1_policy();
-    g1p->phase_times()->record_string_dedup_queue_fixup_worker_time(worker_id, queue_fixup_time_ms);
-    g1p->phase_times()->record_string_dedup_table_fixup_worker_time(worker_id, table_fixup_time_ms);
+    {
+      G1GCParPhaseTimesTracker x(_phase_times, G1GCPhaseTimes::StringDedupQueueFixup, worker_id);
+      G1StringDedupQueue::unlink_or_oops_do(&_cl);
+    }
+    {
+      G1GCParPhaseTimesTracker x(_phase_times, G1GCPhaseTimes::StringDedupTableFixup, worker_id);
+      G1StringDedupTable::unlink_or_oops_do(&_cl, worker_id);
+    }
   }
 };
 
-void G1StringDedup::unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, bool allow_resize_and_rehash) {
+void G1StringDedup::unlink_or_oops_do(BoolObjectClosure* is_alive,
+                                      OopClosure* keep_alive,
+                                      bool allow_resize_and_rehash,
+                                      G1GCPhaseTimes* phase_times) {
   assert(is_enabled(), "String deduplication not enabled");
-  G1CollectorPolicy* g1p = G1CollectedHeap::heap()->g1_policy();
-  g1p->phase_times()->note_string_dedup_fixup_start();
-  double fixup_start = os::elapsedTime();
 
-  G1StringDedupUnlinkOrOopsDoTask task(is_alive, keep_alive, allow_resize_and_rehash);
+  G1StringDedupUnlinkOrOopsDoTask task(is_alive, keep_alive, allow_resize_and_rehash, phase_times);
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
   g1h->set_par_threads();
   g1h->workers()->run_task(&task);
   g1h->set_par_threads(0);
-
-  double fixup_time_ms = (os::elapsedTime() - fixup_start) * 1000.0;
-  g1p->phase_times()->record_string_dedup_fixup_time(fixup_time_ms);
-  g1p->phase_times()->note_string_dedup_fixup_end();
 }
 
 void G1StringDedup::threads_do(ThreadClosure* tc) {
--- a/hotspot/src/share/vm/gc_implementation/g1/g1StringDedup.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1StringDedup.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -91,6 +91,7 @@
 class ThreadClosure;
 class outputStream;
 class G1StringDedupTable;
+class G1GCPhaseTimes;
 
 //
 // Main interface for interacting with string deduplication.
@@ -131,7 +132,7 @@
   static void oops_do(OopClosure* keep_alive);
   static void unlink(BoolObjectClosure* is_alive);
   static void unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive,
-                                bool allow_resize_and_rehash = true);
+                                bool allow_resize_and_rehash, G1GCPhaseTimes* phase_times = NULL);
 
   static void threads_do(ThreadClosure* tc);
   static void print_worker_threads_on(outputStream* st);
--- a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, 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
@@ -86,7 +86,7 @@
           "If true, enable reference discovery during concurrent "          \
           "marking and reference processing at the end of remark.")         \
                                                                             \
-  product(intx, G1SATBBufferSize, 1*K,                                      \
+  product(size_t, G1SATBBufferSize, 1*K,                                    \
           "Number of entries in an SATB log buffer.")                       \
                                                                             \
   develop(intx, G1SATBProcessCompletedThreshold, 20,                        \
@@ -112,7 +112,7 @@
             "Prints the liveness information for all regions in the heap "  \
             "at the end of a marking cycle.")                               \
                                                                             \
-  product(intx, G1UpdateBufferSize, 256,                                    \
+  product(size_t, G1UpdateBufferSize, 256,                                  \
           "Size of an update buffer")                                       \
                                                                             \
   product(intx, G1ConcRefinementYellowZone, 0,                              \
@@ -148,7 +148,7 @@
           "Select green, yellow and red zones adaptively to meet the "      \
           "the pause requirements.")                                        \
                                                                             \
-  product(uintx, G1ConcRSLogCacheSize, 10,                                  \
+  product(size_t, G1ConcRSLogCacheSize, 10,                                 \
           "Log base 2 of the length of conc RS hot-card cache.")            \
                                                                             \
   product(uintx, G1ConcRSHotCardLimit, 4,                                   \
@@ -210,7 +210,7 @@
           "When set, G1 will fail when it encounters an FP 'error', "       \
           "so as to allow debugging")                                       \
                                                                             \
-  product(uintx, G1HeapRegionSize, 0,                                       \
+  product(size_t, G1HeapRegionSize, 0,                                      \
           "Size of the G1 regions.")                                        \
                                                                             \
   product(uintx, G1ConcRefinementThreads, 0,                                \
@@ -220,7 +220,7 @@
   develop(bool, G1VerifyCTCleanup, false,                                   \
           "Verify card table cleanup.")                                     \
                                                                             \
-  product(uintx, G1RSetScanBlockSize, 64,                                   \
+  product(size_t, G1RSetScanBlockSize, 64,                                  \
           "Size of a work unit of cards claimed by a worker thread"         \
           "during RSet scanning.")                                          \
                                                                             \
--- a/hotspot/src/share/vm/gc_implementation/g1/g1_specialized_oop_closures.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1_specialized_oop_closures.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, 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
@@ -30,23 +30,8 @@
 // non-virtually, using a mechanism defined in this file.  Extend these
 // macros in the obvious way to add specializations for new closures.
 
-enum G1Barrier {
-  G1BarrierNone,
-  G1BarrierEvac,
-  G1BarrierKlass
-};
-
-enum G1Mark {
-  G1MarkNone,
-  G1MarkFromRoot,
-  G1MarkPromotedFromRoot
-};
-
 // Forward declarations.
 
-template<G1Barrier barrier, G1Mark do_mark_object>
-class G1ParCopyClosure;
-
 class G1ParScanClosure;
 class G1ParPushHeapRSClosure;
 
@@ -61,26 +46,16 @@
 class G1InvokeIfNotTriggeredClosure;
 class G1UpdateRSOrPushRefOopClosure;
 
-#ifdef FURTHER_SPECIALIZED_OOP_OOP_ITERATE_CLOSURES
-#error "FURTHER_SPECIALIZED_OOP_OOP_ITERATE_CLOSURES already defined."
-#endif
-
-#define FURTHER_SPECIALIZED_OOP_OOP_ITERATE_CLOSURES(f) \
-      f(G1ParScanClosure,_nv)                           \
-      f(G1ParPushHeapRSClosure,_nv)                     \
-      f(FilterIntoCSClosure,_nv)                        \
-      f(FilterOutOfRegionClosure,_nv)                   \
-      f(G1CMOopClosure,_nv)                             \
-      f(G1RootRegionScanClosure,_nv)                    \
-      f(G1Mux2Closure,_nv)                              \
-      f(G1TriggerClosure,_nv)                           \
-      f(G1InvokeIfNotTriggeredClosure,_nv)              \
+#define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_G1(f) \
+      f(G1ParScanClosure,_nv)                      \
+      f(G1ParPushHeapRSClosure,_nv)                \
+      f(FilterIntoCSClosure,_nv)                   \
+      f(FilterOutOfRegionClosure,_nv)              \
+      f(G1CMOopClosure,_nv)                        \
+      f(G1RootRegionScanClosure,_nv)               \
+      f(G1Mux2Closure,_nv)                         \
+      f(G1TriggerClosure,_nv)                      \
+      f(G1InvokeIfNotTriggeredClosure,_nv)         \
       f(G1UpdateRSOrPushRefOopClosure,_nv)
 
-#ifdef FURTHER_SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES
-#error "FURTHER_SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES already defined."
-#endif
-
-#define FURTHER_SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES(f)
-
 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1_SPECIALIZED_OOP_CLOSURES_HPP
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -106,18 +106,18 @@
 }
 
 void HeapRegion::setup_heap_region_size(size_t initial_heap_size, size_t max_heap_size) {
-  uintx region_size = G1HeapRegionSize;
+  size_t region_size = G1HeapRegionSize;
   if (FLAG_IS_DEFAULT(G1HeapRegionSize)) {
     size_t average_heap_size = (initial_heap_size + max_heap_size) / 2;
     region_size = MAX2(average_heap_size / HeapRegionBounds::target_number(),
-                       (uintx) HeapRegionBounds::min_size());
+                       HeapRegionBounds::min_size());
   }
 
   int region_size_log = log2_long((jlong) region_size);
   // Recalculate the region size to make sure it's a power of
   // 2. This means that region_size is the largest power of 2 that's
   // <= what we've calculated so far.
-  region_size = ((uintx)1 << region_size_log);
+  region_size = ((size_t)1 << region_size_log);
 
   // Now make sure that we don't go over or under our limits.
   if (region_size < HeapRegionBounds::min_size()) {
@@ -139,7 +139,7 @@
   guarantee(GrainBytes == 0, "we should only set it once");
   // The cast to int is safe, given that we've bounded region_size by
   // MIN_REGION_SIZE and MAX_REGION_SIZE.
-  GrainBytes = (size_t)region_size;
+  GrainBytes = region_size;
 
   guarantee(GrainWords == 0, "we should only set it once");
   GrainWords = GrainBytes >> LogHeapWordSize;
@@ -933,6 +933,16 @@
   _offsets.resize(new_end - bottom());
 }
 
+#ifndef PRODUCT
+void G1OffsetTableContigSpace::mangle_unused_area() {
+  mangle_unused_area_complete();
+}
+
+void G1OffsetTableContigSpace::mangle_unused_area_complete() {
+  SpaceMangler::mangle_region(MemRegion(top(), end()));
+}
+#endif
+
 void G1OffsetTableContigSpace::print() const {
   print_short();
   gclog_or_tty->print_cr(" [" INTPTR_FORMAT ", " INTPTR_FORMAT ", "
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -27,7 +27,6 @@
 
 #include "gc_implementation/g1/g1AllocationContext.hpp"
 #include "gc_implementation/g1/g1BlockOffsetTable.hpp"
-#include "gc_implementation/g1/g1_specialized_oop_closures.hpp"
 #include "gc_implementation/g1/heapRegionType.hpp"
 #include "gc_implementation/g1/survRateGroup.hpp"
 #include "gc_implementation/shared/ageTable.hpp"
@@ -155,6 +154,9 @@
   void set_bottom(HeapWord* value);
   void set_end(HeapWord* value);
 
+  void mangle_unused_area() PRODUCT_RETURN;
+  void mangle_unused_area_complete() PRODUCT_RETURN;
+
   HeapWord* scan_top() const;
   void record_timestamp();
   void reset_gc_time_stamp() { _gc_time_stamp = 0; }
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -145,6 +145,24 @@
   }
 }
 
+MemoryUsage HeapRegionManager::get_auxiliary_data_memory_usage() const {
+  size_t used_sz =
+    _prev_bitmap_mapper->committed_size() +
+    _next_bitmap_mapper->committed_size() +
+    _bot_mapper->committed_size() +
+    _cardtable_mapper->committed_size() +
+    _card_counts_mapper->committed_size();
+
+  size_t committed_sz =
+    _prev_bitmap_mapper->reserved_size() +
+    _next_bitmap_mapper->reserved_size() +
+    _bot_mapper->reserved_size() +
+    _cardtable_mapper->reserved_size() +
+    _card_counts_mapper->reserved_size();
+
+  return MemoryUsage(0, used_sz, committed_sz, committed_sz);
+}
+
 uint HeapRegionManager::expand_by(uint num_regions) {
   return expand_at(0, num_regions);
 }
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, 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
@@ -28,6 +28,7 @@
 #include "gc_implementation/g1/g1BiasedArray.hpp"
 #include "gc_implementation/g1/g1RegionToSpaceMapper.hpp"
 #include "gc_implementation/g1/heapRegionSet.hpp"
+#include "services/memoryUsage.hpp"
 
 class HeapRegion;
 class HeapRegionClosure;
@@ -196,6 +197,8 @@
   // Return the maximum number of regions in the heap.
   uint max_length() const { return (uint)_regions.length(); }
 
+  MemoryUsage get_auxiliary_data_memory_usage() const;
+
   MemRegion reserved() const { return MemRegion(heap_bottom(), heap_end()); }
 
   // Expand the sequence to reflect that the heap has grown. Either create new
--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp"
 #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp"
 #include "gc_implementation/parNew/parNewGeneration.hpp"
 #include "gc_implementation/parNew/parOopClosures.inline.hpp"
@@ -325,7 +326,7 @@
 private:
   ParallelTaskTerminator& _term;
   ParNewGeneration&       _gen;
-  Generation&             _next_gen;
+  Generation&             _old_gen;
  public:
   bool is_valid(int id) const { return id < length(); }
   ParallelTaskTerminator* terminator() { return &_term; }
@@ -338,7 +339,7 @@
   Stack<oop, mtGC>* overflow_stacks,
   size_t desired_plab_sz, ParallelTaskTerminator& term)
   : ResourceArray(sizeof(ParScanThreadState), num_threads),
-    _gen(gen), _next_gen(old_gen), _term(term)
+    _gen(gen), _old_gen(old_gen), _term(term)
 {
   assert(num_threads > 0, "sanity check!");
   assert(ParGCUseLocalOverflow == (overflow_stacks != NULL),
@@ -471,8 +472,8 @@
     _gen.age_table()->merge(local_table);
 
     // Inform old gen that we're done.
-    _next_gen.par_promote_alloc_done(i);
-    _next_gen.par_oop_since_save_marks_iterate_done(i);
+    _old_gen.par_promote_alloc_done(i);
+    _old_gen.par_oop_since_save_marks_iterate_done(i);
   }
 
   if (UseConcMarkSweepGC) {
@@ -574,10 +575,10 @@
   par_scan_state()->end_term_time();
 }
 
-ParNewGenTask::ParNewGenTask(ParNewGeneration* gen, Generation* next_gen,
-                HeapWord* young_old_boundary, ParScanThreadStateSet* state_set) :
+ParNewGenTask::ParNewGenTask(ParNewGeneration* gen, Generation* old_gen,
+                             HeapWord* young_old_boundary, ParScanThreadStateSet* state_set) :
     AbstractGangTask("ParNewGeneration collection"),
-    _gen(gen), _next_gen(next_gen),
+    _gen(gen), _old_gen(old_gen),
     _young_old_boundary(young_old_boundary),
     _state_set(state_set)
   {}
@@ -601,8 +602,6 @@
   // We would need multiple old-gen queues otherwise.
   assert(gch->n_gens() == 2, "Par young collection currently only works with one older gen.");
 
-  Generation* old_gen = gch->next_gen(_gen);
-
   ParScanThreadState& par_scan_state = _state_set->thread_state(worker_id);
   assert(_state_set->is_valid(worker_id), "Should not have been called");
 
@@ -619,7 +618,7 @@
                          true,  // Process younger gens, if any,
                                 // as strong roots.
                          false, // no scope; this is parallel code
-                         SharedHeap::SO_ScavengeCodeCache,
+                         GenCollectedHeap::SO_ScavengeCodeCache,
                          GenCollectedHeap::StrongAndWeakRoots,
                          &par_scan_state.to_space_root_closure(),
                          &par_scan_state.older_gen_closure(),
@@ -763,8 +762,9 @@
 class ParNewRefProcTaskProxy: public AbstractGangTask {
   typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask;
 public:
-  ParNewRefProcTaskProxy(ProcessTask& task, ParNewGeneration& gen,
-                         Generation& next_gen,
+  ParNewRefProcTaskProxy(ProcessTask& task,
+                         ParNewGeneration& gen,
+                         Generation& old_gen,
                          HeapWord* young_old_boundary,
                          ParScanThreadStateSet& state_set);
 
@@ -776,20 +776,20 @@
 private:
   ParNewGeneration&      _gen;
   ProcessTask&           _task;
-  Generation&            _next_gen;
+  Generation&            _old_gen;
   HeapWord*              _young_old_boundary;
   ParScanThreadStateSet& _state_set;
 };
 
-ParNewRefProcTaskProxy::ParNewRefProcTaskProxy(
-    ProcessTask& task, ParNewGeneration& gen,
-    Generation& next_gen,
-    HeapWord* young_old_boundary,
-    ParScanThreadStateSet& state_set)
+ParNewRefProcTaskProxy::ParNewRefProcTaskProxy(ProcessTask& task,
+                                               ParNewGeneration& gen,
+                                               Generation& old_gen,
+                                               HeapWord* young_old_boundary,
+                                               ParScanThreadStateSet& state_set)
   : AbstractGangTask("ParNewGeneration parallel reference processing"),
     _gen(gen),
     _task(task),
-    _next_gen(next_gen),
+    _old_gen(old_gen),
     _young_old_boundary(young_old_boundary),
     _state_set(state_set)
 {
@@ -893,7 +893,7 @@
   from()->set_next_compaction_space(to());
   gch->set_incremental_collection_failed();
   // Inform the next generation that a promotion failure occurred.
-  _next_gen->promotion_failure_occurred();
+  _old_gen->promotion_failure_occurred();
 
   // Trace promotion failure in the parallel GC threads
   thread_state_set.trace_promotion_failed(gc_tracer());
@@ -927,7 +927,7 @@
   workers->set_active_workers(active_workers);
   assert(gch->n_gens() == 2,
          "Par collection currently only works with single older gen.");
-  _next_gen = gch->next_gen(this);
+  _old_gen = gch->old_gen();
 
   // If the next generation is too full to accommodate worst-case promotion
   // from this generation, pass on collection; let the next generation
@@ -952,8 +952,6 @@
   // Capture heap used before collection (for printing).
   size_t gch_prev_used = gch->used();
 
-  SpecializationStats::clear();
-
   age_table()->clear();
   to()->clear(SpaceDecorator::Mangle);
 
@@ -968,10 +966,10 @@
   // because only those workers go through the termination protocol.
   ParallelTaskTerminator _term(n_workers, task_queues());
   ParScanThreadStateSet thread_state_set(workers->active_workers(),
-                                         *to(), *this, *_next_gen, *task_queues(),
+                                         *to(), *this, *_old_gen, *task_queues(),
                                          _overflow_stacks, desired_plab_sz(), _term);
 
-  ParNewGenTask tsk(this, _next_gen, reserved().end(), &thread_state_set);
+  ParNewGenTask tsk(this, _old_gen, reserved().end(), &thread_state_set);
   gch->set_par_threads(n_workers);
   gch->rem_set()->prepare_for_younger_refs_iterate(true);
   // It turns out that even when we're using 1 thread, doing the work in a
@@ -1073,8 +1071,6 @@
   jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
   update_time_of_last_gc(now);
 
-  SpecializationStats::print();
-
   rp->set_enqueuing_is_done(true);
   if (rp->processing_is_mt()) {
     ParNewRefProcTaskExecutor task_executor(*this, thread_state_set);
@@ -1127,14 +1123,6 @@
   return forward_ptr;
 }
 
-#ifdef ASSERT
-bool ParNewGeneration::is_legal_forward_ptr(oop p) {
-  return
-    (p == ClaimedForwardPtr)
-    || Universe::heap()->is_in_reserved(p);
-}
-#endif
-
 void ParNewGeneration::preserve_mark_if_necessary(oop obj, markOop m) {
   if (m->must_be_preserved_for_promotion_failure(obj)) {
     // We should really have separate per-worker stacks, rather
@@ -1191,8 +1179,8 @@
     }
 
     if (!_promotion_failed) {
-      new_obj = _next_gen->par_promote(par_scan_state->thread_num(),
-                                        old, m, sz);
+      new_obj = _old_gen->par_promote(par_scan_state->thread_num(),
+                                      old, m, sz);
     }
 
     if (new_obj == NULL) {
@@ -1209,6 +1197,7 @@
   } else {
     // Is in to-space; do copying ourselves.
     Copy::aligned_disjoint_words((HeapWord*)old, (HeapWord*)new_obj, sz);
+    assert(Universe::heap()->is_in_reserved(new_obj), "illegal forwarding pointer value.");
     forward_ptr = old->forward_to_atomic(new_obj);
     // Restore the mark word copied above.
     new_obj->set_mark(m);
--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, 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,6 +25,7 @@
 #ifndef SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARNEWGENERATION_HPP
 #define SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARNEWGENERATION_HPP
 
+#include "gc_implementation/parNew/parOopClosures.hpp"
 #include "gc_implementation/shared/gcTrace.hpp"
 #include "gc_implementation/shared/parGCAllocBuffer.hpp"
 #include "gc_implementation/shared/copyFailedInfo.hpp"
@@ -233,13 +234,13 @@
 class ParNewGenTask: public AbstractGangTask {
  private:
   ParNewGeneration*            _gen;
-  Generation*                  _next_gen;
+  Generation*                  _old_gen;
   HeapWord*                    _young_old_boundary;
   class ParScanThreadStateSet* _state_set;
 
 public:
   ParNewGenTask(ParNewGeneration*      gen,
-                Generation*            next_gen,
+                Generation*            old_gen,
                 HeapWord*              young_old_boundary,
                 ParScanThreadStateSet* state_set);
 
@@ -419,8 +420,6 @@
   }
 
   static oop real_forwardee(oop obj);
-
-  DEBUG_ONLY(static bool is_legal_forward_ptr(oop p);)
 };
 
 #endif // SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARNEWGENERATION_HPP
--- a/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.inline.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.inline.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2015, 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
@@ -29,6 +29,7 @@
 #include "gc_implementation/parNew/parOopClosures.hpp"
 #include "memory/cardTableRS.hpp"
 #include "memory/genCollectedHeap.hpp"
+#include "memory/genOopClosures.inline.hpp"
 
 template <class T> inline void ParScanWeakRefClosure::do_oop_work(T* p) {
   assert (!oopDesc::is_null(*p), "null weak reference?");
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, 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,6 +25,7 @@
 #include "precompiled.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "code/codeCache.hpp"
+#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
 #include "gc_implementation/parallelScavenge/pcTasks.hpp"
 #include "gc_implementation/parallelScavenge/psParallelCompact.hpp"
 #include "gc_implementation/shared/gcTimer.hpp"
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, 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 @@
 #define SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSMARKSWEEP_HPP
 
 #include "gc_implementation/shared/collectorCounters.hpp"
-#include "gc_implementation/shared/markSweep.inline.hpp"
+#include "gc_implementation/shared/markSweep.hpp"
 #include "utilities/stack.hpp"
 
 class PSAdaptiveSizePolicy;
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, 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
@@ -29,7 +29,6 @@
 #include "gc_implementation/parallelScavenge/parMarkBitMap.hpp"
 #include "gc_implementation/parallelScavenge/psCompactionManager.hpp"
 #include "gc_implementation/shared/collectorCounters.hpp"
-#include "gc_implementation/shared/markSweep.hpp"
 #include "gc_implementation/shared/mutableSpace.hpp"
 #include "memory/sharedHeap.hpp"
 #include "oops/oop.hpp"
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2015, 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,6 +34,7 @@
 #include "memory/padded.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/oop.psgc.inline.hpp"
+#include "utilities/stack.inline.hpp"
 
 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
 
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -40,6 +40,7 @@
 #include "runtime/thread.hpp"
 #include "runtime/vmThread.hpp"
 #include "services/management.hpp"
+#include "utilities/stack.inline.hpp"
 #include "utilities/taskqueue.hpp"
 
 //
--- a/hotspot/src/share/vm/gc_implementation/shared/cSpaceCounters.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/shared/cSpaceCounters.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2015, 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
@@ -63,3 +63,20 @@
                                      _space->capacity(), CHECK);
   }
 }
+
+void CSpaceCounters::update_capacity() {
+  _capacity->set_value(_space->capacity());
+}
+
+void CSpaceCounters::update_used() {
+  _used->set_value(_space->used());
+}
+
+void CSpaceCounters::update_all() {
+  update_used();
+  update_capacity();
+}
+
+jlong ContiguousSpaceUsedHelper::take_sample(){
+  return _space->used();
+}
--- a/hotspot/src/share/vm/gc_implementation/shared/cSpaceCounters.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/shared/cSpaceCounters.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2015, 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 @@
 #define SHARE_VM_GC_IMPLEMENTATION_SHARED_CSPACECOUNTERS_HPP
 
 #include "gc_implementation/shared/generationCounters.hpp"
-#include "memory/space.inline.hpp"
+#include "memory/space.hpp"
 #include "runtime/perfData.hpp"
 
 // A CSpaceCounters is a holder class for performance counters
@@ -56,18 +56,9 @@
       if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space);
   }
 
-  virtual inline void update_capacity() {
-    _capacity->set_value(_space->capacity());
-  }
-
-  virtual inline void update_used() {
-    _used->set_value(_space->used());
-  }
-
-  virtual inline void update_all() {
-    update_used();
-    update_capacity();
-  }
+  virtual void update_capacity();
+  virtual void update_used();
+  virtual void update_all();
 
   const char* name_space() const        { return _name_space; }
 };
@@ -79,9 +70,7 @@
   public:
     ContiguousSpaceUsedHelper(ContiguousSpace* space) : _space(space) { }
 
-    inline jlong take_sample() {
-      return _space->used();
-    }
+    jlong take_sample();
 };
 
 #endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_CSPACECOUNTERS_HPP
--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, 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
@@ -84,6 +84,14 @@
 
 void MarkSweep::FollowStackClosure::do_void() { follow_stack(); }
 
+void PreservedMark::adjust_pointer() {
+  MarkSweep::adjust_pointer(&_obj);
+}
+
+void PreservedMark::restore() {
+  _obj->set_mark(_mark);
+}
+
 // We preserve the mark which should be replaced at the end and the location
 // that it will go.  Note that the object that this markOop belongs to isn't
 // currently at that address but it will be after phase4
--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, 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,8 @@
 #define SHARE_VM_GC_IMPLEMENTATION_SHARED_MARKSWEEP_HPP
 
 #include "gc_interface/collectedHeap.hpp"
-#include "memory/universe.hpp"
+#include "memory/genOopClosures.hpp"
+#include "memory/iterator.hpp"
 #include "oops/markOop.hpp"
 #include "oops/oop.hpp"
 #include "runtime/timer.hpp"
@@ -182,13 +183,8 @@
     _mark = mark;
   }
 
-  void adjust_pointer() {
-    MarkSweep::adjust_pointer(&_obj);
-  }
-
-  void restore() {
-    _obj->set_mark(_mark);
-  }
+  void adjust_pointer();
+  void restore();
 };
 
 #endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_MARKSWEEP_HPP
--- a/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -98,7 +98,7 @@
   if (!is_init_completed()) {
     vm_exit_during_initialization(
       err_msg("GC triggered before VM initialization completed. Try increasing "
-              "NewSize, current value " UINTX_FORMAT "%s.",
+              "NewSize, current value " SIZE_FORMAT "%s.",
               byte_size_in_proper_unit(NewSize),
               proper_unit_for_byte_size(NewSize)));
   }
--- a/hotspot/src/share/vm/memory/cardTableRS.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/memory/cardTableRS.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -27,7 +27,7 @@
 #include "memory/cardTableRS.hpp"
 #include "memory/genCollectedHeap.hpp"
 #include "memory/generation.hpp"
-#include "memory/space.hpp"
+#include "memory/space.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/atomic.inline.hpp"
 #include "runtime/java.hpp"
--- a/hotspot/src/share/vm/memory/collectorPolicy.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/memory/collectorPolicy.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -104,15 +104,15 @@
 
   // User inputs from -Xmx and -Xms must be aligned
   _min_heap_byte_size = align_size_up(_min_heap_byte_size, _heap_alignment);
-  uintx aligned_initial_heap_size = align_size_up(InitialHeapSize, _heap_alignment);
-  uintx aligned_max_heap_size = align_size_up(MaxHeapSize, _heap_alignment);
+  size_t aligned_initial_heap_size = align_size_up(InitialHeapSize, _heap_alignment);
+  size_t aligned_max_heap_size = align_size_up(MaxHeapSize, _heap_alignment);
 
   // Write back to flags if the values changed
   if (aligned_initial_heap_size != InitialHeapSize) {
-    FLAG_SET_ERGO(uintx, InitialHeapSize, aligned_initial_heap_size);
+    FLAG_SET_ERGO(size_t, InitialHeapSize, aligned_initial_heap_size);
   }
   if (aligned_max_heap_size != MaxHeapSize) {
-    FLAG_SET_ERGO(uintx, MaxHeapSize, aligned_max_heap_size);
+    FLAG_SET_ERGO(size_t, MaxHeapSize, aligned_max_heap_size);
   }
 
   if (FLAG_IS_CMDLINE(InitialHeapSize) && _min_heap_byte_size != 0 &&
@@ -120,9 +120,9 @@
     vm_exit_during_initialization("Incompatible minimum and initial heap sizes specified");
   }
   if (!FLAG_IS_DEFAULT(InitialHeapSize) && InitialHeapSize > MaxHeapSize) {
-    FLAG_SET_ERGO(uintx, MaxHeapSize, InitialHeapSize);
+    FLAG_SET_ERGO(size_t, MaxHeapSize, InitialHeapSize);
   } else if (!FLAG_IS_DEFAULT(MaxHeapSize) && InitialHeapSize > MaxHeapSize) {
-    FLAG_SET_ERGO(uintx, InitialHeapSize, MaxHeapSize);
+    FLAG_SET_ERGO(size_t, InitialHeapSize, MaxHeapSize);
     if (InitialHeapSize < _min_heap_byte_size) {
       _min_heap_byte_size = InitialHeapSize;
     }
@@ -131,7 +131,7 @@
   _initial_heap_byte_size = InitialHeapSize;
   _max_heap_byte_size = MaxHeapSize;
 
-  FLAG_SET_ERGO(uintx, MinHeapDeltaBytes, align_size_up(MinHeapDeltaBytes, _space_alignment));
+  FLAG_SET_ERGO(size_t, MinHeapDeltaBytes, align_size_up(MinHeapDeltaBytes, _space_alignment));
 
   DEBUG_ONLY(CollectorPolicy::assert_flags();)
 }
@@ -282,18 +282,18 @@
   // All generational heaps have a youngest gen; handle those flags here
 
   // Make sure the heap is large enough for two generations
-  uintx smallest_new_size = young_gen_size_lower_bound();
-  uintx smallest_heap_size = align_size_up(smallest_new_size + align_size_up(_space_alignment, _gen_alignment),
+  size_t smallest_new_size = young_gen_size_lower_bound();
+  size_t smallest_heap_size = align_size_up(smallest_new_size + align_size_up(_space_alignment, _gen_alignment),
                                            _heap_alignment);
   if (MaxHeapSize < smallest_heap_size) {
-    FLAG_SET_ERGO(uintx, MaxHeapSize, smallest_heap_size);
+    FLAG_SET_ERGO(size_t, MaxHeapSize, smallest_heap_size);
     _max_heap_byte_size = MaxHeapSize;
   }
   // If needed, synchronize _min_heap_byte size and _initial_heap_byte_size
   if (_min_heap_byte_size < smallest_heap_size) {
     _min_heap_byte_size = smallest_heap_size;
     if (InitialHeapSize < _min_heap_byte_size) {
-      FLAG_SET_ERGO(uintx, InitialHeapSize, smallest_heap_size);
+      FLAG_SET_ERGO(size_t, InitialHeapSize, smallest_heap_size);
       _initial_heap_byte_size = smallest_heap_size;
     }
   }
@@ -306,8 +306,8 @@
 
   // Now take the actual NewSize into account. We will silently increase NewSize
   // if the user specified a smaller or unaligned value.
-  uintx bounded_new_size = bound_minus_alignment(NewSize, MaxHeapSize);
-  bounded_new_size = MAX2(smallest_new_size, (uintx)align_size_down(bounded_new_size, _gen_alignment));
+  size_t bounded_new_size = bound_minus_alignment(NewSize, MaxHeapSize);
+  bounded_new_size = MAX2(smallest_new_size, (size_t)align_size_down(bounded_new_size, _gen_alignment));
   if (bounded_new_size != NewSize) {
     // Do not use FLAG_SET_ERGO to update NewSize here, since this will override
     // if NewSize was set on the command line or not. This information is needed
@@ -320,21 +320,21 @@
   if (!FLAG_IS_DEFAULT(MaxNewSize)) {
     if (MaxNewSize >= MaxHeapSize) {
       // Make sure there is room for an old generation
-      uintx smaller_max_new_size = MaxHeapSize - _gen_alignment;
+      size_t smaller_max_new_size = MaxHeapSize - _gen_alignment;
       if (FLAG_IS_CMDLINE(MaxNewSize)) {
         warning("MaxNewSize (" SIZE_FORMAT "k) is equal to or greater than the entire "
                 "heap (" SIZE_FORMAT "k).  A new max generation size of " SIZE_FORMAT "k will be used.",
                 MaxNewSize/K, MaxHeapSize/K, smaller_max_new_size/K);
       }
-      FLAG_SET_ERGO(uintx, MaxNewSize, smaller_max_new_size);
+      FLAG_SET_ERGO(size_t, MaxNewSize, smaller_max_new_size);
       if (NewSize > MaxNewSize) {
-        FLAG_SET_ERGO(uintx, NewSize, MaxNewSize);
+        FLAG_SET_ERGO(size_t, NewSize, MaxNewSize);
         _initial_young_size = NewSize;
       }
     } else if (MaxNewSize < _initial_young_size) {
-      FLAG_SET_ERGO(uintx, MaxNewSize, _initial_young_size);
+      FLAG_SET_ERGO(size_t, MaxNewSize, _initial_young_size);
     } else if (!is_size_aligned(MaxNewSize, _gen_alignment)) {
-      FLAG_SET_ERGO(uintx, MaxNewSize, align_size_down(MaxNewSize, _gen_alignment));
+      FLAG_SET_ERGO(size_t, MaxNewSize, align_size_down(MaxNewSize, _gen_alignment));
     }
     _max_young_size = MaxNewSize;
   }
@@ -347,7 +347,7 @@
               "A new max generation size of " SIZE_FORMAT "k will be used.",
               NewSize/K, MaxNewSize/K, NewSize/K);
     }
-    FLAG_SET_ERGO(uintx, MaxNewSize, NewSize);
+    FLAG_SET_ERGO(size_t, MaxNewSize, NewSize);
     _max_young_size = MaxNewSize;
   }
 
@@ -369,9 +369,9 @@
     size_t calculated_heapsize = (OldSize / NewRatio) * (NewRatio + 1);
 
     calculated_heapsize = align_size_up(calculated_heapsize, _heap_alignment);
-    FLAG_SET_ERGO(uintx, MaxHeapSize, calculated_heapsize);
+    FLAG_SET_ERGO(size_t, MaxHeapSize, calculated_heapsize);
     _max_heap_byte_size = MaxHeapSize;
-    FLAG_SET_ERGO(uintx, InitialHeapSize, calculated_heapsize);
+    FLAG_SET_ERGO(size_t, InitialHeapSize, calculated_heapsize);
     _initial_heap_byte_size = InitialHeapSize;
   }
 
@@ -380,19 +380,19 @@
     if (_max_heap_size_cmdline) {
       // Somebody has set a maximum heap size with the intention that we should not
       // exceed it. Adjust New/OldSize as necessary.
-      uintx calculated_size = NewSize + OldSize;
+      size_t calculated_size = NewSize + OldSize;
       double shrink_factor = (double) MaxHeapSize / calculated_size;
-      uintx smaller_new_size = align_size_down((uintx)(NewSize * shrink_factor), _gen_alignment);
-      FLAG_SET_ERGO(uintx, NewSize, MAX2(young_gen_size_lower_bound(), smaller_new_size));
+      size_t smaller_new_size = align_size_down((size_t)(NewSize * shrink_factor), _gen_alignment);
+      FLAG_SET_ERGO(size_t, NewSize, MAX2(young_gen_size_lower_bound(), smaller_new_size));
       _initial_young_size = NewSize;
 
       // OldSize is already aligned because above we aligned MaxHeapSize to
       // _heap_alignment, and we just made sure that NewSize is aligned to
       // _gen_alignment. In initialize_flags() we verified that _heap_alignment
       // is a multiple of _gen_alignment.
-      FLAG_SET_ERGO(uintx, OldSize, MaxHeapSize - NewSize);
+      FLAG_SET_ERGO(size_t, OldSize, MaxHeapSize - NewSize);
     } else {
-      FLAG_SET_ERGO(uintx, MaxHeapSize, align_size_up(NewSize + OldSize, _heap_alignment));
+      FLAG_SET_ERGO(size_t, MaxHeapSize, align_size_up(NewSize + OldSize, _heap_alignment));
       _max_heap_byte_size = MaxHeapSize;
     }
   }
@@ -405,7 +405,7 @@
       // Need to compare against the flag value for max since _max_young_size
       // might not have been set yet.
       if (new_size >= _min_young_size && new_size <= MaxNewSize) {
-        FLAG_SET_ERGO(uintx, NewSize, new_size);
+        FLAG_SET_ERGO(size_t, NewSize, new_size);
         _initial_young_size = NewSize;
       }
     }
@@ -561,15 +561,15 @@
 
   // Write back to flags if necessary.
   if (NewSize != _initial_young_size) {
-    FLAG_SET_ERGO(uintx, NewSize, _initial_young_size);
+    FLAG_SET_ERGO(size_t, NewSize, _initial_young_size);
   }
 
   if (MaxNewSize != _max_young_size) {
-    FLAG_SET_ERGO(uintx, MaxNewSize, _max_young_size);
+    FLAG_SET_ERGO(size_t, MaxNewSize, _max_young_size);
   }
 
   if (OldSize != _initial_old_size) {
-    FLAG_SET_ERGO(uintx, OldSize, _initial_old_size);
+    FLAG_SET_ERGO(size_t, OldSize, _initial_old_size);
   }
 
   if (PrintGCDetails && Verbose) {
@@ -601,7 +601,7 @@
     HandleMark hm; // Discard any handles allocated in each iteration.
 
     // First allocation attempt is lock-free.
-    Generation *young = gch->get_gen(0);
+    Generation *young = gch->young_gen();
     assert(young->supports_inline_contig_alloc(),
       "Otherwise, must do alloc within heap lock");
     if (young->should_allocate(size, is_tlab)) {
@@ -615,8 +615,8 @@
     {
       MutexLocker ml(Heap_lock);
       if (PrintGC && Verbose) {
-        gclog_or_tty->print_cr("TwoGenerationCollectorPolicy::mem_allocate_work:"
-                      " attempting locked slow path allocation");
+        gclog_or_tty->print_cr("GenCollectorPolicy::mem_allocate_work:"
+                               " attempting locked slow path allocation");
       }
       // Note that only large objects get a shot at being
       // allocated in later generations.
@@ -705,7 +705,7 @@
     // Give a warning if we seem to be looping forever.
     if ((QueuedAllocationWarningCount > 0) &&
         (try_count % QueuedAllocationWarningCount == 0)) {
-          warning("TwoGenerationCollectorPolicy::mem_allocate_work retries %d times \n\t"
+          warning("GenCollectorPolicy::mem_allocate_work retries %d times \n\t"
                   " size=" SIZE_FORMAT " %s", try_count, size, is_tlab ? "(TLAB)" : "");
     }
   }
@@ -715,10 +715,14 @@
                                                        bool   is_tlab) {
   GenCollectedHeap *gch = GenCollectedHeap::heap();
   HeapWord* result = NULL;
-  for (int i = number_of_generations() - 1; i >= 0 && result == NULL; i--) {
-    Generation *gen = gch->get_gen(i);
-    if (gen->should_allocate(size, is_tlab)) {
-      result = gen->expand_and_allocate(size, is_tlab);
+  Generation *old = gch->old_gen();
+  if (old->should_allocate(size, is_tlab)) {
+    result = old->expand_and_allocate(size, is_tlab);
+  }
+  if (result == NULL) {
+    Generation *young = gch->young_gen();
+    if (young->should_allocate(size, is_tlab)) {
+      result = young->expand_and_allocate(size, is_tlab);
     }
   }
   assert(result == NULL || gch->is_in_reserved(result), "result not in heap");
@@ -891,7 +895,7 @@
 bool GenCollectorPolicy::should_try_older_generation_allocation(
         size_t word_size) const {
   GenCollectedHeap* gch = GenCollectedHeap::heap();
-  size_t young_capacity = gch->get_gen(0)->capacity_before_gc();
+  size_t young_capacity = gch->young_gen()->capacity_before_gc();
   return    (word_size > heap_word_size(young_capacity))
          || GC_locker::is_active_and_needs_gc()
          || gch->incremental_collection_failed();
@@ -903,7 +907,7 @@
 //
 
 void MarkSweepPolicy::initialize_alignments() {
-  _space_alignment = _gen_alignment = (uintx)Generation::GenGrain;
+  _space_alignment = _gen_alignment = (size_t)Generation::GenGrain;
   _heap_alignment = compute_heap_alignment();
 }
 
@@ -935,18 +939,18 @@
     // for both min and initial young size if less than min heap.
     flag_value = 20 * M;
     set_basic_flag_values();
-    FLAG_SET_CMDLINE(uintx, NewSize, flag_value);
+    FLAG_SET_CMDLINE(size_t, NewSize, flag_value);
     verify_young_min(flag_value);
 
     set_basic_flag_values();
-    FLAG_SET_CMDLINE(uintx, NewSize, flag_value);
+    FLAG_SET_CMDLINE(size_t, NewSize, flag_value);
     verify_young_initial(flag_value);
 
     // If NewSize is set on command line, but is larger than the min
     // heap size, it should only be used for initial young size.
     flag_value = 80 * M;
     set_basic_flag_values();
-    FLAG_SET_CMDLINE(uintx, NewSize, flag_value);
+    FLAG_SET_CMDLINE(size_t, NewSize, flag_value);
     verify_young_initial(flag_value);
 
     // If NewSize has been ergonomically set, the collector policy
@@ -954,11 +958,11 @@
     // using NewRatio.
     flag_value = 20 * M;
     set_basic_flag_values();
-    FLAG_SET_ERGO(uintx, NewSize, flag_value);
+    FLAG_SET_ERGO(size_t, NewSize, flag_value);
     verify_young_min(flag_value);
 
     set_basic_flag_values();
-    FLAG_SET_ERGO(uintx, NewSize, flag_value);
+    FLAG_SET_ERGO(size_t, NewSize, flag_value);
     verify_scaled_young_initial(InitialHeapSize);
 
     restore_flags();
@@ -974,11 +978,11 @@
     // for both min and initial old size if less than min heap.
     flag_value = 20 * M;
     set_basic_flag_values();
-    FLAG_SET_CMDLINE(uintx, OldSize, flag_value);
+    FLAG_SET_CMDLINE(size_t, OldSize, flag_value);
     verify_old_min(flag_value);
 
     set_basic_flag_values();
-    FLAG_SET_CMDLINE(uintx, OldSize, flag_value);
+    FLAG_SET_CMDLINE(size_t, OldSize, flag_value);
     // Calculate what we expect the flag to be.
     size_t expected_old_initial = align_size_up(InitialHeapSize, heap_alignment) - MaxNewSize;
     verify_old_initial(expected_old_initial);
@@ -989,10 +993,10 @@
     // We intentionally set MaxNewSize + OldSize > MaxHeapSize (see over_size).
     flag_value = 30 * M;
     set_basic_flag_values();
-    FLAG_SET_CMDLINE(uintx, OldSize, flag_value);
+    FLAG_SET_CMDLINE(size_t, OldSize, flag_value);
     size_t over_size = 20*M;
     size_t new_size_value = align_size_up(MaxHeapSize, heap_alignment) - flag_value + over_size;
-    FLAG_SET_CMDLINE(uintx, MaxNewSize, new_size_value);
+    FLAG_SET_CMDLINE(size_t, MaxNewSize, new_size_value);
     // Calculate what we expect the flag to be.
     expected_old_initial = align_size_up(MaxHeapSize, heap_alignment) - MaxNewSize;
     verify_old_initial(expected_old_initial);
@@ -1053,11 +1057,11 @@
   static size_t original_OldSize;
 
   static void set_basic_flag_values() {
-    FLAG_SET_ERGO(uintx, MaxHeapSize, 180 * M);
-    FLAG_SET_ERGO(uintx, InitialHeapSize, 100 * M);
-    FLAG_SET_ERGO(uintx, OldSize, 4 * M);
-    FLAG_SET_ERGO(uintx, NewSize, 1 * M);
-    FLAG_SET_ERGO(uintx, MaxNewSize, 80 * M);
+    FLAG_SET_ERGO(size_t, MaxHeapSize, 180 * M);
+    FLAG_SET_ERGO(size_t, InitialHeapSize, 100 * M);
+    FLAG_SET_ERGO(size_t, OldSize, 4 * M);
+    FLAG_SET_ERGO(size_t, NewSize, 1 * M);
+    FLAG_SET_ERGO(size_t, MaxNewSize, 80 * M);
     Arguments::set_min_heap_size(40 * M);
   }
 
--- a/hotspot/src/share/vm/memory/defNewGeneration.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/memory/defNewGeneration.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -226,7 +226,7 @@
 
   compute_space_boundaries(0, SpaceDecorator::Clear, SpaceDecorator::Mangle);
   update_counters();
-  _next_gen = NULL;
+  _old_gen = NULL;
   _tenuring_threshold = MaxTenuringThreshold;
   _pretenure_size_threshold_words = PretenureSizeThreshold >> LogHeapWordSize;
 
@@ -383,8 +383,8 @@
   assert(next_level < gch->_n_gens,
          "DefNewGeneration cannot be an oldest gen");
 
-  Generation* next_gen = gch->get_gen(next_level);
-  size_t old_size = next_gen->capacity();
+  Generation* old_gen = gch->old_gen();
+  size_t old_size = old_gen->capacity();
   size_t new_size_before = _virtual_space.committed_size();
   size_t min_new_size = spec()->init_size();
   size_t max_new_size = reserved().byte_size();
@@ -568,7 +568,7 @@
   DefNewTracer gc_tracer;
   gc_tracer.report_gc_start(gch->gc_cause(), _gc_timer->gc_start());
 
-  _next_gen = gch->next_gen(this);
+  _old_gen = gch->old_gen();
 
   // If the next generation is too full to accommodate promotion
   // from this generation, pass on collection; let the next generation
@@ -590,8 +590,6 @@
 
   gch->trace_heap_before_gc(&gc_tracer);
 
-  SpecializationStats::clear();
-
   // These can be shared for all code paths
   IsAliveClosure is_alive(this);
   ScanWeakRefClosure scan_weak_ref(this);
@@ -628,7 +626,7 @@
                          true,  // Process younger gens, if any,
                                 // as strong roots.
                          true,  // activate StrongRootsScope
-                         SharedHeap::SO_ScavengeCodeCache,
+                         GenCollectedHeap::SO_ScavengeCodeCache,
                          GenCollectedHeap::StrongAndWeakRoots,
                          &fsc_with_no_gc_barrier,
                          &fsc_with_gc_barrier,
@@ -688,7 +686,7 @@
     gch->set_incremental_collection_failed();
 
     // Inform the next generation that a promotion failure occurred.
-    _next_gen->promotion_failure_occurred();
+    _old_gen->promotion_failure_occurred();
     gc_tracer.report_promotion_failed(_promotion_failed_info);
 
     // Reset the PromotionFailureALot counters.
@@ -700,7 +698,6 @@
   // set new iteration safe limit for the survivor spaces
   from()->set_concurrent_iteration_safe_limit(from()->top());
   to()->set_concurrent_iteration_safe_limit(to()->top());
-  SpecializationStats::print();
 
   // We need to use a monotonically non-decreasing time in ms
   // or we will see time-warp warnings and os::javaTimeMillis()
@@ -793,7 +790,7 @@
 
   // Otherwise try allocating obj tenured
   if (obj == NULL) {
-    obj = _next_gen->promote(old, s);
+    obj = _old_gen->promote(old, s);
     if (obj == NULL) {
       handle_promotion_failure(old);
       return old;
@@ -898,11 +895,11 @@
     }
     return false;
   }
-  if (_next_gen == NULL) {
+  if (_old_gen == NULL) {
     GenCollectedHeap* gch = GenCollectedHeap::heap();
-    _next_gen = gch->next_gen(this);
+    _old_gen = gch->old_gen();
   }
-  return _next_gen->promotion_attempt_is_safe(used());
+  return _old_gen->promotion_attempt_is_safe(used());
 }
 
 void DefNewGeneration::gc_epilogue(bool full) {
@@ -1022,8 +1019,7 @@
   return eden();
 }
 
-HeapWord* DefNewGeneration::allocate(size_t word_size,
-                                     bool is_tlab) {
+HeapWord* DefNewGeneration::allocate(size_t word_size, bool is_tlab) {
   // This is the slow-path allocation for the DefNewGeneration.
   // Most allocations are fast-path in compiled code.
   // We try to allocate from the eden.  If that works, we are happy.
@@ -1031,8 +1027,8 @@
   // have to use it here, as well.
   HeapWord* result = eden()->par_allocate(word_size);
   if (result != NULL) {
-    if (CMSEdenChunksRecordAlways && _next_gen != NULL) {
-      _next_gen->sample_eden_chunk();
+    if (CMSEdenChunksRecordAlways && _old_gen != NULL) {
+      _old_gen->sample_eden_chunk();
     }
   } else {
     // If the eden is full and the last collection bailed out, we are running
@@ -1047,8 +1043,8 @@
 HeapWord* DefNewGeneration::par_allocate(size_t word_size,
                                          bool is_tlab) {
   HeapWord* res = eden()->par_allocate(word_size);
-  if (CMSEdenChunksRecordAlways && _next_gen != NULL) {
-    _next_gen->sample_eden_chunk();
+  if (CMSEdenChunksRecordAlways && _old_gen != NULL) {
+    _old_gen->sample_eden_chunk();
   }
   return res;
 }
--- a/hotspot/src/share/vm/memory/defNewGeneration.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/memory/defNewGeneration.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, 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
@@ -29,11 +29,14 @@
 #include "gc_implementation/shared/cSpaceCounters.hpp"
 #include "gc_implementation/shared/generationCounters.hpp"
 #include "gc_implementation/shared/copyFailedInfo.hpp"
+#include "memory/generation.hpp"
 #include "utilities/stack.hpp"
 
 class ContiguousSpace;
 class ScanClosure;
 class STWGCTimer;
+class CSpaceCounters;
+class ScanWeakRefClosure;
 
 // DefNewGeneration is a young generation containing eden, from- and
 // to-space.
@@ -42,7 +45,7 @@
   friend class VMStructs;
 
 protected:
-  Generation* _next_gen;
+  Generation* _old_gen;
   uint        _tenuring_threshold;   // Tenuring threshold for next collection.
   ageTable    _age_table;
   // Size of object to pretenure in words; command line provides bytes
--- a/hotspot/src/share/vm/memory/defNewGeneration.inline.hpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/memory/defNewGeneration.inline.hpp	Fri Mar 27 14:52:45 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, 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,8 +25,10 @@
 #ifndef SHARE_VM_MEMORY_DEFNEWGENERATION_INLINE_HPP
 #define SHARE_VM_MEMORY_DEFNEWGENERATION_INLINE_HPP
 
+#include "gc_interface/collectedHeap.hpp"
 #include "memory/cardTableRS.hpp"
 #include "memory/defNewGeneration.hpp"
+#include "memory/genOopClosures.inline.hpp"
 #include "memory/space.hpp"
 
 // Methods of protected closure types
--- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp	Fri Mar 27 10:57:42 2015 +0100
+++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp	Fri Mar 27 14:52:45 2015 +0000
@@ -26,6 +26,7 @@
 #include "classfile/symbolTable.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
+#include "code/codeCache.hpp"
 #include "code/icBuffer.hpp"
 #include "gc_implementation/shared/collectorCounters.hpp"
 #include "gc_implementation/shared/gcTrace.hpp"
@@ -47,6 +48,7 @@
 #include "runtime/handles.inline.hpp"
 #include "runtime/java.hpp"
 #include "runtime/vmThread.hpp"
+#include "services/management.hpp"
 #include "services/memoryService.hpp"
 #include "utilities/vmError.hpp"
 #include "utilities/workgroup.hpp"
@@ -61,7 +63,15 @@
 
 // The set of potentially parallel tasks in root scanning.
 enum GCH_strong_roots_tasks {
-  // We probably want to parallelize both of these internally, but for now...
+  GCH_PS_Universe_oops_do,
+  GCH_PS_JNIHandles_oops_do,
+  GCH_PS_ObjectSynchronizer_oops_do,
+  GCH_PS_FlatProfiler_oops_do,
+  GCH_PS_Management_oops_do,
+  GCH_PS_SystemDictionary_oops_do,
+  GCH_PS_ClassLoaderDataGraph_oops_do,
+  GCH_PS_jvmti_oops_do,
+  GCH_PS_CodeCache_oops_do,
   GCH_PS_younger_gens,
   // Leave this one last.
   GCH_PS_NumElements
@@ -71,13 +81,9 @@
   SharedHeap(policy),
   _rem_set(NULL),
   _gen_policy(policy),
-  _gen_process_roots_tasks(new SubTasksDone(GCH_PS_NumElements)),
+  _process_strong_tasks(new SubTasksDone(GCH_PS_NumElements)),
   _full_collections_completed(0)
 {
-  if (_gen_process_roots_tasks == NULL ||
-      !_gen_process_roots_tasks->valid()) {
-    vm_exit_during_initialization("Failed necessary allocation.");
-  }
   assert(policy != NULL, "Sanity check");
 }
 
@@ -177,18 +183,17 @@
   SharedHeap::post_initialize();
   GenCollectorPolicy *policy = (GenCollectorPolicy *)collector_policy();
   guarantee(policy->is_generation_policy(), "Illegal policy type");
-  assert((get_gen(0)->kind() == Generation::DefNew) ||
-         (get_gen(0)->kind() == Generation::ParNew),
+  assert((_young_gen->kind() == Generation::DefNew) ||
+         (_young_gen->kind() == Generation::ParNew),
     "Wrong youngest generation type");
-  DefNewGeneration* def_new_gen = (DefNewGeneration*)get_gen(0);
+  DefNewGeneration* def_new_gen = (DefNewGeneration*)_young_gen;
 
-  Generation* old_gen = get_gen(1);
-  assert(old_gen->kind() == Generation::ConcurrentMarkSweep ||
-         old_gen->kind() == Generation::MarkSweepCompact,
+  assert(_old_gen->kind() == Generation::ConcurrentMarkSweep ||
+         _old_gen->kind() == Generation::MarkSweepCompact,
     "Wrong generation kind");
 
   policy->initialize_size_policy(def_new_gen->eden()->capacity(),
-                                 old_gen->capacity(),
+                                 _old_gen->capacity(),
                                  def_new_gen->from()->capacity());
   policy->initialize_gc_policy_counters();
 }
@@ -570,29 +575,137 @@
 
 void GenCollectedHeap::set_par_threads(uint t) {
   SharedHeap::set_par_threads(t);
-  _gen_process_roots_tasks->set_n_threads(t);
+  set_n_termination(t);
 }
 
-void GenCollectedHeap::
-gen_process_roots(int level,
-                  bool younger_gens_as_roots,
-                  bool activate_scope,
-                  SharedHeap::ScanningOption so,
-                  OopsInGenClosure* not_older_gens,
-                  OopsInGenClosure* weak_roots,
-                  OopsInGenClosure* older_gens,
-                  CLDClosure* cld_closure,
-                  CLDClosure* weak_cld_closure,
-                  CodeBlobClosure* code_closure) {
+void GenCollectedHeap::set_n_termination(uint t) {
+  _process_strong_tasks->set_n_threads(t);
+}
+
+#ifdef ASSERT
+class AssertNonScavengableClosure: public OopClosure {
+public:
+  virtual void do_oop(oop* p) {