changeset 7659:5cf403c92ec4

Merge
author iignatyev
date Fri, 12 Dec 2014 21:32:43 +0300
parents 239c6f5f0db3 9150dc2bebca
children 94df826bd8ec
files agent/src/share/classes/sun/jvm/hotspot/memory/OneContigSpaceCardGeneration.java make/solaris/makefiles/add_gnu_debuglink.make make/solaris/makefiles/fix_empty_sec_hdr_flags.make src/os/solaris/add_gnu_debuglink/add_gnu_debuglink.c src/os/solaris/fix_empty_sec_hdr_flags/fix_empty_sec_hdr_flags.c src/share/vm/memory/generation.inline.hpp test/compiler/5057225/Test5057225.java test/compiler/5091921/Test5091921.java test/compiler/5091921/Test6186134.java test/compiler/5091921/Test6196102.java test/compiler/5091921/Test6357214.java test/compiler/5091921/Test6559156.java test/compiler/5091921/Test6753639.java test/compiler/5091921/Test6850611.java test/compiler/5091921/Test6890943.java test/compiler/5091921/Test6897150.java test/compiler/5091921/Test6905845.java test/compiler/5091921/Test6931567.java test/compiler/5091921/Test6935022.java test/compiler/5091921/Test6959129.java test/compiler/5091921/Test6985295.java test/compiler/5091921/Test6992759.java test/compiler/5091921/Test7005594.java test/compiler/5091921/Test7005594.sh test/compiler/5091921/Test7020614.java test/compiler/5091921/input6890943.txt test/compiler/5091921/output6890943.txt test/compiler/6340864/TestByteVect.java test/compiler/6340864/TestDoubleVect.java test/compiler/6340864/TestFloatVect.java test/compiler/6340864/TestIntVect.java test/compiler/6340864/TestLongVect.java test/compiler/6340864/TestShortVect.java test/compiler/6378821/Test6378821.java test/compiler/6431242/Test.java test/compiler/6443505/Test6443505.java test/compiler/6478991/NullCheckTest.java test/compiler/6539464/Test.java test/compiler/6579789/Test6579789.java test/compiler/6589834/InlinedArrayCloneTestCase.java test/compiler/6589834/Test_ia32.java test/compiler/6603011/Test.java test/compiler/6636138/Test1.java test/compiler/6636138/Test2.java test/compiler/6646019/Test.java test/compiler/6646020/Tester.java test/compiler/6659207/Test.java test/compiler/6661247/Test.java test/compiler/6663621/IVTest.java test/compiler/6663848/Tester.java test/compiler/6663854/Test6663854.java test/compiler/6689060/Test.java test/compiler/6695810/Test.java test/compiler/6700047/Test6700047.java test/compiler/6711100/Test.java test/compiler/6711117/Test.java test/compiler/6712835/Test6712835.java test/compiler/6714694/Tester.java test/compiler/6716441/Tester.java test/compiler/6724218/Test.java test/compiler/6726999/Test.java test/compiler/6732154/Test6732154.java test/compiler/6741738/Tester.java test/compiler/6756768/Test6756768.java test/compiler/6756768/Test6756768_2.java test/compiler/6757316/Test6757316.java test/compiler/6758234/Test6758234.java test/compiler/6769124/TestArrayCopy6769124.java test/compiler/6769124/TestDeoptInt6769124.java test/compiler/6769124/TestUnalignedLoad6769124.java test/compiler/6772683/InterruptedTest.java test/compiler/6775880/Test.java test/compiler/6778657/Test.java test/compiler/6792161/Test6792161.java test/compiler/6795161/Test.java test/compiler/6795362/Test6795362.java test/compiler/6795465/Test6795465.java test/compiler/6796786/Test6796786.java test/compiler/6797305/Test6797305.java test/compiler/6799693/Test.java test/compiler/6800154/Test6800154.java test/compiler/6805724/Test6805724.java test/compiler/6814842/Test6814842.java test/compiler/6823354/Test6823354.java test/compiler/6823453/Test.java test/compiler/6826736/Test.java test/compiler/6832293/Test.java test/compiler/6833129/Test.java test/compiler/6837011/Test6837011.java test/compiler/6837094/Test.java test/compiler/6843752/Test.java test/compiler/6849574/Test.java test/compiler/6851282/Test.java test/compiler/6852078/Test6852078.java test/compiler/6855164/Test.java test/compiler/6855215/Test6855215.java test/compiler/6857159/Test6857159.java test/compiler/6857159/Test6857159.sh test/compiler/6859338/Test6859338.java test/compiler/6860469/Test.java test/compiler/6863155/Test6863155.java test/compiler/6863420/Test.java test/compiler/6865031/Test.java test/compiler/6865265/StackOverflowBug.java test/compiler/6866651/Test.java test/compiler/6875866/Test.java test/compiler/6877254/Test.java test/compiler/6879902/Test6879902.java test/compiler/6880034/Test6880034.java test/compiler/6885584/Test6885584.java test/compiler/6891750/Test6891750.java test/compiler/6892265/Test.java test/compiler/6894807/IsInstanceTest.java test/compiler/6894807/Test6894807.sh test/compiler/6895383/Test.java test/compiler/6896617/Test6896617.java test/compiler/6896727/Test.java test/compiler/6901572/Test.java test/compiler/6909839/Test6909839.java test/compiler/6910484/Test.java test/compiler/6910605/Test.java test/compiler/6910618/Test.java test/compiler/6912517/Test.java test/compiler/6916644/Test6916644.java test/compiler/6921969/TestMultiplyLongHiZero.java test/compiler/6930043/Test6930043.java test/compiler/6932496/Test6932496.java test/compiler/6934604/TestByteBoxing.java test/compiler/6934604/TestDoubleBoxing.java test/compiler/6934604/TestFloatBoxing.java test/compiler/6934604/TestIntBoxing.java test/compiler/6934604/TestLongBoxing.java test/compiler/6934604/TestShortBoxing.java test/compiler/6935535/Test.java test/compiler/6942326/Test.java test/compiler/6946040/TestCharShortByteSwap.java test/compiler/6956668/Test6956668.java test/compiler/6958485/Test.java test/compiler/6968348/Test6968348.java test/compiler/6973329/Test.java test/compiler/6982370/Test6982370.java test/compiler/6990212/Test6990212.java test/compiler/7002666/Test7002666.java test/compiler/7009231/Test7009231.java test/compiler/7009359/Test7009359.java test/compiler/7017746/Test.java test/compiler/7024475/Test7024475.java test/compiler/7029152/Test.java test/compiler/7041100/Test7041100.java test/compiler/7042153/Test7042153.java test/compiler/7044738/Test7044738.java test/compiler/7046096/Test7046096.java test/compiler/7047069/Test7047069.java test/compiler/7048332/Test7048332.java test/compiler/7052494/Test7052494.java test/compiler/7068051/Test7068051.java test/compiler/7070134/Stemmer.java test/compiler/7070134/Test7070134.sh test/compiler/7070134/words test/compiler/7082949/Test7082949.java test/compiler/7088020/Test7088020.java test/compiler/7088419/CRCTest.java test/compiler/7090976/Test7090976.java test/compiler/7100757/Test7100757.java test/compiler/7103261/Test7103261.java test/compiler/7110586/Test7110586.java test/compiler/7116216/LargeFrame.java test/compiler/7116216/StackOverflow.java test/compiler/7119644/TestBooleanVect.java test/compiler/7119644/TestByteDoubleVect.java test/compiler/7119644/TestByteFloatVect.java test/compiler/7119644/TestByteIntVect.java test/compiler/7119644/TestByteLongVect.java test/compiler/7119644/TestByteShortVect.java test/compiler/7119644/TestByteVect.java test/compiler/7119644/TestCharShortVect.java test/compiler/7119644/TestCharVect.java test/compiler/7119644/TestDoubleVect.java test/compiler/7119644/TestFloatDoubleVect.java test/compiler/7119644/TestFloatVect.java test/compiler/7119644/TestIntDoubleVect.java test/compiler/7119644/TestIntFloatVect.java test/compiler/7119644/TestIntLongVect.java test/compiler/7119644/TestIntVect.java test/compiler/7119644/TestLongDoubleVect.java test/compiler/7119644/TestLongFloatVect.java test/compiler/7119644/TestLongVect.java test/compiler/7119644/TestShortDoubleVect.java test/compiler/7119644/TestShortFloatVect.java test/compiler/7119644/TestShortIntVect.java test/compiler/7119644/TestShortLongVect.java test/compiler/7119644/TestShortVect.java test/compiler/7123108/Test7123108.java test/compiler/7125879/Test7125879.java test/compiler/7141637/SpreadNullArg.java test/compiler/7160610/Test7160610.java test/compiler/7169782/Test7169782.java test/compiler/7174363/Test7174363.java test/compiler/7177917/Test7177917.java test/compiler/7179138/Test7179138_1.java test/compiler/7179138/Test7179138_2.java test/compiler/7184394/TestAESBase.java test/compiler/7184394/TestAESDecode.java test/compiler/7184394/TestAESEncode.java test/compiler/7184394/TestAESMain.java test/compiler/7190310/Test7190310.java test/compiler/7190310/Test7190310_unsafe.java test/compiler/7192963/TestByteVect.java test/compiler/7192963/TestDoubleVect.java test/compiler/7192963/TestFloatVect.java test/compiler/7192963/TestIntVect.java test/compiler/7192963/TestLongVect.java test/compiler/7192963/TestShortVect.java test/compiler/7196199/Test7196199.java test/compiler/7199742/Test7199742.java test/compiler/7200264/Test7200264.sh test/compiler/7200264/TestIntVect.java test/compiler/8000805/Test8000805.java test/compiler/8001183/TestCharVect.java test/compiler/8002069/Test8002069.java test/compiler/8004051/Test8004051.java test/compiler/8004741/Test8004741.java test/compiler/8004867/TestIntAtomicCAS.java test/compiler/8004867/TestIntAtomicOrdered.java test/compiler/8004867/TestIntAtomicVolatile.java test/compiler/8004867/TestIntUnsafeCAS.java test/compiler/8004867/TestIntUnsafeOrdered.java test/compiler/8004867/TestIntUnsafeVolatile.java test/compiler/8005033/Test8005033.java test/compiler/8005419/Test8005419.java test/compiler/8005956/PolynomialRoot.java test/compiler/8007294/Test8007294.java test/compiler/8007722/Test8007722.java test/compiler/8009761/Test8009761.java test/compiler/8010927/Test8010927.java test/compiler/8011706/Test8011706.java test/compiler/8011771/Test8011771.java test/compiler/8011901/Test8011901.java test/compiler/8015436/Test8015436.java test/compiler/EliminateAutoBox/UnsignedLoads.java test/compiler/EscapeAnalysis/Test8020215.java test/compiler/EscapeAnalysis/TestAllocatedEscapesPtrComparison.java test/compiler/EscapeAnalysis/TestUnsafePutAddressNullObjMustNotEscape.java test/compiler/IntegerArithmetic/TestIntegerComparison.java
diffstat 776 files changed, 170153 insertions(+), 167415 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Wed Dec 10 13:58:30 2014 +0000
+++ b/.hgtags	Fri Dec 12 21:32:43 2014 +0300
@@ -442,3 +442,5 @@
 b1c2dd843f247a1db19e1e85eb62ca405f72dc26 jdk9-b37
 c363a8b87e477ee45d6d3cb2a36cb365141bc596 jdk9-b38
 9cb75e5e394827ccbaf2e15524108a412dc4ddc5 jdk9-b39
+6b09b3193d731e3288e2a240c504a20d0a06c766 jdk9-b40
+1d29b13e8a515a7ea3b882f140576d5d675bc11f jdk9-b41
--- a/agent/src/share/classes/sun/jvm/hotspot/memory/Generation.java	Wed Dec 10 13:58:30 2014 +0000
+++ b/agent/src/share/classes/sun/jvm/hotspot/memory/Generation.java	Fri Dec 12 21:32:43 2014 +0300
@@ -37,10 +37,7 @@
       <ul>
       <li> CardGeneration
         <ul>
-        <li> OneContigSpaceCardGeneration
-          <ul>
-          <li> TenuredGeneration
-          </ul>
+        <li> TenuredGeneration
         </ul>
       <li> DefNewGeneration
       </ul>
--- a/agent/src/share/classes/sun/jvm/hotspot/memory/OneContigSpaceCardGeneration.java	Wed Dec 10 13:58:30 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.memory;
-
-import java.io.*;
-import java.util.*;
-
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.runtime.*;
-import sun.jvm.hotspot.types.*;
-
-/** <P> OneSpaceOldGeneration models a heap of old objects contained
-    in a single contiguous space. </P>
-
-    <P> Garbage collection is performed using mark-compact. </P> */
-
-public abstract class OneContigSpaceCardGeneration extends CardGeneration {
-  private static AddressField theSpaceField;
-
-  static {
-    VM.registerVMInitializedObserver(new Observer() {
-        public void update(Observable o, Object data) {
-          initialize(VM.getVM().getTypeDataBase());
-        }
-      });
-  }
-
-  private static synchronized void initialize(TypeDataBase db) {
-    Type type = db.lookupType("OneContigSpaceCardGeneration");
-
-    theSpaceField = type.getAddressField("_the_space");
-  }
-
-  public OneContigSpaceCardGeneration(Address addr) {
-    super(addr);
-  }
-
-  public ContiguousSpace theSpace() {
-    return (ContiguousSpace) VMObjectFactory.newObject(ContiguousSpace.class, theSpaceField.getValue(addr));
-  }
-
-  public boolean isIn(Address p) {
-    return theSpace().contains(p);
-  }
-
-  /** Space queries */
-  public long capacity()            { return theSpace().capacity();                                }
-  public long used()                { return theSpace().used();                                    }
-  public long free()                { return theSpace().free();                                    }
-  public long contiguousAvailable() { return theSpace().free() + virtualSpace().uncommittedSize(); }
-
-  public void spaceIterate(SpaceClosure blk, boolean usedOnly) {
-    blk.doSpace(theSpace());
-  }
-
-  public void printOn(PrintStream tty) {
-    tty.print("  old ");
-    theSpace().printOn(tty);
-  }
-}
--- a/agent/src/share/classes/sun/jvm/hotspot/memory/TenuredGeneration.java	Wed Dec 10 13:58:30 2014 +0000
+++ b/agent/src/share/classes/sun/jvm/hotspot/memory/TenuredGeneration.java	Fri Dec 12 21:32:43 2014 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2014, 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
@@ -24,13 +24,62 @@
 
 package sun.jvm.hotspot.memory;
 
+import java.io.*;
+import java.util.*;
+
 import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.types.*;
 
-public class TenuredGeneration extends OneContigSpaceCardGeneration {
+/** <P> TenuredGeneration models a heap of old objects contained
+    in a single contiguous space. </P>
+
+    <P> Garbage collection is performed using mark-compact. </P> */
+
+public class TenuredGeneration extends CardGeneration {
+  private static AddressField theSpaceField;
+
+  static {
+    VM.registerVMInitializedObserver(new Observer() {
+        public void update(Observable o, Object data) {
+          initialize(VM.getVM().getTypeDataBase());
+        }
+      });
+  }
+
+  private static synchronized void initialize(TypeDataBase db) {
+    Type type = db.lookupType("TenuredGeneration");
+
+    theSpaceField = type.getAddressField("_the_space");
+  }
+
   public TenuredGeneration(Address addr) {
     super(addr);
   }
 
+  public ContiguousSpace theSpace() {
+    return (ContiguousSpace) VMObjectFactory.newObject(ContiguousSpace.class, theSpaceField.getValue(addr));
+  }
+
+  public boolean isIn(Address p) {
+    return theSpace().contains(p);
+  }
+
+  /** Space queries */
+  public long capacity()            { return theSpace().capacity();                                }
+  public long used()                { return theSpace().used();                                    }
+  public long free()                { return theSpace().free();                                    }
+  public long contiguousAvailable() { return theSpace().free() + virtualSpace().uncommittedSize(); }
+
+  public void spaceIterate(SpaceClosure blk, boolean usedOnly) {
+    blk.doSpace(theSpace());
+  }
+
+  public void printOn(PrintStream tty) {
+    tty.print("  old ");
+    theSpace().printOn(tty);
+  }
+
   public Generation.Name kind() {
     return Generation.Name.MARK_SWEEP_COMPACT;
   }
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/OopUtilities.java	Wed Dec 10 13:58:30 2014 +0000
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/OopUtilities.java	Fri Dec 12 21:32:43 2014 +0300
@@ -219,7 +219,7 @@
     if (threadNameField == null) {
       SystemDictionary sysDict = VM.getVM().getSystemDictionary();
       InstanceKlass k = sysDict.getThreadKlass();
-      threadNameField  = (OopField) k.findField("name", "[C");
+      threadNameField  = (OopField) k.findField("name", "Ljava/lang/String;");
       threadGroupField = (OopField) k.findField("group", "Ljava/lang/ThreadGroup;");
       threadEETopField = (LongField) k.findField("eetop", "J");
       threadTIDField = (LongField) k.findField("tid", "J");
@@ -258,7 +258,7 @@
 
   public static String threadOopGetName(Oop threadOop) {
     initThreadFields();
-    return charArrayToString((TypeArray) threadNameField.getValue(threadOop));
+    return stringOopToString(threadNameField.getValue(threadOop));
   }
 
   /** May return null if, e.g., thread was not started */
--- a/make/bsd/makefiles/sa.make	Wed Dec 10 13:58:30 2014 +0000
+++ b/make/bsd/makefiles/sa.make	Fri Dec 12 21:32:43 2014 +0300
@@ -40,6 +40,8 @@
 
 include $(GAMMADIR)/make/sa.files
 
+-include $(HS_ALT_MAKE)/bsd/makefiles/sa.make
+
 TOPDIR    = $(shell echo `pwd`)
 GENERATED = $(TOPDIR)/../generated
 
@@ -63,6 +65,10 @@
   SA_CLASSPATH=$(shell test -f $(ALT_SA_CLASSPATH) && echo $(ALT_SA_CLASSPATH))
 endif
 
+ifneq ($(SA_CLASSPATH),)
+  SA_CLASSPATH_ARG := -classpath $(SA_CLASSPATH)
+endif
+
 # TODO: if it's a modules image, check if SA module is installed.
 MODULELIB_PATH= $(BOOT_JAVA_HOME)/lib/modules
 
@@ -114,7 +120,7 @@
 # are in AGENT_FILES, so use the shell to expand them.
 # Be extra carefull to not produce too long command lines in the shell!
 	$(foreach file,$(AGENT_FILES),$(shell ls -1 $(file) >> $(AGENT_FILES_LIST)))
-	$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) @$(AGENT_FILES_LIST)
+	$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) $(SA_CLASSPATH_ARG) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) @$(AGENT_FILES_LIST)
 	$(QUIETLY) $(REMOTE) $(COMPILE.RMIC)  -classpath $(SA_CLASSDIR) -d $(SA_CLASSDIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
 	$(QUIETLY) echo "$(SA_BUILD_VERSION_PROP)" > $(SA_PROPERTIES)
 	$(QUIETLY) rm -f $(SA_CLASSDIR)/sun/jvm/hotspot/utilities/soql/sa.js
--- a/make/solaris/makefiles/add_gnu_debuglink.make	Wed Dec 10 13:58:30 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-#
-# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#  
-#
-
-# Rules to build add_gnu_debuglink, used by vm.make on Solaris
-
-# Allow $(ADD_GNU_DEBUGLINK) to be called from any directory.
-# We don't set or use the GENERATED macro to avoid affecting
-# other HotSpot Makefiles.
-TOPDIR                    = $(shell echo `pwd`)
-ADD_GNU_DEBUGLINK         = $(TOPDIR)/../generated/add_gnu_debuglink
-
-ADD_GNU_DEBUGLINK_DIR     = $(GAMMADIR)/src/os/solaris/add_gnu_debuglink
-ADD_GNU_DEBUGLINK_SRC     = $(ADD_GNU_DEBUGLINK_DIR)/add_gnu_debuglink.c
-ADD_GNU_DEBUGLINK_FLAGS   = 
-LIBS_ADD_GNU_DEBUGLINK   += -lelf
-
-ifeq ("${Platform_compiler}", "sparcWorks")
-# Enable the following ADD_GNU_DEBUGLINK_FLAGS addition if you need to
-# compare the built ELF objects.
-#
-# The -g option makes static data global and the "-W0,-noglobal"
-# option tells the compiler to not globalize static data using a unique
-# globalization prefix. Instead force the use of a static globalization
-# prefix based on the source filepath so the objects from two identical
-# compilations are the same.
-#
-# Note: The blog says to use "-W0,-xglobalstatic", but that doesn't
-#       seem to work. I got "-W0,-noglobal" from Kelly and that works.
-#ADD_GNU_DEBUGLINK_FLAGS += -W0,-noglobal
-endif # Platform_compiler == sparcWorks
-
-$(ADD_GNU_DEBUGLINK): $(ADD_GNU_DEBUGLINK_SRC)
-	$(CC) -g -o $@ $< $(ADD_GNU_DEBUGLINK_FLAGS) $(LIBS_ADD_GNU_DEBUGLINK)
--- a/make/solaris/makefiles/defs.make	Wed Dec 10 13:58:30 2014 +0000
+++ b/make/solaris/makefiles/defs.make	Fri Dec 12 21:32:43 2014 +0300
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2014, 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
@@ -138,6 +138,55 @@
         OBJCOPY=$(shell test -x $(ALT_OBJCOPY) && echo $(ALT_OBJCOPY))
       endif
 
+      ifneq ($(OBJCOPY),)
+        # OBJCOPY version check:
+        # - version number is last blank separate word on first line
+        # - version number formats that have been seen:
+        #   - <major>.<minor>
+        #   - <major>.<minor>.<micro>
+        #
+        # Full Debug Symbols on Solaris needs version 2.21.1 or newer.
+        #
+        OBJCOPY_VERS_CHK := $(shell \
+          $(OBJCOPY) --version \
+            | sed -n \
+                  -e 's/.* //' \
+                  -e '/^[01]\./b bad' \
+                  -e '/^2\./{' \
+                  -e '  s/^2\.//' \
+                  -e '  /^[0-9]$$/b bad' \
+                  -e '  /^[0-9]\./b bad' \
+                  -e '  /^1[0-9]$$/b bad' \
+                  -e '  /^1[0-9]\./b bad' \
+                  -e '  /^20\./b bad' \
+                  -e '  /^21\.0$$/b bad' \
+                  -e '  /^21\.0\./b bad' \
+                  -e '}' \
+                  -e ':good' \
+                  -e 's/.*/VALID_VERSION/p' \
+                  -e 'q' \
+                  -e ':bad' \
+                  -e 's/.*/BAD_VERSION/p' \
+                  -e 'q' \
+          )
+        ifeq ($(OBJCOPY_VERS_CHK),BAD_VERSION)
+          _JUNK_ := $(shell \
+            echo >&2 "WARNING: $(OBJCOPY) --version info:"; \
+            $(OBJCOPY) --version | sed -n -e 's/^/WARNING: /p' -e 'q' >&2; \
+            echo >&2 "WARNING: an objcopy version of 2.21.1 or newer" \
+              "is needed to create valid .debuginfo files."; \
+            echo >&2 "WARNING: ignoring above objcopy command."; \
+            echo >&2 "WARNING: patch 149063-01 or newer contains the" \
+              "correct Solaris 10 SPARC version."; \
+            echo >&2 "WARNING: patch 149064-01 or newer contains the" \
+              "correct Solaris 10 X86 version."; \
+            echo >&2 "WARNING: Solaris 11 Update 1 contains the" \
+              "correct version."; \
+            )
+          OBJCOPY=
+        endif
+      endif
+
       ifeq ($(OBJCOPY),)
         $(eval $(call print_info, "no objcopy cmd found so cannot create .debuginfo files."))
         ENABLE_FULL_DEBUG_SYMBOLS=0
--- a/make/solaris/makefiles/dtrace.make	Wed Dec 10 13:58:30 2014 +0000
+++ b/make/solaris/makefiles/dtrace.make	Fri Dec 12 21:32:43 2014 +0300
@@ -101,25 +101,16 @@
 XLIBJVM_DTRACE_DEBUGINFO   = $(XLIBJVM_DIR)/$(LIBJVM_DTRACE_DEBUGINFO)
 XLIBJVM_DTRACE_DIZ         = $(XLIBJVM_DIR)/$(LIBJVM_DTRACE_DIZ)
 
-$(XLIBJVM_DB): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS).h $(LIBJVM_DB_MAPFILE)
+$(XLIBJVM_DB): $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS).h $(LIBJVM_DB_MAPFILE)
 	@echo $(LOG_INFO) Making $@
 	$(QUIETLY) mkdir -p $(XLIBJVM_DIR) ; \
 	$(CC) $(SYMFLAG) $(ARCHFLAG/$(ISA)) -D$(TYPE) -I. -I$(GENERATED) \
 		$(SHARED_FLAG) $(LFLAGS_JVM_DB) -o $@ $(DTRACE_SRCDIR)/$(JVM_DB).c -lc
 ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
-# gobjcopy crashes on "empty" section headers with the SHF_ALLOC flag set.
-# Clear the SHF_ALLOC flag (if set) from empty section headers.
-# An empty section header has sh_addr == 0 and sh_size == 0.
-# This problem has only been seen on Solaris X64, but we call this tool
-# on all Solaris builds just in case.
-	$(QUIETLY) $(FIX_EMPTY_SEC_HDR_FLAGS) $@
 	$(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(XLIBJVM_DB_DEBUGINFO)
-# $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections.
-# Use $(ADD_GNU_DEBUGLINK) until a fixed $(OBJCOPY) is available.
-#         $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DB_DEBUGINFO) $(LIBJVM_DB) ;
 # Do this part in the $(XLIBJVM_DIR) subdir so $(XLIBJVM_DIR) is not
 # in the link name:
-	( cd $(XLIBJVM_DIR) && $(ADD_GNU_DEBUGLINK) $(LIBJVM_DB_DEBUGINFO) $(LIBJVM_DB) )
+	( cd $(XLIBJVM_DIR) && $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DB_DEBUGINFO) $(LIBJVM_DB) )
   ifeq ($(STRIP_POLICY),all_strip)
 	$(QUIETLY) $(STRIP) $@
   else
@@ -136,20 +127,16 @@
   endif
 endif
 
-$(XLIBJVM_DTRACE): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE)
+$(XLIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE)
 	@echo $(LOG_INFO) Making $@
 	$(QUIETLY) mkdir -p $(XLIBJVM_DIR) ; \
 	$(CC) $(SYMFLAG) $(ARCHFLAG/$(ISA)) -D$(TYPE) -I. \
 		$(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c -lc -lthread -ldoor
 ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
-# Clear the SHF_ALLOC flag (if set) from empty section headers.
-	$(QUIETLY) $(FIX_EMPTY_SEC_HDR_FLAGS) $@
 	$(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(XLIBJVM_DTRACE_DEBUGINFO)
-# $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections.
-#         $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DTRACE_DEBUGINFO) $(LIBJVM_DTRACE) ;
 # Do this part in the $(XLIBJVM_DIR) subdir so $(XLIBJVM_DIR) is not
 # in the link name:
-	( cd $(XLIBJVM_DIR) && $(ADD_GNU_DEBUGLINK) $(LIBJVM_DTRACE_DEBUGINFO) $(LIBJVM_DTRACE) )
+	( cd $(XLIBJVM_DIR) && $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DTRACE_DEBUGINFO) $(LIBJVM_DTRACE) )
   ifeq ($(STRIP_POLICY),all_strip)
 	$(QUIETLY) $(STRIP) $@
   else
@@ -206,17 +193,13 @@
 $(JVMOFFS.o): $(JVMOFFS).h $(JVMOFFS).cpp 
 	$(QUIETLY) $(CXX) -c -I. -o $@ $(ARCHFLAG) -D$(TYPE) $(JVMOFFS).cpp
 
-$(LIBJVM_DB): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS.o) $(XLIBJVM_DB) $(LIBJVM_DB_MAPFILE)
+$(LIBJVM_DB): $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS.o) $(XLIBJVM_DB) $(LIBJVM_DB_MAPFILE)
 	@echo $(LOG_INFO) Making $@
 	$(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) -D$(TYPE) -I. -I$(GENERATED) \
 		$(SHARED_FLAG) $(LFLAGS_JVM_DB) -o $@ $(DTRACE_SRCDIR)/$(JVM_DB).c -lc
 ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
-# Clear the SHF_ALLOC flag (if set) from empty section headers.
-	$(QUIETLY) $(FIX_EMPTY_SEC_HDR_FLAGS) $@
 	$(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJVM_DB_DEBUGINFO)
-# $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections.
-#	$(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DB_DEBUGINFO) $@
-	$(QUIETLY) $(ADD_GNU_DEBUGLINK) $(LIBJVM_DB_DEBUGINFO) $@
+	$(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DB_DEBUGINFO) $@
   ifeq ($(STRIP_POLICY),all_strip)
 	$(QUIETLY) $(STRIP) $@
   else
@@ -231,17 +214,13 @@
   endif
 endif
 
-$(LIBJVM_DTRACE): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(XLIBJVM_DTRACE) $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE)
+$(LIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(XLIBJVM_DTRACE) $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE)
 	@echo $(LOG_INFO) Making $@
 	$(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) -D$(TYPE) -I.  \
 		$(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c -lc -lthread -ldoor
 ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
-# Clear the SHF_ALLOC flag (if set) from empty section headers.
-	$(QUIETLY) $(FIX_EMPTY_SEC_HDR_FLAGS) $@
 	$(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJVM_DTRACE_DEBUGINFO)
-# $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections.
-#	$(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DTRACE_DEBUGINFO) $@
-	$(QUIETLY) $(ADD_GNU_DEBUGLINK) $(LIBJVM_DTRACE_DEBUGINFO) $@
+	$(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DTRACE_DEBUGINFO) $@
   ifeq ($(STRIP_POLICY),all_strip)
 	$(QUIETLY) $(STRIP) $@
   else
--- a/make/solaris/makefiles/fix_empty_sec_hdr_flags.make	Wed Dec 10 13:58:30 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-#
-# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#  
-#
-
-# Rules to build fix_empty_sec_hdr_flags, used by vm.make on Solaris
-
-# Allow $(FIX_EMPTY_SEC_HDR_FLAGS) to be called from any directory.
-# We don't set or use the GENERATED macro to avoid affecting
-# other HotSpot Makefiles.
-TOPDIR                          = $(shell echo `pwd`)
-FIX_EMPTY_SEC_HDR_FLAGS         = $(TOPDIR)/../generated/fix_empty_sec_hdr_flags
-
-FIX_EMPTY_SEC_HDR_FLAGS_DIR     = $(GAMMADIR)/src/os/solaris/fix_empty_sec_hdr_flags
-FIX_EMPTY_SEC_HDR_FLAGS_SRC     = $(FIX_EMPTY_SEC_HDR_FLAGS_DIR)/fix_empty_sec_hdr_flags.c
-FIX_EMPTY_SEC_HDR_FLAGS_FLAGS   = 
-LIBS_FIX_EMPTY_SEC_HDR_FLAGS   += -lelf
-
-ifeq ("${Platform_compiler}", "sparcWorks")
-# Enable the following FIX_EMPTY_SEC_HDR_FLAGS_FLAGS addition if you need to
-# compare the built ELF objects.
-#
-# The -g option makes static data global and the "-W0,-noglobal"
-# option tells the compiler to not globalize static data using a unique
-# globalization prefix. Instead force the use of a static globalization
-# prefix based on the source filepath so the objects from two identical
-# compilations are the same.
-#
-# Note: The blog says to use "-W0,-xglobalstatic", but that doesn't
-#       seem to work. I got "-W0,-noglobal" from Kelly and that works.
-#FIX_EMPTY_SEC_HDR_FLAGS_FLAGS += -W0,-noglobal
-endif # Platform_compiler == sparcWorks
-
-$(FIX_EMPTY_SEC_HDR_FLAGS): $(FIX_EMPTY_SEC_HDR_FLAGS_SRC)
-	$(CC) -g -o $@ $< $(FIX_EMPTY_SEC_HDR_FLAGS_FLAGS) $(LIBS_FIX_EMPTY_SEC_HDR_FLAGS)
--- a/make/solaris/makefiles/gcc.make	Wed Dec 10 13:58:30 2014 +0000
+++ b/make/solaris/makefiles/gcc.make	Fri Dec 12 21:32:43 2014 +0300
@@ -226,18 +226,8 @@
 # Allow no optimizations.
 DEBUG_CFLAGS=-O0
 
-# Use the stabs format for debugging information (this is the default
-# on gcc-2.91). It's good enough, has all the information about line
-# numbers and local variables, and libjvm.so is only about 16M.
-# Change this back to "-g" if you want the most expressive format.
-# (warning: that could easily inflate libjvm.so to 150M!)
-# Note: The Itanium gcc compiler crashes when using -gstabs.
-DEBUG_CFLAGS/ia64  = -g
-DEBUG_CFLAGS/amd64 = -g
-DEBUG_CFLAGS += $(DEBUG_CFLAGS/$(BUILDARCH))
-ifeq ($(DEBUG_CFLAGS/$(BUILDARCH)),)
-  DEBUG_CFLAGS += -gstabs
-endif
+# Enable debug symbols
+DEBUG_CFLAGS += -g
 
 # Enable bounds checking.
 ifeq "$(shell expr \( $(CC_VER_MAJOR) \> 3 \) )" "1"
--- a/make/solaris/makefiles/jsig.make	Wed Dec 10 13:58:30 2014 +0000
+++ b/make/solaris/makefiles/jsig.make	Fri Dec 12 21:32:43 2014 +0300
@@ -47,22 +47,13 @@
 LFLAGS_JSIG += -mt -xnolib
 endif
 
-$(LIBJSIG): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(JSIGSRCDIR)/jsig.c $(LIBJSIG_MAPFILE)
+$(LIBJSIG): $(JSIGSRCDIR)/jsig.c $(LIBJSIG_MAPFILE)
 	@echo $(LOG_INFO) Making signal interposition lib...
 	$(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \
                          $(LFLAGS_JSIG) -o $@ $(JSIGSRCDIR)/jsig.c -ldl
 ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
-# gobjcopy crashes on "empty" section headers with the SHF_ALLOC flag set.
-# Clear the SHF_ALLOC flag (if set) from empty section headers.
-# An empty section header has sh_addr == 0 and sh_size == 0.
-# This problem has only been seen on Solaris X64, but we call this tool
-# on all Solaris builds just in case.
-	$(QUIETLY) $(FIX_EMPTY_SEC_HDR_FLAGS) $@
 	$(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJSIG_DEBUGINFO)
-# $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections.
-# Use $(ADD_GNU_DEBUGLINK) until a fixed $(OBJCOPY) is available.
-#	$(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJSIG_DEBUGINFO) $@
-	$(QUIETLY) $(ADD_GNU_DEBUGLINK) $(LIBJSIG_DEBUGINFO) $@
+	$(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJSIG_DEBUGINFO) $@
   ifeq ($(STRIP_POLICY),all_strip)
 	$(QUIETLY) $(STRIP) $@
   else
--- a/make/solaris/makefiles/saproc.make	Wed Dec 10 13:58:30 2014 +0000
+++ b/make/solaris/makefiles/saproc.make	Fri Dec 12 21:32:43 2014 +0300
@@ -90,7 +90,7 @@
 #SOLARIS_11_B159_OR_LATER=-DSOLARIS_11_B159_OR_LATER
 
 
-$(LIBSAPROC): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(SASRCFILES) $(SADISOBJ) $(SAMAPFILE)
+$(LIBSAPROC): $(SASRCFILES) $(SADISOBJ) $(SAMAPFILE)
 	$(QUIETLY) if [ "$(BOOT_JAVA_HOME)" = "" ]; then \
 	  echo "ALT_BOOTDIR, BOOTDIR or JAVA_HOME needs to be defined to build SA"; \
 	  exit 1; \
@@ -121,17 +121,8 @@
 	           -c -o $(SADISOBJ)
 
 ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
-# gobjcopy crashes on "empty" section headers with the SHF_ALLOC flag set.
-# Clear the SHF_ALLOC flag (if set) from empty section headers.
-# An empty section header has sh_addr == 0 and sh_size == 0.
-# This problem has only been seen on Solaris X64, but we call this tool
-# on all Solaris builds just in case.
-	$(QUIETLY) $(FIX_EMPTY_SEC_HDR_FLAGS) $@
 	$(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBSAPROC_DEBUGINFO)
-# $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections.
-# Use $(ADD_GNU_DEBUGLINK) until a fixed $(OBJCOPY) is available.
-#	$(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBSAPROC_DEBUGINFO) $@
-	$(QUIETLY) $(ADD_GNU_DEBUGLINK) $(LIBSAPROC_DEBUGINFO) $@
+	$(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBSAPROC_DEBUGINFO) $@
   ifeq ($(STRIP_POLICY),all_strip)
 	$(QUIETLY) $(STRIP) $@
   else
--- a/make/solaris/makefiles/sparcWorks.make	Wed Dec 10 13:58:30 2014 +0000
+++ b/make/solaris/makefiles/sparcWorks.make	Fri Dec 12 21:32:43 2014 +0300
@@ -496,15 +496,6 @@
   FASTDEBUG_CFLAGS += -xs
 endif
 
-# Special global options for SS12
-ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \>= 509), 1)
-  # There appears to be multiple issues with the new Dwarf2 debug format, so
-  #   we tell the compiler to use the older 'stabs' debug format all the time.
-  #   Note that this needs to be used in optimized compiles too to be 100%.
-  #   This is a workaround for SS12 (5.9) bug 6694600
-  CFLAGS += -xdebugformat=stabs
-endif
-
 # Enable the following CFLAGS additions if you need to compare the
 # built ELF objects.
 #
--- a/make/solaris/makefiles/vm.make	Wed Dec 10 13:58:30 2014 +0000
+++ b/make/solaris/makefiles/vm.make	Fri Dec 12 21:32:43 2014 +0300
@@ -155,14 +155,6 @@
 include $(MAKEFILES_DIR)/dtrace.make
 
 #----------------------------------------------------------------------
-# add_gnu_debuglink tool
-include $(MAKEFILES_DIR)/add_gnu_debuglink.make
-
-#----------------------------------------------------------------------
-# fix_empty_sec_hdr_flags tool
-include $(MAKEFILES_DIR)/fix_empty_sec_hdr_flags.make
-
-#----------------------------------------------------------------------
 # JVM
 
 JVM      = jvm
@@ -302,7 +294,7 @@
 LINK_VM = $(LINK_LIB.CXX)
 endif
 # making the library:
-$(LIBJVM): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(LIBJVM.o) $(LIBJVM_MAPFILE)
+$(LIBJVM): $(LIBJVM.o) $(LIBJVM_MAPFILE)
 ifeq ($(filter -sbfast -xsbfast, $(CFLAGS_BROWSE)),)
 	@echo $(LOG_INFO) Linking vm...
 	$(QUIETLY) $(LINK_LIB.CXX/PRE_HOOK)
@@ -310,17 +302,8 @@
 	$(QUIETLY) $(LINK_LIB.CXX/POST_HOOK)
 	$(QUIETLY) rm -f $@.1 && ln -s $@ $@.1
 ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
-# gobjcopy crashes on "empty" section headers with the SHF_ALLOC flag set.
-# Clear the SHF_ALLOC flag (if set) from empty section headers.
-# An empty section header has sh_addr == 0 and sh_size == 0.
-# This problem has only been seen on Solaris X64, but we call this tool
-# on all Solaris builds just in case.
-	$(QUIETLY) $(FIX_EMPTY_SEC_HDR_FLAGS) $@
 	$(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJVM_DEBUGINFO)
-# $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections.
-# Use $(ADD_GNU_DEBUGLINK) until a fixed $(OBJCOPY) is available.
-#	$(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DEBUGINFO) $@
-	$(QUIETLY) $(ADD_GNU_DEBUGLINK) $(LIBJVM_DEBUGINFO) $@
+	$(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DEBUGINFO) $@
   ifeq ($(STRIP_POLICY),all_strip)
 	$(QUIETLY) $(STRIP) $@
   else
--- a/make/windows/makefiles/vm.make	Wed Dec 10 13:58:30 2014 +0000
+++ b/make/windows/makefiles/vm.make	Fri Dec 12 21:32:43 2014 +0300
@@ -89,19 +89,24 @@
 
 # If you modify exports below please do the corresponding changes in
 # src/share/tools/ProjectCreator/WinGammaPlatformVC7.java
-LD_FLAGS=$(LD_FLAGS) $(STACK_SIZE) /subsystem:windows /dll /base:0x8000000 \
-  /export:JNI_GetDefaultJavaVMInitArgs       \
-  /export:JNI_CreateJavaVM                   \
-  /export:JVM_FindClassFromBootLoader        \
-  /export:JNI_GetCreatedJavaVMs              \
-  /export:jio_snprintf                       \
-  /export:jio_printf                         \
-  /export:jio_fprintf                        \
-  /export:jio_vfprintf                       \
-  /export:jio_vsnprintf                      \
-  $(AGCT_EXPORT)                             \
-  /export:JVM_GetVersionInfo                 \
-  /export:JVM_InitAgentProperties
+!if "$(BUILDARCH)" == "amd64"
+EXPORT_LIST=
+!else
+EXPORT_LIST=/export:JNI_GetDefaultJavaVMInitArgs \
+            /export:JNI_CreateJavaVM             \
+            /export:JVM_FindClassFromBootLoader  \
+            /export:JNI_GetCreatedJavaVMs        \
+            /export:jio_snprintf                 \
+            /export:jio_printf                   \
+            /export:jio_fprintf                  \
+            /export:jio_vfprintf                 \
+            /export:jio_vsnprintf                \
+            $(AGCT_EXPORT)                       \
+            /export:JVM_GetVersionInfo           \
+            /export:JVM_InitAgentProperties
+!endif
+
+LD_FLAGS=$(LD_FLAGS) $(STACK_SIZE) /subsystem:windows /dll /base:0x8000000 $(EXPORT_LIST)
 
 CXX_INCLUDE_DIRS=/I "..\generated"
 
--- a/src/cpu/x86/vm/vm_version_x86.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/cpu/x86/vm/vm_version_x86.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -570,10 +570,12 @@
   static uint cores_per_cpu()  {
     uint result = 1;
     if (is_intel()) {
-      if (supports_processor_topology()) {
+      bool supports_topology = supports_processor_topology();
+      if (supports_topology) {
         result = _cpuid_info.tpl_cpuidB1_ebx.bits.logical_cpus /
                  _cpuid_info.tpl_cpuidB0_ebx.bits.logical_cpus;
-      } else {
+      }
+      if (!supports_topology || result == 0) {
         result = (_cpuid_info.dcp_cpuid4_eax.bits.cores_per_cpu + 1);
       }
     } else if (is_amd()) {
--- a/src/cpu/zero/vm/stack_zero.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/cpu/zero/vm/stack_zero.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -30,7 +30,9 @@
 
 int ZeroStack::suggest_size(Thread *thread) const {
   assert(needs_setup(), "already set up");
-  return align_size_down(abi_stack_available(thread) / 2, wordSize);
+  int abi_available = abi_stack_available(thread);
+  assert(abi_available >= 0, "available abi stack must be >= 0");
+  return align_size_down(abi_available / 2, wordSize);
 }
 
 void ZeroStack::handle_overflow(TRAPS) {
--- a/src/cpu/zero/vm/stack_zero.inline.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/cpu/zero/vm/stack_zero.inline.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -48,9 +48,11 @@
 // to use under normal circumstances.  Note that the returned
 // value can be negative.
 inline int ZeroStack::abi_stack_available(Thread *thread) const {
-  int stack_used = thread->stack_base() - (address) &stack_used;
+  guarantee(Thread::current() == thread, "should run in the same thread");
+  int stack_used = thread->stack_base() - (address) &stack_used
+    + (StackYellowPages+StackRedPages+StackShadowPages) * os::vm_page_size();
   int stack_free = thread->stack_size() - stack_used;
-  return stack_free - shadow_pages_size();
+  return stack_free;
 }
 
 #endif // CPU_ZERO_VM_STACK_ZERO_INLINE_HPP
--- a/src/os/aix/vm/os_aix.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/os/aix/vm/os_aix.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -107,6 +107,12 @@
 #include <sys/vminfo.h>
 #include <sys/wait.h>
 
+// If RUSAGE_THREAD for getrusage() has not been defined, do it here. The code calling
+// getrusage() is prepared to handle the associated failure.
+#ifndef RUSAGE_THREAD
+#define RUSAGE_THREAD   (1)               /* only the calling thread */
+#endif
+
 // Add missing declarations (should be in procinfo.h but isn't until AIX 6.1).
 #if !defined(_AIXVERSION_610)
 extern "C" {
@@ -512,15 +518,13 @@
 
 #define DEFAULT_LIBPATH "/usr/lib:/lib"
 #define EXTENSIONS_DIR  "/lib/ext"
-#define ENDORSED_DIR    "/lib/endorsed"
 
   // Buffer that fits several sprintfs.
   // Note that the space for the trailing null is provided
   // by the nulls included by the sizeof operator.
   const size_t bufsize =
-    MAX3((size_t)MAXPATHLEN,  // For dll_dir & friends.
-         (size_t)MAXPATHLEN + sizeof(EXTENSIONS_DIR), // extensions dir
-         (size_t)MAXPATHLEN + sizeof(ENDORSED_DIR)); // endorsed dir
+    MAX2((size_t)MAXPATHLEN,  // For dll_dir & friends.
+         (size_t)MAXPATHLEN + sizeof(EXTENSIONS_DIR)); // extensions dir
   char *buf = (char *)NEW_C_HEAP_ARRAY(char, bufsize, mtInternal);
 
   // sysclasspath, java_home, dll_dir
@@ -565,21 +569,16 @@
   char *ld_library_path = (char *)NEW_C_HEAP_ARRAY(char, strlen(v) + 1 + sizeof(DEFAULT_LIBPATH) + 1, mtInternal);
   sprintf(ld_library_path, "%s%s" DEFAULT_LIBPATH, v, v_colon);
   Arguments::set_library_path(ld_library_path);
-  FREE_C_HEAP_ARRAY(char, ld_library_path, mtInternal);
+  FREE_C_HEAP_ARRAY(char, ld_library_path);
 
   // Extensions directories.
   sprintf(buf, "%s" EXTENSIONS_DIR, Arguments::get_java_home());
   Arguments::set_ext_dirs(buf);
 
-  // Endorsed standards default directory.
-  sprintf(buf, "%s" ENDORSED_DIR, Arguments::get_java_home());
-  Arguments::set_endorsed_dirs(buf);
-
-  FREE_C_HEAP_ARRAY(char, buf, mtInternal);
+  FREE_C_HEAP_ARRAY(char, buf);
 
 #undef DEFAULT_LIBPATH
 #undef EXTENSIONS_DIR
-#undef ENDORSED_DIR
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -1072,15 +1071,19 @@
   return (1000 * 1000);
 }
 
-// For now, we say that linux does not support vtime. I have no idea
-// whether it can actually be made to (DLD, 9/13/05).
-
-bool os::supports_vtime() { return false; }
+bool os::supports_vtime() { return true; }
 bool os::enable_vtime()   { return false; }
 bool os::vtime_enabled()  { return false; }
+
 double os::elapsedVTime() {
-  // better than nothing, but not much
-  return elapsedTime();
+  struct rusage usage;
+  int retval = getrusage(RUSAGE_THREAD, &usage);
+  if (retval == 0) {
+    return usage.ru_utime.tv_sec + usage.ru_stime.tv_sec + (usage.ru_utime.tv_usec + usage.ru_stime.tv_usec) / (1000.0 * 1000);
+  } else {
+    // better than nothing, but not much
+    return elapsedTime();
+  }
 }
 
 jlong os::javaTimeMillis() {
@@ -1297,11 +1300,11 @@
     // release the storage
     for (int i = 0; i < n; i++) {
       if (pelements[i] != NULL) {
-        FREE_C_HEAP_ARRAY(char, pelements[i], mtInternal);
+        FREE_C_HEAP_ARRAY(char, pelements[i]);
       }
     }
     if (pelements != NULL) {
-      FREE_C_HEAP_ARRAY(char*, pelements, mtInternal);
+      FREE_C_HEAP_ARRAY(char*, pelements);
     }
   } else {
     snprintf(buffer, buflen, "%s/lib%s.so", pname, fname);
@@ -2778,6 +2781,10 @@
   return ::read(fd, buf, nBytes);
 }
 
+size_t os::read_at(int fd, void *buf, unsigned int nBytes, jlong offset) {
+  return ::pread(fd, buf, nBytes, offset);
+}
+
 void os::naked_short_sleep(jlong ms) {
   struct timespec req;
 
--- a/src/os/aix/vm/perfMemory_aix.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/os/aix/vm/perfMemory_aix.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2014, 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.
  *
@@ -127,7 +127,7 @@
       }
     }
   }
-  FREE_C_HEAP_ARRAY(char, destfile, mtInternal);
+  FREE_C_HEAP_ARRAY(char, destfile);
 }
 
 
@@ -279,14 +279,14 @@
                                      "pw_name zero length");
       }
     }
-    FREE_C_HEAP_ARRAY(char, pwbuf, mtInternal);
+    FREE_C_HEAP_ARRAY(char, pwbuf);
     return NULL;
   }
 
   char* user_name = NEW_C_HEAP_ARRAY(char, strlen(p->pw_name) + 1, mtInternal);
   strcpy(user_name, p->pw_name);
 
-  FREE_C_HEAP_ARRAY(char, pwbuf, mtInternal);
+  FREE_C_HEAP_ARRAY(char, pwbuf);
   return user_name;
 }
 
@@ -347,7 +347,7 @@
     DIR* subdirp = os::opendir(usrdir_name);
 
     if (subdirp == NULL) {
-      FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
+      FREE_C_HEAP_ARRAY(char, usrdir_name);
       continue;
     }
 
@@ -358,7 +358,7 @@
     // symlink can be exploited.
     //
     if (!is_directory_secure(usrdir_name)) {
-      FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
+      FREE_C_HEAP_ARRAY(char, usrdir_name);
       os::closedir(subdirp);
       continue;
     }
@@ -382,13 +382,13 @@
         // don't follow symbolic links for the file
         RESTARTABLE(::lstat(filename, &statbuf), result);
         if (result == OS_ERR) {
-           FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+           FREE_C_HEAP_ARRAY(char, filename);
            continue;
         }
 
         // skip over files that are not regular files.
         if (!S_ISREG(statbuf.st_mode)) {
-          FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+          FREE_C_HEAP_ARRAY(char, filename);
           continue;
         }
 
@@ -398,7 +398,7 @@
           if (statbuf.st_ctime > oldest_ctime) {
             char* user = strchr(dentry->d_name, '_') + 1;
 
-            if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user, mtInternal);
+            if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user);
             oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1, mtInternal);
 
             strcpy(oldest_user, user);
@@ -406,15 +406,15 @@
           }
         }
 
-        FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+        FREE_C_HEAP_ARRAY(char, filename);
       }
     }
     os::closedir(subdirp);
-    FREE_C_HEAP_ARRAY(char, udbuf, mtInternal);
-    FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
+    FREE_C_HEAP_ARRAY(char, udbuf);
+    FREE_C_HEAP_ARRAY(char, usrdir_name);
   }
   os::closedir(tmpdirp);
-  FREE_C_HEAP_ARRAY(char, tdbuf, mtInternal);
+  FREE_C_HEAP_ARRAY(char, tdbuf);
 
   return(oldest_user);
 }
@@ -481,7 +481,7 @@
 
   remove_file(path);
 
-  FREE_C_HEAP_ARRAY(char, path, mtInternal);
+  FREE_C_HEAP_ARRAY(char, path);
 }
 
 
@@ -558,7 +558,7 @@
     errno = 0;
   }
   os::closedir(dirp);
-  FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
+  FREE_C_HEAP_ARRAY(char, dbuf);
 }
 
 // make the user specific temporary directory. Returns true if
@@ -703,11 +703,11 @@
 
   fd = create_sharedmem_resources(dirname, filename, size);
 
-  FREE_C_HEAP_ARRAY(char, user_name, mtInternal);
-  FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
+  FREE_C_HEAP_ARRAY(char, user_name);
+  FREE_C_HEAP_ARRAY(char, dirname);
 
   if (fd == -1) {
-    FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+    FREE_C_HEAP_ARRAY(char, filename);
     return NULL;
   }
 
@@ -723,7 +723,7 @@
       warning("mmap failed -  %s\n", strerror(errno));
     }
     remove_file(filename);
-    FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+    FREE_C_HEAP_ARRAY(char, filename);
     return NULL;
   }
 
@@ -769,7 +769,7 @@
     remove_file(backing_store_file_name);
     // Don't.. Free heap memory could deadlock os::abort() if it is called
     // from signal handler. OS will reclaim the heap memory.
-    // FREE_C_HEAP_ARRAY(char, backing_store_file_name, mtInternal);
+    // FREE_C_HEAP_ARRAY(char, backing_store_file_name);
     backing_store_file_name = NULL;
   }
 }
@@ -853,9 +853,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");
@@ -871,9 +871,9 @@
   strcpy(rfilename, filename);
 
   // free the c heap resources that are no longer needed
-  if (luser != user) FREE_C_HEAP_ARRAY(char, luser, mtInternal);
-  FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
-  FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+  if (luser != user) FREE_C_HEAP_ARRAY(char, luser);
+  FREE_C_HEAP_ARRAY(char, dirname);
+  FREE_C_HEAP_ARRAY(char, filename);
 
   // open the shared memory file for the give vmid
   fd = open_sharedmem_file(rfilename, file_flags, CHECK);
--- a/src/os/bsd/vm/os_bsd.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/os/bsd/vm/os_bsd.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -353,7 +353,6 @@
 // Base path of extensions installed on the system.
 #define SYS_EXT_DIR     "/usr/java/packages"
 #define EXTENSIONS_DIR  "/lib/ext"
-#define ENDORSED_DIR    "/lib/endorsed"
 
 #ifndef __APPLE__
 
@@ -361,9 +360,8 @@
   // Note that the space for the colon and the trailing null are provided
   // by the nulls included by the sizeof operator.
   const size_t bufsize =
-    MAX3((size_t)MAXPATHLEN,  // For dll_dir & friends.
-         (size_t)MAXPATHLEN + sizeof(EXTENSIONS_DIR) + sizeof(SYS_EXT_DIR) + sizeof(EXTENSIONS_DIR), // extensions dir
-         (size_t)MAXPATHLEN + sizeof(ENDORSED_DIR)); // endorsed dir
+    MAX2((size_t)MAXPATHLEN,  // For dll_dir & friends.
+         (size_t)MAXPATHLEN + sizeof(EXTENSIONS_DIR) + sizeof(SYS_EXT_DIR) + sizeof(EXTENSIONS_DIR)); // extensions dir
   char *buf = (char *)NEW_C_HEAP_ARRAY(char, bufsize, mtInternal);
 
   // sysclasspath, java_home, dll_dir
@@ -418,18 +416,14 @@
                                                      mtInternal);
     sprintf(ld_library_path, "%s%s" SYS_EXT_DIR "/lib/%s:" DEFAULT_LIBPATH, v, v_colon, cpu_arch);
     Arguments::set_library_path(ld_library_path);
-    FREE_C_HEAP_ARRAY(char, ld_library_path, mtInternal);
+    FREE_C_HEAP_ARRAY(char, ld_library_path);
   }
 
   // Extensions directories.
   sprintf(buf, "%s" EXTENSIONS_DIR ":" SYS_EXT_DIR EXTENSIONS_DIR, Arguments::get_java_home());
   Arguments::set_ext_dirs(buf);
 
-  // Endorsed standards default directory.
-  sprintf(buf, "%s" ENDORSED_DIR, Arguments::get_java_home());
-  Arguments::set_endorsed_dirs(buf);
-
-  FREE_C_HEAP_ARRAY(char, buf, mtInternal);
+  FREE_C_HEAP_ARRAY(char, buf);
 
 #else // __APPLE__
 
@@ -445,9 +439,8 @@
   // Note that the space for the colon and the trailing null are provided
   // by the nulls included by the sizeof operator.
   const size_t bufsize =
-    MAX3((size_t)MAXPATHLEN,  // for dll_dir & friends.
-         (size_t)MAXPATHLEN + sizeof(EXTENSIONS_DIR) + system_ext_size, // extensions dir
-         (size_t)MAXPATHLEN + sizeof(ENDORSED_DIR)); // endorsed dir
+    MAX2((size_t)MAXPATHLEN,  // for dll_dir & friends.
+         (size_t)MAXPATHLEN + sizeof(EXTENSIONS_DIR) + system_ext_size); // extensions dir
   char *buf = (char *)NEW_C_HEAP_ARRAY(char, bufsize, mtInternal);
 
   // sysclasspath, java_home, dll_dir
@@ -513,7 +506,7 @@
     sprintf(ld_library_path, "%s%s%s%s%s" SYS_EXTENSIONS_DIR ":" SYS_EXTENSIONS_DIRS ":.",
             v, v_colon, l, l_colon, user_home_dir);
     Arguments::set_library_path(ld_library_path);
-    FREE_C_HEAP_ARRAY(char, ld_library_path, mtInternal);
+    FREE_C_HEAP_ARRAY(char, ld_library_path);
   }
 
   // Extensions directories.
@@ -525,11 +518,7 @@
           user_home_dir, Arguments::get_java_home());
   Arguments::set_ext_dirs(buf);
 
-  // Endorsed standards default directory.
-  sprintf(buf, "%s" ENDORSED_DIR, Arguments::get_java_home());
-  Arguments::set_endorsed_dirs(buf);
-
-  FREE_C_HEAP_ARRAY(char, buf, mtInternal);
+  FREE_C_HEAP_ARRAY(char, buf);
 
 #undef SYS_EXTENSIONS_DIR
 #undef SYS_EXTENSIONS_DIRS
@@ -538,7 +527,6 @@
 
 #undef SYS_EXT_DIR
 #undef EXTENSIONS_DIR
-#undef ENDORSED_DIR
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -1315,11 +1303,11 @@
     // release the storage
     for (int i = 0; i < n; i++) {
       if (pelements[i] != NULL) {
-        FREE_C_HEAP_ARRAY(char, pelements[i], mtInternal);
+        FREE_C_HEAP_ARRAY(char, pelements[i]);
       }
     }
     if (pelements != NULL) {
-      FREE_C_HEAP_ARRAY(char*, pelements, mtInternal);
+      FREE_C_HEAP_ARRAY(char*, pelements);
     }
   } else {
     snprintf(buffer, buflen, "%s/" JNI_LIB_PREFIX "%s" JNI_LIB_SUFFIX, pname, fname);
@@ -2576,6 +2564,10 @@
   RESTARTABLE_RETURN_INT(::read(fd, buf, nBytes));
 }
 
+size_t os::read_at(int fd, void *buf, unsigned int nBytes, jlong offset) {
+  RESTARTABLE_RETURN_INT(::pread(fd, buf, nBytes, offset));
+}
+
 void os::naked_short_sleep(jlong ms) {
   struct timespec req;
 
--- a/src/os/bsd/vm/perfMemory_bsd.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/os/bsd/vm/perfMemory_bsd.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -127,7 +127,7 @@
       }
     }
   }
-  FREE_C_HEAP_ARRAY(char, destfile, mtInternal);
+  FREE_C_HEAP_ARRAY(char, destfile);
 }
 
 
@@ -279,14 +279,14 @@
                                      "pw_name zero length");
       }
     }
-    FREE_C_HEAP_ARRAY(char, pwbuf, mtInternal);
+    FREE_C_HEAP_ARRAY(char, pwbuf);
     return NULL;
   }
 
   char* user_name = NEW_C_HEAP_ARRAY(char, strlen(p->pw_name) + 1, mtInternal);
   strcpy(user_name, p->pw_name);
 
-  FREE_C_HEAP_ARRAY(char, pwbuf, mtInternal);
+  FREE_C_HEAP_ARRAY(char, pwbuf);
   return user_name;
 }
 
@@ -347,7 +347,7 @@
     DIR* subdirp = os::opendir(usrdir_name);
 
     if (subdirp == NULL) {
-      FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
+      FREE_C_HEAP_ARRAY(char, usrdir_name);
       continue;
     }
 
@@ -358,7 +358,7 @@
     // symlink can be exploited.
     //
     if (!is_directory_secure(usrdir_name)) {
-      FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
+      FREE_C_HEAP_ARRAY(char, usrdir_name);
       os::closedir(subdirp);
       continue;
     }
@@ -382,13 +382,13 @@
         // don't follow symbolic links for the file
         RESTARTABLE(::lstat(filename, &statbuf), result);
         if (result == OS_ERR) {
-           FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+           FREE_C_HEAP_ARRAY(char, filename);
            continue;
         }
 
         // skip over files that are not regular files.
         if (!S_ISREG(statbuf.st_mode)) {
-          FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+          FREE_C_HEAP_ARRAY(char, filename);
           continue;
         }
 
@@ -398,7 +398,7 @@
           if (statbuf.st_ctime > oldest_ctime) {
             char* user = strchr(dentry->d_name, '_') + 1;
 
-            if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user, mtInternal);
+            if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user);
             oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1, mtInternal);
 
             strcpy(oldest_user, user);
@@ -406,15 +406,15 @@
           }
         }
 
-        FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+        FREE_C_HEAP_ARRAY(char, filename);
       }
     }
     os::closedir(subdirp);
-    FREE_C_HEAP_ARRAY(char, udbuf, mtInternal);
-    FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
+    FREE_C_HEAP_ARRAY(char, udbuf);
+    FREE_C_HEAP_ARRAY(char, usrdir_name);
   }
   os::closedir(tmpdirp);
-  FREE_C_HEAP_ARRAY(char, tdbuf, mtInternal);
+  FREE_C_HEAP_ARRAY(char, tdbuf);
 
   return(oldest_user);
 }
@@ -481,7 +481,7 @@
 
   remove_file(path);
 
-  FREE_C_HEAP_ARRAY(char, path, mtInternal);
+  FREE_C_HEAP_ARRAY(char, path);
 }
 
 
@@ -558,7 +558,7 @@
     errno = 0;
   }
   os::closedir(dirp);
-  FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
+  FREE_C_HEAP_ARRAY(char, dbuf);
 }
 
 // make the user specific temporary directory. Returns true if
@@ -725,11 +725,11 @@
 
   fd = create_sharedmem_resources(dirname, filename, size);
 
-  FREE_C_HEAP_ARRAY(char, user_name, mtInternal);
-  FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
+  FREE_C_HEAP_ARRAY(char, user_name);
+  FREE_C_HEAP_ARRAY(char, dirname);
 
   if (fd == -1) {
-    FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+    FREE_C_HEAP_ARRAY(char, filename);
     return NULL;
   }
 
@@ -743,7 +743,7 @@
       warning("mmap failed -  %s\n", strerror(errno));
     }
     remove_file(filename);
-    FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+    FREE_C_HEAP_ARRAY(char, filename);
     return NULL;
   }
 
@@ -872,9 +872,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");
@@ -890,9 +890,9 @@
   strcpy(rfilename, filename);
 
   // free the c heap resources that are no longer needed
-  if (luser != user) FREE_C_HEAP_ARRAY(char, luser, mtInternal);
-  FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
-  FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+  if (luser != user) FREE_C_HEAP_ARRAY(char, luser);
+  FREE_C_HEAP_ARRAY(char, dirname);
+  FREE_C_HEAP_ARRAY(char, filename);
 
   // open the shared memory file for the give vmid
   fd = open_sharedmem_file(rfilename, file_flags, CHECK);
--- a/src/os/linux/vm/os_linux.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/os/linux/vm/os_linux.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -338,15 +338,13 @@
 // Base path of extensions installed on the system.
 #define SYS_EXT_DIR     "/usr/java/packages"
 #define EXTENSIONS_DIR  "/lib/ext"
-#define ENDORSED_DIR    "/lib/endorsed"
 
   // Buffer that fits several sprintfs.
   // Note that the space for the colon and the trailing null are provided
   // by the nulls included by the sizeof operator.
   const size_t bufsize =
-    MAX3((size_t)MAXPATHLEN,  // For dll_dir & friends.
-         (size_t)MAXPATHLEN + sizeof(EXTENSIONS_DIR) + sizeof(SYS_EXT_DIR) + sizeof(EXTENSIONS_DIR), // extensions dir
-         (size_t)MAXPATHLEN + sizeof(ENDORSED_DIR)); // endorsed dir
+    MAX2((size_t)MAXPATHLEN,  // For dll_dir & friends.
+         (size_t)MAXPATHLEN + sizeof(EXTENSIONS_DIR) + sizeof(SYS_EXT_DIR) + sizeof(EXTENSIONS_DIR)); // extensions dir
   char *buf = (char *)NEW_C_HEAP_ARRAY(char, bufsize, mtInternal);
 
   // sysclasspath, java_home, dll_dir
@@ -404,23 +402,18 @@
                                                      mtInternal);
     sprintf(ld_library_path, "%s%s" SYS_EXT_DIR "/lib/%s:" DEFAULT_LIBPATH, v, v_colon, cpu_arch);
     Arguments::set_library_path(ld_library_path);
-    FREE_C_HEAP_ARRAY(char, ld_library_path, mtInternal);
+    FREE_C_HEAP_ARRAY(char, ld_library_path);
   }
 
   // Extensions directories.
   sprintf(buf, "%s" EXTENSIONS_DIR ":" SYS_EXT_DIR EXTENSIONS_DIR, Arguments::get_java_home());
   Arguments::set_ext_dirs(buf);
 
-  // Endorsed standards default directory.
-  sprintf(buf, "%s" ENDORSED_DIR, Arguments::get_java_home());
-  Arguments::set_endorsed_dirs(buf);
-
-  FREE_C_HEAP_ARRAY(char, buf, mtInternal);
+  FREE_C_HEAP_ARRAY(char, buf);
 
 #undef DEFAULT_LIBPATH
 #undef SYS_EXT_DIR
 #undef EXTENSIONS_DIR
-#undef ENDORSED_DIR
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -1621,11 +1614,11 @@
     // release the storage
     for (int i = 0; i < n; i++) {
       if (pelements[i] != NULL) {
-        FREE_C_HEAP_ARRAY(char, pelements[i], mtInternal);
+        FREE_C_HEAP_ARRAY(char, pelements[i]);
       }
     }
     if (pelements != NULL) {
-      FREE_C_HEAP_ARRAY(char*, pelements, mtInternal);
+      FREE_C_HEAP_ARRAY(char*, pelements);
     }
   } else {
     snprintf(buffer, buflen, "%s/lib%s.so", pname, fname);
@@ -2936,7 +2929,7 @@
       }
     }
   }
-  FREE_C_HEAP_ARRAY(unsigned long, cpu_map, mtInternal);
+  FREE_C_HEAP_ARRAY(unsigned long, cpu_map);
 }
 
 int os::Linux::get_node_by_cpu(int cpu_id) {
@@ -3784,6 +3777,10 @@
   return ::read(fd, buf, nBytes);
 }
 
+size_t os::read_at(int fd, void *buf, unsigned int nBytes, jlong offset) {
+  return ::pread(fd, buf, nBytes, offset);
+}
+
 // Short sleep, direct OS call.
 //
 // Note: certain versions of Linux CFS scheduler (since 2.6.23) do not guarantee
--- a/src/os/linux/vm/perfMemory_linux.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/os/linux/vm/perfMemory_linux.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -127,7 +127,7 @@
       }
     }
   }
-  FREE_C_HEAP_ARRAY(char, destfile, mtInternal);
+  FREE_C_HEAP_ARRAY(char, destfile);
 }
 
 
@@ -279,14 +279,14 @@
                                      "pw_name zero length");
       }
     }
-    FREE_C_HEAP_ARRAY(char, pwbuf, mtInternal);
+    FREE_C_HEAP_ARRAY(char, pwbuf);
     return NULL;
   }
 
   char* user_name = NEW_C_HEAP_ARRAY(char, strlen(p->pw_name) + 1, mtInternal);
   strcpy(user_name, p->pw_name);
 
-  FREE_C_HEAP_ARRAY(char, pwbuf, mtInternal);
+  FREE_C_HEAP_ARRAY(char, pwbuf);
   return user_name;
 }
 
@@ -347,7 +347,7 @@
     DIR* subdirp = os::opendir(usrdir_name);
 
     if (subdirp == NULL) {
-      FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
+      FREE_C_HEAP_ARRAY(char, usrdir_name);
       continue;
     }
 
@@ -358,7 +358,7 @@
     // symlink can be exploited.
     //
     if (!is_directory_secure(usrdir_name)) {
-      FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
+      FREE_C_HEAP_ARRAY(char, usrdir_name);
       os::closedir(subdirp);
       continue;
     }
@@ -382,13 +382,13 @@
         // don't follow symbolic links for the file
         RESTARTABLE(::lstat(filename, &statbuf), result);
         if (result == OS_ERR) {
-           FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+           FREE_C_HEAP_ARRAY(char, filename);
            continue;
         }
 
         // skip over files that are not regular files.
         if (!S_ISREG(statbuf.st_mode)) {
-          FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+          FREE_C_HEAP_ARRAY(char, filename);
           continue;
         }
 
@@ -398,7 +398,7 @@
           if (statbuf.st_ctime > oldest_ctime) {
             char* user = strchr(dentry->d_name, '_') + 1;
 
-            if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user, mtInternal);
+            if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user);
             oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1, mtInternal);
 
             strcpy(oldest_user, user);
@@ -406,15 +406,15 @@
           }
         }
 
-        FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+        FREE_C_HEAP_ARRAY(char, filename);
       }
     }
     os::closedir(subdirp);
-    FREE_C_HEAP_ARRAY(char, udbuf, mtInternal);
-    FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
+    FREE_C_HEAP_ARRAY(char, udbuf);
+    FREE_C_HEAP_ARRAY(char, usrdir_name);
   }
   os::closedir(tmpdirp);
-  FREE_C_HEAP_ARRAY(char, tdbuf, mtInternal);
+  FREE_C_HEAP_ARRAY(char, tdbuf);
 
   return(oldest_user);
 }
@@ -481,7 +481,7 @@
 
   remove_file(path);
 
-  FREE_C_HEAP_ARRAY(char, path, mtInternal);
+  FREE_C_HEAP_ARRAY(char, path);
 }
 
 
@@ -558,7 +558,7 @@
     errno = 0;
   }
   os::closedir(dirp);
-  FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
+  FREE_C_HEAP_ARRAY(char, dbuf);
 }
 
 // make the user specific temporary directory. Returns true if
@@ -725,11 +725,11 @@
 
   fd = create_sharedmem_resources(dirname, filename, size);
 
-  FREE_C_HEAP_ARRAY(char, user_name, mtInternal);
-  FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
+  FREE_C_HEAP_ARRAY(char, user_name);
+  FREE_C_HEAP_ARRAY(char, dirname);
 
   if (fd == -1) {
-    FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+    FREE_C_HEAP_ARRAY(char, filename);
     return NULL;
   }
 
@@ -743,7 +743,7 @@
       warning("mmap failed -  %s\n", strerror(errno));
     }
     remove_file(filename);
-    FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+    FREE_C_HEAP_ARRAY(char, filename);
     return NULL;
   }
 
@@ -872,9 +872,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");
@@ -890,9 +890,9 @@
   strcpy(rfilename, filename);
 
   // free the c heap resources that are no longer needed
-  if (luser != user) FREE_C_HEAP_ARRAY(char, luser, mtInternal);
-  FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
-  FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+  if (luser != user) FREE_C_HEAP_ARRAY(char, luser);
+  FREE_C_HEAP_ARRAY(char, dirname);
+  FREE_C_HEAP_ARRAY(char, filename);
 
   // open the shared memory file for the give vmid
   fd = open_sharedmem_file(rfilename, file_flags, THREAD);
--- a/src/os/solaris/add_gnu_debuglink/add_gnu_debuglink.c	Wed Dec 10 13:58:30 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,285 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-/*
- * Name:        add_gnu_debuglink.c
- *
- * Description: Add a ".gnu_debuglink" section that refers to the specified
- *     debug_info_path to the specified ELF object.
- *
- *     This program is adapted from the example program shown on the
- *     elf(3elf) man page and from code from the Solaris compiler
- *     driver.
- */
-
-/*
- * needed to define SHF_EXCLUDE
- */
-#define ELF_TARGET_ALL
-
-#include <fcntl.h>
-#include <stdio.h>
-#include <libelf.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-static void failure(void);
-static unsigned int gnu_debuglink_crc32(unsigned int crc, unsigned char *buf,
-                                        size_t len);
-
-void
-main(int argc, char ** argv) {
-                                 /* new ELF section name */
-    static char SEC_NAME[] = ".gnu_debuglink";
-
-    unsigned char buffer[8 * 1024];  /* I/O buffer */
-    int           buffer_len;        /* buffer length */
-    char *        debug_info_path;   /* debug info path */
-    void *        ehdr;              /* ELF header */
-    Elf *         elf;               /* ELF descriptor */
-    char *        elf_ident;         /* ELF identity string */
-    char *        elf_obj;           /* elf_obj file */
-    int           fd;                /* descriptor for files */
-    unsigned int  file_crc = 0;      /* CRC for debug info file */
-    int           is_elfclass64;     /* is an ELFCLASS64 file? */
-    Elf_Data *    link_dat;          /* ELF data for new debug info link */
-    Elf_Data *    name_dat;          /* ELF data for new section name */
-    Elf_Scn *     new_scn;           /* new ELF section descriptor */
-    void *        new_shdr;          /* new ELF section header */
-    Elf_Scn *     scn;               /* ELF section descriptor */
-    void *        shdr;              /* ELF section header */
-
-    if (argc != 3) {
-        (void) fprintf(stderr, "Usage: %s debug_info_path elf_obj\n", argv[0]);
-        exit(2);
-    }
-
-    debug_info_path = argv[1];  /* save for later */
-    if ((fd = open(debug_info_path, O_RDONLY)) == -1) {
-        (void) fprintf(stderr, "%s: cannot open file.\n", debug_info_path);
-        exit(3);
-    }
-
-    (void) printf("Computing CRC for '%s'\n", debug_info_path);
-    (void) fflush(stdout);
-    /* compute CRC for the debug info file */
-    for (;;) {
-        int len = read(fd, buffer, sizeof buffer);
-        if (len <= 0) {
-            break;
-        }
-        file_crc = gnu_debuglink_crc32(file_crc, buffer, len);
-    }
-    (void) close(fd);
-
-    /* open the elf_obj */
-    elf_obj = argv[2];
-    if ((fd = open(elf_obj, O_RDWR)) == -1) {
-        (void) fprintf(stderr, "%s: cannot open file.\n", elf_obj);
-        exit(4);
-    }
-
-    (void) printf("Opening '%s' for update\n", elf_obj);
-    (void) fflush(stdout);
-    (void) elf_version(EV_CURRENT);  /* coordinate ELF versions */
-
-    /* obtain the ELF descriptors from the input file */
-    if ((elf = elf_begin(fd, ELF_C_RDWR, NULL)) == NULL) {
-        failure();
-    }
-
-    /* determine if ELFCLASS64 or not? */
-    elf_ident = elf_getident(elf, NULL);
-    is_elfclass64 = (elf_ident[EI_CLASS] == ELFCLASS64);
-
-    /* get the ELF header */
-    if (is_elfclass64) {
-        ehdr = elf64_getehdr(elf);
-    } else {
-        ehdr = elf32_getehdr(elf);
-    }
-    if (ehdr == NULL) {
-        failure();
-    }
-
-    /* get the ELF section descriptor */
-    if (is_elfclass64) {
-        scn = elf_getscn(elf, ((Elf64_Ehdr *) ehdr)->e_shstrndx);
-    } else {
-        scn = elf_getscn(elf, ((Elf32_Ehdr *) ehdr)->e_shstrndx);
-    }
-    if (scn == NULL) {
-        failure();
-    }
-
-    /* get the section header */
-    if (is_elfclass64) {
-        shdr = elf64_getshdr(scn);
-    } else {
-        shdr = elf32_getshdr(scn);
-    }
-    if (shdr == NULL) {
-        failure();
-    }
-
-    (void) printf("Adding ELF data for new section name\n");
-    (void) fflush(stdout);
-    name_dat = elf_newdata(scn);
-    name_dat->d_buf = (void *) SEC_NAME;
-    if (is_elfclass64) {
-        name_dat->d_off = ((Elf64_Shdr *) shdr)->sh_size + 1;
-    } else {
-        name_dat->d_off = ((Elf32_Shdr *) shdr)->sh_size + 1;
-    }
-    name_dat->d_align = 1;
-    name_dat->d_size = strlen(SEC_NAME) + 1;
-
-    new_scn = elf_newscn(elf);
-
-    if (is_elfclass64) {
-        new_shdr = elf64_getshdr(new_scn);
-        ((Elf64_Shdr *) new_shdr)->sh_flags = SHF_EXCLUDE;
-        ((Elf64_Shdr *) new_shdr)->sh_type = SHT_PROGBITS;
-        ((Elf64_Shdr *) new_shdr)->sh_name = ((Elf64_Shdr *) shdr)->sh_size;
-        ((Elf64_Shdr *) new_shdr)->sh_addralign = 1;
-        ((Elf64_Shdr *) shdr)->sh_size += (strlen(SEC_NAME) + 1);
-    } else {
-        new_shdr = elf32_getshdr(new_scn);
-        ((Elf32_Shdr *) new_shdr)->sh_flags = SHF_EXCLUDE;
-        ((Elf32_Shdr *) new_shdr)->sh_type = SHT_PROGBITS;
-        ((Elf32_Shdr *) new_shdr)->sh_name = ((Elf32_Shdr *) shdr)->sh_size;
-        ((Elf32_Shdr *) new_shdr)->sh_addralign = 1;
-        ((Elf32_Shdr *) shdr)->sh_size += (strlen(SEC_NAME) + 1);
-    }
-
-    (void) printf("Adding ELF data for debug_info_path value\n");
-    (void) fflush(stdout);
-    (void) memset(buffer, 0, sizeof buffer);
-    buffer_len = strlen(debug_info_path) + 1;  /* +1 for NUL */
-    (void) strncpy((char *) buffer, debug_info_path, buffer_len);
-    if (buffer_len % 4 != 0) {
-        /* not on a 4 byte boundary so pad to the next one */
-        buffer_len += (4 - buffer_len % 4);
-    }
-    /* save the CRC */
-    (void) memcpy(&buffer[buffer_len], &file_crc, sizeof file_crc);
-    buffer_len += sizeof file_crc;
-
-    link_dat = elf_newdata(new_scn);
-    link_dat->d_type = ELF_T_BYTE;
-    link_dat->d_size = buffer_len;
-    link_dat->d_buf = buffer;
-    link_dat->d_align = 1;
-
-    (void) printf("Saving updates to '%s'\n", elf_obj);
-    (void) fflush(stdout);
-    (void) elf_update(elf, ELF_C_NULL);   /* recalc ELF memory structures */
-    (void) elf_update(elf, ELF_C_WRITE);  /* write out changes to ELF obj */
-    (void) elf_end(elf);                  /* done with ELF obj */
-    (void) close(fd);
-
-    (void) printf("Done updating '%s'\n", elf_obj);
-    (void) fflush(stdout);
-    exit(0);
-}  /* end main */
-
-
-static void
-failure() {
-    (void) fprintf(stderr, "%s\n", elf_errmsg(elf_errno()));
-    exit(5);
-}
-
-
-/*
- * The CRC used in gnu_debuglink, retrieved from
- * http://sourceware.org/gdb/current/onlinedocs/gdb/Separate-Debug-Files.html#Separate-Debug-Files.
- */
-
-static unsigned int
-gnu_debuglink_crc32(unsigned int crc, unsigned char *buf, size_t len) {
-    static const unsigned int crc32_table[256] = {
-        0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
-        0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
-        0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
-        0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
-        0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
-        0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
-        0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
-        0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
-        0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
-        0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
-        0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
-        0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
-        0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
-        0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
-        0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
-        0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
-        0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
-        0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
-        0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
-        0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
-        0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
-        0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
-        0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
-        0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
-        0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
-        0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
-        0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
-        0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
-        0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
-        0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
-        0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
-        0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
-        0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
-        0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
-        0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
-        0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
-        0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
-        0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
-        0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
-        0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
-        0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
-        0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
-        0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
-        0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
-        0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
-        0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
-        0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
-        0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
-        0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
-        0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
-        0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
-        0x2d02ef8d
-    };
-
-    unsigned char *end;
-
-    crc = ~crc & 0xffffffff;
-    for (end = buf + len; buf < end; ++buf) {
-        crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
-    }
-    return ~crc & 0xffffffff;
-}
--- a/src/os/solaris/fix_empty_sec_hdr_flags/fix_empty_sec_hdr_flags.c	Wed Dec 10 13:58:30 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,181 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-/*
- * Name:        fix_empty_sec_hdr_flags.c
- *
- * Description: Remove the SHF_ALLOC flag from "empty" section headers.
- *     An "empty" section header has sh_addr == 0 and sh_size == 0.
- *
- *     This program is adapted from the example program shown on the
- *     elf(3elf) man page and from code from the Solaris compiler
- *     driver.
- */
-
-#include <fcntl.h>
-#include <stdio.h>
-#include <libelf.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-static void failure(void);
-
-void
-main(int argc, char ** argv) {
-    void *        ehdr;           /* ELF header */
-    unsigned int  i;              /* section counter */
-    int           fd;             /* descriptor for file */
-    Elf *         elf;            /* ELF descriptor */
-    char *        elf_ident;      /* ELF identity string */
-    char *        elf_obj;        /* elf_obj file */
-    int           fix_count;      /* number of flags fixed */
-    int           is_elfclass64;  /* is an ELFCLASS64 file? */
-    Elf_Scn *     scn;            /* ELF section descriptor */
-    void *        shdr;           /* ELF section header */
-    Elf_Data *    shstrtab;       /* ELF section header string table */
-
-    if (argc != 2) {
-        (void) fprintf(stderr, "Usage: %s elf_obj\n", argv[0]);
-        exit(2);
-    }
-
-    /* open the elf_obj */
-    elf_obj = argv[1];
-    if ((fd = open(elf_obj, O_RDWR)) == -1) {
-        (void) fprintf(stderr, "%s: cannot open file.\n", elf_obj);
-        exit(3);
-    }
-
-    (void) printf("Opening '%s' for update\n", elf_obj);
-    (void) fflush(stdout);
-    (void) elf_version(EV_CURRENT);  /* coordinate ELF versions */
-
-    /* obtain the ELF descriptors from the input file */
-    if ((elf = elf_begin(fd, ELF_C_RDWR, NULL)) == NULL) {
-        failure();
-    }
-
-    /* determine if ELFCLASS64 or not? */
-    elf_ident = elf_getident(elf, NULL);
-    is_elfclass64 = (elf_ident[EI_CLASS] == ELFCLASS64);
-
-    /* get the ELF header */
-    if (is_elfclass64) {
-        ehdr = elf64_getehdr(elf);
-    } else {
-        ehdr = elf32_getehdr(elf);
-    }
-    if (ehdr == NULL) {
-        failure();
-    }
-
-    /* get the ELF section descriptor */
-    if (is_elfclass64) {
-        scn = elf_getscn(elf, ((Elf64_Ehdr *) ehdr)->e_shstrndx);
-    } else {
-        scn = elf_getscn(elf, ((Elf32_Ehdr *) ehdr)->e_shstrndx);
-    }
-    if (scn == NULL) {
-        failure();
-    }
-
-    /* get the section header string table */
-    shstrtab = elf_getdata(scn, NULL);
-    if (shstrtab == NULL) {
-        failure();
-    }
-
-    fix_count = 0;
-
-    /* traverse the sections of the input file */
-    for (i = 1, scn = NULL; scn = elf_nextscn(elf, scn); i++) {
-        int    has_flag_set;  /* is SHF_ALLOC flag set? */
-        int    is_empty;      /* is section empty? */
-        char * name;          /* short hand pointer */
-
-        /* get the section header */
-        if (is_elfclass64) {
-            shdr = elf64_getshdr(scn);
-        } else {
-            shdr = elf32_getshdr(scn);
-        }
-        if (shdr == NULL) {
-            failure();
-        }
-
-        if (is_elfclass64) {
-            name = (char *)shstrtab->d_buf + ((Elf64_Shdr *) shdr)->sh_name;
-        } else {
-            name = (char *)shstrtab->d_buf + ((Elf32_Shdr *) shdr)->sh_name;
-        }
-
-        if (is_elfclass64) {
-            has_flag_set = ((Elf64_Shdr *) shdr)->sh_flags & SHF_ALLOC;
-            is_empty = ((Elf64_Shdr *) shdr)->sh_addr == 0 &&
-                ((Elf64_Shdr *) shdr)->sh_size == 0;
-        } else {
-            has_flag_set = ((Elf32_Shdr *) shdr)->sh_flags & SHF_ALLOC;
-            is_empty = ((Elf32_Shdr *) shdr)->sh_addr == 0 &&
-                ((Elf32_Shdr *) shdr)->sh_size == 0;
-        }
-
-        if (is_empty && has_flag_set) {
-            (void) printf("section[%u] '%s' is empty, "
-                "but SHF_ALLOC flag is set.\n", i, name);
-            (void) printf("Clearing the SHF_ALLOC flag.\n");
-
-            if (is_elfclass64) {
-                ((Elf64_Shdr *) shdr)->sh_flags &= ~SHF_ALLOC;
-            } else {
-                ((Elf32_Shdr *) shdr)->sh_flags &= ~SHF_ALLOC;
-            }
-            fix_count++;
-        }
-    }  /* end for each ELF section */
-
-    if (fix_count > 0) {
-        (void) printf("Saving %d updates to '%s'\n", fix_count, elf_obj);
-        (void) fflush(stdout);
-        (void) elf_update(elf, ELF_C_NULL);   /* recalc ELF memory structures */
-        (void) elf_update(elf, ELF_C_WRITE);  /* write out changes to ELF obj */
-    } else {
-        (void) printf("No SHF_ALLOC flags needed to be cleared.\n");
-    }
-
-    (void) elf_end(elf);                  /* done with ELF obj */
-    (void) close(fd);
-
-    (void) printf("Done %s '%s'\n",
-               (fix_count > 0) ? "updating" : "with", elf_obj);
-    (void) fflush(stdout);
-    exit(0);
-}  /* end main */
-
-
-static void
-failure() {
-    (void) fprintf(stderr, "%s\n", elf_errmsg(elf_errno()));
-    exit(6);
-}
--- a/src/os/solaris/vm/os_solaris.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/os/solaris/vm/os_solaris.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -506,7 +506,7 @@
     }
   }
   if (available_id != NULL) {
-    FREE_C_HEAP_ARRAY(bool, available_id, mtInternal);
+    FREE_C_HEAP_ARRAY(bool, available_id);
   }
   return true;
 }
@@ -538,7 +538,7 @@
     }
   }
   if (id_array != NULL) {
-    FREE_C_HEAP_ARRAY(processorid_t, id_array, mtInternal);
+    FREE_C_HEAP_ARRAY(processorid_t, id_array);
   }
   return result;
 }
@@ -609,17 +609,15 @@
 // Base path of extensions installed on the system.
 #define SYS_EXT_DIR     "/usr/jdk/packages"
 #define EXTENSIONS_DIR  "/lib/ext"
-#define ENDORSED_DIR    "/lib/endorsed"
 
   char cpu_arch[12];
   // Buffer that fits several sprintfs.
   // Note that the space for the colon and the trailing null are provided
   // by the nulls included by the sizeof operator.
   const size_t bufsize =
-    MAX4((size_t)MAXPATHLEN,  // For dll_dir & friends.
+    MAX3((size_t)MAXPATHLEN,  // For dll_dir & friends.
          sizeof(SYS_EXT_DIR) + sizeof("/lib/") + strlen(cpu_arch), // invariant ld_library_path
-         (size_t)MAXPATHLEN + sizeof(EXTENSIONS_DIR) + sizeof(SYS_EXT_DIR) + sizeof(EXTENSIONS_DIR), // extensions dir
-         (size_t)MAXPATHLEN + sizeof(ENDORSED_DIR)); // endorsed dir
+         (size_t)MAXPATHLEN + sizeof(EXTENSIONS_DIR) + sizeof(SYS_EXT_DIR) + sizeof(EXTENSIONS_DIR)); // extensions dir
   char *buf = (char *)NEW_C_HEAP_ARRAY(char, bufsize, mtInternal);
 
   // sysclasspath, java_home, dll_dir
@@ -675,7 +673,7 @@
 
     // Determine search path count and required buffer size.
     if (dlinfo(RTLD_SELF, RTLD_DI_SERINFOSIZE, (void *)info) == -1) {
-      FREE_C_HEAP_ARRAY(char, buf, mtInternal);
+      FREE_C_HEAP_ARRAY(char, buf);
       vm_exit_during_initialization("dlinfo SERINFOSIZE request", dlerror());
     }
 
@@ -686,8 +684,8 @@
 
     // Obtain search path information.
     if (dlinfo(RTLD_SELF, RTLD_DI_SERINFO, (void *)info) == -1) {
-      FREE_C_HEAP_ARRAY(char, buf, mtInternal);
-      FREE_C_HEAP_ARRAY(char, info, mtInternal);
+      FREE_C_HEAP_ARRAY(char, buf);
+      FREE_C_HEAP_ARRAY(char, info);
       vm_exit_during_initialization("dlinfo SERINFO request", dlerror());
     }
 
@@ -757,23 +755,18 @@
     // Callee copies into its own buffer.
     Arguments::set_library_path(library_path);
 
-    FREE_C_HEAP_ARRAY(char, library_path, mtInternal);
-    FREE_C_HEAP_ARRAY(char, info, mtInternal);
+    FREE_C_HEAP_ARRAY(char, library_path);
+    FREE_C_HEAP_ARRAY(char, info);
   }
 
   // Extensions directories.
   sprintf(buf, "%s" EXTENSIONS_DIR ":" SYS_EXT_DIR EXTENSIONS_DIR, Arguments::get_java_home());
   Arguments::set_ext_dirs(buf);
 
-  // Endorsed standards default directory.
-  sprintf(buf, "%s" ENDORSED_DIR, Arguments::get_java_home());
-  Arguments::set_endorsed_dirs(buf);
-
-  FREE_C_HEAP_ARRAY(char, buf, mtInternal);
+  FREE_C_HEAP_ARRAY(char, buf);
 
 #undef SYS_EXT_DIR
 #undef EXTENSIONS_DIR
-#undef ENDORSED_DIR
 }
 
 void os::breakpoint() {
@@ -1599,11 +1592,11 @@
     // release the storage
     for (int i = 0; i < n; i++) {
       if (pelements[i] != NULL) {
-        FREE_C_HEAP_ARRAY(char, pelements[i], mtInternal);
+        FREE_C_HEAP_ARRAY(char, pelements[i]);
       }
     }
     if (pelements != NULL) {
-      FREE_C_HEAP_ARRAY(char*, pelements, mtInternal);
+      FREE_C_HEAP_ARRAY(char*, pelements);
     }
   } else {
     snprintf(buffer, buflen, "%s/lib%s.so", pname, fname);
@@ -3167,6 +3160,15 @@
   return res;
 }
 
+size_t os::read_at(int fd, void *buf, unsigned int nBytes, jlong offset) {
+  size_t res;
+  JavaThread* thread = (JavaThread*)Thread::current();
+  assert(thread->thread_state() == _thread_in_vm, "Assumed _thread_in_vm");
+  ThreadBlockInVM tbiv(thread);
+  RESTARTABLE(::pread(fd, buf, (size_t) nBytes, offset), res);
+  return res;
+}
+
 size_t os::restartable_read(int fd, void *buf, unsigned int nBytes) {
   size_t res;
   assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_native,
@@ -4681,7 +4683,7 @@
       size_t lgrp_limit = os::numa_get_groups_num();
       int *lgrp_ids = NEW_C_HEAP_ARRAY(int, lgrp_limit, mtInternal);
       size_t lgrp_num = os::numa_get_leaf_groups(lgrp_ids, lgrp_limit);
-      FREE_C_HEAP_ARRAY(int, lgrp_ids, mtInternal);
+      FREE_C_HEAP_ARRAY(int, lgrp_ids);
       if (lgrp_num < 2) {
         // There's only one locality group, disable NUMA.
         UseNUMA = false;
--- a/src/os/solaris/vm/perfMemory_solaris.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/os/solaris/vm/perfMemory_solaris.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -129,7 +129,7 @@
       }
     }
   }
-  FREE_C_HEAP_ARRAY(char, destfile, mtInternal);
+  FREE_C_HEAP_ARRAY(char, destfile);
 }
 
 
@@ -270,14 +270,14 @@
                                      "pw_name zero length");
       }
     }
-    FREE_C_HEAP_ARRAY(char, pwbuf, mtInternal);
+    FREE_C_HEAP_ARRAY(char, pwbuf);
     return NULL;
   }
 
   char* user_name = NEW_C_HEAP_ARRAY(char, strlen(p->pw_name) + 1, mtInternal);
   strcpy(user_name, p->pw_name);
 
-  FREE_C_HEAP_ARRAY(char, pwbuf, mtInternal);
+  FREE_C_HEAP_ARRAY(char, pwbuf);
   return user_name;
 }
 
@@ -338,7 +338,7 @@
     DIR* subdirp = os::opendir(usrdir_name);
 
     if (subdirp == NULL) {
-      FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
+      FREE_C_HEAP_ARRAY(char, usrdir_name);
       continue;
     }
 
@@ -349,7 +349,7 @@
     // symlink can be exploited.
     //
     if (!is_directory_secure(usrdir_name)) {
-      FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
+      FREE_C_HEAP_ARRAY(char, usrdir_name);
       os::closedir(subdirp);
       continue;
     }
@@ -373,13 +373,13 @@
         // don't follow symbolic links for the file
         RESTARTABLE(::lstat(filename, &statbuf), result);
         if (result == OS_ERR) {
-           FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+           FREE_C_HEAP_ARRAY(char, filename);
            continue;
         }
 
         // skip over files that are not regular files.
         if (!S_ISREG(statbuf.st_mode)) {
-          FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+          FREE_C_HEAP_ARRAY(char, filename);
           continue;
         }
 
@@ -389,7 +389,7 @@
           if (statbuf.st_ctime > oldest_ctime) {
             char* user = strchr(dentry->d_name, '_') + 1;
 
-            if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user, mtInternal);
+            if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user);
             oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1, mtInternal);
 
             strcpy(oldest_user, user);
@@ -397,15 +397,15 @@
           }
         }
 
-        FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+        FREE_C_HEAP_ARRAY(char, filename);
       }
     }
     os::closedir(subdirp);
-    FREE_C_HEAP_ARRAY(char, udbuf, mtInternal);
-    FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
+    FREE_C_HEAP_ARRAY(char, udbuf);
+    FREE_C_HEAP_ARRAY(char, usrdir_name);
   }
   os::closedir(tmpdirp);
-  FREE_C_HEAP_ARRAY(char, tdbuf, mtInternal);
+  FREE_C_HEAP_ARRAY(char, tdbuf);
 
   return(oldest_user);
 }
@@ -520,7 +520,7 @@
 
   remove_file(path);
 
-  FREE_C_HEAP_ARRAY(char, path, mtInternal);
+  FREE_C_HEAP_ARRAY(char, path);
 }
 
 
@@ -597,7 +597,7 @@
     errno = 0;
   }
   os::closedir(dirp);
-  FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
+  FREE_C_HEAP_ARRAY(char, dbuf);
 }
 
 // make the user specific temporary directory. Returns true if
@@ -742,11 +742,11 @@
 
   fd = create_sharedmem_resources(dirname, filename, size);
 
-  FREE_C_HEAP_ARRAY(char, user_name, mtInternal);
-  FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
+  FREE_C_HEAP_ARRAY(char, user_name);
+  FREE_C_HEAP_ARRAY(char, dirname);
 
   if (fd == -1) {
-    FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+    FREE_C_HEAP_ARRAY(char, filename);
     return NULL;
   }
 
@@ -760,7 +760,7 @@
       warning("mmap failed -  %s\n", strerror(errno));
     }
     remove_file(filename);
-    FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+    FREE_C_HEAP_ARRAY(char, filename);
     return NULL;
   }
 
@@ -890,9 +890,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");
@@ -908,9 +908,9 @@
   strcpy(rfilename, filename);
 
   // free the c heap resources that are no longer needed
-  if (luser != user) FREE_C_HEAP_ARRAY(char, luser, mtInternal);
-  FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
-  FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+  if (luser != user) FREE_C_HEAP_ARRAY(char, luser);
+  FREE_C_HEAP_ARRAY(char, dirname);
+  FREE_C_HEAP_ARRAY(char, filename);
 
   // open the shared memory file for the give vmid
   fd = open_sharedmem_file(rfilename, file_flags, THREAD);
--- a/src/os/windows/vm/os_windows.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/os/windows/vm/os_windows.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -211,7 +211,7 @@
     }
     strcpy(home_path, home_dir);
     Arguments::set_java_home(home_path);
-    FREE_C_HEAP_ARRAY(char, home_path, mtInternal);
+    FREE_C_HEAP_ARRAY(char, home_path);
 
     dll_path = NEW_C_HEAP_ARRAY(char, strlen(home_dir) + strlen(bin) + 1,
                                 mtInternal);
@@ -221,7 +221,7 @@
     strcpy(dll_path, home_dir);
     strcat(dll_path, bin);
     Arguments::set_dll_dir(dll_path);
-    FREE_C_HEAP_ARRAY(char, dll_path, mtInternal);
+    FREE_C_HEAP_ARRAY(char, dll_path);
 
     if (!set_boot_path('\\', ';')) {
       return;
@@ -276,7 +276,7 @@
     strcat(library_path, ";.");
 
     Arguments::set_library_path(library_path);
-    FREE_C_HEAP_ARRAY(char, library_path, mtInternal);
+    FREE_C_HEAP_ARRAY(char, library_path);
   }
 
   // Default extensions directory
@@ -292,19 +292,6 @@
   #undef BIN_DIR
   #undef PACKAGE_DIR
 
-  // Default endorsed standards directory.
-  {
-#define ENDORSED_DIR "\\lib\\endorsed"
-    size_t len = strlen(Arguments::get_java_home()) + sizeof(ENDORSED_DIR);
-    char * buf = NEW_C_HEAP_ARRAY(char, len, mtInternal);
-    sprintf(buf, "%s%s", Arguments::get_java_home(), ENDORSED_DIR);
-    Arguments::set_endorsed_dirs(buf);
-    // (Arguments::set_endorsed_dirs() calls SystemProperty::set_value(), which
-    //  duplicates the input.)
-    FREE_C_HEAP_ARRAY(char, buf, mtInternal);
-#undef ENDORSED_DIR
-  }
-
 #ifndef _WIN64
   // set our UnhandledExceptionFilter and save any previous one
   prev_uef_handler = SetUnhandledExceptionFilter(Handle_FLT_Exception);
@@ -1136,7 +1123,7 @@
 
   dirp->path = (char *)malloc(strlen(dirname) + 5, mtInternal);
   if (dirp->path == 0) {
-    free(dirp, mtInternal);
+    free(dirp);
     errno = ENOMEM;
     return 0;
   }
@@ -1144,13 +1131,13 @@
 
   fattr = GetFileAttributes(dirp->path);
   if (fattr == 0xffffffff) {
-    free(dirp->path, mtInternal);
-    free(dirp, mtInternal);
+    free(dirp->path);
+    free(dirp);
     errno = ENOENT;
     return 0;
   } else if ((fattr & FILE_ATTRIBUTE_DIRECTORY) == 0) {
-    free(dirp->path, mtInternal);
-    free(dirp, mtInternal);
+    free(dirp->path);
+    free(dirp);
     errno = ENOTDIR;
     return 0;
   }
@@ -1168,8 +1155,8 @@
   dirp->handle = FindFirstFile(dirp->path, &dirp->find_data);
   if (dirp->handle == INVALID_HANDLE_VALUE) {
     if (GetLastError() != ERROR_FILE_NOT_FOUND) {
-      free(dirp->path, mtInternal);
-      free(dirp, mtInternal);
+      free(dirp->path);
+      free(dirp);
       errno = EACCES;
       return 0;
     }
@@ -1207,8 +1194,8 @@
     }
     dirp->handle = INVALID_HANDLE_VALUE;
   }
-  free(dirp->path, mtInternal);
-  free(dirp, mtInternal);
+  free(dirp->path);
+  free(dirp);
   return 0;
 }
 
@@ -1275,11 +1262,11 @@
     // release the storage
     for (int i = 0; i < n; i++) {
       if (pelements[i] != NULL) {
-        FREE_C_HEAP_ARRAY(char, pelements[i], mtInternal);
+        FREE_C_HEAP_ARRAY(char, pelements[i]);
       }
     }
     if (pelements != NULL) {
-      FREE_C_HEAP_ARRAY(char*, pelements, mtInternal);
+      FREE_C_HEAP_ARRAY(char*, pelements);
     }
   } else {
     jio_snprintf(buffer, buflen, "%s\\%s.dll", pname, fname);
@@ -2745,7 +2732,7 @@
 
   void free_node_list() {
     if (_numa_used_node_list != NULL) {
-      FREE_C_HEAP_ARRAY(int, _numa_used_node_list, mtInternal);
+      FREE_C_HEAP_ARRAY(int, _numa_used_node_list);
     }
   }
 
@@ -3781,8 +3768,8 @@
   return NULL;
 }
 
-#define MAX_EXIT_HANDLES    16
-#define EXIT_TIMEOUT      1000 /* 1 sec */
+#define MAX_EXIT_HANDLES PRODUCT_ONLY(32)   NOT_PRODUCT(128)
+#define EXIT_TIMEOUT     PRODUCT_ONLY(1000) NOT_PRODUCT(4000) /* 1 sec in product, 4 sec in debug */
 
 static BOOL CALLBACK init_crit_sect_call(PINIT_ONCE, PVOID pcrit_sect, PVOID*) {
   InitializeCriticalSection((CRITICAL_SECTION*)pcrit_sect);
@@ -3833,6 +3820,9 @@
         // If there's no free slot in the array of the kept handles, we'll have to
         // wait until at least one thread completes exiting.
         if ((handle_count = j) == MAX_EXIT_HANDLES) {
+          // Raise the priority of the oldest exiting thread to increase its chances
+          // to complete sooner.
+          SetThreadPriority(handles[0], THREAD_PRIORITY_ABOVE_NORMAL);
           res = WaitForMultipleObjects(MAX_EXIT_HANDLES, handles, FALSE, EXIT_TIMEOUT);
           if (res >= WAIT_OBJECT_0 && res < (WAIT_OBJECT_0 + MAX_EXIT_HANDLES)) {
             i = (res - WAIT_OBJECT_0);
@@ -3841,7 +3831,8 @@
               handles[i] = handles[i + 1];
             }
           } else {
-            warning("WaitForMultipleObjects failed in %s: %d\n", __FILE__, __LINE__);
+            warning("WaitForMultipleObjects %s in %s: %d\n",
+                    (res == WAIT_FAILED ? "failed" : "timed out"), __FILE__, __LINE__);
             // Don't keep handles, if we failed waiting for them.
             for (i = 0; i < MAX_EXIT_HANDLES; ++i) {
               CloseHandle(handles[i]);
@@ -3867,9 +3858,20 @@
         if (handle_count > 0) {
           // Before ending the process, make sure all the threads that had called
           // _endthreadex() completed.
+
+          // Set the priority level of the current thread to the same value as
+          // the priority level of exiting threads.
+          // This is to ensure it will be given a fair chance to execute if
+          // the timeout expires.
+          hthr = GetCurrentThread();
+          SetThreadPriority(hthr, THREAD_PRIORITY_ABOVE_NORMAL);
+          for (i = 0; i < handle_count; ++i) {
+            SetThreadPriority(handles[i], THREAD_PRIORITY_ABOVE_NORMAL);
+          }
           res = WaitForMultipleObjects(handle_count, handles, TRUE, EXIT_TIMEOUT);
-          if (res == WAIT_FAILED) {
-            warning("WaitForMultipleObjects failed in %s: %d\n", __FILE__, __LINE__);
+          if (res < WAIT_OBJECT_0 || res >= (WAIT_OBJECT_0 + MAX_EXIT_HANDLES)) {
+            warning("WaitForMultipleObjects %s in %s: %d\n",
+                    (res == WAIT_FAILED ? "failed" : "timed out"), __FILE__, __LINE__);
           }
           for (i = 0; i < handle_count; ++i) {
             CloseHandle(handles[i]);
@@ -4376,6 +4378,23 @@
   return (jlong) ::_lseeki64(fd, offset, whence);
 }
 
+size_t os::read_at(int fd, void *buf, unsigned int nBytes, jlong offset) {
+  OVERLAPPED ov;
+  DWORD nread;
+  BOOL result;
+
+  ZeroMemory(&ov, sizeof(ov));
+  ov.Offset = (DWORD)offset;
+  ov.OffsetHigh = (DWORD)(offset >> 32);
+
+  HANDLE h = (HANDLE)::_get_osfhandle(fd);
+
+  result = ReadFile(h, (LPVOID)buf, nBytes, &nread, &ov);
+
+  return result ? nread : 0;
+}
+
+
 // This method is a slightly reworked copy of JDK's sysNativePath
 // from src/windows/hpi/src/path_md.c
 
@@ -4627,7 +4646,7 @@
 
   error = ::PeekConsoleInput(han, lpBuffer, numEvents, &numEventsRead);
   if (error == 0) {
-    os::free(lpBuffer, mtInternal);
+    os::free(lpBuffer);
     return FALSE;
   }
 
@@ -4648,7 +4667,7 @@
   }
 
   if (lpBuffer != NULL) {
-    os::free(lpBuffer, mtInternal);
+    os::free(lpBuffer);
   }
 
   *pbytes = (long) actualLength;
--- a/src/os/windows/vm/perfMemory_windows.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/os/windows/vm/perfMemory_windows.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -122,7 +122,7 @@
     }
   }
 
-  FREE_C_HEAP_ARRAY(char, destfile, mtInternal);
+  FREE_C_HEAP_ARRAY(char, destfile);
 }
 
 // Shared Memory Implementation Details
@@ -335,7 +335,7 @@
     DIR* subdirp = os::opendir(usrdir_name);
 
     if (subdirp == NULL) {
-      FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
+      FREE_C_HEAP_ARRAY(char, usrdir_name);
       continue;
     }
 
@@ -346,7 +346,7 @@
     // symlink can be exploited.
     //
     if (!is_directory_secure(usrdir_name)) {
-      FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
+      FREE_C_HEAP_ARRAY(char, usrdir_name);
       os::closedir(subdirp);
       continue;
     }
@@ -367,13 +367,13 @@
         strcat(filename, udentry->d_name);
 
         if (::stat(filename, &statbuf) == OS_ERR) {
-           FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+           FREE_C_HEAP_ARRAY(char, filename);
            continue;
         }
 
         // skip over files that are not regular files.
         if ((statbuf.st_mode & S_IFMT) != S_IFREG) {
-          FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+          FREE_C_HEAP_ARRAY(char, filename);
           continue;
         }
 
@@ -395,22 +395,22 @@
         if (statbuf.st_ctime > latest_ctime) {
           char* user = strchr(dentry->d_name, '_') + 1;
 
-          if (latest_user != NULL) FREE_C_HEAP_ARRAY(char, latest_user, mtInternal);
+          if (latest_user != NULL) FREE_C_HEAP_ARRAY(char, latest_user);
           latest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1, mtInternal);
 
           strcpy(latest_user, user);
           latest_ctime = statbuf.st_ctime;
         }
 
-        FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+        FREE_C_HEAP_ARRAY(char, filename);
       }
     }
     os::closedir(subdirp);
-    FREE_C_HEAP_ARRAY(char, udbuf, mtInternal);
-    FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
+    FREE_C_HEAP_ARRAY(char, udbuf);
+    FREE_C_HEAP_ARRAY(char, usrdir_name);
   }
   os::closedir(tmpdirp);
-  FREE_C_HEAP_ARRAY(char, tdbuf, mtInternal);
+  FREE_C_HEAP_ARRAY(char, tdbuf);
 
   return(latest_user);
 }
@@ -502,7 +502,7 @@
     }
   }
 
-  FREE_C_HEAP_ARRAY(char, path, mtInternal);
+  FREE_C_HEAP_ARRAY(char, path);
 }
 
 // returns true if the process represented by pid is alive, otherwise
@@ -683,7 +683,7 @@
     errno = 0;
   }
   os::closedir(dirp);
-  FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
+  FREE_C_HEAP_ARRAY(char, dbuf);
 }
 
 // create a file mapping object with the requested name, and size
@@ -749,11 +749,11 @@
     // be an ACL we enlisted. free the resources.
     //
     if (success && exists && pACL != NULL && !isdefault) {
-      FREE_C_HEAP_ARRAY(char, pACL, mtInternal);
+      FREE_C_HEAP_ARRAY(char, pACL);
     }
 
     // free the security descriptor
-    FREE_C_HEAP_ARRAY(char, pSD, mtInternal);
+    FREE_C_HEAP_ARRAY(char, pSD);
   }
 }
 
@@ -768,7 +768,7 @@
     lpSA->lpSecurityDescriptor = NULL;
 
     // free the security attributes structure
-    FREE_C_HEAP_ARRAY(char, lpSA, mtInternal);
+    FREE_C_HEAP_ARRAY(char, lpSA);
   }
 }
 
@@ -815,7 +815,7 @@
       warning("GetTokenInformation failure: lasterror = %d,"
               " rsize = %d\n", GetLastError(), rsize);
     }
-    FREE_C_HEAP_ARRAY(char, token_buf, mtInternal);
+    FREE_C_HEAP_ARRAY(char, token_buf);
     CloseHandle(hAccessToken);
     return NULL;
   }
@@ -828,15 +828,15 @@
       warning("GetTokenInformation failure: lasterror = %d,"
               " rsize = %d\n", GetLastError(), rsize);
     }
-    FREE_C_HEAP_ARRAY(char, token_buf, mtInternal);
-    FREE_C_HEAP_ARRAY(char, pSID, mtInternal);
+    FREE_C_HEAP_ARRAY(char, token_buf);
+    FREE_C_HEAP_ARRAY(char, pSID);
     CloseHandle(hAccessToken);
     return NULL;
   }
 
   // close the access token.
   CloseHandle(hAccessToken);
-  FREE_C_HEAP_ARRAY(char, token_buf, mtInternal);
+  FREE_C_HEAP_ARRAY(char, token_buf);
 
   return pSID;
 }
@@ -920,7 +920,7 @@
     if (PrintMiscellaneous && Verbose) {
       warning("InitializeAcl failure: lasterror = %d \n", GetLastError());
     }
-    FREE_C_HEAP_ARRAY(char, newACL, mtInternal);
+    FREE_C_HEAP_ARRAY(char, newACL);
     return false;
   }
 
@@ -933,7 +933,7 @@
         if (PrintMiscellaneous && Verbose) {
           warning("InitializeAcl failure: lasterror = %d \n", GetLastError());
         }
-        FREE_C_HEAP_ARRAY(char, newACL, mtInternal);
+        FREE_C_HEAP_ARRAY(char, newACL);
         return false;
       }
       if (((ACCESS_ALLOWED_ACE *)ace)->Header.AceFlags && INHERITED_ACE) {
@@ -960,7 +960,7 @@
           if (PrintMiscellaneous && Verbose) {
             warning("AddAce failure: lasterror = %d \n", GetLastError());
           }
-          FREE_C_HEAP_ARRAY(char, newACL, mtInternal);
+          FREE_C_HEAP_ARRAY(char, newACL);
           return false;
         }
       }
@@ -976,7 +976,7 @@
         warning("AddAccessAllowedAce failure: lasterror = %d \n",
                 GetLastError());
       }
-      FREE_C_HEAP_ARRAY(char, newACL, mtInternal);
+      FREE_C_HEAP_ARRAY(char, newACL);
       return false;
     }
   }
@@ -991,7 +991,7 @@
         if (PrintMiscellaneous && Verbose) {
           warning("InitializeAcl failure: lasterror = %d \n", GetLastError());
         }
-        FREE_C_HEAP_ARRAY(char, newACL, mtInternal);
+        FREE_C_HEAP_ARRAY(char, newACL);
         return false;
       }
       if (!AddAce(newACL, ACL_REVISION, MAXDWORD, ace,
@@ -999,7 +999,7 @@
         if (PrintMiscellaneous && Verbose) {
           warning("AddAce failure: lasterror = %d \n", GetLastError());
         }
-        FREE_C_HEAP_ARRAY(char, newACL, mtInternal);
+        FREE_C_HEAP_ARRAY(char, newACL);
         return false;
       }
       ace_index++;
@@ -1012,7 +1012,7 @@
       warning("SetSecurityDescriptorDacl failure:"
               " lasterror = %d \n", GetLastError());
     }
-    FREE_C_HEAP_ARRAY(char, newACL, mtInternal);
+    FREE_C_HEAP_ARRAY(char, newACL);
     return false;
   }
 
@@ -1032,7 +1032,7 @@
         warning("SetSecurityDescriptorControl failure:"
                 " lasterror = %d \n", GetLastError());
       }
-      FREE_C_HEAP_ARRAY(char, newACL, mtInternal);
+      FREE_C_HEAP_ARRAY(char, newACL);
       return false;
     }
   }
@@ -1149,7 +1149,7 @@
   // create a security attributes structure with access control
   // entries as initialized above.
   LPSECURITY_ATTRIBUTES lpSA = make_security_attr(aces, 3);
-  FREE_C_HEAP_ARRAY(char, aces[0].pSid, mtInternal);
+  FREE_C_HEAP_ARRAY(char, aces[0].pSid);
   FreeSid(everybodySid);
   FreeSid(administratorsSid);
   return(lpSA);
@@ -1464,15 +1464,15 @@
   assert(((size != 0) && (size % os::vm_page_size() == 0)),
          "unexpected PerfMemry region size");
 
-  FREE_C_HEAP_ARRAY(char, user, mtInternal);
+  FREE_C_HEAP_ARRAY(char, user);
 
   // create the shared memory resources
   sharedmem_fileMapHandle =
                create_sharedmem_resources(dirname, filename, objectname, size);
 
-  FREE_C_HEAP_ARRAY(char, filename, mtInternal);
-  FREE_C_HEAP_ARRAY(char, objectname, mtInternal);
-  FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
+  FREE_C_HEAP_ARRAY(char, filename);
+  FREE_C_HEAP_ARRAY(char, objectname);
+  FREE_C_HEAP_ARRAY(char, dirname);
 
   if (sharedmem_fileMapHandle == NULL) {
     return NULL;
@@ -1627,7 +1627,7 @@
   // store file, we also don't following them when attaching
   //
   if (!is_directory_secure(dirname)) {
-    FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
+    FREE_C_HEAP_ARRAY(char, dirname);
     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
               "Process not found");
   }
@@ -1646,10 +1646,10 @@
   strcpy(robjectname, objectname);
 
   // free the c heap resources that are no longer needed
-  if (luser != user) FREE_C_HEAP_ARRAY(char, luser, mtInternal);
-  FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
-  FREE_C_HEAP_ARRAY(char, filename, mtInternal);
-  FREE_C_HEAP_ARRAY(char, objectname, mtInternal);
+  if (luser != user) FREE_C_HEAP_ARRAY(char, luser);
+  FREE_C_HEAP_ARRAY(char, dirname);
+  FREE_C_HEAP_ARRAY(char, filename);
+  FREE_C_HEAP_ARRAY(char, objectname);
 
   if (*sizep == 0) {
     size = sharedmem_filesize(rfilename, CHECK);
--- a/src/os_cpu/windows_x86/vm/os_windows_x86.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/os_cpu/windows_x86/vm/os_windows_x86.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -654,7 +654,11 @@
 #ifndef PRODUCT
 void os::verify_stack_alignment() {
 #ifdef AMD64
-  assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment");
+  // The current_stack_pointer() calls generated get_previous_sp stub routine.
+  // Only enable the assert after the routine becomes available.
+  if (StubRoutines::code1() != NULL) {
+    assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment");
+  }
 #endif
 }
 #endif
--- a/src/share/tools/ProjectCreator/BuildConfig.java	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/tools/ProjectCreator/BuildConfig.java	Fri Dec 12 21:32:43 2014 +0300
@@ -512,7 +512,9 @@
 abstract class GenericDebugNonKernelConfig extends GenericDebugConfig {
     protected void init(Vector includes, Vector defines) {
         super.init(includes, defines);
-        getCI().getAdditionalNonKernelLinkerFlags(getV("LinkerFlags"));
+        if (get("PlatformName").equals("Win32")) {
+            getCI().getAdditionalNonKernelLinkerFlags(getV("LinkerFlags"));
+        }
    }
 }
 
--- a/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java	Fri Dec 12 21:32:43 2014 +0300
@@ -401,16 +401,18 @@
     Vector getBaseLinkerFlags(String outDir, String outDll, String platformName) {
         Vector rv = new Vector();
 
-        addAttr(rv, "AdditionalOptions",
-                "/export:JNI_GetDefaultJavaVMInitArgs " +
-                "/export:JNI_CreateJavaVM " +
-                "/export:JVM_FindClassFromBootLoader "+
-                "/export:JNI_GetCreatedJavaVMs "+
-                "/export:jio_snprintf /export:jio_printf "+
-                "/export:jio_fprintf /export:jio_vfprintf "+
-                "/export:jio_vsnprintf "+
-                "/export:JVM_GetVersionInfo "+
-                "/export:JVM_InitAgentProperties");
+        if(platformName.equals("Win32")) {
+            addAttr(rv, "AdditionalOptions",
+                    "/export:JNI_GetDefaultJavaVMInitArgs " +
+                    "/export:JNI_CreateJavaVM " +
+                    "/export:JVM_FindClassFromBootLoader "+
+                    "/export:JNI_GetCreatedJavaVMs "+
+                    "/export:jio_snprintf /export:jio_printf "+
+                    "/export:jio_fprintf /export:jio_vfprintf "+
+                    "/export:jio_vsnprintf "+
+                    "/export:JVM_GetVersionInfo "+
+                    "/export:JVM_InitAgentProperties");
+        }
         addAttr(rv, "AdditionalDependencies", "kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;Wsock32.lib;winmm.lib;psapi.lib;version.lib");
         addAttr(rv, "OutputFile", outDll);
         addAttr(rv, "SuppressStartupBanner", "true");
--- a/src/share/vm/asm/codeBuffer.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/asm/codeBuffer.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -1025,7 +1025,7 @@
 
   ~CodeString() {
     assert(_next == NULL, "wrong interface for freeing list");
-    os::free((void*)_string, mtCode);
+    os::free((void*)_string);
   }
 
   bool is_comment() const { return _offset >= 0; }
--- a/src/share/vm/ci/ciEnv.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/ci/ciEnv.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -53,6 +53,7 @@
 #include "runtime/reflection.hpp"
 #include "runtime/sharedRuntime.hpp"
 #include "runtime/thread.inline.hpp"
+#include "trace/tracing.hpp"
 #include "utilities/dtrace.hpp"
 #include "utilities/macros.hpp"
 #ifdef COMPILER1
@@ -1141,6 +1142,16 @@
   }
 }
 
+void ciEnv::report_failure(const char* reason) {
+  // Create and fire JFR event
+  EventCompilerFailure event;
+  if (event.should_commit()) {
+    event.set_compileID(compile_id());
+    event.set_failure(reason);
+    event.commit();
+  }
+}
+
 // ------------------------------------------------------------------
 // ciEnv::record_method_not_compilable()
 void ciEnv::record_method_not_compilable(const char* reason, bool all_tiers) {
--- a/src/share/vm/ci/ciEnv.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/ci/ciEnv.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -450,7 +450,8 @@
   // Check for changes to the system dictionary during compilation
   bool system_dictionary_modification_counter_changed();
 
-  void record_failure(const char* reason);
+  void record_failure(const char* reason);      // Record failure and report later
+  void report_failure(const char* reason);      // Report failure immediately
   void record_method_not_compilable(const char* reason, bool all_tiers = true);
   void record_out_of_memory_failure();
 
--- a/src/share/vm/ci/ciTypeFlow.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/ci/ciTypeFlow.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -35,6 +35,8 @@
 #include "interpreter/bytecode.hpp"
 #include "interpreter/bytecodes.hpp"
 #include "memory/allocation.inline.hpp"
+#include "opto/compile.hpp"
+#include "opto/node.hpp"
 #include "runtime/deoptimization.hpp"
 #include "utilities/growableArray.hpp"
 
@@ -2646,7 +2648,7 @@
       assert (!blk->has_pre_order(), "");
       blk->set_next_pre_order();
 
-      if (_next_pre_order >= MaxNodeLimit / 2) {
+      if (_next_pre_order >= (int)Compile::current()->max_node_limit() / 2) {
         // Too many basic blocks.  Bail out.
         // This can happen when try/finally constructs are nested to depth N,
         // and there is O(2**N) cloning of jsr bodies.  See bug 4697245!
--- a/src/share/vm/classfile/classFileParser.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/classfile/classFileParser.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -3108,21 +3108,39 @@
   }
 }
 
-// Transfer ownership of metadata allocated to the InstanceKlass.
-void ClassFileParser::apply_parsed_class_metadata(
-                                            instanceKlassHandle this_klass,
-                                            int java_fields_count, TRAPS) {
-  // Assign annotations if needed
-  if (_annotations != NULL || _type_annotations != NULL ||
-      _fields_annotations != NULL || _fields_type_annotations != NULL) {
+// Create the Annotations object that will
+// hold the annotations array for the Klass.
+void ClassFileParser::create_combined_annotations(TRAPS) {
+    if (_annotations == NULL &&
+        _type_annotations == NULL &&
+        _fields_annotations == NULL &&
+        _fields_type_annotations == NULL) {
+      // Don't create the Annotations object unnecessarily.
+      return;
+    }
+
     Annotations* annotations = Annotations::allocate(_loader_data, CHECK);
     annotations->set_class_annotations(_annotations);
     annotations->set_class_type_annotations(_type_annotations);
     annotations->set_fields_annotations(_fields_annotations);
     annotations->set_fields_type_annotations(_fields_type_annotations);
-    this_klass->set_annotations(annotations);
-  }
-
+
+    // This is the Annotations object that will be
+    // assigned to InstanceKlass being constructed.
+    _combined_annotations = annotations;
+
+    // The annotations arrays below has been transfered the
+    // _combined_annotations so these fields can now be cleared.
+    _annotations             = NULL;
+    _type_annotations        = NULL;
+    _fields_annotations      = NULL;
+    _fields_type_annotations = NULL;
+}
+
+// Transfer ownership of metadata allocated to the InstanceKlass.
+void ClassFileParser::apply_parsed_class_metadata(
+                                            instanceKlassHandle this_klass,
+                                            int java_fields_count, TRAPS) {
   _cp->set_pool_holder(this_klass());
   this_klass->set_constants(_cp);
   this_klass->set_fields(_fields, java_fields_count);
@@ -3130,6 +3148,7 @@
   this_klass->set_inner_classes(_inner_classes);
   this_klass->set_local_interfaces(_local_interfaces);
   this_klass->set_transitive_interfaces(_transitive_interfaces);
+  this_klass->set_annotations(_combined_annotations);
 
   // Clear out these fields so they don't get deallocated by the destructor
   clear_class_metadata();
@@ -4002,6 +4021,10 @@
     ClassAnnotationCollector parsed_annotations;
     parse_classfile_attributes(&parsed_annotations, CHECK_(nullHandle));
 
+    // Finalize the Annotations metadata object,
+    // now that all annotation arrays have been created.
+    create_combined_annotations(CHECK_(nullHandle));
+
     // Make sure this is the end of class file stream
     guarantee_property(cfs->at_eos(), "Extra bytes at the end of class file %s", CHECK_(nullHandle));
 
@@ -4302,10 +4325,27 @@
   InstanceKlass::deallocate_interfaces(_loader_data, _super_klass(),
                                        _local_interfaces, _transitive_interfaces);
 
-  MetadataFactory::free_array<u1>(_loader_data, _annotations);
-  MetadataFactory::free_array<u1>(_loader_data, _type_annotations);
-  Annotations::free_contents(_loader_data, _fields_annotations);
-  Annotations::free_contents(_loader_data, _fields_type_annotations);
+  if (_combined_annotations != NULL) {
+    // After all annotations arrays have been created, they are installed into the
+    // Annotations object that will be assigned to the InstanceKlass being created.
+
+    // Deallocate the Annotations object and the installed annotations arrays.
+    _combined_annotations->deallocate_contents(_loader_data);
+
+    // If the _combined_annotations pointer is non-NULL,
+    // then the other annotations fields should have been cleared.
+    assert(_annotations             == NULL, "Should have been cleared");
+    assert(_type_annotations        == NULL, "Should have been cleared");
+    assert(_fields_annotations      == NULL, "Should have been cleared");
+    assert(_fields_type_annotations == NULL, "Should have been cleared");
+  } else {
+    // If the annotations arrays were not installed into the Annotations object,
+    // then they have to be deallocated explicitly.
+    MetadataFactory::free_array<u1>(_loader_data, _annotations);
+    MetadataFactory::free_array<u1>(_loader_data, _type_annotations);
+    Annotations::free_contents(_loader_data, _fields_annotations);
+    Annotations::free_contents(_loader_data, _fields_type_annotations);
+  }
 
   clear_class_metadata();
 
--- a/src/share/vm/classfile/classFileParser.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/classfile/classFileParser.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -75,6 +75,7 @@
   Array<u2>*       _inner_classes;
   Array<Klass*>*   _local_interfaces;
   Array<Klass*>*   _transitive_interfaces;
+  Annotations*     _combined_annotations;
   AnnotationArray* _annotations;
   AnnotationArray* _type_annotations;
   Array<AnnotationArray*>* _fields_annotations;
@@ -86,6 +87,8 @@
   void set_class_generic_signature_index(u2 x) { _generic_signature_index = x; }
   void set_class_sde_buffer(char* x, int len)  { _sde_buffer = x; _sde_length = len; }
 
+  void create_combined_annotations(TRAPS);
+
   void init_parsed_class_attributes(ClassLoaderData* loader_data) {
     _loader_data = loader_data;
     _synthetic_flag = false;
@@ -110,6 +113,7 @@
     _inner_classes = NULL;
     _local_interfaces = NULL;
     _transitive_interfaces = NULL;
+    _combined_annotations = NULL;
     _annotations = _type_annotations = NULL;
     _fields_annotations = _fields_type_annotations = NULL;
   }
--- a/src/share/vm/classfile/classLoader.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/classfile/classLoader.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -28,6 +28,7 @@
 #include "classfile/classLoader.hpp"
 #include "classfile/classLoaderExt.hpp"
 #include "classfile/classLoaderData.inline.hpp"
+#include "classfile/imageFile.hpp"
 #include "classfile/javaClasses.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
@@ -68,7 +69,7 @@
 #endif
 
 
-// Entry points in zip.dll for loading zip/jar file entries
+// Entry points in zip.dll for loading zip/jar file entries and image file entries
 
 typedef void * * (JNICALL *ZipOpen_t)(const char *name, char **pmsg);
 typedef void (JNICALL *ZipClose_t)(jzfile *zip);
@@ -76,6 +77,7 @@
 typedef jboolean (JNICALL *ReadEntry_t)(jzfile *zip, jzentry *entry, unsigned char *buf, char *namebuf);
 typedef jboolean (JNICALL *ReadMappedEntry_t)(jzfile *zip, jzentry *entry, unsigned char **buf, char *namebuf);
 typedef jzentry* (JNICALL *GetNextEntry_t)(jzfile *zip, jint n);
+typedef jboolean (JNICALL *ZipInflateFully_t)(void *inBuf, jlong inLen, void *outBuf, jlong outLen, char **pmsg);
 typedef jint     (JNICALL *Crc32_t)(jint crc, const jbyte *buf, jint len);
 
 static ZipOpen_t         ZipOpen            = NULL;
@@ -85,6 +87,7 @@
 static ReadMappedEntry_t ReadMappedEntry    = NULL;
 static GetNextEntry_t    GetNextEntry       = NULL;
 static canonicalize_fn_t CanonicalizeEntry  = NULL;
+static ZipInflateFully_t ZipInflateFully    = NULL;
 static Crc32_t           Crc32              = NULL;
 
 // Globals
@@ -162,7 +165,7 @@
 
 
 MetaIndex::~MetaIndex() {
-  FREE_C_HEAP_ARRAY(char*, _meta_package_names, mtClass);
+  FREE_C_HEAP_ARRAY(char*, _meta_package_names);
 }
 
 
@@ -248,7 +251,7 @@
   if (ZipClose != NULL) {
     (*ZipClose)(_zip);
   }
-  FREE_C_HEAP_ARRAY(char, _zip_name, mtClass);
+  FREE_C_HEAP_ARRAY(char, _zip_name);
 }
 
 u1* ClassPathZipEntry::open_entry(const char* name, jint* filesize, bool nul_terminate, TRAPS) {
@@ -323,6 +326,8 @@
 }
 
 bool LazyClassPathEntry::is_jar_file() {
+  size_t len = strlen(_path);
+  if (len < 4 || strcmp(_path + len - 4, ".jar") != 0) return false;
   return ((_st.st_mode & S_IFREG) == S_IFREG);
 }
 
@@ -386,6 +391,78 @@
   }
 }
 
+ClassPathImageEntry::ClassPathImageEntry(char* name) : ClassPathEntry(), _image(new ImageFile(name)) {
+  bool opened = _image->open();
+  if (!opened) {
+    _image = NULL;
+  }
+}
+
+ClassPathImageEntry::~ClassPathImageEntry() {
+  if (_image) {
+    _image->close();
+    _image = NULL;
+  }
+}
+
+const char* ClassPathImageEntry::name() {
+  return _image ? _image->name() : "";
+}
+
+ClassFileStream* ClassPathImageEntry::open_stream(const char* name, TRAPS) {
+  u1* buffer;
+  u8 size;
+  _image->get_resource(name, buffer, size);
+
+  if (buffer) {
+    if (UsePerfData) {
+      ClassLoader::perf_sys_classfile_bytes_read()->inc(size);
+    }
+    return new ClassFileStream(buffer, (int)size, (char*)name);  // Resource allocated
+  }
+
+  return NULL;
+}
+
+#ifndef PRODUCT
+void ClassPathImageEntry::compile_the_world(Handle loader, TRAPS) {
+  tty->print_cr("CompileTheWorld : Compiling all classes in %s", name());
+  tty->cr();
+  const ImageStrings strings = _image->get_strings();
+  // Retrieve each path component string.
+  u4 count = _image->get_location_count();
+  for (u4 i = 0; i < count; i++) {
+    u1* location_data = _image->get_location_data(i);
+
+    if (location_data) {
+       ImageLocation location(location_data);
+       const char* parent = location.get_attribute(ImageLocation::ATTRIBUTE_PARENT, strings);
+       const char* base = location.get_attribute(ImageLocation::ATTRIBUTE_BASE, strings);
+       const char* extension = location.get_attribute(ImageLocation::ATTRIBUTE_EXTENSION, strings);
+       assert((strlen(parent) + strlen(base) + strlen(extension)) < JVM_MAXPATHLEN, "path exceeds buffer");
+       char path[JVM_MAXPATHLEN];
+       strcpy(path, parent);
+       strcat(path, base);
+       strcat(path, extension);
+       ClassLoader::compile_the_world_in(path, loader, CHECK);
+    }
+  }
+  if (HAS_PENDING_EXCEPTION) {
+  if (PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())) {
+    CLEAR_PENDING_EXCEPTION;
+    tty->print_cr("\nCompileTheWorld : Ran out of memory\n");
+    tty->print_cr("Increase class metadata storage if a limit was set");
+  } else {
+    tty->print_cr("\nCompileTheWorld : Unexpected exception occurred\n");
+  }
+  }
+}
+
+bool ClassPathImageEntry::is_jrt() {
+  return string_ends_with(name(), "bootmodules.jimage");
+}
+#endif
+
 static void print_meta_index(LazyClassPathEntry* entry,
                              GrowableArray<char*>& meta_packages) {
   tty->print("[Meta index for %s=", entry->name());
@@ -635,7 +712,7 @@
   }
   ClassPathEntry* new_entry = NULL;
   if ((st->st_mode & S_IFREG) == S_IFREG) {
-    // Regular file, should be a zip file
+    // Regular file, should be a zip or image file
     // Canonicalized filename
     char canonical_path[JVM_MAXPATHLEN];
     if (!get_canonical_path(path, canonical_path, JVM_MAXPATHLEN)) {
@@ -646,6 +723,11 @@
         return NULL;
       }
     }
+    // TODO - add proper criteria for selecting image file
+    ClassPathImageEntry* entry = new ClassPathImageEntry(canonical_path);
+    if (entry->is_open()) {
+      new_entry = entry;
+    } else {
     char* error_msg = NULL;
     jzfile* zip;
     {
@@ -656,9 +738,6 @@
     }
     if (zip != NULL && error_msg == NULL) {
       new_entry = new ClassPathZipEntry(zip, path);
-      if (TraceClassLoading || TraceClassPaths) {
-        tty->print_cr("[Opened %s]", path);
-      }
     } else {
       ResourceMark rm(thread);
       char *msg;
@@ -676,10 +755,14 @@
         return NULL;
       }
     }
+    }
+    if (TraceClassLoading || TraceClassPaths) {
+      tty->print_cr("[Opened %s]", path);
+    }
   } else {
     // Directory
     new_entry = new ClassPathDirEntry(path);
-    if (TraceClassLoading || TraceClassPaths) {
+    if (TraceClassLoading) {
       tty->print_cr("[Path %s]", path);
     }
   }
@@ -802,6 +885,7 @@
   ReadEntry    = CAST_TO_FN_PTR(ReadEntry_t, os::dll_lookup(handle, "ZIP_ReadEntry"));
   ReadMappedEntry = CAST_TO_FN_PTR(ReadMappedEntry_t, os::dll_lookup(handle, "ZIP_ReadMappedEntry"));
   GetNextEntry = CAST_TO_FN_PTR(GetNextEntry_t, os::dll_lookup(handle, "ZIP_GetNextEntry"));
+  ZipInflateFully = CAST_TO_FN_PTR(ZipInflateFully_t, os::dll_lookup(handle, "ZIP_InflateFully"));
   Crc32        = CAST_TO_FN_PTR(Crc32_t, os::dll_lookup(handle, "ZIP_CRC32"));
 
   // ZIP_Close is not exported on Windows in JDK5.0 so don't abort if ZIP_Close is NULL
@@ -810,12 +894,20 @@
     vm_exit_during_initialization("Corrupted ZIP library", path);
   }
 
+  if (ZipInflateFully == NULL) {
+    vm_exit_during_initialization("Corrupted ZIP library ZIP_InflateFully missing", path);
+  }
+
   // Lookup canonicalize entry in libjava.dll
   void *javalib_handle = os::native_java_library();
   CanonicalizeEntry = CAST_TO_FN_PTR(canonicalize_fn_t, os::dll_lookup(javalib_handle, "Canonicalize"));
   // This lookup only works on 1.3. Do not check for non-null here
 }
 
+jboolean ClassLoader::decompress(void *in, u8 inSize, void *out, u8 outSize, char **pmsg) {
+  return (*ZipInflateFully)(in, inSize, out, outSize, pmsg);
+}
+
 int ClassLoader::crc32(int crc, const char* buf, int len) {
   assert(Crc32 != NULL, "ZIP_CRC32 is not found");
   return (*Crc32)(crc, (const jbyte*)buf, len);
@@ -1368,8 +1460,7 @@
   tty->cr();
 }
 
-
-bool ClassPathDirEntry::is_rt_jar() {
+bool ClassPathDirEntry::is_jrt() {
   return false;
 }
 
@@ -1394,13 +1485,13 @@
   }
 }
 
-bool ClassPathZipEntry::is_rt_jar() {
+bool ClassPathZipEntry::is_jrt() {
   real_jzfile* zip = (real_jzfile*) _zip;
   int len = (int)strlen(zip->name);
   // Check whether zip name ends in "rt.jar"
   // This will match other archives named rt.jar as well, but this is
   // only used for debugging.
-  return (len >= 6) && (strcasecmp(zip->name + len - 6, "rt.jar") == 0);
+  return string_ends_with(zip->name, "rt.jar");
 }
 
 void LazyClassPathEntry::compile_the_world(Handle loader, TRAPS) {
@@ -1410,7 +1501,7 @@
   }
 }
 
-bool LazyClassPathEntry::is_rt_jar() {
+bool LazyClassPathEntry::is_jrt() {
   Thread* THREAD = Thread::current();
   ClassPathEntry* cpe = resolve_entry(THREAD);
   return (cpe != NULL) ? cpe->is_jar_file() : false;
@@ -1429,7 +1520,7 @@
   jlong start = os::javaTimeMillis();
   while (e != NULL) {
     // We stop at rt.jar, unless it is the first bootstrap path entry
-    if (e->is_rt_jar() && e != _first_entry) break;
+    if (e->is_jrt() && e != _first_entry) break;
     e->compile_the_world(system_class_loader, CATCH);
     e = e->next();
   }
@@ -1477,9 +1568,9 @@
 }
 
 void ClassLoader::compile_the_world_in(char* name, Handle loader, TRAPS) {
-  int len = (int)strlen(name);
-  if (len > 6 && strcmp(".class", name + len - 6) == 0) {
+  if (string_ends_with(name, ".class")) {
     // We have a .class file
+    int len = (int)strlen(name);
     char buffer[2048];
     strncpy(buffer, name, len - 6);
     buffer[len-6] = 0;
--- a/src/share/vm/classfile/classLoader.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/classfile/classLoader.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -67,7 +67,7 @@
   virtual ClassFileStream* open_stream(const char* name, TRAPS) = 0;
   // Debugging
   NOT_PRODUCT(virtual void compile_the_world(Handle loader, TRAPS) = 0;)
-  NOT_PRODUCT(virtual bool is_rt_jar() = 0;)
+  NOT_PRODUCT(virtual bool is_jrt() = 0;)
 };
 
 
@@ -81,7 +81,7 @@
   ClassFileStream* open_stream(const char* name, TRAPS);
   // Debugging
   NOT_PRODUCT(void compile_the_world(Handle loader, TRAPS);)
-  NOT_PRODUCT(bool is_rt_jar();)
+  NOT_PRODUCT(bool is_jrt();)
 };
 
 
@@ -113,7 +113,7 @@
   void contents_do(void f(const char* name, void* context), void* context);
   // Debugging
   NOT_PRODUCT(void compile_the_world(Handle loader, TRAPS);)
-  NOT_PRODUCT(bool is_rt_jar();)
+  NOT_PRODUCT(bool is_jrt();)
 };
 
 
@@ -139,7 +139,25 @@
   virtual bool is_lazy();
   // Debugging
   NOT_PRODUCT(void compile_the_world(Handle loader, TRAPS);)
-  NOT_PRODUCT(bool is_rt_jar();)
+  NOT_PRODUCT(bool is_jrt();)
+};
+
+// For java image files
+class ImageFile;
+class ClassPathImageEntry: public ClassPathEntry {
+private:
+  ImageFile *_image;
+public:
+  bool is_jar_file()  { return false;  }
+  bool is_open()  { return _image != NULL; }
+  const char* name();
+  ClassPathImageEntry(char* name);
+  ~ClassPathImageEntry();
+  ClassFileStream* open_stream(const char* name, TRAPS);
+
+  // Debugging
+  NOT_PRODUCT(void compile_the_world(Handle loader, TRAPS);)
+  NOT_PRODUCT(bool is_jrt();)
 };
 
 class PackageHashtable;
@@ -227,6 +245,7 @@
   // to avoid confusing the zip library
   static bool get_canonical_path(const char* orig, char* out, int len);
  public:
+  static jboolean decompress(void *in, u8 inSize, void *out, u8 outSize, char **pmsg);
   static int crc32(int crc, const char* buf, int len);
   static bool update_class_path_entry_list(const char *path,
                                            bool check_for_duplicates,
--- a/src/share/vm/classfile/classLoaderData.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/classfile/classLoaderData.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -65,9 +65,8 @@
 #include "utilities/growableArray.hpp"
 #include "utilities/macros.hpp"
 #include "utilities/ostream.hpp"
-
 #if INCLUDE_TRACE
- #include "trace/tracing.hpp"
+#include "trace/tracing.hpp"
 #endif
 
 ClassLoaderData * ClassLoaderData::_the_null_class_loader_data = NULL;
@@ -978,4 +977,4 @@
   event.commit();
 }
 
-#endif /* INCLUDE_TRACE */
+#endif // INCLUDE_TRACE
--- a/src/share/vm/classfile/classLoaderData.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/classfile/classLoaderData.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -31,8 +31,9 @@
 #include "memory/metaspaceCounters.hpp"
 #include "runtime/mutex.hpp"
 #include "utilities/growableArray.hpp"
+#include "utilities/macros.hpp"
 #if INCLUDE_TRACE
-# include "utilities/ticks.hpp"
+#include "utilities/ticks.hpp"
 #endif
 
 //
--- a/src/share/vm/classfile/classLoaderExt.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/classfile/classLoaderExt.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -63,6 +63,9 @@
                                    ClassPathEntry* new_entry) {
     ClassLoader::add_to_list(new_entry);
   }
+  static void append_boot_classpath(ClassPathEntry* new_entry) {
+    ClassLoader::add_to_list(new_entry);
+  }
   static void setup_search_paths() {}
 };
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/classfile/imageFile.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -0,0 +1,286 @@
+/*
+ * Copyright (c) 2014, 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/imageFile.hpp"
+#include "runtime/os.inline.hpp"
+#include "utilities/bytes.hpp"
+
+
+// Compute the Perfect Hashing hash code for the supplied string.
+u4 ImageStrings::hash_code(const char* string, u4 seed) {
+  u1* bytes = (u1*)string;
+
+  // Compute hash code.
+  for (u1 byte = *bytes++; byte; byte = *bytes++) {
+    seed = (seed * HASH_MULTIPLIER) ^ byte;
+  }
+
+  // Ensure the result is unsigned.
+  return seed & 0x7FFFFFFF;
+}
+
+// Test to see if string begins with start.  If so returns remaining portion
+// of string.  Otherwise, NULL.
+const char* ImageStrings::starts_with(const char* string, const char* start) {
+  char ch1, ch2;
+
+  // Match up the strings the best we can.
+  while ((ch1 = *string) && (ch2 = *start)) {
+    if (ch1 != ch2) {
+      // Mismatch, return NULL.
+      return NULL;
+    }
+
+    string++, start++;
+  }
+
+  // Return remainder of string.
+  return string;
+}
+
+ImageLocation::ImageLocation(u1* data) {
+  // Deflate the attribute stream into an array of attributes.
+  memset(_attributes, 0, sizeof(_attributes));
+  u1 byte;
+
+  while ((byte = *data) != ATTRIBUTE_END) {
+    u1 kind = attribute_kind(byte);
+    u1 n = attribute_length(byte);
+    assert(kind < ATTRIBUTE_COUNT, "invalid image location attribute");
+    _attributes[kind] = attribute_value(data + 1, n);
+    data += n + 1;
+  }
+}
+
+ImageFile::ImageFile(const char* name) {
+  // Copy the image file name.
+  _name = NEW_C_HEAP_ARRAY(char, strlen(name)+1, mtClass);
+  strcpy(_name, name);
+
+  // Initialize for a closed file.
+  _fd = -1;
+  _memory_mapped = true;
+  _index_data = NULL;
+}
+
+ImageFile::~ImageFile() {
+  // Ensure file is closed.
+  close();
+
+  // Free up name.
+  FREE_C_HEAP_ARRAY(char, _name);
+}
+
+bool ImageFile::open() {
+  // If file exists open for reading.
+  struct stat st;
+  if (os::stat(_name, &st) != 0 ||
+    (st.st_mode & S_IFREG) != S_IFREG ||
+    (_fd = os::open(_name, 0, O_RDONLY)) == -1) {
+    return false;
+  }
+
+  // Read image file header and verify.
+  u8 header_size = sizeof(ImageHeader);
+  if (os::read(_fd, &_header, header_size) != header_size ||
+    _header._magic != IMAGE_MAGIC ||
+    _header._major_version != MAJOR_VERSION ||
+    _header._minor_version != MINOR_VERSION) {
+    close();
+    return false;
+  }
+
+  // Memory map index.
+  _index_size = index_size();
+  _index_data = (u1*)os::map_memory(_fd, _name, 0, NULL, _index_size, true, false);
+
+  // Failing that, read index into C memory.
+  if (_index_data == NULL) {
+    _memory_mapped = false;
+    _index_data = NEW_RESOURCE_ARRAY(u1, _index_size);
+
+    if (os::seek_to_file_offset(_fd, 0) == -1) {
+      close();
+      return false;
+    }
+
+    if (os::read(_fd, _index_data, _index_size) != _index_size) {
+      close();
+      return false;
+    }
+
+    return true;
+  }
+
+// Used to advance a pointer, unstructured.
+#undef nextPtr
+#define nextPtr(base, fromType, count, toType) (toType*)((fromType*)(base) + (count))
+  // Pull tables out from the index.
+  _redirect_table = nextPtr(_index_data, u1, header_size, s4);
+  _offsets_table = nextPtr(_redirect_table, s4, _header._location_count, u4);
+  _location_bytes = nextPtr(_offsets_table, u4, _header._location_count, u1);
+  _string_bytes = nextPtr(_location_bytes, u1, _header._locations_size, u1);
+#undef nextPtr
+
+  // Successful open.
+  return true;
+}
+
+void ImageFile::close() {
+  // Dealllocate the index.
+  if (_index_data) {
+    if (_memory_mapped) {
+      os::unmap_memory((char*)_index_data, _index_size);
+    } else {
+      FREE_RESOURCE_ARRAY(u1, _index_data, _index_size);
+    }
+
+    _index_data = NULL;
+  }
+
+  // close file.
+  if (_fd != -1) {
+    os::close(_fd);
+    _fd = -1;
+  }
+
+}
+
+// Return the attribute stream for a named resourced.
+u1* ImageFile::find_location_data(const char* path) const {
+  // Compute hash.
+  u4 hash = ImageStrings::hash_code(path) % _header._location_count;
+  s4 redirect = _redirect_table[hash];
+
+  if (!redirect) {
+    return NULL;
+  }
+
+  u4 index;
+
+  if (redirect < 0) {
+    // If no collision.
+    index = -redirect - 1;
+  } else {
+    // If collision, recompute hash code.
+    index = ImageStrings::hash_code(path, redirect) % _header._location_count;
+  }
+
+  assert(index < _header._location_count, "index exceeds location count");
+  u4 offset = _offsets_table[index];
+  assert(offset < _header._locations_size, "offset exceeds location attributes size");
+
+  if (offset == 0) {
+    return NULL;
+  }
+
+  return _location_bytes + offset;
+}
+
+// Verify that a found location matches the supplied path.
+bool ImageFile::verify_location(ImageLocation& location, const char* path) const {
+  // Retrieve each path component string.
+  ImageStrings strings(_string_bytes, _header._strings_size);
+  // Match a path with each subcomponent without concatenation (copy).
+  // Match up path parent.
+  const char* parent = location.get_attribute(ImageLocation::ATTRIBUTE_PARENT, strings);
+  const char* next = ImageStrings::starts_with(path, parent);
+  // Continue only if a complete match.
+  if (!next) return false;
+  // Match up path base.
+  const char* base = location.get_attribute(ImageLocation::ATTRIBUTE_BASE, strings);
+  next = ImageStrings::starts_with(next, base);
+  // Continue only if a complete match.
+  if (!next) return false;
+  // Match up path extension.
+  const char* extension = location.get_attribute(ImageLocation::ATTRIBUTE_EXTENSION, strings);
+  next = ImageStrings::starts_with(next, extension);
+
+  // True only if complete match and no more characters.
+  return next && *next == '\0';
+}
+
+// Return the resource for the supplied location.
+u1* ImageFile::get_resource(ImageLocation& location) const {
+  // Retrieve the byte offset and size of the resource.
+  u8 offset = _index_size + location.get_attribute(ImageLocation::ATTRIBUTE_OFFSET);
+  u8 size = location.get_attribute(ImageLocation::ATTRIBUTE_UNCOMPRESSED);
+  u8 compressed_size = location.get_attribute(ImageLocation::ATTRIBUTE_COMPRESSED);
+  u8 read_size = compressed_size ? compressed_size : size;
+
+  // Allocate space for the resource.
+  u1* data = NEW_RESOURCE_ARRAY(u1, read_size);
+
+  bool is_read = os::read_at(_fd, data, read_size, offset) == read_size;
+  guarantee(is_read, "error reading from image or short read");
+
+  // If not compressed, just return the data.
+  if (!compressed_size) {
+    return data;
+  }
+
+  u1* uncompressed = NEW_RESOURCE_ARRAY(u1, size);
+  char* msg = NULL;
+  jboolean res = ClassLoader::decompress(data, compressed_size, uncompressed, size, &msg);
+  if (!res) warning("decompression failed due to %s\n", msg);
+  guarantee(res, "decompression failed");
+
+  return uncompressed;
+}
+
+void ImageFile::get_resource(const char* path, u1*& buffer, u8& size) const {
+  buffer = NULL;
+  size = 0;
+  u1* data = find_location_data(path);
+  if (data) {
+    ImageLocation location(data);
+    if (verify_location(location, path)) {
+      size = location.get_attribute(ImageLocation::ATTRIBUTE_UNCOMPRESSED);
+      buffer = get_resource(location);
+    }
+  }
+}
+
+GrowableArray<const char*>* ImageFile::packages(const char* name) {
+  char entry[JVM_MAXPATHLEN];
+  bool overflow = jio_snprintf(entry, sizeof(entry), "%s/packages.offsets", name) == -1;
+  guarantee(!overflow, "package name overflow");
+
+  u1* buffer;
+  u8 size;
+
+  get_resource(entry, buffer, size);
+  guarantee(buffer, "missing module packages reource");
+  ImageStrings strings(_string_bytes, _header._strings_size);
+  GrowableArray<const char*>* pkgs = new GrowableArray<const char*>();
+  int count = size / 4;
+  for (int i = 0; i < count; i++) {
+    u4 offset = Bytes::get_Java_u4(buffer + (i*4));
+    const char* p = strings.get(offset);
+    pkgs->append(p);
+  }
+
+  return pkgs;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/classfile/imageFile.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -0,0 +1,343 @@
+/*
+ * Copyright (c) 2014, 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_CLASSFILE_IMAGEFILE_HPP
+#define SHARE_VM_CLASSFILE_IMAGEFILE_HPP
+
+#include "classfile/classLoader.hpp"
+#include "memory/allocation.hpp"
+#include "memory/allocation.inline.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+// Image files are an alternate file format for storing classes and resources. The
+// goal is to supply file access which is faster and smaller that the jar format.
+// It should be noted that unlike jars information stored in an image is in native
+// endian format. This allows the image to be memory mapped into memory without
+// endian translation.  This also means that images are platform dependent.
+//
+// Image files are structured as three sections;
+//
+//         +-----------+
+//         |  Header   |
+//         +-----------+
+//         |           |
+//         | Directory |
+//         |           |
+//         +-----------+
+//         |           |
+//         |           |
+//         | Resources |
+//         |           |
+//         |           |
+//         +-----------+
+//
+// The header contains information related to identification and description of
+// contents.
+//
+//         +-------------------------+
+//         |   Magic (0xCAFEDADA)    |
+//         +------------+------------+
+//         | Major Vers | Minor Vers |
+//         +------------+------------+
+//         |      Location Count     |
+//         +-------------------------+
+//         |      Attributes Size    |
+//         +-------------------------+
+//         |       Strings Size      |
+//         +-------------------------+
+//
+// Magic - means of identifying validity of the file.  This avoids requiring a
+//         special file extension.
+// Major vers, minor vers - differences in version numbers indicate structural
+//                          changes in the image.
+// Location count - number of locations/resources in the file.  This count is also
+//                  the length of lookup tables used in the directory.
+// Attributes size - number of bytes in the region used to store location attribute
+//                   streams.
+// Strings size - the size of the region used to store strings used by the
+//                directory and meta data.
+//
+// The directory contains information related to resource lookup. The algorithm
+// used for lookup is "A Practical Minimal Perfect Hashing Method"
+// (http://homepages.dcc.ufmg.br/~nivio/papers/wea05.pdf). Given a path string
+// in the form <package>/<base>.<extension>  return the resource location
+// information;
+//
+//     redirectIndex = hash(path, DEFAULT_SEED) % count;
+//     redirect = redirectTable[redirectIndex];
+//     if (redirect == 0) return not found;
+//     locationIndex = redirect < 0 ? -1 - redirect : hash(path, redirect) % count;
+//     location = locationTable[locationIndex];
+//     if (!verify(location, path)) return not found;
+//     return location;
+//
+// Note: The hash function takes an initial seed value.  A different seed value
+// usually returns a different result for strings that would otherwise collide with
+// other seeds. The verify function guarantees the found resource location is
+// indeed the resource we are looking for.
+//
+// The following is the format of the directory;
+//
+//         +-------------------+
+//         |   Redirect Table  |
+//         +-------------------+
+//         | Attribute Offsets |
+//         +-------------------+
+//         |   Attribute Data  |
+//         +-------------------+
+//         |      Strings      |
+//         +-------------------+
+//
+// Redirect Table - Array of 32-bit signed values representing actions that
+//                  should take place for hashed strings that map to that
+//                  value.  Negative values indicate no hash collision and can be
+//                  quickly converted to indices into attribute offsets.  Positive
+//                  values represent a new seed for hashing an index into attribute
+//                  offsets.  Zero indicates not found.
+// Attribute Offsets - Array of 32-bit unsigned values representing offsets into
+//                     attribute data.  Attribute offsets can be iterated to do a
+//                     full survey of resources in the image.
+// Attribute Data - Bytes representing compact attribute data for locations. (See
+//                  comments in ImageLocation.)
+// Strings - Collection of zero terminated UTF-8 strings used by the directory and
+//           image meta data.  Each string is accessed by offset.  Each string is
+//           unique.  Offset zero is reserved for the empty string.
+//
+// Note that the memory mapped directory assumes 32 bit alignment of the image
+// header, the redirect table and the attribute offsets.
+//
+
+
+// Manage image file string table.
+class ImageStrings {
+private:
+  // Data bytes for strings.
+  u1* _data;
+  // Number of bytes in the string table.
+  u4 _size;
+
+public:
+  // Prime used to generate hash for Perfect Hashing.
+  static const u4 HASH_MULTIPLIER = 0x01000193;
+
+  ImageStrings(u1* data, u4 size) : _data(data), _size(size) {}
+
+  // Return the UTF-8 string beginning at offset.
+  inline const char* get(u4 offset) const {
+    assert(offset < _size, "offset exceeds string table size");
+    return (const char*)(_data + offset);
+  }
+
+  // Compute the Perfect Hashing hash code for the supplied string.
+  inline static u4 hash_code(const char* string) {
+    return hash_code(string, HASH_MULTIPLIER);
+  }
+
+  // Compute the Perfect Hashing hash code for the supplied string, starting at seed.
+  static u4 hash_code(const char* string, u4 seed);
+
+  // Test to see if string begins with start.  If so returns remaining portion
+  // of string.  Otherwise, NULL.  Used to test sections of a path without
+  // copying.
+  static const char* starts_with(const char* string, const char* start);
+
+};
+
+// Manage image file location attribute streams.  Within an image, a location's
+// attributes are compressed into a stream of bytes.  An attribute stream is
+// composed of individual attribute sequences.  Each attribute sequence begins with
+// a header byte containing the attribute 'kind' (upper 5 bits of header) and the
+// 'length' less 1 (lower 3 bits of header) of bytes that follow containing the
+// attribute value.  Attribute values present as most significant byte first.
+//
+// Ex. Container offset (ATTRIBUTE_OFFSET) 0x33562 would be represented as 0x22
+// (kind = 4, length = 3), 0x03, 0x35, 0x62.
+//
+// An attribute stream is terminated with a header kind of ATTRIBUTE_END (header
+// byte of zero.)
+//
+// ImageLocation inflates the stream into individual values stored in the long
+// array _attributes. This allows an attribute value can be quickly accessed by
+// direct indexing. Unspecified values default to zero.
+//
+// Notes:
+//  - Even though ATTRIBUTE_END is used to mark the end of the attribute stream,
+//    streams will contain zero byte values to represent lesser significant bits.
+//    Thus, detecting a zero byte is not sufficient to detect the end of an attribute
+//    stream.
+//  - ATTRIBUTE_OFFSET represents the number of bytes from the beginning of the region
+//    storing the resources.  Thus, in an image this represents the number of bytes
+//    after the directory.
+//  - Currently, compressed resources are represented by having a non-zero
+//    ATTRIBUTE_COMPRESSED value.  This represents the number of bytes stored in the
+//    image, and the value of ATTRIBUTE_UNCOMPRESSED represents number of bytes of the
+//    inflated resource in memory. If the ATTRIBUTE_COMPRESSED is zero then the value
+//    of ATTRIBUTE_UNCOMPRESSED represents both the number of bytes in the image and
+//    in memory.  In the future, additional compression techniques will be used and
+//    represented differently.
+//  - Package strings include trailing slash and extensions include prefix period.
+//
+class ImageLocation {
+public:
+  // Attribute kind enumeration.
+  static const u1 ATTRIBUTE_END = 0; // End of attribute stream marker
+  static const u1 ATTRIBUTE_BASE = 1; // String table offset of resource path base
+  static const u1 ATTRIBUTE_PARENT = 2; // String table offset of resource path parent
+  static const u1 ATTRIBUTE_EXTENSION = 3; // String table offset of resource path extension
+  static const u1 ATTRIBUTE_OFFSET = 4; // Container byte offset of resource
+  static const u1 ATTRIBUTE_COMPRESSED = 5; // In image byte size of the compressed resource
+  static const u1 ATTRIBUTE_UNCOMPRESSED = 6; // In memory byte size of the uncompressed resource
+  static const u1 ATTRIBUTE_COUNT = 7; // Number of attribute kinds
+
+private:
+  // Values of inflated attributes.
+  u8 _attributes[ATTRIBUTE_COUNT];
+
+  // Return the attribute value number of bytes.
+  inline static u1 attribute_length(u1 data) {
+    return (data & 0x7) + 1;
+  }
+
+  // Return the attribute kind.
+  inline static u1 attribute_kind(u1 data) {
+    u1 kind = data >> 3;
+    assert(kind < ATTRIBUTE_COUNT, "invalid attribute kind");
+    return kind;
+  }
+
+  // Return the attribute length.
+  inline static u8 attribute_value(u1* data, u1 n) {
+    assert(0 < n && n <= 8, "invalid attribute value length");
+    u8 value = 0;
+
+    // Most significant bytes first.
+    for (u1 i = 0; i < n; i++) {
+      value <<= 8;
+      value |= data[i];
+    }
+
+    return value;
+  }
+
+public:
+  ImageLocation(u1* data);
+
+  // Retrieve an attribute value from the inflated array.
+  inline u8 get_attribute(u1 kind) const {
+    assert(ATTRIBUTE_END < kind && kind < ATTRIBUTE_COUNT, "invalid attribute kind");
+    return _attributes[kind];
+  }
+
+  // Retrieve an attribute string value from the inflated array.
+  inline const char* get_attribute(u4 kind, const ImageStrings& strings) const {
+    return strings.get((u4)get_attribute(kind));
+  }
+};
+
+// Manage the image file.
+class ImageFile: public CHeapObj<mtClass> {
+private:
+  // Image file marker.
+  static const u4 IMAGE_MAGIC = 0xCAFEDADA;
+  // Image file major version number.
+  static const u2 MAJOR_VERSION = 0;
+  // Image file minor version number.
+  static const u2 MINOR_VERSION = 1;
+
+  struct ImageHeader {
+    u4 _magic;          // Image file marker
+    u2 _major_version;  // Image file major version number
+    u2 _minor_version;  // Image file minor version number
+    u4 _location_count; // Number of locations managed in index.
+    u4 _locations_size; // Number of bytes in attribute table.
+    u4 _strings_size;   // Number of bytes in string table.
+  };
+
+  char* _name;          // Name of image
+  int _fd;              // File descriptor
+  bool _memory_mapped;  // Is file memory mapped
+  ImageHeader _header;  // Image header
+  u8 _index_size;       // Total size of index
+  u1* _index_data;      // Raw index data
+  s4* _redirect_table;  // Perfect hash redirect table
+  u4* _offsets_table;   // Location offset table
+  u1* _location_bytes;  // Location attributes
+  u1* _string_bytes;    // String table
+
+  // Compute number of bytes in image file index.
+  inline u8 index_size() {
+    return sizeof(ImageHeader) +
+    _header._location_count * sizeof(u4) * 2 +
+    _header._locations_size +
+    _header._strings_size;
+  }
+
+public:
+  ImageFile(const char* name);
+  ~ImageFile();
+
+  // Open image file for access.
+  bool open();
+  // Close image file.
+  void close();
+
+  // Retrieve name of image file.
+  inline const char* name() const {
+    return _name;
+  }
+
+  // Return a string table accessor.
+  inline const ImageStrings get_strings() const {
+    return ImageStrings(_string_bytes, _header._strings_size);
+  }
+
+  // Return number of locations in image file index.
+  inline u4 get_location_count() const {
+    return _header._location_count;
+  }
+
+  // Return location attribute stream for location i.
+  inline u1* get_location_data(u4 i) const {
+    u4 offset = _offsets_table[i];
+
+    return offset != 0 ? _location_bytes + offset : NULL;
+  }
+
+  // Return the attribute stream for a named resourced.
+  u1* find_location_data(const char* path) const;
+
+  // Verify that a found location matches the supplied path.
+  bool verify_location(ImageLocation& location, const char* path) const;
+
+  // Return the resource for the supplied location info.
+  u1* get_resource(ImageLocation& location) const;
+
+  // Return the resource associated with the path else NULL if not found.
+  void get_resource(const char* path, u1*& buffer, u8& size) const;
+
+  // Return an array of packages for a given module
+  GrowableArray<const char*>* packages(const char* name);
+};
+
+#endif // SHARE_VM_CLASSFILE_IMAGEFILE_HPP
--- a/src/share/vm/classfile/javaClasses.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/classfile/javaClasses.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -41,6 +41,7 @@
 #include "oops/method.hpp"
 #include "oops/symbol.hpp"
 #include "oops/typeArrayOop.hpp"
+#include "prims/jvmtiRedefineClassesTrace.hpp"
 #include "runtime/fieldDescriptor.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/interfaceSupport.hpp"
@@ -944,7 +945,7 @@
   assert(_group_offset == 0, "offsets should be initialized only once");
 
   Klass* k = SystemDictionary::Thread_klass();
-  compute_offset(_name_offset,      k, vmSymbols::name_name(),      vmSymbols::char_array_signature());
+  compute_offset(_name_offset,      k, vmSymbols::name_name(),      vmSymbols::string_signature());
   compute_offset(_group_offset,     k, vmSymbols::group_name(),     vmSymbols::threadgroup_signature());
   compute_offset(_contextClassLoader_offset, k, vmSymbols::contextClassLoader_name(), vmSymbols::classloader_signature());
   compute_offset(_inheritedAccessControlContext_offset, k, vmSymbols::inheritedAccessControlContext_name(), vmSymbols::accesscontrolcontext_signature());
@@ -974,15 +975,12 @@
 }
 
 
-typeArrayOop java_lang_Thread::name(oop java_thread) {
-  oop name = java_thread->obj_field(_name_offset);
-  assert(name == NULL || (name->is_typeArray() && TypeArrayKlass::cast(name->klass())->element_type() == T_CHAR), "just checking");
-  return typeArrayOop(name);
-}
-
-
-void java_lang_Thread::set_name(oop java_thread, typeArrayOop name) {
-  assert(java_thread->obj_field(_name_offset) == NULL, "name should be NULL");
+oop java_lang_Thread::name(oop java_thread) {
+  return java_thread->obj_field(_name_offset);
+}
+
+
+void java_lang_Thread::set_name(oop java_thread, oop name) {
   java_thread->obj_field_put(_name_offset, name);
 }
 
@@ -2797,12 +2795,35 @@
   return (Metadata*)mname->address_field(_vmtarget_offset);
 }
 
+bool java_lang_invoke_MemberName::is_method(oop mname) {
+  assert(is_instance(mname), "must be MemberName");
+  return (flags(mname) & (MN_IS_METHOD | MN_IS_CONSTRUCTOR)) > 0;
+}
+
 #if INCLUDE_JVMTI
 // Can be executed on VM thread only
-void java_lang_invoke_MemberName::adjust_vmtarget(oop mname, Metadata* ref) {
-  assert((is_instance(mname) && (flags(mname) & (MN_IS_METHOD | MN_IS_CONSTRUCTOR)) > 0), "wrong type");
+void java_lang_invoke_MemberName::adjust_vmtarget(oop mname, Method* old_method,
+                                                  Method* new_method, bool* trace_name_printed) {
+  assert(is_method(mname), "wrong type");
   assert(Thread::current()->is_VM_thread(), "not VM thread");
-  mname->address_field_put(_vmtarget_offset, (address)ref);
+
+  Method* target = (Method*)mname->address_field(_vmtarget_offset);
+  if (target == old_method) {
+    mname->address_field_put(_vmtarget_offset, (address)new_method);
+
+    if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
+      if (!(*trace_name_printed)) {
+        // RC_TRACE_MESG macro has an embedded ResourceMark
+        RC_TRACE_MESG(("adjust: name=%s",
+                       old_method->method_holder()->external_name()));
+        *trace_name_printed = true;
+      }
+      // RC_TRACE macro has an embedded ResourceMark
+      RC_TRACE(0x00400000, ("MemberName method update: %s(%s)",
+                            new_method->name()->as_C_string(),
+                            new_method->signature()->as_C_string()));
+    }
+  }
 }
 #endif // INCLUDE_JVMTI
 
--- a/src/share/vm/classfile/javaClasses.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/classfile/javaClasses.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -345,8 +345,8 @@
   // Set JavaThread for instance
   static void set_thread(oop java_thread, JavaThread* thread);
   // Name
-  static typeArrayOop name(oop java_thread);
-  static void set_name(oop java_thread, typeArrayOop name);
+  static oop name(oop java_thread);
+  static void set_name(oop java_thread, oop name);
   // Priority
   static ThreadPriority priority(oop java_thread);
   static void set_priority(oop java_thread, ThreadPriority priority);
@@ -1100,7 +1100,8 @@
   static Metadata*      vmtarget(oop mname);
   static void       set_vmtarget(oop mname, Metadata* target);
 #if INCLUDE_JVMTI
-  static void       adjust_vmtarget(oop mname, Metadata* target);
+  static void       adjust_vmtarget(oop mname, Method* old_method, Method* new_method,
+                                    bool* trace_name_printed);
 #endif // INCLUDE_JVMTI
 
   static intptr_t       vmindex(oop mname);
@@ -1114,6 +1115,8 @@
     return obj != NULL && is_subclass(obj->klass());
   }
 
+  static bool is_method(oop obj);
+
   // Relevant integer codes (keep these in synch. with MethodHandleNatives.Constants):
   enum {
     MN_IS_METHOD            = 0x00010000, // method (not constructor)
--- a/src/share/vm/classfile/loaderConstraints.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/classfile/loaderConstraints.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2014, 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
@@ -164,7 +164,7 @@
 
         // Purge entry
         *p = probe->next();
-        FREE_C_HEAP_ARRAY(oop, probe->loaders(), mtClass);
+        FREE_C_HEAP_ARRAY(oop, probe->loaders());
         free_entry(probe);
       } else {
 #ifdef ASSERT
@@ -340,7 +340,7 @@
         ClassLoaderData** new_loaders = NEW_C_HEAP_ARRAY(ClassLoaderData*, n, mtClass);
         memcpy(new_loaders, p->loaders(), sizeof(ClassLoaderData*) * p->num_loaders());
         p->set_max_loaders(n);
-        FREE_C_HEAP_ARRAY(ClassLoaderData*, p->loaders(), mtClass);
+        FREE_C_HEAP_ARRAY(ClassLoaderData*, p->loaders());
         p->set_loaders(new_loaders);
     }
 }
@@ -422,7 +422,7 @@
   }
 
   *pp2 = p2->next();
-  FREE_C_HEAP_ARRAY(oop, p2->loaders(), mtClass);
+  FREE_C_HEAP_ARRAY(oop, p2->loaders());
   free_entry(p2);
   return;
 }
--- a/src/share/vm/classfile/sharedPathsMiscInfo.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/classfile/sharedPathsMiscInfo.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -110,7 +110,7 @@
 bool SharedPathsMiscInfo::check(jint type, const char* path) {
   switch (type) {
   case BOOT:
-    if (strcmp(path, Arguments::get_sysclasspath()) != 0) {
+    if (os::file_name_strcmp(path, Arguments::get_sysclasspath()) != 0) {
       return fail("[BOOT classpath mismatch, actual: -Dsun.boot.class.path=", Arguments::get_sysclasspath());
     }
     break;
--- a/src/share/vm/classfile/sharedPathsMiscInfo.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/classfile/sharedPathsMiscInfo.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -89,7 +89,7 @@
   }
   ~SharedPathsMiscInfo() {
     if (_allocated) {
-      FREE_C_HEAP_ARRAY(char, _buf_start, mtClass);
+      FREE_C_HEAP_ARRAY(char, _buf_start);
     }
   }
   int get_used_bytes() {
--- a/src/share/vm/classfile/systemDictionary.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/classfile/systemDictionary.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -66,7 +66,7 @@
 #include "classfile/systemDictionaryShared.hpp"
 #endif
 #if INCLUDE_TRACE
- #include "trace/tracing.hpp"
+#include "trace/tracing.hpp"
 #endif
 
 Dictionary*            SystemDictionary::_dictionary          = NULL;
@@ -2659,7 +2659,7 @@
                                       class_loader->klass() : (Klass*)NULL);
     event.commit();
   }
-#endif /* INCLUDE_TRACE */
+#endif // INCLUDE_TRACE
 }
 
 #ifndef PRODUCT
--- a/src/share/vm/code/codeBlob.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/code/codeBlob.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -168,7 +168,7 @@
 
 void CodeBlob::flush() {
   if (_oop_maps) {
-    FREE_C_HEAP_ARRAY(unsigned char, _oop_maps, mtCode);
+    FREE_C_HEAP_ARRAY(unsigned char, _oop_maps);
     _oop_maps = NULL;
   }
   _strings.free();
--- a/src/share/vm/code/codeCache.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/code/codeCache.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -1190,7 +1190,7 @@
     }
   }
 
-  FREE_C_HEAP_ARRAY(int, buckets, mtCode);
+  FREE_C_HEAP_ARRAY(int, buckets);
   print_memory_overhead();
 }
 
--- a/src/share/vm/code/dependencies.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/code/dependencies.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -912,6 +912,8 @@
   bool is_witness(Klass* k) {
     if (doing_subtype_search()) {
       return Dependencies::is_concrete_klass(k);
+    } else if (!k->oop_is_instance()) {
+      return false; // no methods to find in an array type
     } else {
       Method* m = InstanceKlass::cast(k)->find_method(_name, _signature);
       if (m == NULL || !Dependencies::is_concrete_method(m))  return false;
@@ -1118,7 +1120,7 @@
   Klass* chain;       // scratch variable
 #define ADD_SUBCLASS_CHAIN(k)                     {  \
     assert(chaini < CHAINMAX, "oob");                \
-    chain = InstanceKlass::cast(k)->subklass();      \
+    chain = k->subklass();                           \
     if (chain != NULL)  chains[chaini++] = chain;    }
 
   // Look for non-abstract subclasses.
@@ -1129,35 +1131,37 @@
   // (Their subclasses are additional indirect implementors.
   // See InstanceKlass::add_implementor.)
   // (Note:  nof_implementors is always zero for non-interfaces.)
-  int nof_impls = InstanceKlass::cast(context_type)->nof_implementors();
-  if (nof_impls > 1) {
-    // Avoid this case: *I.m > { A.m, C }; B.m > C
-    // Here, I.m has 2 concrete implementations, but m appears unique
-    // as A.m, because the search misses B.m when checking C.
-    // The inherited method B.m was getting missed by the walker
-    // when interface 'I' was the starting point.
-    // %%% Until this is fixed more systematically, bail out.
-    // (Old CHA had the same limitation.)
-    return context_type;
-  }
-  if (nof_impls > 0) {
-    Klass* impl = InstanceKlass::cast(context_type)->implementor();
-    assert(impl != NULL, "just checking");
-    // If impl is the same as the context_type, then more than one
-    // implementor has seen. No exact info in this case.
-    if (impl == context_type) {
-      return context_type;  // report an inexact witness to this sad affair
+  if (top_level_call) {
+    int nof_impls = InstanceKlass::cast(context_type)->nof_implementors();
+    if (nof_impls > 1) {
+      // Avoid this case: *I.m > { A.m, C }; B.m > C
+      // Here, I.m has 2 concrete implementations, but m appears unique
+      // as A.m, because the search misses B.m when checking C.
+      // The inherited method B.m was getting missed by the walker
+      // when interface 'I' was the starting point.
+      // %%% Until this is fixed more systematically, bail out.
+      // (Old CHA had the same limitation.)
+      return context_type;
     }
-    if (do_counts)
-      { NOT_PRODUCT(deps_find_witness_steps++); }
-    if (is_participant(impl)) {
-      if (!participants_hide_witnesses) {
+    if (nof_impls > 0) {
+      Klass* impl = InstanceKlass::cast(context_type)->implementor();
+      assert(impl != NULL, "just checking");
+      // If impl is the same as the context_type, then more than one
+      // implementor has seen. No exact info in this case.
+      if (impl == context_type) {
+        return context_type;  // report an inexact witness to this sad affair
+      }
+      if (do_counts)
+        { NOT_PRODUCT(deps_find_witness_steps++); }
+      if (is_participant(impl)) {
+        if (!participants_hide_witnesses) {
+          ADD_SUBCLASS_CHAIN(impl);
+        }
+      } else if (is_witness(impl) && !ignore_witness(impl)) {
+        return impl;
+      } else {
         ADD_SUBCLASS_CHAIN(impl);
       }
-    } else if (is_witness(impl) && !ignore_witness(impl)) {
-      return impl;
-    } else {
-      ADD_SUBCLASS_CHAIN(impl);
     }
   }
 
--- a/src/share/vm/compiler/compileBroker.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/compiler/compileBroker.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -594,7 +594,7 @@
  * Add a CompileTask to a CompileQueue.
  */
 void CompileQueue::add(CompileTask* task) {
-  assert(lock()->owned_by_self(), "must own lock");
+  assert(MethodCompileQueue_lock->owned_by_self(), "must own lock");
 
   task->set_next(NULL);
   task->set_prev(NULL);
@@ -625,7 +625,7 @@
   }
 
   // Notify CompilerThreads that a task is available.
-  lock()->notify_all();
+  MethodCompileQueue_lock->notify_all();
 }
 
 /**
@@ -635,7 +635,7 @@
  * compilation is disabled.
  */
 void CompileQueue::free_all() {
-  MutexLocker mu(lock());
+  MutexLocker mu(MethodCompileQueue_lock);
   CompileTask* next = _first;
 
   // Iterate over all tasks in the compile queue
@@ -653,14 +653,14 @@
   _first = NULL;
 
   // Wake up all threads that block on the queue.
-  lock()->notify_all();
+  MethodCompileQueue_lock->notify_all();
 }
 
 /**
  * Get the next CompileTask from a CompileQueue
  */
 CompileTask* CompileQueue::get() {
-  MutexLocker locker(lock());
+  MutexLocker locker(MethodCompileQueue_lock);
   // If _first is NULL we have no more compile jobs. There are two reasons for
   // having no compile jobs: First, we compiled everything we wanted. Second,
   // we ran out of code cache so compilation has been disabled. In the latter
@@ -681,7 +681,7 @@
     // We need a timed wait here, since compiler threads can exit if compilation
     // is disabled forever. We use 5 seconds wait time; the exiting of compiler threads
     // is not critical and we do not want idle compiler threads to wake up too often.
-    lock()->wait(!Mutex::_no_safepoint_check_flag, 5*1000);
+    MethodCompileQueue_lock->wait(!Mutex::_no_safepoint_check_flag, 5*1000);
   }
 
   if (CompileBroker::is_compilation_disabled_forever()) {
@@ -701,7 +701,7 @@
 // Clean & deallocate stale compile tasks.
 // Temporarily releases MethodCompileQueue lock.
 void CompileQueue::purge_stale_tasks() {
-  assert(lock()->owned_by_self(), "must own lock");
+  assert(MethodCompileQueue_lock->owned_by_self(), "must own lock");
   if (_first_stale != NULL) {
     // Stale tasks are purged when MCQ lock is released,
     // but _first_stale updates are protected by MCQ lock.
@@ -710,7 +710,7 @@
     CompileTask* head = _first_stale;
     _first_stale = NULL;
     {
-      MutexUnlocker ul(lock());
+      MutexUnlocker ul(MethodCompileQueue_lock);
       for (CompileTask* task = head; task != NULL; ) {
         CompileTask* next_task = task->next();
         CompileTaskWrapper ctw(task); // Frees the task
@@ -722,7 +722,7 @@
 }
 
 void CompileQueue::remove(CompileTask* task) {
-   assert(lock()->owned_by_self(), "must own lock");
+   assert(MethodCompileQueue_lock->owned_by_self(), "must own lock");
   if (task->prev() != NULL) {
     task->prev()->set_next(task->next());
   } else {
@@ -742,7 +742,7 @@
 }
 
 void CompileQueue::remove_and_mark_stale(CompileTask* task) {
-  assert(lock()->owned_by_self(), "must own lock");
+  assert(MethodCompileQueue_lock->owned_by_self(), "must own lock");
   remove(task);
 
   // Enqueue the task for reclamation (should be done outside MCQ lock)
@@ -780,7 +780,7 @@
 }
 
 void CompileQueue::print(outputStream* st) {
-  assert(lock()->owned_by_self(), "must own lock");
+  assert(MethodCompileQueue_lock->owned_by_self(), "must own lock");
   st->print_cr("Contents of %s", name());
   st->print_cr("----------------------------");
   CompileTask* task = _first;
@@ -1066,11 +1066,11 @@
 #endif // !ZERO && !SHARK
   // Initialize the compilation queue
   if (c2_compiler_count > 0) {
-    _c2_compile_queue  = new CompileQueue("C2 compile queue",  MethodCompileQueue_lock);
+    _c2_compile_queue  = new CompileQueue("C2 compile queue");
     _compilers[1]->set_num_compiler_threads(c2_compiler_count);
   }
   if (c1_compiler_count > 0) {
-    _c1_compile_queue  = new CompileQueue("C1 compile queue",  MethodCompileQueue_lock);
+    _c1_compile_queue  = new CompileQueue("C1 compile queue");
     _compilers[0]->set_num_compiler_threads(c1_compiler_count);
   }
 
@@ -1214,7 +1214,7 @@
 
   // Acquire our lock.
   {
-    MutexLocker locker(queue->lock(), thread);
+    MutexLocker locker(MethodCompileQueue_lock, thread);
 
     // Make sure the method has not slipped into the queues since
     // last we checked; note that those checks were "fast bail-outs".
@@ -1807,7 +1807,7 @@
                      os::file_separator(), thread_id, os::current_process_id());
       }
 
-      fp = fopen(file_name, "at");
+      fp = fopen(file_name, "wt");
       if (fp != NULL) {
         if (LogCompilation && Verbose) {
           tty->print_cr("Opening compilation log %s", file_name);
@@ -1985,6 +1985,7 @@
 
     if (ci_env.failing()) {
       task->set_failure_reason(ci_env.failure_reason());
+      ci_env.report_failure(ci_env.failure_reason());
       const char* retry_message = ci_env.retry_message();
       if (_compilation_log != NULL) {
         _compilation_log->log_failure(thread, task, ci_env.failure_reason(), retry_message);
--- a/src/share/vm/compiler/compileBroker.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/compiler/compileBroker.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -195,7 +195,6 @@
 class CompileQueue : public CHeapObj<mtCompiler> {
  private:
   const char* _name;
-  Monitor*    _lock;
 
   CompileTask* _first;
   CompileTask* _last;
@@ -206,9 +205,8 @@
 
   void purge_stale_tasks();
  public:
-  CompileQueue(const char* name, Monitor* lock) {
+  CompileQueue(const char* name) {
     _name = name;
-    _lock = lock;
     _first = NULL;
     _last = NULL;
     _size = 0;
@@ -216,7 +214,6 @@
   }
 
   const char*  name() const                      { return _name; }
-  Monitor*     lock() const                      { return _lock; }
 
   void         add(CompileTask* task);
   void         remove(CompileTask* task);
@@ -418,6 +415,7 @@
     shutdown_compilaton = 2
   };
 
+  static jint get_compilation_activity_mode() { return _should_compile_new_jobs; }
   static bool should_compile_new_jobs() { return UseCompiler && (_should_compile_new_jobs == run_compilation); }
   static bool set_should_compile_new_jobs(jint new_state) {
     // Return success if the current caller set it
--- a/src/share/vm/compiler/compileLog.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/compiler/compileLog.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -56,10 +56,10 @@
 }
 
 CompileLog::~CompileLog() {
-  delete _out;
+  delete _out; // Close fd in fileStream::~fileStream()
   _out = NULL;
-  FREE_C_HEAP_ARRAY(char, _identities, mtCompiler);
-  FREE_C_HEAP_ARRAY(char, _file, mtCompiler);
+  FREE_C_HEAP_ARRAY(char, _identities);
+  FREE_C_HEAP_ARRAY(char, _file);
 }
 
 
@@ -278,10 +278,9 @@
       }
       file->print_raw_cr("</compilation_log>");
       close(partial_fd);
-      unlink(partial_file);
     }
     CompileLog* next_log = log->_next;
-    delete log;
+    delete log; // Removes partial file
     log = next_log;
   }
   _first = NULL;
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -52,21 +52,9 @@
 }
 
 void ConcurrentMarkSweepPolicy::initialize_generations() {
-  _generations = NEW_C_HEAP_ARRAY3(GenerationSpecPtr, number_of_generations(), mtGC,
-    CURRENT_PC, AllocFailStrategy::RETURN_NULL);
-  if (_generations == NULL)
-    vm_exit_during_initialization("Unable to allocate gen spec");
-
-  Generation::Name yg_name =
-    UseParNewGC ? Generation::ParNew : Generation::DefNew;
-  _generations[0] = new GenerationSpec(yg_name, _initial_young_size,
-                                       _max_young_size);
-  _generations[1] = new GenerationSpec(Generation::ConcurrentMarkSweep,
-                                       _initial_old_size, _max_old_size);
-
-  if (_generations[0] == NULL || _generations[1] == NULL) {
-    vm_exit_during_initialization("Unable to allocate gen spec");
-  }
+  _generations = NEW_C_HEAP_ARRAY(GenerationSpecPtr, number_of_generations(), mtGC);
+  _generations[0] = new GenerationSpec(Generation::ParNew, _initial_young_size, _max_young_size);
+  _generations[1] = new GenerationSpec(Generation::ConcurrentMarkSweep, _initial_old_size, _max_old_size);
 }
 
 void ConcurrentMarkSweepPolicy::initialize_size_policy(size_t init_eden_size,
@@ -82,10 +70,5 @@
 
 void ConcurrentMarkSweepPolicy::initialize_gc_policy_counters() {
   // initialize the policy counters - 2 collectors, 3 generations
-  if (UseParNewGC) {
-    _gc_policy_counters = new GCPolicyCounters("ParNew:CMS", 2, 3);
-  }
-  else {
-    _gc_policy_counters = new GCPolicyCounters("Copy:CMS", 2, 3);
-  }
+  _gc_policy_counters = new GCPolicyCounters("ParNew:CMS", 2, 3);
 }
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -90,7 +90,8 @@
                     CMSRescanMultiple),
   _marking_task_size(CardTableModRefBS::card_size_in_words * BitsPerWord *
                     CMSConcMarkMultiple),
-  _collector(NULL)
+  _collector(NULL),
+  _preconsumptionDirtyCardClosure(NULL)
 {
   assert(sizeof(FreeChunk) / BytesPerWord <= MinChunkSize,
          "FreeChunk is larger than expected");
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -155,6 +155,9 @@
   // Used to keep track of limit of sweep for the space
   HeapWord* _sweep_limit;
 
+  // Used to make the young collector update the mod union table
+  MemRegionClosure* _preconsumptionDirtyCardClosure;
+
   // Support for compacting cms
   HeapWord* cross_threshold(HeapWord* start, HeapWord* end);
   HeapWord* forward(oop q, size_t size, CompactPoint* cp, HeapWord* compact_top);
@@ -356,6 +359,14 @@
   void initialize_sequential_subtasks_for_marking(int n_threads,
          HeapWord* low = NULL);
 
+  virtual MemRegionClosure* preconsumptionDirtyCardClosure() const {
+    return _preconsumptionDirtyCardClosure;
+  }
+
+  void setPreconsumptionDirtyCardClosure(MemRegionClosure* cl) {
+    _preconsumptionDirtyCardClosure = cl;
+  }
+
   // Space enquiries
   size_t used() const;
   size_t free() const;
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -623,7 +623,8 @@
 
   // Support for parallelizing young gen rescan
   GenCollectedHeap* gch = GenCollectedHeap::heap();
-  _young_gen = gch->prev_gen(_cmsGen);
+  assert(gch->prev_gen(_cmsGen)->kind() == Generation::ParNew, "CMS can only be used with ParNew");
+  _young_gen = (ParNewGeneration*)gch->prev_gen(_cmsGen);
   if (gch->supports_inline_contig_alloc()) {
     _top_addr = gch->top_addr();
     _end_addr = gch->end_addr();
@@ -650,15 +651,15 @@
         || _cursor == NULL) {
       warning("Failed to allocate survivor plab/chunk array");
       if (_survivor_plab_array  != NULL) {
-        FREE_C_HEAP_ARRAY(ChunkArray, _survivor_plab_array, mtGC);
+        FREE_C_HEAP_ARRAY(ChunkArray, _survivor_plab_array);
         _survivor_plab_array = NULL;
       }
       if (_survivor_chunk_array != NULL) {
-        FREE_C_HEAP_ARRAY(HeapWord*, _survivor_chunk_array, mtGC);
+        FREE_C_HEAP_ARRAY(HeapWord*, _survivor_chunk_array);
         _survivor_chunk_array = NULL;
       }
       if (_cursor != NULL) {
-        FREE_C_HEAP_ARRAY(size_t, _cursor, mtGC);
+        FREE_C_HEAP_ARRAY(size_t, _cursor);
         _cursor = NULL;
       }
     } else {
@@ -668,10 +669,10 @@
         if (vec == NULL) {
           warning("Failed to allocate survivor plab array");
           for (int j = i; j > 0; j--) {
-            FREE_C_HEAP_ARRAY(HeapWord*, _survivor_plab_array[j-1].array(), mtGC);
+            FREE_C_HEAP_ARRAY(HeapWord*, _survivor_plab_array[j-1].array());
           }
-          FREE_C_HEAP_ARRAY(ChunkArray, _survivor_plab_array, mtGC);
-          FREE_C_HEAP_ARRAY(HeapWord*, _survivor_chunk_array, mtGC);
+          FREE_C_HEAP_ARRAY(ChunkArray, _survivor_plab_array);
+          FREE_C_HEAP_ARRAY(HeapWord*, _survivor_chunk_array);
           _survivor_plab_array = NULL;
           _survivor_chunk_array = NULL;
           _survivor_chunk_capacity = 0;
@@ -792,11 +793,6 @@
   }
 }
 
-CompactibleSpace*
-ConcurrentMarkSweepGeneration::first_compaction_space() const {
-  return _cmsSpace;
-}
-
 void ConcurrentMarkSweepGeneration::reset_after_compaction() {
   // Clear the promotion information.  These pointers can be adjusted
   // along with all the other pointers into the heap but
@@ -807,10 +803,6 @@
   }
 }
 
-void ConcurrentMarkSweepGeneration::space_iterate(SpaceClosure* blk, bool usedOnly) {
-  blk->do_space(_cmsSpace);
-}
-
 void ConcurrentMarkSweepGeneration::compute_new_size() {
   assert_locked_or_safepoint(Heap_lock);
 
@@ -881,7 +873,7 @@
         expand_bytes);
     }
     // safe if expansion fails
-    expand(expand_bytes, 0, CMSExpansionCause::_satisfy_free_ratio);
+    expand_for_gc_cause(expand_bytes, 0, CMSExpansionCause::_satisfy_free_ratio);
     if (PrintGCDetails && Verbose) {
       gclog_or_tty->print_cr("  Expanded free fraction %f",
         ((double) free()) / capacity());
@@ -1047,8 +1039,7 @@
   if (res == NULL) {
     // expand and retry
     size_t s = _cmsSpace->expansionSpaceRequired(obj_size);  // HeapWords
-    expand(s*HeapWordSize, MinHeapDeltaBytes,
-      CMSExpansionCause::_satisfy_promotion);
+    expand_for_gc_cause(s*HeapWordSize, MinHeapDeltaBytes, CMSExpansionCause::_satisfy_promotion);
     // Since there's currently no next generation, we don't try to promote
     // into a more senior generation.
     assert(next_gen() == NULL, "assumption, based upon which no attempt "
@@ -1203,14 +1194,6 @@
 
 void
 ConcurrentMarkSweepGeneration::
-par_promote_alloc_undo(int thread_num,
-                       HeapWord* obj, size_t word_sz) {
-  // CMS does not support promotion undo.
-  ShouldNotReachHere();
-}
-
-void
-ConcurrentMarkSweepGeneration::
 par_promote_alloc_done(int thread_num) {
   CMSParGCThreadState* ps = _par_gc_thread_states[thread_num];
   ps->lab.retire(thread_num);
@@ -1641,13 +1624,12 @@
   do_compaction_work(clear_all_soft_refs);
 
   // Has the GC time limit been exceeded?
-  DefNewGeneration* young_gen = _young_gen->as_DefNewGeneration();
-  size_t max_eden_size = young_gen->max_capacity() -
-                         young_gen->to()->capacity() -
-                         young_gen->from()->capacity();
+  size_t max_eden_size = _young_gen->max_capacity() -
+                         _young_gen->to()->capacity() -
+                         _young_gen->from()->capacity();
   GCCause::Cause gc_cause = gch->gc_cause();
   size_policy()->check_gc_overhead_limit(_young_gen->used(),
-                                         young_gen->eden()->used(),
+                                         _young_gen->eden()->used(),
                                          _cmsGen->max_capacity(),
                                          max_eden_size,
                                          full,
@@ -1768,10 +1750,9 @@
 }
 
 void CMSCollector::print_eden_and_survivor_chunk_arrays() {
-  DefNewGeneration* dng = _young_gen->as_DefNewGeneration();
-  ContiguousSpace* eden_space = dng->eden();
-  ContiguousSpace* from_space = dng->from();
-  ContiguousSpace* to_space   = dng->to();
+  ContiguousSpace* eden_space = _young_gen->eden();
+  ContiguousSpace* from_space = _young_gen->from();
+  ContiguousSpace* to_space   = _young_gen->to();
   // Eden
   if (_eden_chunk_array != NULL) {
     gclog_or_tty->print_cr("eden " PTR_FORMAT "-" PTR_FORMAT "-" PTR_FORMAT "(" SIZE_FORMAT ")",
@@ -2634,13 +2615,6 @@
 ALL_SINCE_SAVE_MARKS_CLOSURES(CMS_SINCE_SAVE_MARKS_DEFN)
 
 void
-ConcurrentMarkSweepGeneration::younger_refs_iterate(OopsInGenClosure* cl) {
-  cl->set_generation(this);
-  younger_refs_in_space_iterate(_cmsSpace, cl);
-  cl->reset_generation();
-}
-
-void
 ConcurrentMarkSweepGeneration::oop_iterate(ExtendedOopClosure* cl) {
   if (freelistLock()->owned_by_self()) {
     Generation::oop_iterate(cl);
@@ -2812,23 +2786,17 @@
   CMSSynchronousYieldRequest yr;
   assert(!tlab, "Can't deal with TLAB allocation");
   MutexLockerEx x(freelistLock(), Mutex::_no_safepoint_check_flag);
-  expand(word_size*HeapWordSize, MinHeapDeltaBytes,
-    CMSExpansionCause::_satisfy_allocation);
+  expand_for_gc_cause(word_size*HeapWordSize, MinHeapDeltaBytes, CMSExpansionCause::_satisfy_allocation);
   if (GCExpandToAllocateDelayMillis > 0) {
     os::sleep(Thread::current(), GCExpandToAllocateDelayMillis, false);
   }
   return have_lock_and_allocate(word_size, tlab);
 }
 
-// YSR: All of this generation expansion/shrinking stuff is an exact copy of
-// OneContigSpaceCardGeneration, which makes me wonder if we should move this
-// to CardGeneration and share it...
-bool ConcurrentMarkSweepGeneration::expand(size_t bytes, size_t expand_bytes) {
-  return CardGeneration::expand(bytes, expand_bytes);
-}
-
-void ConcurrentMarkSweepGeneration::expand(size_t bytes, size_t expand_bytes,
-  CMSExpansionCause::Cause cause)
+void ConcurrentMarkSweepGeneration::expand_for_gc_cause(
+    size_t bytes,
+    size_t expand_bytes,
+    CMSExpansionCause::Cause cause)
 {
 
   bool success = expand(bytes, expand_bytes);
@@ -2857,8 +2825,7 @@
       return NULL;
     }
     // Otherwise, we try expansion.
-    expand(word_sz*HeapWordSize, MinHeapDeltaBytes,
-      CMSExpansionCause::_allocate_par_lab);
+    expand_for_gc_cause(word_sz*HeapWordSize, MinHeapDeltaBytes, CMSExpansionCause::_allocate_par_lab);
     // Now go around the loop and try alloc again;
     // A competing par_promote might beat us to the expansion space,
     // so we may go around the loop again if promotion fails again.
@@ -2885,8 +2852,7 @@
       return false;
     }
     // Otherwise, we try expansion.
-    expand(refill_size_bytes, MinHeapDeltaBytes,
-      CMSExpansionCause::_allocate_par_spooling_space);
+    expand_for_gc_cause(refill_size_bytes, MinHeapDeltaBytes, CMSExpansionCause::_allocate_par_spooling_space);
     // Now go around the loop and try alloc again;
     // A competing allocation might beat us to the expansion space,
     // so we may go around the loop again if allocation fails again.
@@ -2896,77 +2862,16 @@
   }
 }
 
-
-void ConcurrentMarkSweepGeneration::shrink_by(size_t bytes) {
-  assert_locked_or_safepoint(ExpandHeap_lock);
-  // Shrink committed space
-  _virtual_space.shrink_by(bytes);
-  // Shrink space; this also shrinks the space's BOT
-  _cmsSpace->set_end((HeapWord*) _virtual_space.high());
-  size_t new_word_size = heap_word_size(_cmsSpace->capacity());
-  // Shrink the shared block offset array
-  _bts->resize(new_word_size);
-  MemRegion mr(_cmsSpace->bottom(), new_word_size);
-  // Shrink the card table
-  Universe::heap()->barrier_set()->resize_covered_region(mr);
-
-  if (Verbose && PrintGC) {
-    size_t new_mem_size = _virtual_space.committed_size();
-    size_t old_mem_size = new_mem_size + bytes;
-    gclog_or_tty->print_cr("Shrinking %s from " SIZE_FORMAT "K to " SIZE_FORMAT "K",
-                  name(), old_mem_size/K, new_mem_size/K);
-  }
-}
-
 void ConcurrentMarkSweepGeneration::shrink(size_t bytes) {
-  assert_locked_or_safepoint(Heap_lock);
-  size_t size = ReservedSpace::page_align_size_down(bytes);
   // Only shrink if a compaction was done so that all the free space
   // in the generation is in a contiguous block at the end.
-  if (size > 0 && did_compact()) {
-    shrink_by(size);
-  }
-}
-
-bool ConcurrentMarkSweepGeneration::grow_by(size_t bytes) {
+  if (did_compact()) {
+    CardGeneration::shrink(bytes);
+  }
+}
+
+void ConcurrentMarkSweepGeneration::assert_correct_size_change_locking() {
   assert_locked_or_safepoint(Heap_lock);
-  bool result = _virtual_space.expand_by(bytes);
-  if (result) {
-    size_t new_word_size =
-      heap_word_size(_virtual_space.committed_size());
-    MemRegion mr(_cmsSpace->bottom(), new_word_size);
-    _bts->resize(new_word_size);  // resize the block offset shared array
-    Universe::heap()->barrier_set()->resize_covered_region(mr);
-    // Hmmmm... why doesn't CFLS::set_end verify locking?
-    // This is quite ugly; FIX ME XXX
-    _cmsSpace->assert_locked(freelistLock());
-    _cmsSpace->set_end((HeapWord*)_virtual_space.high());
-
-    // update the space and generation capacity counters
-    if (UsePerfData) {
-      _space_counters->update_capacity();
-      _gen_counters->update_all();
-    }
-
-    if (Verbose && PrintGC) {
-      size_t new_mem_size = _virtual_space.committed_size();
-      size_t old_mem_size = new_mem_size - bytes;
-      gclog_or_tty->print_cr("Expanding %s from " SIZE_FORMAT "K by " SIZE_FORMAT "K to " SIZE_FORMAT "K",
-                    name(), old_mem_size/K, bytes/K, new_mem_size/K);
-    }
-  }
-  return result;
-}
-
-bool ConcurrentMarkSweepGeneration::grow_to_reserved() {
-  assert_locked_or_safepoint(Heap_lock);
-  bool success = true;
-  const size_t remaining_bytes = _virtual_space.uncommitted_size();
-  if (remaining_bytes > 0) {
-    success = grow_by(remaining_bytes);
-    DEBUG_ONLY(if (!success) warning("grow to reserved failed");)
-  }
-  return success;
 }
 
 void ConcurrentMarkSweepGeneration::shrink_free_list_by(size_t bytes) {
@@ -4094,10 +3999,6 @@
   }
 
   if (clean_survivor) {  // preclean the active survivor space(s)
-    assert(_young_gen->kind() == Generation::DefNew ||
-           _young_gen->kind() == Generation::ParNew,
-         "incorrect type for cast");
-    DefNewGeneration* dng = (DefNewGeneration*)_young_gen;
     PushAndMarkClosure pam_cl(this, _span, ref_processor(),
                              &_markBitMap, &_modUnionTable,
                              &_markStack, true /* precleaning phase */);
@@ -4110,8 +4011,8 @@
     SurvivorSpacePrecleanClosure
       sss_cl(this, _span, &_markBitMap, &_markStack,
              &pam_cl, before_count, CMSYield);
-    dng->from()->object_iterate_careful(&sss_cl);
-    dng->to()->object_iterate_careful(&sss_cl);
+    _young_gen->from()->object_iterate_careful(&sss_cl);
+    _young_gen->to()->object_iterate_careful(&sss_cl);
   }
   MarkRefsIntoAndScanClosure
     mrias_cl(_span, ref_processor(), &_markBitMap, &_modUnionTable,
@@ -4696,10 +4597,10 @@
 };
 
 void CMSParMarkTask::work_on_young_gen_roots(uint worker_id, OopsInGenClosure* cl) {
-  DefNewGeneration* dng = _collector->_young_gen->as_DefNewGeneration();
-  ContiguousSpace* eden_space = dng->eden();
-  ContiguousSpace* from_space = dng->from();
-  ContiguousSpace* to_space   = dng->to();
+  ParNewGeneration* young_gen = _collector->_young_gen;
+  ContiguousSpace* eden_space = young_gen->eden();
+  ContiguousSpace* from_space = young_gen->from();
+  ContiguousSpace* to_space   = young_gen->to();
 
   HeapWord** eca = _collector->_eden_chunk_array;
   size_t     ect = _collector->_eden_chunk_index;
@@ -5168,11 +5069,10 @@
 CMSCollector::
 initialize_sequential_subtasks_for_young_gen_rescan(int n_threads) {
   assert(n_threads > 0, "Unexpected n_threads argument");
-  DefNewGeneration* dng = (DefNewGeneration*)_young_gen;
 
   // Eden space
-  if (!dng->eden()->is_empty()) {
-    SequentialSubTasksDone* pst = dng->eden()->par_seq_tasks();
+  if (!_young_gen->eden()->is_empty()) {
+    SequentialSubTasksDone* pst = _young_gen->eden()->par_seq_tasks();
     assert(!pst->valid(), "Clobbering existing data?");
     // Each valid entry in [0, _eden_chunk_index) represents a task.
     size_t n_tasks = _eden_chunk_index + 1;
@@ -5185,14 +5085,14 @@
 
   // Merge the survivor plab arrays into _survivor_chunk_array
   if (_survivor_plab_array != NULL) {
-    merge_survivor_plab_arrays(dng->from(), n_threads);
+    merge_survivor_plab_arrays(_young_gen->from(), n_threads);
   } else {
     assert(_survivor_chunk_index == 0, "Error");
   }
 
   // To space
   {
-    SequentialSubTasksDone* pst = dng->to()->par_seq_tasks();
+    SequentialSubTasksDone* pst = _young_gen->to()->par_seq_tasks();
     assert(!pst->valid(), "Clobbering existing data?");
     // Sets the condition for completion of the subtask (how many threads
     // need to finish in order to be done).
@@ -5203,7 +5103,7 @@
 
   // From space
   {
-    SequentialSubTasksDone* pst = dng->from()->par_seq_tasks();
+    SequentialSubTasksDone* pst = _young_gen->from()->par_seq_tasks();
     assert(!pst->valid(), "Clobbering existing data?");
     size_t n_tasks = _survivor_chunk_index + 1;
     assert(n_tasks == 1 || _survivor_chunk_array != NULL, "Error");
@@ -5945,7 +5845,6 @@
 }
 
 void CMSCollector::do_CMS_operation(CMS_op_type op, GCCause::Cause gc_cause) {
-  gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
   TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
   GCTraceTime t(GCCauseString("GC", gc_cause), PrintGC, !PrintGCDetails, NULL, _gc_tracer_cm->gc_id());
   TraceCollectorStats tcs(counters());
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2014, 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,9 +30,10 @@
 #include "gc_implementation/shared/gcStats.hpp"
 #include "gc_implementation/shared/gcWhen.hpp"
 #include "gc_implementation/shared/generationCounters.hpp"
+#include "memory/cardGeneration.hpp"
 #include "memory/freeBlockDictionary.hpp"
-#include "memory/generation.hpp"
 #include "memory/iterator.hpp"
+#include "memory/space.hpp"
 #include "runtime/mutexLocker.hpp"
 #include "runtime/virtualspace.hpp"
 #include "services/memoryService.hpp"
@@ -171,9 +172,7 @@
 // Represents a marking stack used by the CMS collector.
 // Ideally this should be GrowableArray<> just like MSC's marking stack(s).
 class CMSMarkStack: public CHeapObj<mtGC>  {
-  //
   friend class CMSCollector;   // To get at expansion stats further below.
-  //
 
   VirtualSpace _virtual_space;  // Space for the stack
   oop*   _base;      // Bottom of stack
@@ -721,7 +720,8 @@
 
  private:
   // Support for parallelizing young gen rescan in CMS remark phase
-  Generation* _young_gen;  // the younger gen
+  ParNewGeneration* _young_gen;  // the younger gen
+
   HeapWord** _top_addr;    // ... Top of Eden
   HeapWord** _end_addr;    // ... End of Eden
   Mutex*     _eden_chunk_lock;
@@ -1030,6 +1030,9 @@
   void set_expansion_cause(CMSExpansionCause::Cause v) { _expansion_cause = v;}
   CMSExpansionCause::Cause expansion_cause() const { return _expansion_cause; }
 
+  // Accessing spaces
+  CompactibleSpace* space() const { return (CompactibleSpace*)_cmsSpace; }
+
  private:
   // For parallel young-gen GC support.
   CMSParGCThreadState** _par_gc_thread_states;
@@ -1063,6 +1066,10 @@
   double initiating_occupancy() const { return _initiating_occupancy; }
   void   init_initiating_occupancy(intx io, uintx tr);
 
+  void expand_for_gc_cause(size_t bytes, size_t expand_bytes, CMSExpansionCause::Cause cause);
+
+  void assert_correct_size_change_locking();
+
  public:
   ConcurrentMarkSweepGeneration(ReservedSpace rs, size_t initial_byte_size,
                                 int level, CardTableRS* ct,
@@ -1099,23 +1106,14 @@
   // Override
   virtual void ref_processor_init();
 
-  // Grow generation by specified size (returns false if unable to grow)
-  bool grow_by(size_t bytes);
-  // Grow generation to reserved size.
-  bool grow_to_reserved();
-
   void clear_expansion_cause() { _expansion_cause = CMSExpansionCause::_no_expansion; }
 
   // Space enquiries
-  size_t capacity() const;
-  size_t used() const;
-  size_t free() const;
   double occupancy() const { return ((double)used())/((double)capacity()); }
   size_t contiguous_available() const;
   size_t unsafe_max_alloc_nogc() const;
 
   // over-rides
-  MemRegion used_region() const;
   MemRegion used_region_at_save_marks() const;
 
   // Does a "full" (forced) collection invoked on this generation collect
@@ -1126,10 +1124,6 @@
     return !ScavengeBeforeFullGC;
   }
 
-  void space_iterate(SpaceClosure* blk, bool usedOnly = false);
-
-  // Support for compaction
-  CompactibleSpace* first_compaction_space() const;
   // Adjust quantities in the generation affected by
   // the compaction.
   void reset_after_compaction();
@@ -1151,9 +1145,6 @@
   // Overrides for parallel promotion.
   virtual oop par_promote(int thread_num,
                           oop obj, markOop m, size_t word_sz);
-  // This one should not be called for CMS.
-  virtual void par_promote_alloc_undo(int thread_num,
-                                      HeapWord* obj, size_t word_sz);
   virtual void par_promote_alloc_done(int thread_num);
   virtual void par_oop_since_save_marks_iterate_done(int thread_num);
 
@@ -1192,18 +1183,13 @@
   }
 
   // Allocation failure
-  void expand(size_t bytes, size_t expand_bytes,
-    CMSExpansionCause::Cause cause);
-  virtual bool expand(size_t bytes, size_t expand_bytes);
   void shrink(size_t bytes);
-  void shrink_by(size_t bytes);
   HeapWord* expand_and_par_lab_allocate(CMSParGCThreadState* ps, size_t word_sz);
   bool expand_and_ensure_spooling_space(PromotionInfo* promo);
 
   // Iteration support and related enquiries
   void save_marks();
   bool no_allocs_since_save_marks();
-  void younger_refs_iterate(OopsInGenClosure* cl);
 
   // Iteration support specific to CMS generations
   void save_sweep_limit();
@@ -1256,8 +1242,6 @@
   virtual const char* short_name() const { return "CMS"; }
   void        print() const;
   void printOccupancy(const char* s);
-  bool must_be_youngest() const { return false; }
-  bool must_be_oldest()   const { return true; }
 
   // Resize the generation after a compacting GC.  The
   // generation can be treated as a contiguous space
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.inline.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.inline.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2014, 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,8 +29,9 @@
 #include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp"
 #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp"
 #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp"
+#include "gc_implementation/parNew/parNewGeneration.hpp"
 #include "gc_implementation/shared/gcUtil.hpp"
-#include "memory/defNewGeneration.hpp"
+#include "memory/genCollectedHeap.hpp"
 
 inline void CMSBitMap::clear_all() {
   assert_locked();
@@ -257,11 +258,11 @@
 }
 
 inline size_t CMSCollector::get_eden_used() const {
-  return _young_gen->as_DefNewGeneration()->eden()->used();
+  return _young_gen->eden()->used();
 }
 
 inline size_t CMSCollector::get_eden_capacity() const {
-  return _young_gen->as_DefNewGeneration()->eden()->capacity();
+  return _young_gen->eden()->capacity();
 }
 
 inline bool CMSStats::valid() const {
@@ -368,22 +369,6 @@
   cmsSpace()->save_sweep_limit();
 }
 
-inline size_t ConcurrentMarkSweepGeneration::capacity() const {
-  return _cmsSpace->capacity();
-}
-
-inline size_t ConcurrentMarkSweepGeneration::used() const {
-  return _cmsSpace->used();
-}
-
-inline size_t ConcurrentMarkSweepGeneration::free() const {
-  return _cmsSpace->free();
-}
-
-inline MemRegion ConcurrentMarkSweepGeneration::used_region() const {
-  return _cmsSpace->used_region();
-}
-
 inline MemRegion ConcurrentMarkSweepGeneration::used_region_at_save_marks() const {
   return _cmsSpace->used_region_at_save_marks();
 }
--- a/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -107,7 +107,7 @@
     for (uint i = 0; i < _n_threads; i++) {
       delete _threads[i];
     }
-    FREE_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _threads, mtGC);
+    FREE_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _threads);
   }
 }
 
--- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -180,9 +180,32 @@
   }
 };
 
+class ParClearNextMarkBitmapTask : public AbstractGangTask {
+  ClearBitmapHRClosure* _cl;
+  HeapRegionClaimer     _hrclaimer;
+  bool                  _suspendible; // If the task is suspendible, workers must join the STS.
+
+public:
+  ParClearNextMarkBitmapTask(ClearBitmapHRClosure *cl, uint n_workers, bool suspendible) :
+      _cl(cl), _suspendible(suspendible), AbstractGangTask("Parallel Clear Bitmap Task"), _hrclaimer(n_workers) {}
+
+  void work(uint worker_id) {
+    if (_suspendible) {
+      SuspendibleThreadSet::join();
+    }
+    G1CollectedHeap::heap()->heap_region_par_iterate(_cl, worker_id, &_hrclaimer, true);
+    if (_suspendible) {
+      SuspendibleThreadSet::leave();
+    }
+  }
+};
+
 void CMBitMap::clearAll() {
+  G1CollectedHeap* g1h = G1CollectedHeap::heap();
   ClearBitmapHRClosure cl(NULL, this, false /* may_yield */);
-  G1CollectedHeap::heap()->heap_region_iterate(&cl);
+  uint n_workers = g1h->workers()->active_workers();
+  ParClearNextMarkBitmapTask task(&cl, n_workers, false);
+  g1h->workers()->run_task(&task);
   guarantee(cl.complete(), "Must have completed iteration.");
   return;
 }
@@ -861,7 +884,8 @@
   guarantee(!g1h->mark_in_progress(), "invariant");
 
   ClearBitmapHRClosure cl(this, _nextMarkBitMap, true /* may_yield */);
-  g1h->heap_region_iterate(&cl);
+  ParClearNextMarkBitmapTask task(&cl, parallel_marking_threads(), true);
+  _parallel_workers->run_task(&task);
 
   // Clear the liveness counting data. If the marking has been aborted, the abort()
   // call already did that.
@@ -2099,6 +2123,7 @@
   // We reclaimed old regions so we should calculate the sizes to make
   // sure we update the old gen/space data.
   g1h->g1mm()->update_sizes();
+  g1h->allocation_context_stats().update_after_mark();
 
   g1h->trace_heap_after_concurrent_cycle();
 }
@@ -3219,7 +3244,6 @@
   _g1h->set_par_threads(n_workers);
   _g1h->workers()->run_task(&g1_par_agg_task);
   _g1h->set_par_threads(0);
-  _g1h->allocation_context_stats().update_at_remark();
 }
 
 // Clear the per-worker arrays used to store the per-region counting data
--- a/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -280,7 +280,6 @@
       // We may have aborted just before the remark. Do not bother clearing the
       // bitmap then, as it has been done during mark abort.
       if (!cm()->has_aborted()) {
-        SuspendibleThreadSetJoiner sts;
         _cm->clearNextBitmap();
       } else {
         assert(!G1VerifyBitmaps || _cm->nextMarkBitmapIsClear(), "Next mark bitmap must be clear");
--- a/src/share/vm/gc_implementation/g1/g1AllocationContext.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/g1/g1AllocationContext.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -45,7 +45,7 @@
 public:
   inline void clear() { }
   inline void update(bool full_gc) { }
-  inline void update_at_remark() { }
+  inline void update_after_mark() { }
   inline bool available() { return false; }
 };
 
--- a/src/share/vm/gc_implementation/g1/g1Allocator.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/g1/g1Allocator.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -59,7 +59,7 @@
       !(retained_region->top() == retained_region->end()) &&
       !retained_region->is_empty() &&
       !retained_region->is_humongous()) {
-    retained_region->record_top_and_timestamp();
+    retained_region->record_timestamp();
     // The retained region was added to the old region set when it was
     // retired. We have to remove it now, since we don't allow regions
     // we allocate to in the region sets. We'll re-add it later, when
@@ -94,6 +94,9 @@
   // want either way so no reason to check explicitly for either
   // condition.
   _retained_old_gc_alloc_region = old_gc_alloc_region(context)->release();
+  if (_retained_old_gc_alloc_region != NULL) {
+    _retained_old_gc_alloc_region->record_retained_region();
+  }
 
   if (ResizePLAB) {
     _g1h->_survivor_plab_stats.adjust_desired_plab_sz(no_of_gc_workers);
--- a/src/share/vm/gc_implementation/g1/g1CodeCacheRemSet.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/g1/g1CodeCacheRemSet.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -111,13 +111,13 @@
       // read next before freeing.
       e = e->next();
       unlink_entry(to_remove);
-      FREE_C_HEAP_ARRAY(char, to_remove, mtGC);
+      FREE_C_HEAP_ARRAY(char, to_remove);
     }
   }
   assert(number_of_entries() == 0, "should have removed all entries");
   free_buckets();
   for (BasicHashtableEntry<mtGC>* e = new_entry_free_list(); e != NULL; e = new_entry_free_list()) {
-    FREE_C_HEAP_ARRAY(char, e, mtGC);
+    FREE_C_HEAP_ARRAY(char, e);
   }
 }
 
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -352,7 +352,7 @@
 }
 
 void G1RegionMappingChangedListener::reset_from_card_cache(uint start_idx, size_t num_regions) {
-  OtherRegionsTable::invalidate(start_idx, num_regions);
+  HeapRegionRemSet::invalidate_from_card_cache(start_idx, num_regions);
 }
 
 void G1RegionMappingChangedListener::on_commit(uint start_idx, size_t num_regions, bool zero_filled) {
@@ -1222,7 +1222,6 @@
 
     // Timing
     assert(gc_cause() != GCCause::_java_lang_system_gc || explicit_gc, "invariant");
-    gclog_or_tty->date_stamp(G1Log::fine() && PrintGCDateStamps);
     TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty);
 
     {
@@ -2258,6 +2257,7 @@
     case GCCause::_java_lang_system_gc:     return ExplicitGCInvokesConcurrent;
     case GCCause::_g1_humongous_allocation: return true;
     case GCCause::_update_allocation_context_stats_inc: return true;
+    case GCCause::_wb_conc_mark:            return true;
     default:                                return false;
   }
 }
@@ -2552,8 +2552,9 @@
 void
 G1CollectedHeap::heap_region_par_iterate(HeapRegionClosure* cl,
                                          uint worker_id,
-                                         HeapRegionClaimer *hrclaimer) const {
-  _hrm.par_iterate(cl, worker_id, hrclaimer);
+                                         HeapRegionClaimer *hrclaimer,
+                                         bool concurrent) const {
+  _hrm.par_iterate(cl, worker_id, hrclaimer, concurrent);
 }
 
 // Clear the cached CSet starting regions and (more importantly)
@@ -3561,7 +3562,7 @@
 void
 G1CollectedHeap::cleanup_surviving_young_words() {
   guarantee( _surviving_young_words != NULL, "pre-condition" );
-  FREE_C_HEAP_ARRAY(size_t, _surviving_young_words, mtGC);
+  FREE_C_HEAP_ARRAY(size_t, _surviving_young_words);
   _surviving_young_words = NULL;
 }
 
@@ -6530,7 +6531,7 @@
       // We really only need to do this for old regions given that we
       // should never scan survivors. But it doesn't hurt to do it
       // for survivors too.
-      new_alloc_region->record_top_and_timestamp();
+      new_alloc_region->record_timestamp();
       if (survivor) {
         new_alloc_region->set_survivor();
         _hr_printer.alloc(new_alloc_region, G1HRPrinter::Survivor);
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -1380,10 +1380,13 @@
   // in the range [0..max(ParallelGCThreads-1, 1)]. Applies "blk->doHeapRegion"
   // to each of the regions, by attempting to claim the region using the
   // HeapRegionClaimer and, if successful, applying the closure to the claimed
-  // region.
+  // region. The concurrent argument should be set to true if iteration is
+  // performed concurrently, during which no assumptions are made for consistent
+  // attributes of the heap regions (as they might be modified while iterating).
   void heap_region_par_iterate(HeapRegionClosure* cl,
                                uint worker_id,
-                               HeapRegionClaimer* hrclaimer) const;
+                               HeapRegionClaimer* hrclaimer,
+                               bool concurrent = false) const;
 
   // Clear the cached cset start regions and (more importantly)
   // the time stamps. Called when we reset the GC time stamp.
--- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -1425,6 +1425,18 @@
 #endif // PRODUCT
 }
 
+bool G1CollectorPolicy::is_young_list_full() {
+  uint young_list_length = _g1->young_list()->length();
+  uint young_list_target_length = _young_list_target_length;
+  return young_list_length >= young_list_target_length;
+}
+
+bool G1CollectorPolicy::can_expand_young_list() {
+  uint young_list_length = _g1->young_list()->length();
+  uint young_list_max_length = _young_list_max_length;
+  return young_list_length < young_list_max_length;
+}
+
 uint G1CollectorPolicy::max_regions(int purpose) {
   switch (purpose) {
     case GCAllocForSurvived:
--- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -26,6 +26,7 @@
 #define SHARE_VM_GC_IMPLEMENTATION_G1_G1COLLECTORPOLICY_HPP
 
 #include "gc_implementation/g1/collectionSetChooser.hpp"
+#include "gc_implementation/g1/g1Allocator.hpp"
 #include "gc_implementation/g1/g1MMUTracker.hpp"
 #include "memory/collectorPolicy.hpp"
 
@@ -807,7 +808,7 @@
 
   // If an expansion would be appropriate, because recent GC overhead had
   // exceeded the desired limit, return an amount to expand by.
-  size_t expansion_amount();
+  virtual size_t expansion_amount();
 
   // Print tracing information.
   void print_tracing_info() const;
@@ -826,17 +827,9 @@
 
   size_t young_list_target_length() const { return _young_list_target_length; }
 
-  bool is_young_list_full() {
-    uint young_list_length = _g1->young_list()->length();
-    uint young_list_target_length = _young_list_target_length;
-    return young_list_length >= young_list_target_length;
-  }
+  bool is_young_list_full();
 
-  bool can_expand_young_list() {
-    uint young_list_length = _g1->young_list()->length();
-    uint young_list_max_length = _young_list_max_length;
-    return young_list_length < young_list_max_length;
-  }
+  bool can_expand_young_list();
 
   uint young_list_max_length() {
     return _young_list_max_length;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy_ext.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2014, 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_G1COLLECTORPOLICY_EXT_HPP
+#define SHARE_VM_GC_IMPLEMENTATION_G1_G1COLLECTORPOLICY_EXT_HPP
+
+#include "gc_implementation/g1/g1CollectorPolicy.hpp"
+
+class G1CollectorPolicyExt : public G1CollectorPolicy { };
+
+#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1COLLECTORPOLICY_EXT_HPP
--- a/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -53,7 +53,7 @@
   }
 
   ~WorkerDataArray() {
-    FREE_C_HEAP_ARRAY(T, _data, mtGC);
+    FREE_C_HEAP_ARRAY(T, _data);
   }
 
   void set(uint worker_i, T value) {
--- a/src/share/vm/gc_implementation/g1/g1HotCardCache.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/g1/g1HotCardCache.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, 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,7 +53,7 @@
 G1HotCardCache::~G1HotCardCache() {
   if (default_use_cache()) {
     assert(_hot_cache != NULL, "Logic");
-    FREE_C_HEAP_ARRAY(jbyte*, _hot_cache, mtGC);
+    FREE_C_HEAP_ARRAY(jbyte*, _hot_cache);
   }
 }
 
--- a/src/share/vm/gc_implementation/g1/g1ParScanThreadState.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/g1/g1ParScanThreadState.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -65,7 +65,7 @@
 G1ParScanThreadState::~G1ParScanThreadState() {
   _g1_par_allocator->retire_alloc_buffers();
   delete _g1_par_allocator;
-  FREE_C_HEAP_ARRAY(size_t, _surviving_young_words_base, mtGC);
+  FREE_C_HEAP_ARRAY(size_t, _surviving_young_words_base);
 }
 
 void
--- a/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -94,7 +94,7 @@
   for (uint i = 0; i < n_workers(); i++) {
     assert(_cset_rs_update_cl[i] == NULL, "it should be");
   }
-  FREE_C_HEAP_ARRAY(OopsInHeapRegionClosure*, _cset_rs_update_cl, mtGC);
+  FREE_C_HEAP_ARRAY(OopsInHeapRegionClosure*, _cset_rs_update_cl);
 }
 
 class ScanRSClosure : public HeapRegionClosure {
@@ -140,11 +140,9 @@
 
     // Set the "from" region in the closure.
     _oc->set_region(r);
-    HeapWord* card_start = _bot_shared->address_for_index(index);
-    HeapWord* card_end = card_start + G1BlockOffsetSharedArray::N_words;
-    Space *sp = SharedHeap::heap()->space_containing(card_start);
-    MemRegion sm_region = sp->used_region_at_save_marks();
-    MemRegion mr = sm_region.intersection(MemRegion(card_start,card_end));
+    MemRegion card_region(_bot_shared->address_for_index(index), G1BlockOffsetSharedArray::N_words);
+    MemRegion pre_gc_allocated(r->bottom(), r->scan_top());
+    MemRegion mr = pre_gc_allocated.intersection(card_region);
     if (!mr.is_empty() && !_ct_bs->is_card_claimed(index)) {
       // We make the card as "claimed" lazily (so races are possible
       // but they're benign), which reduces the number of duplicate
@@ -353,7 +351,7 @@
   for (uint i = 0; i < n_workers(); ++i) {
     _total_cards_scanned += _cards_scanned[i];
   }
-  FREE_C_HEAP_ARRAY(size_t, _cards_scanned, mtGC);
+  FREE_C_HEAP_ARRAY(size_t, _cards_scanned);
   _cards_scanned = NULL;
   // Cleanup after copy
   _g1->set_refine_cte_cl_concurrency(true);
--- a/src/share/vm/gc_implementation/g1/g1RemSetSummary.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/g1/g1RemSetSummary.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -59,7 +59,7 @@
 
   void free_and_null() {
     if (_rs_threads_vtimes) {
-      FREE_C_HEAP_ARRAY(double, _rs_threads_vtimes, mtGC);
+      FREE_C_HEAP_ARRAY(double, _rs_threads_vtimes);
       _rs_threads_vtimes = NULL;
       _num_vtimes = 0;
     }
--- a/src/share/vm/gc_implementation/g1/g1StringDedupTable.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/g1/g1StringDedupTable.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -187,7 +187,7 @@
 }
 
 G1StringDedupTable::~G1StringDedupTable() {
-  FREE_C_HEAP_ARRAY(G1StringDedupEntry*, _buckets, mtGC);
+  FREE_C_HEAP_ARRAY(G1StringDedupEntry*, _buckets);
 }
 
 void G1StringDedupTable::create() {
--- a/src/share/vm/gc_implementation/g1/heapRegion.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/g1/heapRegion.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -326,7 +326,7 @@
 
   hr_clear(false /*par*/, false /*clear_space*/);
   set_top(bottom());
-  record_top_and_timestamp();
+  record_timestamp();
 
   assert(mr.end() == orig_end(),
          err_msg("Given region end address " PTR_FORMAT " should match exactly "
@@ -416,9 +416,9 @@
 
   // If we're within a stop-world GC, then we might look at a card in a
   // GC alloc region that extends onto a GC LAB, which may not be
-  // parseable.  Stop such at the "saved_mark" of the region.
+  // parseable.  Stop such at the "scan_top" of the region.
   if (g1h->is_gc_active()) {
-    mr = mr.intersection(used_region_at_save_marks());
+    mr = mr.intersection(MemRegion(bottom(), scan_top()));
   } else {
     mr = mr.intersection(used_region());
   }
@@ -969,7 +969,7 @@
 
 void G1OffsetTableContigSpace::clear(bool mangle_space) {
   set_top(bottom());
-  set_saved_mark_word(bottom());
+  _scan_top = bottom();
   CompactibleSpace::clear(mangle_space);
   reset_bot();
 }
@@ -1001,41 +1001,42 @@
   return _offsets.threshold();
 }
 
-HeapWord* G1OffsetTableContigSpace::saved_mark_word() const {
+HeapWord* G1OffsetTableContigSpace::scan_top() const {
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
-  assert( _gc_time_stamp <= g1h->get_gc_time_stamp(), "invariant" );
   HeapWord* local_top = top();
   OrderAccess::loadload();
-  if (_gc_time_stamp < g1h->get_gc_time_stamp()) {
+  const unsigned local_time_stamp = _gc_time_stamp;
+  assert(local_time_stamp <= g1h->get_gc_time_stamp(), "invariant");
+  if (local_time_stamp < g1h->get_gc_time_stamp()) {
     return local_top;
   } else {
-    return Space::saved_mark_word();
+    return _scan_top;
   }
 }
 
-void G1OffsetTableContigSpace::record_top_and_timestamp() {
+void G1OffsetTableContigSpace::record_timestamp() {
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
   unsigned curr_gc_time_stamp = g1h->get_gc_time_stamp();
 
   if (_gc_time_stamp < curr_gc_time_stamp) {
-    // The order of these is important, as another thread might be
-    // about to start scanning this region. If it does so after
-    // set_saved_mark and before _gc_time_stamp = ..., then the latter
-    // will be false, and it will pick up top() as the high water mark
-    // of region. If it does so after _gc_time_stamp = ..., then it
-    // will pick up the right saved_mark_word() as the high water mark
-    // of the region. Either way, the behavior will be correct.
-    Space::set_saved_mark_word(top());
-    OrderAccess::storestore();
+    // Setting the time stamp here tells concurrent readers to look at
+    // scan_top to know the maximum allowed address to look at.
+
+    // scan_top should be bottom for all regions except for the
+    // retained old alloc region which should have scan_top == top
+    HeapWord* st = _scan_top;
+    guarantee(st == _bottom || st == _top, "invariant");
+
     _gc_time_stamp = curr_gc_time_stamp;
-    // No need to do another barrier to flush the writes above. If
-    // this is called in parallel with other threads trying to
-    // allocate into the region, the caller should call this while
-    // holding a lock and when the lock is released the writes will be
-    // flushed.
   }
 }
 
+void G1OffsetTableContigSpace::record_retained_region() {
+  // scan_top is the maximum address where it's safe for the next gc to
+  // scan this region.
+  _scan_top = top();
+}
+
 void G1OffsetTableContigSpace::safe_object_iterate(ObjectClosure* blk) {
   object_iterate(blk);
 }
@@ -1063,6 +1064,8 @@
 void G1OffsetTableContigSpace::initialize(MemRegion mr, bool clear_space, bool mangle_space) {
   CompactibleSpace::initialize(mr, clear_space, mangle_space);
   _top = bottom();
+  _scan_top = bottom();
+  set_saved_mark_word(NULL);
   reset_bot();
 }
 
--- a/src/share/vm/gc_implementation/g1/heapRegion.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/g1/heapRegion.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -101,28 +101,25 @@
 // OffsetTableContigSpace.  If the two versions of BlockOffsetTable could
 // be reconciled, then G1OffsetTableContigSpace could go away.
 
-// The idea behind time stamps is the following. Doing a save_marks on
-// all regions at every GC pause is time consuming (if I remember
-// well, 10ms or so). So, we would like to do that only for regions
-// that are GC alloc regions. To achieve this, we use time
-// stamps. For every evacuation pause, G1CollectedHeap generates a
-// unique time stamp (essentially a counter that gets
-// incremented). Every time we want to call save_marks on a region,
-// we set the saved_mark_word to top and also copy the current GC
-// time stamp to the time stamp field of the space. Reading the
-// saved_mark_word involves checking the time stamp of the
-// region. If it is the same as the current GC time stamp, then we
-// can safely read the saved_mark_word field, as it is valid. If the
-// time stamp of the region is not the same as the current GC time
-// stamp, then we instead read top, as the saved_mark_word field is
-// invalid. Time stamps (on the regions and also on the
-// G1CollectedHeap) are reset at every cleanup (we iterate over
-// the regions anyway) and at the end of a Full GC. The current scheme
-// that uses sequential unsigned ints will fail only if we have 4b
+// The idea behind time stamps is the following. We want to keep track of
+// the highest address where it's safe to scan objects for each region.
+// This is only relevant for current GC alloc regions so we keep a time stamp
+// per region to determine if the region has been allocated during the current
+// GC or not. If the time stamp is current we report a scan_top value which
+// was saved at the end of the previous GC for retained alloc regions and which is
+// equal to the bottom for all other regions.
+// There is a race between card scanners and allocating gc workers where we must ensure
+// that card scanners do not read the memory allocated by the gc workers.
+// In order to enforce that, we must not return a value of _top which is more recent than the
+// time stamp. This is due to the fact that a region may become a gc alloc region at
+// some point after we've read the timestamp value as being < the current time stamp.
+// The time stamps are re-initialized to zero at cleanup and at Full GCs.
+// The current scheme that uses sequential unsigned ints will fail only if we have 4b
 // evacuation pauses between two cleanups, which is _highly_ unlikely.
 class G1OffsetTableContigSpace: public CompactibleSpace {
   friend class VMStructs;
   HeapWord* _top;
+  HeapWord* volatile _scan_top;
  protected:
   G1BlockOffsetArrayContigSpace _offsets;
   Mutex _par_alloc_lock;
@@ -166,10 +163,11 @@
   void set_bottom(HeapWord* value);
   void set_end(HeapWord* value);
 
-  virtual HeapWord* saved_mark_word() const;
-  void record_top_and_timestamp();
+  HeapWord* scan_top() const;
+  void record_timestamp();
   void reset_gc_time_stamp() { _gc_time_stamp = 0; }
   unsigned get_gc_time_stamp() { return _gc_time_stamp; }
+  void record_retained_region();
 
   // See the comment above in the declaration of _pre_dummy_top for an
   // explanation of what it is.
@@ -191,6 +189,8 @@
   virtual HeapWord* allocate(size_t word_size);
   HeapWord* par_allocate(size_t word_size);
 
+  HeapWord* saved_mark_word() const { ShouldNotReachHere(); return NULL; }
+
   // MarkSweep support phase3
   virtual HeapWord* initialize_threshold();
   virtual HeapWord* cross_threshold(HeapWord* start, HeapWord* end);
--- a/src/share/vm/gc_implementation/g1/heapRegionManager.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/g1/heapRegionManager.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -260,7 +260,7 @@
   return num_regions;
 }
 
-void HeapRegionManager::par_iterate(HeapRegionClosure* blk, uint worker_id, HeapRegionClaimer* hrclaimer) const {
+void HeapRegionManager::par_iterate(HeapRegionClosure* blk, uint worker_id, HeapRegionClaimer* hrclaimer, bool concurrent) const {
   const uint start_index = hrclaimer->start_region_for_worker(worker_id);
 
   // Every worker will actually look at all regions, skipping over regions that
@@ -279,7 +279,11 @@
     // We'll ignore "continues humongous" regions (we'll process them
     // when we come across their corresponding "start humongous"
     // region) and regions already claimed.
-    if (hrclaimer->is_region_claimed(index) || r->is_continues_humongous()) {
+    // However, if the iteration is specified as concurrent, the values for
+    // is_starts_humongous and is_continues_humongous can not be trusted,
+    // and we should just blindly iterate over regions regardless of their
+    // humongous status.
+    if (hrclaimer->is_region_claimed(index) || (!concurrent && r->is_continues_humongous())) {
       continue;
     }
     // OK, try to claim it
@@ -287,7 +291,9 @@
       continue;
     }
     // Success!
-    if (r->is_starts_humongous()) {
+    // As mentioned above, special treatment of humongous regions can only be
+    // done if we are iterating non-concurrently.
+    if (!concurrent && r->is_starts_humongous()) {
       // If the region is "starts humongous" we'll iterate over its
       // "continues humongous" first; in fact we'll do them
       // first. The order is important. In one case, calling the
@@ -449,7 +455,7 @@
 
 HeapRegionClaimer::~HeapRegionClaimer() {
   if (_claims != NULL) {
-    FREE_C_HEAP_ARRAY(uint, _claims, mtGC);
+    FREE_C_HEAP_ARRAY(uint, _claims);
   }
 }
 
--- a/src/share/vm/gc_implementation/g1/heapRegionManager.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/g1/heapRegionManager.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -222,7 +222,7 @@
   // terminating the iteration early if doHeapRegion() returns true.
   void iterate(HeapRegionClosure* blk) const;
 
-  void par_iterate(HeapRegionClosure* blk, uint worker_id, HeapRegionClaimer* hrclaimer) const;
+  void par_iterate(HeapRegionClosure* blk, uint worker_id, HeapRegionClaimer* hrclaimer, bool concurrent) const;
 
   // Uncommit up to num_regions_to_remove regions that are completely free.
   // Return the actual number of uncommitted regions.
--- a/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -407,20 +407,8 @@
   }
 }
 
-void OtherRegionsTable::initialize(uint max_regions) {
-  FromCardCache::initialize(HeapRegionRemSet::num_par_rem_sets(), max_regions);
-}
-
-void OtherRegionsTable::invalidate(uint start_idx, size_t num_regions) {
-  FromCardCache::invalidate(start_idx, num_regions);
-}
-
-void OtherRegionsTable::print_from_card_cache() {
-  FromCardCache::print();
-}
-
 void OtherRegionsTable::add_reference(OopOrNarrowOopStar from, uint tid) {
-  uint cur_hrm_ind = hr()->hrm_index();
+  uint cur_hrm_ind = _hr->hrm_index();
 
   if (G1TraceHeapRegionRememberedSet) {
     gclog_or_tty->print_cr("ORT::add_reference_work(" PTR_FORMAT "->" PTR_FORMAT ").",
@@ -434,7 +422,7 @@
 
   if (G1TraceHeapRegionRememberedSet) {
     gclog_or_tty->print_cr("Table for [" PTR_FORMAT "...): card %d (cache = %d)",
-                  hr()->bottom(), from_card,
+                  _hr->bottom(), from_card,
                   FromCardCache::at(tid, cur_hrm_ind));
   }
 
@@ -477,13 +465,13 @@
       if (G1HRRSUseSparseTable &&
           _sparse_table.add_card(from_hrm_ind, card_index)) {
         if (G1RecordHRRSOops) {
-          HeapRegionRemSet::record(hr(), from);
+          HeapRegionRemSet::record(_hr, from);
           if (G1TraceHeapRegionRememberedSet) {
             gclog_or_tty->print("   Added card " PTR_FORMAT " to region "
                                 "[" PTR_FORMAT "...) for ref " PTR_FORMAT ".\n",
                                 align_size_down(uintptr_t(from),
                                                 CardTableModRefBS::card_size),
-                                hr()->bottom(), from);
+                                _hr->bottom(), from);
           }
         }
         if (G1TraceHeapRegionRememberedSet) {
@@ -539,13 +527,13 @@
   prt->add_reference(from);
 
   if (G1RecordHRRSOops) {
-    HeapRegionRemSet::record(hr(), from);
+    HeapRegionRemSet::record(_hr, from);
     if (G1TraceHeapRegionRememberedSet) {
       gclog_or_tty->print("Added card " PTR_FORMAT " to region "
                           "[" PTR_FORMAT "...) for ref " PTR_FORMAT ".\n",
                           align_size_down(uintptr_t(from),
                                           CardTableModRefBS::card_size),
-                          hr()->bottom(), from);
+                          _hr->bottom(), from);
     }
   }
   assert(contains_reference(from), "We just added it!");
@@ -614,7 +602,7 @@
     if (G1TraceHeapRegionRememberedSet) {
       gclog_or_tty->print("Coarsened entry in region [" PTR_FORMAT "...] "
                  "for region [" PTR_FORMAT "...] (" SIZE_FORMAT " coarse entries).\n",
-                 hr()->bottom(),
+                 _hr->bottom(),
                  max->hr()->bottom(),
                  _n_coarse_entries);
     }
@@ -627,13 +615,11 @@
   return max;
 }
 
-
-// At present, this must be called stop-world single-threaded.
 void OtherRegionsTable::scrub(CardTableModRefBS* ctbs,
                               BitMap* region_bm, BitMap* card_bm) {
   // First eliminated garbage regions from the coarse map.
   if (G1RSScrubVerbose) {
-    gclog_or_tty->print_cr("Scrubbing region %u:", hr()->hrm_index());
+    gclog_or_tty->print_cr("Scrubbing region %u:", _hr->hrm_index());
   }
 
   assert(_coarse_map.size() == region_bm->size(), "Precondition");
@@ -752,7 +738,7 @@
 }
 
 void OtherRegionsTable::clear_fcc() {
-  FromCardCache::clear(hr()->hrm_index());
+  FromCardCache::clear(_hr->hrm_index());
 }
 
 void OtherRegionsTable::clear() {
@@ -774,27 +760,6 @@
   clear_fcc();
 }
 
-bool OtherRegionsTable::del_single_region_table(size_t ind,
-                                                HeapRegion* hr) {
-  assert(0 <= ind && ind < _max_fine_entries, "Preconditions.");
-  PerRegionTable** prev_addr = &_fine_grain_regions[ind];
-  PerRegionTable* prt = *prev_addr;
-  while (prt != NULL && prt->hr() != hr) {
-    prev_addr = prt->collision_list_next_addr();
-    prt = prt->collision_list_next();
-  }
-  if (prt != NULL) {
-    assert(prt->hr() == hr, "Loop postcondition.");
-    *prev_addr = prt->collision_list_next();
-    unlink_from_all(prt);
-    PerRegionTable::free(prt);
-    _n_fine_entries--;
-    return true;
-  } else {
-    return false;
-  }
-}
-
 bool OtherRegionsTable::contains_reference(OopOrNarrowOopStar from) const {
   // Cast away const in this case.
   MutexLockerEx x((Mutex*)_m, Mutex::_no_safepoint_check_flag);
@@ -975,7 +940,7 @@
   _hrrs(hrrs),
   _g1h(G1CollectedHeap::heap()),
   _coarse_map(&hrrs->_other_regions._coarse_map),
-  _bosa(hrrs->bosa()),
+  _bosa(hrrs->_bosa),
   _is(Sparse),
   // Set these values so that we increment to the first region.
   _coarse_cur_region_index(-1),
--- a/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -162,32 +162,36 @@
   // to hold _m, and the fine-grain table to be full.
   PerRegionTable* delete_region_table();
 
-  // If a PRT for "hr" is in the bucket list indicated by "ind" (which must
-  // be the correct index for "hr"), delete it and return true; else return
-  // false.
-  bool del_single_region_table(size_t ind, HeapRegion* hr);
-
   // link/add the given fine grain remembered set into the "all" list
   void link_to_all(PerRegionTable * prt);
   // unlink/remove the given fine grain remembered set into the "all" list
   void unlink_from_all(PerRegionTable * prt);
 
+  bool contains_reference_locked(OopOrNarrowOopStar from) const;
+
+  // Clear the from_card_cache entries for this region.
+  void clear_fcc();
 public:
+  // Create a new remembered set for the given heap region. The given mutex should
+  // be used to ensure consistency.
   OtherRegionsTable(HeapRegion* hr, Mutex* m);
 
-  HeapRegion* hr() const { return _hr; }
-
   // For now.  Could "expand" some tables in the future, so that this made
   // sense.
   void add_reference(OopOrNarrowOopStar from, uint tid);
 
+  // Returns whether the remembered set contains the given reference.
+  bool contains_reference(OopOrNarrowOopStar from) const;
+
   // Removes any entries shown by the given bitmaps to contain only dead
-  // objects.
+  // objects. Not thread safe.
+  // Set bits in the bitmaps indicate that the given region or card is live.
   void scrub(CardTableModRefBS* ctbs, BitMap* region_bm, BitMap* card_bm);
 
-  // Returns whether this remembered set (and all sub-sets) contain no entries.
+  // Returns whether this remembered set (and all sub-sets) does not contain any entry.
   bool is_empty() const;
 
+  // Returns the number of cards contained in this remembered set.
   size_t occupied() const;
   size_t occ_fine() const;
   size_t occ_coarse() const;
@@ -195,31 +199,17 @@
 
   static jint n_coarsenings() { return _n_coarsenings; }
 
-  // Returns size in bytes.
-  // Not const because it takes a lock.
+  // Returns size of the actual remembered set containers in bytes.
   size_t mem_size() const;
+  // Returns the size of static data in bytes.
   static size_t static_mem_size();
+  // Returns the size of the free list content in bytes.
   static size_t fl_mem_size();
 
-  bool contains_reference(OopOrNarrowOopStar from) const;
-  bool contains_reference_locked(OopOrNarrowOopStar from) const;
-
+  // Clear the entire contents of this remembered set.
   void clear();
 
-  // Specifically clear the from_card_cache.
-  void clear_fcc();
-
   void do_cleanup_work(HRRSCleanupTask* hrrs_cleanup_task);
-
-  // Declare the heap size (in # of regions) to the OtherRegionsTable.
-  // (Uses it to initialize from_card_cache).
-  static void initialize(uint max_regions);
-
-  // Declares that regions between start_idx <= i < start_idx + num_regions are
-  // not in use. Make sure that any entries for these regions are invalid.
-  static void invalidate(uint start_idx, size_t num_regions);
-
-  static void print_from_card_cache();
 };
 
 class HeapRegionRemSet : public CHeapObj<mtGC> {
@@ -233,7 +223,6 @@
 
 private:
   G1BlockOffsetSharedArray* _bosa;
-  G1BlockOffsetSharedArray* bosa() const { return _bosa; }
 
   // A set of code blobs (nmethods) whose code contains pointers into
   // the region that owns this RSet.
@@ -268,10 +257,6 @@
   static uint num_par_rem_sets();
   static void setup_remset_size();
 
-  HeapRegion* hr() const {
-    return _other_regions.hr();
-  }
-
   bool is_empty() const {
     return (strong_code_roots_list_length() == 0) && _other_regions.is_empty();
   }
@@ -305,8 +290,9 @@
     _other_regions.add_reference(from, tid);
   }
 
-  // Removes any entries shown by the given bitmaps to contain only dead
-  // objects.
+  // Removes any entries in the remembered set shown by the given bitmaps to
+  // contain only dead objects. Not thread safe.
+  // One bits in the bitmaps indicate that the given region or card is live.
   void scrub(CardTableModRefBS* ctbs, BitMap* region_bm, BitMap* card_bm);
 
   // The region is being reclaimed; clear its remset, and any mention of
@@ -397,16 +383,16 @@
   // Declare the heap size (in # of regions) to the HeapRegionRemSet(s).
   // (Uses it to initialize from_card_cache).
   static void init_heap(uint max_regions) {
-    OtherRegionsTable::initialize(max_regions);
+    FromCardCache::initialize(num_par_rem_sets(), max_regions);
   }
 
-  static void invalidate(uint start_idx, uint num_regions) {
-    OtherRegionsTable::invalidate(start_idx, num_regions);
+  static void invalidate_from_card_cache(uint start_idx, size_t num_regions) {
+    FromCardCache::invalidate(start_idx, num_regions);
   }
 
 #ifndef PRODUCT
   static void print_from_card_cache() {
-    OtherRegionsTable::print_from_card_cache();
+    FromCardCache::print();
   }
 #endif
 
--- a/src/share/vm/gc_implementation/g1/heapRegionSet.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/g1/heapRegionSet.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -449,5 +449,5 @@
 
   bot_storage->uncommit_regions(0, num_regions_in_test);
   delete bot_storage;
-  FREE_C_HEAP_ARRAY(HeapWord, bot_data, mtGC);
+  FREE_C_HEAP_ARRAY(HeapWord, bot_data);
 }
--- a/src/share/vm/gc_implementation/g1/ptrQueue.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/g1/ptrQueue.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2014, 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
@@ -129,7 +129,7 @@
     assert(_buf_free_list != NULL, "_buf_free_list_sz must be wrong.");
     void* b = BufferNode::make_block_from_node(_buf_free_list);
     _buf_free_list = _buf_free_list->next();
-    FREE_C_HEAP_ARRAY(char, b, mtGC);
+    FREE_C_HEAP_ARRAY(char, b);
     _buf_free_list_sz --;
     n--;
   }
--- a/src/share/vm/gc_implementation/g1/sparsePRT.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/g1/sparsePRT.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -154,11 +154,11 @@
 
 RSHashTable::~RSHashTable() {
   if (_entries != NULL) {
-    FREE_C_HEAP_ARRAY(SparsePRTEntry, _entries, mtGC);
+    FREE_C_HEAP_ARRAY(SparsePRTEntry, _entries);
     _entries = NULL;
   }
   if (_buckets != NULL) {
-    FREE_C_HEAP_ARRAY(int, _buckets, mtGC);
+    FREE_C_HEAP_ARRAY(int, _buckets);
     _buckets = NULL;
   }
 }
--- a/src/share/vm/gc_implementation/g1/survRateGroup.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/g1/survRateGroup.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -106,13 +106,13 @@
     _stats_arrays_length = _region_num;
 
     if (old_surv_rate != NULL) {
-      FREE_C_HEAP_ARRAY(double, old_surv_rate, mtGC);
+      FREE_C_HEAP_ARRAY(double, old_surv_rate);
     }
     if (old_accum_surv_rate_pred != NULL) {
-      FREE_C_HEAP_ARRAY(double, old_accum_surv_rate_pred, mtGC);
+      FREE_C_HEAP_ARRAY(double, old_accum_surv_rate_pred);
     }
     if (old_surv_rate_pred != NULL) {
-      FREE_C_HEAP_ARRAY(TruncatedSeq*, old_surv_rate_pred, mtGC);
+      FREE_C_HEAP_ARRAY(TruncatedSeq*, old_surv_rate_pred);
     }
   }
 
--- a/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -92,12 +92,8 @@
 
 void VM_G1IncCollectionPause::doit() {
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
-  assert(!_should_initiate_conc_mark ||
-  ((_gc_cause == GCCause::_gc_locker && GCLockerInvokesConcurrent) ||
-   (_gc_cause == GCCause::_java_lang_system_gc && ExplicitGCInvokesConcurrent) ||
-    _gc_cause == GCCause::_g1_humongous_allocation ||
-    _gc_cause == GCCause::_update_allocation_context_stats_inc),
-      "only a GC locker, a System.gc(), stats update or a hum allocation induced GC should start a cycle");
+  assert(!_should_initiate_conc_mark || g1h->should_do_concurrent_full_gc(_gc_cause),
+      "only a GC locker, a System.gc(), stats update, whitebox, or a hum allocation induced GC should start a cycle");
 
   if (_word_size > 0) {
     // An allocation has been requested. So, try to do that first.
@@ -230,7 +226,6 @@
 }
 
 void VM_CGC_Operation::doit() {
-  gclog_or_tty->date_stamp(G1Log::fine() && PrintGCDateStamps);
   TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty);
   GCTraceTime t(_printGCMessage, G1Log::fine(), true, G1CollectedHeap::heap()->gc_timer_cm(), G1CollectedHeap::heap()->concurrent_mark()->concurrent_gc_id());
   SharedHeap* sh = SharedHeap::heap();
--- a/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -462,7 +462,7 @@
         if (_lowest_non_clean[i] != NULL) {
           assert(n_chunks != _lowest_non_clean_chunk_size[i],
                  "logical consequence");
-          FREE_C_HEAP_ARRAY(CardPtr, _lowest_non_clean[i], mtGC);
+          FREE_C_HEAP_ARRAY(CardPtr, _lowest_non_clean[i]);
           _lowest_non_clean[i] = NULL;
         }
         // Now allocate a new one if necessary.
--- a/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -39,7 +39,6 @@
 #include "memory/genCollectedHeap.hpp"
 #include "memory/genOopClosures.inline.hpp"
 #include "memory/generation.hpp"
-#include "memory/generation.inline.hpp"
 #include "memory/referencePolicy.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/sharedHeap.hpp"
@@ -884,8 +883,6 @@
 
 // A Generation that does parallel young-gen collection.
 
-bool ParNewGeneration::_avoid_promotion_undo = false;
-
 void ParNewGeneration::handle_promotion_failed(GenCollectedHeap* gch, ParScanThreadStateSet& thread_state_set, ParNewTracer& gc_tracer) {
   assert(_promo_failure_scan_stack.is_empty(), "post condition");
   _promo_failure_scan_stack.clear(true); // Clear cached segments.
@@ -934,10 +931,6 @@
   assert(gch->n_gens() == 2,
          "Par collection currently only works with single older gen.");
   _next_gen = gch->next_gen(this);
-  // Do we have to avoid promotion_undo?
-  if (gch->collector_policy()->is_concurrent_mark_sweep_policy()) {
-    set_avoid_promotion_undo(true);
-  }
 
   // If the next generation is too full to accommodate worst-case promotion
   // from this generation, pass on collection; let the next generation
@@ -999,6 +992,11 @@
   thread_state_set.reset(0 /* Bad value in debug if not reset */,
                          promotion_failed());
 
+  // Trace and reset failed promotion info.
+  if (promotion_failed()) {
+    thread_state_set.trace_promotion_failed(gc_tracer);
+  }
+
   // Process (weak) reference objects found during scavenge.
   ReferenceProcessor* rp = ref_processor();
   IsAliveClosure is_alive(this);
@@ -1136,7 +1134,7 @@
 #ifdef ASSERT
 bool ParNewGeneration::is_legal_forward_ptr(oop p) {
   return
-    (_avoid_promotion_undo && p == ClaimedForwardPtr)
+    (p == ClaimedForwardPtr)
     || Universe::heap()->is_in_reserved(p);
 }
 #endif
@@ -1157,7 +1155,7 @@
 // thus avoiding the need to undo the copy as in
 // copy_to_survivor_space_avoiding_with_undo.
 
-oop ParNewGeneration::copy_to_survivor_space_avoiding_promotion_undo(
+oop ParNewGeneration::copy_to_survivor_space(
         ParScanThreadState* par_scan_state, oop old, size_t sz, markOop m) {
   // In the sequential version, this assert also says that the object is
   // not forwarded.  That might not be the case here.  It is the case that
@@ -1277,131 +1275,6 @@
   return forward_ptr;
 }
 
-
-// Multiple GC threads may try to promote the same object.  If two
-// or more GC threads copy the object, only one wins the race to install
-// the forwarding pointer.  The other threads have to undo their copy.
-
-oop ParNewGeneration::copy_to_survivor_space_with_undo(
-        ParScanThreadState* par_scan_state, oop old, size_t sz, markOop m) {
-
-  // In the sequential version, this assert also says that the object is
-  // not forwarded.  That might not be the case here.  It is the case that
-  // the caller observed it to be not forwarded at some time in the past.
-  assert(is_in_reserved(old), "shouldn't be scavenging this oop");
-
-  // The sequential code read "old->age()" below.  That doesn't work here,
-  // since the age is in the mark word, and that might be overwritten with
-  // a forwarding pointer by a parallel thread.  So we must save the mark
-  // word here, install it in a local oopDesc, and then analyze it.
-  oopDesc dummyOld;
-  dummyOld.set_mark(m);
-  assert(!dummyOld.is_forwarded(),
-         "should not be called with forwarding pointer mark word.");
-
-  bool failed_to_promote = false;
-  oop new_obj = NULL;
-  oop forward_ptr;
-
-  // Try allocating obj in to-space (unless too old)
-  if (dummyOld.age() < tenuring_threshold()) {
-    new_obj = (oop)par_scan_state->alloc_in_to_space(sz);
-    if (new_obj == NULL) {
-      set_survivor_overflow(true);
-    }
-  }
-
-  if (new_obj == NULL) {
-    // Either to-space is full or we decided to promote
-    // try allocating obj tenured
-    new_obj = _next_gen->par_promote(par_scan_state->thread_num(),
-                                       old, m, sz);
-
-    if (new_obj == NULL) {
-      // promotion failed, forward to self
-      forward_ptr = old->forward_to_atomic(old);
-      new_obj = old;
-
-      if (forward_ptr != NULL) {
-        return forward_ptr;   // someone else succeeded
-      }
-
-      _promotion_failed = true;
-      failed_to_promote = true;
-
-      preserve_mark_if_necessary(old, m);
-      par_scan_state->register_promotion_failure(sz);
-    }
-  } else {
-    // Is in to-space; do copying ourselves.
-    Copy::aligned_disjoint_words((HeapWord*)old, (HeapWord*)new_obj, sz);
-    // Restore the mark word copied above.
-    new_obj->set_mark(m);
-    // Increment age if new_obj still in new generation
-    new_obj->incr_age();
-    par_scan_state->age_table()->add(new_obj, sz);
-  }
-  assert(new_obj != NULL, "just checking");
-
-#ifndef PRODUCT
-  // This code must come after the CAS test, or it will print incorrect
-  // information.
-  if (TraceScavenge) {
-    gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
-       is_in_reserved(new_obj) ? "copying" : "tenuring",
-       new_obj->klass()->internal_name(), (void *)old, (void *)new_obj, new_obj->size());
-  }
-#endif
-
-  // Now attempt to install the forwarding pointer (atomically).
-  // We have to copy the mark word before overwriting with forwarding
-  // ptr, so we can restore it below in the copy.
-  if (!failed_to_promote) {
-    forward_ptr = old->forward_to_atomic(new_obj);
-  }
-
-  if (forward_ptr == NULL) {
-    oop obj_to_push = new_obj;
-    if (par_scan_state->should_be_partially_scanned(obj_to_push, old)) {
-      // Length field used as index of next element to be scanned.
-      // Real length can be obtained from real_forwardee()
-      arrayOop(old)->set_length(0);
-      obj_to_push = old;
-      assert(obj_to_push->is_forwarded() && obj_to_push->forwardee() != obj_to_push,
-             "push forwarded object");
-    }
-    // Push it on one of the queues of to-be-scanned objects.
-    bool simulate_overflow = false;
-    NOT_PRODUCT(
-      if (ParGCWorkQueueOverflowALot && should_simulate_overflow()) {
-        // simulate a stack overflow
-        simulate_overflow = true;
-      }
-    )
-    if (simulate_overflow || !par_scan_state->work_queue()->push(obj_to_push)) {
-      // Add stats for overflow pushes.
-      push_on_overflow_list(old, par_scan_state);
-      TASKQUEUE_STATS_ONLY(par_scan_state->taskqueue_stats().record_overflow(0));
-    }
-
-    return new_obj;
-  }
-
-  // Oops.  Someone beat us to it.  Undo the allocation.  Where did we
-  // allocate it?
-  if (is_in_reserved(new_obj)) {
-    // Must be in to_space.
-    assert(to()->is_in_reserved(new_obj), "Checking");
-    par_scan_state->undo_alloc_in_to_space((HeapWord*)new_obj, sz);
-  } else {
-    assert(!_avoid_promotion_undo, "Should not be here if avoiding.");
-    _next_gen->par_promote_alloc_undo(par_scan_state->thread_num(),
-                                      (HeapWord*)new_obj, sz);
-  }
-
-  return forward_ptr;
-}
-
 #ifndef PRODUCT
 // It's OK to call this multi-threaded;  the worst thing
 // that can happen is that we'll get a bunch of closely
@@ -1609,7 +1482,7 @@
       // This can become a scaling bottleneck when there is work queue overflow coincident
       // with promotion failure.
       oopDesc* f = cur;
-      FREE_C_HEAP_ARRAY(oopDesc, f, mtGC);
+      FREE_C_HEAP_ARRAY(oopDesc, f);
     } else if (par_scan_state->should_be_partially_scanned(obj_to_push, cur)) {
       assert(arrayOop(cur)->length() == 0, "entire array remaining to be scanned");
       obj_to_push = cur;
--- a/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -329,9 +329,6 @@
   oop _overflow_list;
   NOT_PRODUCT(ssize_t _num_par_pushes;)
 
-  // If true, older generation does not support promotion undo, so avoid.
-  static bool _avoid_promotion_undo;
-
   // This closure is used by the reference processor to filter out
   // references to live referent.
   DefNewGeneration::IsAliveClosure _is_alive_closure;
@@ -349,9 +346,6 @@
 
   bool _survivor_overflow;
 
-  bool avoid_promotion_undo() { return _avoid_promotion_undo; }
-  void set_avoid_promotion_undo(bool v) { _avoid_promotion_undo = v; }
-
   bool survivor_overflow() { return _survivor_overflow; }
   void set_survivor_overflow(bool v) { _survivor_overflow = v; }
 
@@ -372,7 +366,6 @@
 
   // override
   virtual bool refs_discovery_is_mt()     const {
-    assert(UseParNewGC, "ParNewGeneration only when UseParNewGC");
     return ParallelGCThreads > 1;
   }
 
@@ -386,20 +379,7 @@
   // "obj" is the object to be copied, "m" is a recent value of its mark
   // that must not contain a forwarding pointer (though one might be
   // inserted in "obj"s mark word by a parallel thread).
-  inline oop copy_to_survivor_space(ParScanThreadState* par_scan_state,
-                             oop obj, size_t obj_sz, markOop m) {
-    if (_avoid_promotion_undo) {
-       return copy_to_survivor_space_avoiding_promotion_undo(par_scan_state,
-                                                             obj, obj_sz, m);
-    }
-
-    return copy_to_survivor_space_with_undo(par_scan_state, obj, obj_sz, m);
-  }
-
-  oop copy_to_survivor_space_avoiding_promotion_undo(ParScanThreadState* par_scan_state,
-                             oop obj, size_t obj_sz, markOop m);
-
-  oop copy_to_survivor_space_with_undo(ParScanThreadState* par_scan_state,
+  oop copy_to_survivor_space(ParScanThreadState* par_scan_state,
                              oop obj, size_t obj_sz, markOop m);
 
   // in support of testing overflow code
--- a/src/share/vm/gc_implementation/parNew/parOopClosures.inline.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/parNew/parOopClosures.inline.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -28,6 +28,7 @@
 #include "gc_implementation/parNew/parNewGeneration.hpp"
 #include "gc_implementation/parNew/parOopClosures.hpp"
 #include "memory/cardTableRS.hpp"
+#include "memory/genCollectedHeap.hpp"
 
 template <class T> inline void ParScanWeakRefClosure::do_oop_work(T* p) {
   assert (!oopDesc::is_null(*p), "null weak reference?");
--- a/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -429,7 +429,7 @@
       }
       tty->cr();
     }
-    FREE_C_HEAP_ARRAY(uint, processor_assignment, mtGC);
+    FREE_C_HEAP_ARRAY(uint, processor_assignment);
   }
   reset_busy_workers();
   set_unblocked();
@@ -458,11 +458,11 @@
       GCTaskThread::destroy(thread(i));
       set_thread(i, NULL);
     }
-    FREE_C_HEAP_ARRAY(GCTaskThread*, _thread, mtGC);
+    FREE_C_HEAP_ARRAY(GCTaskThread*, _thread);
     _thread = NULL;
   }
   if (_resource_flag != NULL) {
-    FREE_C_HEAP_ARRAY(bool, _resource_flag, mtGC);
+    FREE_C_HEAP_ARRAY(bool, _resource_flag);
     _resource_flag = NULL;
   }
   if (queue() != NULL) {
--- a/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -58,7 +58,7 @@
 
 GCTaskThread::~GCTaskThread() {
   if (_time_stamps != NULL) {
-    FREE_C_HEAP_ARRAY(GCTaskTimeStamp, _time_stamps, mtGC);
+    FREE_C_HEAP_ARRAY(GCTaskTimeStamp, _time_stamps);
   }
 }
 
--- a/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -168,7 +168,6 @@
   {
     HandleMark hm;
 
-    gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
     TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
     GCTraceTime t1(GCCauseString("Full GC", gc_cause), PrintGC, !PrintGCDetails, NULL, _gc_tracer->gc_id());
     TraceCollectorStats tcs(counters());
--- a/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -41,31 +41,24 @@
 
   // Closure accessors
   static OopClosure* mark_and_push_closure()   { return &MarkSweep::mark_and_push_closure; }
-  static VoidClosure* follow_stack_closure()   { return (VoidClosure*)&MarkSweep::follow_stack_closure; }
+  static VoidClosure* follow_stack_closure()   { return &MarkSweep::follow_stack_closure; }
   static CLDClosure* follow_cld_closure()      { return &MarkSweep::follow_cld_closure; }
-  static OopClosure* adjust_pointer_closure()  { return (OopClosure*)&MarkSweep::adjust_pointer_closure; }
+  static OopClosure* adjust_pointer_closure()  { return &MarkSweep::adjust_pointer_closure; }
   static CLDClosure* adjust_cld_closure()      { return &MarkSweep::adjust_cld_closure; }
-  static BoolObjectClosure* is_alive_closure() { return (BoolObjectClosure*)&MarkSweep::is_alive; }
+  static BoolObjectClosure* is_alive_closure() { return &MarkSweep::is_alive; }
 
- debug_only(public:)  // Used for PSParallelCompact debugging
   // Mark live objects
   static void mark_sweep_phase1(bool clear_all_softrefs);
   // Calculate new addresses
   static void mark_sweep_phase2();
- debug_only(private:) // End used for PSParallelCompact debugging
   // Update pointers
   static void mark_sweep_phase3();
   // Move objects to new positions
   static void mark_sweep_phase4();
 
- debug_only(public:)  // Used for PSParallelCompact debugging
   // Temporary data structures for traversal and storing/restoring marks
   static void allocate_stacks();
   static void deallocate_stacks();
-  static void set_ref_processor(ReferenceProcessor* rp) {  // delete this method
-    _ref_processor = rp;
-  }
- debug_only(private:) // End used for PSParallelCompact debugging
 
   // If objects are left in eden after a collection, try to move the boundary
   // and absorb them into the old gen.  Returns true if eden was emptied.
--- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -2055,7 +2055,6 @@
     gc_task_manager()->task_idle_workers();
     heap->set_par_threads(gc_task_manager()->active_workers());
 
-    gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
     TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
     GCTraceTime t1(GCCauseString("Full GC", gc_cause), PrintGC, !PrintGCDetails, NULL, _gc_tracer.gc_id());
     TraceCollectorStats tcs(counters());
--- a/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -147,6 +147,10 @@
     claimed_stack_depth()->push(p);
   }
 
+  inline void promotion_trace_event(oop new_obj, oop old_obj, size_t obj_size,
+                                    uint age, bool tenured,
+                                    const PSPromotionLAB* lab);
+
  protected:
   static OopStarTaskQueueSet* stack_array_depth()   { return _stack_array_depth; }
  public:
--- a/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -64,6 +64,33 @@
   claim_or_forward_internal_depth(p);
 }
 
+inline void PSPromotionManager::promotion_trace_event(oop new_obj, oop old_obj,
+                                                      size_t obj_size,
+                                                      uint age, bool tenured,
+                                                      const PSPromotionLAB* lab) {
+  // Skip if memory allocation failed
+  if (new_obj != NULL) {
+    const ParallelScavengeTracer* gc_tracer = PSScavenge::gc_tracer();
+
+    if (lab != NULL) {
+      // Promotion of object through newly allocated PLAB
+      if (gc_tracer->should_report_promotion_in_new_plab_event()) {
+        size_t obj_bytes = obj_size * HeapWordSize;
+        size_t lab_size = lab->capacity();
+        gc_tracer->report_promotion_in_new_plab_event(old_obj->klass(), obj_bytes,
+                                                      age, tenured, lab_size);
+      }
+    } else {
+      // Promotion of object directly to heap
+      if (gc_tracer->should_report_promotion_outside_plab_event()) {
+        size_t obj_bytes = obj_size * HeapWordSize;
+        gc_tracer->report_promotion_outside_plab_event(old_obj->klass(), obj_bytes,
+                                                       age, tenured);
+      }
+    }
+  }
+}
+
 //
 // This method is pretty bulky. It would be nice to split it up
 // into smaller submethods, but we need to be careful not to hurt
@@ -85,11 +112,11 @@
     bool new_obj_is_tenured = false;
     size_t new_obj_size = o->size();
 
+    // Find the objects age, MT safe.
+    uint age = (test_mark->has_displaced_mark_helper() /* o->has_displaced_mark() */) ?
+      test_mark->displaced_mark_helper()->age() : test_mark->age();
+
     if (!promote_immediately) {
-      // Find the objects age, MT safe.
-      uint age = (test_mark->has_displaced_mark_helper() /* o->has_displaced_mark() */) ?
-        test_mark->displaced_mark_helper()->age() : test_mark->age();
-
       // Try allocating obj in to-space (unless too old)
       if (age < PSScavenge::tenuring_threshold()) {
         new_obj = (oop) _young_lab.allocate(new_obj_size);
@@ -98,6 +125,7 @@
           if (new_obj_size > (YoungPLABSize / 2)) {
             // Allocate this object directly
             new_obj = (oop)young_space()->cas_allocate(new_obj_size);
+            promotion_trace_event(new_obj, o, new_obj_size, age, false, NULL);
           } else {
             // Flush and fill
             _young_lab.flush();
@@ -107,6 +135,7 @@
               _young_lab.initialize(MemRegion(lab_base, YoungPLABSize));
               // Try the young lab allocation again.
               new_obj = (oop) _young_lab.allocate(new_obj_size);
+              promotion_trace_event(new_obj, o, new_obj_size, age, false, &_young_lab);
             } else {
               _young_gen_is_full = true;
             }
@@ -132,6 +161,7 @@
           if (new_obj_size > (OldPLABSize / 2)) {
             // Allocate this object directly
             new_obj = (oop)old_gen()->cas_allocate(new_obj_size);
+            promotion_trace_event(new_obj, o, new_obj_size, age, true, NULL);
           } else {
             // Flush and fill
             _old_lab.flush();
@@ -148,6 +178,7 @@
               _old_lab.initialize(MemRegion(lab_base, OldPLABSize));
               // Try the old lab allocation again.
               new_obj = (oop) _old_lab.allocate(new_obj_size);
+              promotion_trace_event(new_obj, o, new_obj_size, age, true, &_old_lab);
             }
           }
         }
--- a/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -330,7 +330,6 @@
     ResourceMark rm;
     HandleMark hm;
 
-    gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
     TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
     GCTraceTime t1(GCCauseString("GC", gc_cause), PrintGC, !PrintGCDetails, NULL, _gc_tracer.gc_id());
     TraceCollectorStats tcs(counters());
--- a/src/share/vm/gc_implementation/parallelScavenge/psScavenge.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/parallelScavenge/psScavenge.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -92,6 +92,7 @@
 
   // Private accessors
   static CardTableExtension* const card_table()       { assert(_card_table != NULL, "Sanity"); return _card_table; }
+  static const ParallelScavengeTracer* gc_tracer() { return &_gc_tracer; }
 
  public:
   // Accessors
--- a/src/share/vm/gc_implementation/shared/cSpaceCounters.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/shared/cSpaceCounters.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2014, 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,7 +53,7 @@
                  ContiguousSpace* s, GenerationCounters* gc);
 
   ~CSpaceCounters() {
-      if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space, mtInternal);
+      if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space);
   }
 
   virtual inline void update_capacity() {
--- a/src/share/vm/gc_implementation/shared/collectorCounters.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/shared/collectorCounters.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -50,7 +50,7 @@
     CollectorCounters(const char* name, int ordinal);
 
     ~CollectorCounters() {
-      if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space, mtGC);
+      if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space);
     }
 
     inline PerfCounter* invocation_counter() const  { return _invocations; }
--- a/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2014, 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
@@ -55,7 +55,7 @@
                  GenerationCounters* gc, bool sampled=true);
 
   ~GSpaceCounters() {
-    if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space, mtGC);
+    if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space);
   }
 
   inline void update_capacity() {
--- a/src/share/vm/gc_implementation/shared/gcTrace.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/shared/gcTrace.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -172,6 +172,27 @@
   _tenuring_threshold = tenuring_threshold;
 }
 
+bool YoungGCTracer::should_report_promotion_in_new_plab_event() const {
+  return should_send_promotion_in_new_plab_event();
+}
+
+bool YoungGCTracer::should_report_promotion_outside_plab_event() const {
+  return should_send_promotion_outside_plab_event();
+}
+
+void YoungGCTracer::report_promotion_in_new_plab_event(Klass* klass, size_t obj_size,
+                                                       uint age, bool tenured,
+                                                       size_t plab_size) const {
+  assert_set_gc_id();
+  send_promotion_in_new_plab_event(klass, obj_size, age, tenured, plab_size);
+}
+
+void YoungGCTracer::report_promotion_outside_plab_event(Klass* klass, size_t obj_size,
+                                                        uint age, bool tenured) const {
+  assert_set_gc_id();
+  send_promotion_outside_plab_event(klass, obj_size, age, tenured);
+}
+
 void OldGCTracer::report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions) {
   assert_set_gc_id();
 
--- a/src/share/vm/gc_implementation/shared/gcTrace.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/shared/gcTrace.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -156,9 +156,38 @@
   void report_promotion_failed(const PromotionFailedInfo& pf_info);
   void report_tenuring_threshold(const uint tenuring_threshold);
 
+  /*
+   * Methods for reporting Promotion in new or outside PLAB Events.
+   *
+   * The object age is always required as it is not certain that the mark word
+   * of the oop can be trusted at this stage.
+   *
+   * obj_size is the size of the promoted object in bytes.
+   *
+   * tenured should be true if the object has been promoted to the old
+   * space during this GC, if the object is copied to survivor space
+   * from young space or survivor space (aging) tenured should be false.
+   *
+   * plab_size is the size of the newly allocated PLAB in bytes.
+   */
+  bool should_report_promotion_in_new_plab_event() const;
+  bool should_report_promotion_outside_plab_event() const;
+  void report_promotion_in_new_plab_event(Klass* klass, size_t obj_size,
+                                          uint age, bool tenured,
+                                          size_t plab_size) const;
+  void report_promotion_outside_plab_event(Klass* klass, size_t obj_size,
+                                           uint age, bool tenured) const;
+
  private:
   void send_young_gc_event() const;
   void send_promotion_failed_event(const PromotionFailedInfo& pf_info) const;
+  bool should_send_promotion_in_new_plab_event() const;
+  bool should_send_promotion_outside_plab_event() const;
+  void send_promotion_in_new_plab_event(Klass* klass, size_t obj_size,
+                                        uint age, bool tenured,
+                                        size_t plab_size) const;
+  void send_promotion_outside_plab_event(Klass* klass, size_t obj_size,
+                                         uint age, bool tenured) const;
 };
 
 class OldGCTracer : public GCTracer {
--- a/src/share/vm/gc_implementation/shared/gcTraceSend.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/shared/gcTraceSend.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -111,6 +111,44 @@
   }
 }
 
+bool YoungGCTracer::should_send_promotion_in_new_plab_event() const {
+  return EventPromoteObjectInNewPLAB::is_enabled();
+}
+
+bool YoungGCTracer::should_send_promotion_outside_plab_event() const {
+  return EventPromoteObjectOutsidePLAB::is_enabled();
+}
+
+void YoungGCTracer::send_promotion_in_new_plab_event(Klass* klass, size_t obj_size,
+                                                     uint age, bool tenured,
+                                                     size_t plab_size) const {
+
+  EventPromoteObjectInNewPLAB event;
+  if (event.should_commit()) {
+    event.set_gcId(_shared_gc_info.gc_id().id());
+    event.set_class(klass);
+    event.set_objectSize(obj_size);
+    event.set_tenured(tenured);
+    event.set_tenuringAge(age);
+    event.set_plabSize(plab_size);
+    event.commit();
+  }
+}
+
+void YoungGCTracer::send_promotion_outside_plab_event(Klass* klass, size_t obj_size,
+                                                      uint age, bool tenured) const {
+
+  EventPromoteObjectOutsidePLAB event;
+  if (event.should_commit()) {
+    event.set_gcId(_shared_gc_info.gc_id().id());
+    event.set_class(klass);
+    event.set_objectSize(obj_size);
+    event.set_tenured(tenured);
+    event.set_tenuringAge(age);
+    event.commit();
+  }
+}
+
 void OldGCTracer::send_old_gc_event() const {
   EventGCOldGarbageCollection e(UNTIMED);
   if (e.should_commit()) {
--- a/src/share/vm/gc_implementation/shared/gcTraceTime.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/shared/gcTraceTime.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -49,10 +49,8 @@
   }
 
   if (_doit) {
-    if (PrintGCTimeStamps) {
-      gclog_or_tty->stamp();
-      gclog_or_tty->print(": ");
-    }
+    gclog_or_tty->date_stamp(PrintGCDateStamps);
+    gclog_or_tty->stamp(PrintGCTimeStamps);
     if (PrintGCID) {
       gclog_or_tty->print("#%u: ", gc_id.id());
     }
--- a/src/share/vm/gc_implementation/shared/generationCounters.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/shared/generationCounters.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -69,7 +69,7 @@
                      size_t min_capacity, size_t max_capacity, VirtualSpace* v);
 
   ~GenerationCounters() {
-    if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space, mtGC);
+    if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space);
   }
 
   virtual void update_all();
--- a/src/share/vm/gc_implementation/shared/hSpaceCounters.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/shared/hSpaceCounters.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014, 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,7 +54,7 @@
                  size_t initial_capacity, GenerationCounters* gc);
 
   ~HSpaceCounters() {
-    if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space, mtGC);
+    if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space);
   }
 
   inline void update_capacity(size_t v) {
--- a/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -276,7 +276,7 @@
       }
     }
 
-    FREE_C_HEAP_ARRAY(int, lgrp_ids, mtGC);
+    FREE_C_HEAP_ARRAY(int, lgrp_ids);
 
     if (changed) {
       for (JavaThread *thread = Threads::first(); thread; thread = thread->next()) {
--- a/src/share/vm/gc_implementation/shared/objectCountEventSender.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/shared/objectCountEventSender.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -29,8 +29,8 @@
 #include "memory/heapInspection.hpp"
 #include "trace/tracing.hpp"
 #include "utilities/globalDefinitions.hpp"
+#include "utilities/macros.hpp"
 #include "utilities/ticks.hpp"
-
 #if INCLUDE_SERVICES
 
 void ObjectCountEventSender::send(const KlassInfoEntry* entry, GCId gc_id, const Ticks& timestamp) {
--- a/src/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -142,216 +142,3 @@
              "FT"[_retained], _retained_filler.start(), _retained_filler.end());
 }
 #endif // !PRODUCT
-
-const size_t ParGCAllocBufferWithBOT::ChunkSizeInWords =
-MIN2(CardTableModRefBS::par_chunk_heapword_alignment(),
-     ((size_t)Generation::GenGrain)/HeapWordSize);
-const size_t ParGCAllocBufferWithBOT::ChunkSizeInBytes =
-MIN2(CardTableModRefBS::par_chunk_heapword_alignment() * HeapWordSize,
-     (size_t)Generation::GenGrain);
-
-ParGCAllocBufferWithBOT::ParGCAllocBufferWithBOT(size_t word_sz,
-                                                 BlockOffsetSharedArray* bsa) :
-  ParGCAllocBuffer(word_sz),
-  _bsa(bsa),
-  _bt(bsa, MemRegion(_bottom, _hard_end)),
-  _true_end(_hard_end)
-{}
-
-// The buffer comes with its own BOT, with a shared (obviously) underlying
-// BlockOffsetSharedArray. We manipulate this BOT in the normal way
-// as we would for any contiguous space. However, on occasion we
-// need to do some buffer surgery at the extremities before we
-// start using the body of the buffer for allocations. Such surgery
-// (as explained elsewhere) is to prevent allocation on a card that
-// is in the process of being walked concurrently by another GC thread.
-// When such surgery happens at a point that is far removed (to the
-// right of the current allocation point, top), we use the "contig"
-// parameter below to directly manipulate the shared array without
-// modifying the _next_threshold state in the BOT.
-void ParGCAllocBufferWithBOT::fill_region_with_block(MemRegion mr,
-                                                     bool contig) {
-  CollectedHeap::fill_with_object(mr);
-  if (contig) {
-    _bt.alloc_block(mr.start(), mr.end());
-  } else {
-    _bt.BlockOffsetArray::alloc_block(mr.start(), mr.end());
-  }
-}
-
-HeapWord* ParGCAllocBufferWithBOT::allocate_slow(size_t word_sz) {
-  HeapWord* res = NULL;
-  if (_true_end > _hard_end) {
-    assert((HeapWord*)align_size_down(intptr_t(_hard_end),
-                                      ChunkSizeInBytes) == _hard_end,
-           "or else _true_end should be equal to _hard_end");
-    assert(_retained, "or else _true_end should be equal to _hard_end");
-    assert(_retained_filler.end() <= _top, "INVARIANT");
-    CollectedHeap::fill_with_object(_retained_filler);
-    if (_top < _hard_end) {
-      fill_region_with_block(MemRegion(_top, _hard_end), true);
-    }
-    HeapWord* next_hard_end = MIN2(_true_end, _hard_end + ChunkSizeInWords);
-    _retained_filler = MemRegion(_hard_end, FillerHeaderSize);
-    _bt.alloc_block(_retained_filler.start(), _retained_filler.word_size());
-    _top      = _retained_filler.end();
-    _hard_end = next_hard_end;
-    _end      = _hard_end - AlignmentReserve;
-    res       = ParGCAllocBuffer::allocate(word_sz);
-    if (res != NULL) {
-      _bt.alloc_block(res, word_sz);
-    }
-  }
-  return res;
-}
-
-void
-ParGCAllocBufferWithBOT::undo_allocation(HeapWord* obj, size_t word_sz) {
-  ParGCAllocBuffer::undo_allocation(obj, word_sz);
-  // This may back us up beyond the previous threshold, so reset.
-  _bt.set_region(MemRegion(_top, _hard_end));
-  _bt.initialize_threshold();
-}
-
-void ParGCAllocBufferWithBOT::retire(bool end_of_gc, bool retain) {
-  assert(!retain || end_of_gc, "Can only retain at GC end.");
-  if (_retained) {
-    // We're about to make the retained_filler into a block.
-    _bt.BlockOffsetArray::alloc_block(_retained_filler.start(),
-                                      _retained_filler.end());
-  }
-  // Reset _hard_end to _true_end (and update _end)
-  if (retain && _hard_end != NULL) {
-    assert(_hard_end <= _true_end, "Invariant.");
-    _hard_end = _true_end;
-    _end      = MAX2(_top, _hard_end - AlignmentReserve);
-    assert(_end <= _hard_end, "Invariant.");
-  }
-  _true_end = _hard_end;
-  HeapWord* pre_top = _top;
-
-  ParGCAllocBuffer::retire(end_of_gc, retain);
-  // Now any old _retained_filler is cut back to size, the free part is
-  // filled with a filler object, and top is past the header of that
-  // object.
-
-  if (retain && _top < _end) {
-    assert(end_of_gc && retain, "Or else retain should be false.");
-    // If the lab does not start on a card boundary, we don't want to
-    // allocate onto that card, since that might lead to concurrent
-    // allocation and card scanning, which we don't support.  So we fill
-    // the first card with a garbage object.
-    size_t first_card_index = _bsa->index_for(pre_top);
-    HeapWord* first_card_start = _bsa->address_for_index(first_card_index);
-    if (first_card_start < pre_top) {
-      HeapWord* second_card_start =
-        _bsa->inc_by_region_size(first_card_start);
-
-      // Ensure enough room to fill with the smallest block
-      second_card_start = MAX2(second_card_start, pre_top + AlignmentReserve);
-
-      // If the end is already in the first card, don't go beyond it!
-      // Or if the remainder is too small for a filler object, gobble it up.
-      if (_hard_end < second_card_start ||
-          pointer_delta(_hard_end, second_card_start) < AlignmentReserve) {
-        second_card_start = _hard_end;
-      }
-      if (pre_top < second_card_start) {
-        MemRegion first_card_suffix(pre_top, second_card_start);
-        fill_region_with_block(first_card_suffix, true);
-      }
-      pre_top = second_card_start;
-      _top = pre_top;
-      _end = MAX2(_top, _hard_end - AlignmentReserve);
-    }
-
-    // If the lab does not end on a card boundary, we don't want to
-    // allocate onto that card, since that might lead to concurrent
-    // allocation and card scanning, which we don't support.  So we fill
-    // the last card with a garbage object.
-    size_t last_card_index = _bsa->index_for(_hard_end);
-    HeapWord* last_card_start = _bsa->address_for_index(last_card_index);
-    if (last_card_start < _hard_end) {
-
-      // Ensure enough room to fill with the smallest block
-      last_card_start = MIN2(last_card_start, _hard_end - AlignmentReserve);
-
-      // If the top is already in the last card, don't go back beyond it!
-      // Or if the remainder is too small for a filler object, gobble it up.
-      if (_top > last_card_start ||
-          pointer_delta(last_card_start, _top) < AlignmentReserve) {
-        last_card_start = _top;
-      }
-      if (last_card_start < _hard_end) {
-        MemRegion last_card_prefix(last_card_start, _hard_end);
-        fill_region_with_block(last_card_prefix, false);
-      }
-      _hard_end = last_card_start;
-      _end      = MAX2(_top, _hard_end - AlignmentReserve);
-      _true_end = _hard_end;
-      assert(_end <= _hard_end, "Invariant.");
-    }
-
-    // At this point:
-    //   1) we had a filler object from the original top to hard_end.
-    //   2) We've filled in any partial cards at the front and back.
-    if (pre_top < _hard_end) {
-      // Now we can reset the _bt to do allocation in the given area.
-      MemRegion new_filler(pre_top, _hard_end);
-      fill_region_with_block(new_filler, false);
-      _top = pre_top + ParGCAllocBuffer::FillerHeaderSize;
-      // If there's no space left, don't retain.
-      if (_top >= _end) {
-        _retained = false;
-        invalidate();
-        return;
-      }
-      _retained_filler = MemRegion(pre_top, _top);
-      _bt.set_region(MemRegion(_top, _hard_end));
-      _bt.initialize_threshold();
-      assert(_bt.threshold() > _top, "initialize_threshold failed!");
-
-      // There may be other reasons for queries into the middle of the
-      // filler object.  When such queries are done in parallel with
-      // allocation, bad things can happen, if the query involves object
-      // iteration.  So we ensure that such queries do not involve object
-      // iteration, by putting another filler object on the boundaries of
-      // such queries.  One such is the object spanning a parallel card
-      // chunk boundary.
-
-      // "chunk_boundary" is the address of the first chunk boundary less
-      // than "hard_end".
-      HeapWord* chunk_boundary =
-        (HeapWord*)align_size_down(intptr_t(_hard_end-1), ChunkSizeInBytes);
-      assert(chunk_boundary < _hard_end, "Or else above did not work.");
-      assert(pointer_delta(_true_end, chunk_boundary) >= AlignmentReserve,
-             "Consequence of last card handling above.");
-
-      if (_top <= chunk_boundary) {
-        assert(_true_end == _hard_end, "Invariant.");
-        while (_top <= chunk_boundary) {
-          assert(pointer_delta(_hard_end, chunk_boundary) >= AlignmentReserve,
-                 "Consequence of last card handling above.");
-          _bt.BlockOffsetArray::alloc_block(chunk_boundary, _hard_end);
-          CollectedHeap::fill_with_object(chunk_boundary, _hard_end);
-          _hard_end = chunk_boundary;
-          chunk_boundary -= ChunkSizeInWords;
-        }
-        _end = _hard_end - AlignmentReserve;
-        assert(_top <= _end, "Invariant.");
-        // Now reset the initial filler chunk so it doesn't overlap with
-        // the one(s) inserted above.
-        MemRegion new_filler(pre_top, _hard_end);
-        fill_region_with_block(new_filler, false);
-      }
-    } else {
-      _retained = false;
-      invalidate();
-    }
-  } else {
-    assert(!end_of_gc ||
-           (!_retained && _true_end == _hard_end), "Checking.");
-  }
-  assert(_end <= _hard_end, "Invariant.");
-  assert(_top < _end || _top == _hard_end, "Invariant");
-}
--- a/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -216,44 +216,4 @@
   }
 };
 
-class ParGCAllocBufferWithBOT: public ParGCAllocBuffer {
-  BlockOffsetArrayContigSpace _bt;
-  BlockOffsetSharedArray*     _bsa;
-  HeapWord*                   _true_end;  // end of the whole ParGCAllocBuffer
-
-  static const size_t ChunkSizeInWords;
-  static const size_t ChunkSizeInBytes;
-  HeapWord* allocate_slow(size_t word_sz);
-
-  void fill_region_with_block(MemRegion mr, bool contig);
-
-public:
-  ParGCAllocBufferWithBOT(size_t word_sz, BlockOffsetSharedArray* bsa);
-
-  HeapWord* allocate(size_t word_sz) {
-    HeapWord* res = ParGCAllocBuffer::allocate(word_sz);
-    if (res != NULL) {
-      _bt.alloc_block(res, word_sz);
-    } else {
-      res = allocate_slow(word_sz);
-    }
-    return res;
-  }
-
-  void undo_allocation(HeapWord* obj, size_t word_sz);
-
-  virtual void set_buf(HeapWord* buf_start) {
-    ParGCAllocBuffer::set_buf(buf_start);
-    _true_end = _hard_end;
-    _bt.set_region(MemRegion(buf_start, word_sz()));
-    _bt.initialize_threshold();
-  }
-
-  virtual void retire(bool end_of_gc, bool retain);
-
-  MemRegion range() {
-    return MemRegion(_top, _true_end);
-  }
-};
-
 #endif // SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARGCALLOCBUFFER_HPP
--- a/src/share/vm/gc_implementation/shared/spaceCounters.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_implementation/shared/spaceCounters.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2014, 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,7 @@
                 MutableSpace* m, GenerationCounters* gc);
 
   ~SpaceCounters() {
-    if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space, mtGC);
+    if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space);
   }
 
   inline void update_capacity() {
--- a/src/share/vm/gc_interface/gcCause.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_interface/gcCause.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -54,6 +54,9 @@
     case _wb_young_gc:
       return "WhiteBox Initiated Young GC";
 
+    case _wb_conc_mark:
+      return "WhiteBox Initiated Concurrent Mark";
+
     case _update_allocation_context_stats_inc:
     case _update_allocation_context_stats_full:
       return "Update Allocation Context Stats";
--- a/src/share/vm/gc_interface/gcCause.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/gc_interface/gcCause.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -47,6 +47,7 @@
     _heap_inspection,
     _heap_dump,
     _wb_young_gc,
+    _wb_conc_mark,
     _update_allocation_context_stats_inc,
     _update_allocation_context_stats_full,
 
--- a/src/share/vm/interpreter/oopMapCache.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/interpreter/oopMapCache.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -334,7 +334,7 @@
   if (mask_size() > small_mask_limit && _bit_mask[0] != 0) {
     assert(!Thread::current()->resource_area()->contains((void*)_bit_mask[0]),
       "This bit mask should not be in the resource area");
-    FREE_C_HEAP_ARRAY(uintptr_t, _bit_mask[0], mtClass);
+    FREE_C_HEAP_ARRAY(uintptr_t, _bit_mask[0]);
     debug_only(_bit_mask[0] = 0;)
   }
 }
@@ -492,7 +492,7 @@
   flush();
   // Deallocate array
   NOT_PRODUCT(_total_memory_usage -= sizeof(OopMapCache) + (sizeof(OopMapCacheEntry) * _size);)
-  FREE_C_HEAP_ARRAY(OopMapCacheEntry, _array, mtClass);
+  FREE_C_HEAP_ARRAY(OopMapCacheEntry, _array);
 }
 
 OopMapCacheEntry* OopMapCache::entry_at(int i) const {
@@ -603,5 +603,5 @@
   tmp->initialize();
   tmp->fill(method, bci);
   entry->resource_copy(tmp);
-  FREE_C_HEAP_ARRAY(OopMapCacheEntry, tmp, mtInternal);
+  FREE_C_HEAP_ARRAY(OopMapCacheEntry, tmp);
 }
--- a/src/share/vm/memory/allocation.cpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/memory/allocation.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -296,7 +296,7 @@
     // to avoid deadlock with NMT
         while(cur != NULL) {
           next = cur->next();
-      os::free(cur, mtChunk);
+      os::free(cur);
           cur = next;
         }
       }
@@ -384,7 +384,7 @@
    case Chunk::medium_size: ChunkPool::medium_pool()->free(c); break;
    case Chunk::init_size:   ChunkPool::small_pool()->free(c); break;
    case Chunk::tiny_size:   ChunkPool::tiny_pool()->free(c); break;
-   default:                 os::free(c, mtChunk);
+   default:                 os::free(c);
   }
 }
 
--- a/src/share/vm/memory/allocation.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/memory/allocation.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -101,7 +101,7 @@
 //   NEW_RESOURCE_OBJ(type)
 //   NEW_C_HEAP_ARRAY(type, size)
 //   NEW_C_HEAP_OBJ(type, memflags)
-//   FREE_C_HEAP_ARRAY(type, old, memflags)
+//   FREE_C_HEAP_ARRAY(type, old)
 //   FREE_C_HEAP_OBJ(objname, type, memflags)
 //   char* AllocateHeap(size_t size, const char* name);
 //   void  FreeHeap(void* p);
@@ -669,8 +669,8 @@
 #define REALLOC_C_HEAP_ARRAY_RETURN_NULL(type, old, size, memflags)\
   (type*) (ReallocateHeap((char*)(old), (size) * sizeof(type), memflags, AllocFailStrategy::RETURN_NULL))
 
-#define FREE_C_HEAP_ARRAY(type, old, memflags) \
-  FreeHeap((char*)(old), memflags)
+#define FREE_C_HEAP_ARRAY(type, old) \
+  FreeHeap((char*)(old))
 
 // allocate type in heap without calling ctor
 #define NEW_C_HEAP_OBJ(type, memflags)\
@@ -680,8 +680,8 @@
   NEW_C_HEAP_ARRAY_RETURN_NULL(type, 1, memflags)
 
 // deallocate obj of type in heap without calling dtor
-#define FREE_C_HEAP_OBJ(objname, memflags)\
-  FreeHeap((char*)objname, memflags);
+#define FREE_C_HEAP_OBJ(objname)\
+  FreeHeap((char*)objname);
 
 // for statistics
 #ifndef PRODUCT
--- a/src/share/vm/memory/allocation.inline.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/memory/allocation.inline.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -79,11 +79,11 @@
   return p;
 }
 
-inline void FreeHeap(void* p, MEMFLAGS memflags = mtInternal) {
+inline void FreeHeap(void* p) {
   #ifdef ASSERT
   if (PrintMallocFree) trace_heap_free(p);
   #endif
-  os::free(p, memflags);
+  os::free(p);
 }
 
 
@@ -136,11 +136,11 @@
 }
 
 template <MEMFLAGS F> void CHeapObj<F>::operator delete(void* p){
-    FreeHeap(p, F);
+    FreeHeap(p);
 }
 
 template <MEMFLAGS F> void CHeapObj<F>::operator delete [](void* p){
-    FreeHeap(p, F);
+    FreeHeap(p);
 }
 
 template <class E, MEMFLAGS F>
@@ -199,7 +199,7 @@
 void ArrayAllocator<E, F>::free() {
   if (_addr != NULL) {
     if (_use_malloc) {
-      FreeHeap(_addr, F);
+      FreeHeap(_addr);
     } else {
       os::release_memory(_addr, _size);
     }
--- a/src/share/vm/memory/blockOffsetTable.hpp	Wed Dec 10 13:58:30 2014 +0000
+++ b/src/share/vm/memory/blockOffsetTable.hpp	Fri Dec 12 21:32:43 2014 +0300
@@ -251,12 +251,6 @@
   // Return the address indicating the start of the region corresponding to
   // "index" in "_offset_array".
   HeapWord* address_for_index(size_t index) const;
-
-  // Return the address "p" incremented by the size of
-  // a region.  This method does not align the address
-  // returned to the start of a region.  It is a simple
-  // primitive.
-  HeapWord* inc_by_region_size(HeapWord* p) const { return p + N_words; }
 };
 
 //////////////////////////////////////////////////////////////////////////
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/memory/cardGeneration.cpp	Fri Dec 12 21:32:43 2014 +0300
@@ -0,0 +1,360 @@
+/*
+ * Copyright (c) 2014, 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 "memory/blockOffsetTable.inline.hpp"
+#include "memory/cardGeneration.inline.hpp"
+#include "memory/gcLocker.hpp"
+#include "memory/generationSpec.hpp"
+#include "memory/genOopClosures.inline.hpp"
+#include "memory/genRemSet.hpp"
+#include "memory/iterator.hpp"
+#include "memory/memRegion.hpp"
+#include "memory/space.inline.hpp"
+#include "runtime/java.hpp"
+
+CardGeneration::CardGeneration(ReservedSpace rs, size_t initial_byte_size,
+                               int level,
+                               GenRemSet* remset) :
+  Generation(rs, initial_byte_size, level), _rs(remset),
+  _shrink_factor(0), _min_heap_delta_bytes(), _capacity_at_prologue(),
+  _used_at_prologue()
+{
+  HeapWord* start = (HeapWord*)rs.base();
+  size_t reserved_byte_size = rs.size();
+  assert((uintptr_t(start) & 3) == 0, "bad alignment");
+  assert((reserved_byte_size & 3) == 0, "bad alignment");
+  MemRegion reserved_mr(start, heap_word_size(reserved_byte_size));
+  _bts = new BlockOffsetSharedArray(reserved_mr,
+                                    heap_word_size(initial_byte_size));
+  MemRegion committed_mr(start, heap_word_size(initial_byte_size));
+  _rs->resize_covered_region(committed_mr);
+  if (_bts == NULL) {
+    vm_exit_during_initialization("Could not allocate a BlockOffsetArray");
+  }
+
+  // Verify that the start and end of this generation is the start of a card.
+  // If this wasn't true, a single card could span more than on generation,
+  // which would cause problems when we commit/uncommit memory, and when we
+  // clear and dirty cards.
+  guarantee(_rs->is_aligned(reserved_mr.start()), "generation must be card aligned");
+  if (reserved_mr.end() != Universe::heap()->reserved_region().end()) {
+    // Don't check at the very end of the heap as we'll assert that we're probing off
+    // the end if we try.
+    guarantee(_rs->is_aligned(reserved_mr.end()), "generation must be card aligned");
+  }
+  _min_heap_delta_bytes = MinHeapDeltaBytes;
+  _capacity_at_prologue = initial_byte_size;
+  _used_at_prologue = 0;
+}
+
+bool CardGeneration::grow_by(size_t bytes) {
+  assert_correct_size_change_locking();
+  bool result = _virtual_space.expand_by(bytes);
+  if (result) {
+    size_t new_word_size =
+       heap_word_size(_virtual_space.committed_size());
+    MemRegion mr(space()->bottom(), new_word_size);
+    // Expand card table
+    Universe::heap()->barrier_set()->resize_covered_region(mr);
+    // Expand shared block offset array
+    _bts->resize(new_word_size);
+
+    // Fix for bug #4668531
+    if (ZapUnusedHeapArea) {
+      MemRegion mangle_region(space()->end(),
+      (HeapWord*)_virtual_space.high());
+      SpaceMangler::mangle_region(mangle_region);
+    }
+
+    // Expand space -- also expands space's BOT
+    // (which uses (part of) shared array above)
+    space()->set_end((HeapWord*)_virtual_space.high());
+
+    // update the space and generation capacity counters
+    update_counters();
+
+    if (Verbose && PrintGC) {
+      size_t new_mem_size = _virtual_space.committed_size();
+      size_t old_mem_size = new_mem_size - bytes;
+      gclog_or_tty->print_cr("Expanding %s from " SIZE_FORMAT "K by "
+                      SIZE_FORMAT "K to " SIZE_FORMAT "K",
+                      name(), old_mem_size/K, bytes/K, new_mem_size/K);
+    }
+  }
+  return result;
+}
+
+bool CardGeneration::expand(size_t bytes, size_t expand_bytes) {
+  assert_locked_or_safepoint(Heap_lock);
+  if (bytes == 0) {
+    return true;  // That's what grow_by(0) would return
+  }
+  size_t aligned_bytes  = ReservedSpace::page_align_size_up(bytes);
+  if (aligned_bytes == 0){
+    // The alignment caused the number of bytes to wrap.  An expand_by(0) will
+    // return true with the implication that an expansion was done when it
+    // was not.  A call to expand implies a best effort to expand by "bytes"
+    // but not a guarantee.  Align down to give a best effort.  This is likely
+    // the most that the generation can expand since it has some capacity to
+    // start with.
+    aligned_bytes = ReservedSpace::page_align_size_down(bytes);
+  }
+  size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes);
+  bool success = false;
+  if (aligned_expand_bytes > aligned_bytes) {
+    success = grow_by(aligned_expand_bytes);
+  }
+  if (!success) {
+    success = grow_by(aligned_bytes);
+  }
+  if (!success) {
+    success = grow_to_reserved();
+  }
+  if (PrintGC && Verbose) {
+    if (success && GC_locker::is_active_and_needs_gc()) {
+      gclog_or_tty->print_cr("Garbage collection disabled, expanded heap instead");
+    }
+  }
+
+  return success;
+}
+
+bool CardGeneration::grow_to_reserved() {
+  assert_correct_size_change_locking();
+  bool success = true;
+  const size_t remaining_bytes = _virtual_space.uncommitted_size();
+  if (remaining_bytes > 0) {
+    success = grow_by(remaining_bytes);
+    DEBUG_ONLY(if (!success) warning("grow to reserved failed");)
+  }
+  return success;
+}
+
+void CardGeneration::shrink(size_t bytes) {
+  assert_correct_size_change_locking();
+
+  size_t size = ReservedSpace::page_align_size_down(bytes);
+  if (size == 0) {
+    return;
+  }
+
+  // Shrink committed space
+  _virtual_space.shrink_by(size);
+  // Shrink space; this also shrinks the space's BOT
+  space()->set_end((HeapWord*) _virtual_space.high());
+  size_t new_word_size = heap_word_size(space()->capacity());
+  // Shrink the shared block offset array
+  _bts->resize(new_word_size);
+  MemRegion mr(space()->bottom(), new_word_size);
+  // Shrink the card table
+  Universe::heap()->barrier_set()->resize_covered_region(mr);
+
+  if (Verbose && PrintGC) {
+    size_t new_mem_size = _virtual_space.committed_size();
+    size_t old_mem_size = new_mem_size + size;
+    gclog_or_tty->print_cr("Shrinking %s from " SIZE_FORMAT "K to " SIZE_FORMAT "K",
+                  name(), old_mem_size/K, new_mem_size/K);
+  }
+}
+
+// No young generation references, clear this generation's cards.
+void CardGeneration::clear_remembered_set() {
+  _rs->clear(reserved());
+}
+
+// Objects in this generation may have moved, invalidate this
+// generation's cards.
+void CardGeneration::invalidate_remembered_set() {
+  _rs->invalidate(used_region());
+}
+
+void CardGeneration::compute_new_size() {
+  assert(_shrink_factor <= 100, "invalid shrink factor");
+  size_t current_shrink_factor = _shrink_factor;
+  _shrink_factor = 0;
+
+  // We don't have floating point command-line arguments
+  // Note:  argument processing ensures that MinHeapFreeRatio < 100.
+  const double minimum_free_percentage = MinHeapFreeRatio / 100.0;
+  const double maximum_used_percentage = 1.0 - minimum_free_percentage;
+
+  // Compute some numbers about the state of the heap.
+  const size_t used_after_gc = used();
+  const size_t capacity_after_gc = capacity();
+
+  const double min_tmp = used_after_gc / maximum_used_percentage;
+  size_t minimum_desired_capacity = (size_t)MIN2(min_tmp, double(max_uintx));
+  // Don't shrink less than the initial generation size
+  minimum_desired_capacity = MAX2(minimum_desired_capacity,
+                                  spec()->init_size());
+  assert(used_after_gc <= minimum_desired_capacity, "sanity check");
+
+  if (PrintGC && Verbose) {
+    const size_t free_after_gc = free();
+    const double free_percentage = ((double)free_after_gc) / capacity_after_gc;
+    gclog_or_tty->print_cr("TenuredGeneration::compute_new_size: ");
+    gclog_or_tty->print_cr("  "
+                  "  minimum_free_percentage: %6.2f"
+                  "  maximum_used_percentage: %6.2f",
+                  minimum_free_percentage,
+                  maximum_used_percentage);
+    gclog_or_tty->print_cr("  "
+                  "   free_after_gc   : %6.1fK"
+                  "   used_after_gc   : %6.1fK"
+                  "   capacity_after_gc   : %6.1fK",
+                  free_after_gc / (double) K,
+                  used_after_gc / (double) K,
+                  capacity_after_gc / (double) K);
+    gclog_or_tty->print_cr("  "
+                  "   free_percentage: %6.2f",
+                  free_percentage);
+  }
+
+  if (capacity_after_gc < minimum_desired_capacity) {
+    // If we have less free space than we want then expand
+    size_t expand_bytes = minimum_desired_capacity - capacity_after_gc;
+    // Don't expand unless it's significant
+    if (expand_bytes >= _min_heap_delta_bytes) {
+      expand(expand_bytes, 0); // safe if expansion fails
+    }
+    if (PrintGC && Verbose) {
+      gclog_or_tty->print_cr("    expanding:"
+                    "  minimum_desired_capacity: %6.1fK"
+                    "  expand_bytes: %6.1fK"
+                    "  _min_heap_delta_bytes: %6.1fK",
+                    minimum_desired_capacity / (double) K,
+                    expand_bytes / (double) K,
+                    _min_heap_delta_bytes / (double) K);
+    }