changeset 5550:7020d6309d02

Merge
author goetz
date Mon, 07 Jul 2014 08:54:46 +0200
parents 1fb2b8c1442c (current diff) 13f561930b3e (diff)
children 2db9d0890cba
files .hgtags make/hotspot_version make/linux/makefiles/buildtree.make make/linux/makefiles/gcc.make make/linux/makefiles/vm.make src/cpu/sparc/vm/sparc.ad src/cpu/x86/vm/globals_x86.hpp src/cpu/x86/vm/x86_32.ad src/cpu/x86/vm/x86_64.ad src/os/bsd/vm/os_bsd.cpp src/os/linux/vm/os_linux.cpp src/os/linux/vm/os_linux.hpp src/share/vm/classfile/javaClasses.cpp src/share/vm/code/nmethod.cpp src/share/vm/code/nmethod.hpp src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp src/share/vm/gc_interface/collectedHeap.cpp src/share/vm/interpreter/interpreterRuntime.cpp src/share/vm/interpreter/interpreterRuntime.hpp src/share/vm/memory/cardTableModRefBS.cpp src/share/vm/memory/cardTableModRefBS.hpp src/share/vm/memory/collectorPolicy.cpp src/share/vm/memory/defNewGeneration.cpp src/share/vm/memory/universe.cpp src/share/vm/oops/instanceKlass.cpp src/share/vm/opto/compile.cpp src/share/vm/opto/compile.hpp src/share/vm/opto/graphKit.cpp src/share/vm/opto/loopTransform.cpp src/share/vm/opto/matcher.cpp src/share/vm/opto/memnode.cpp src/share/vm/opto/memnode.hpp src/share/vm/opto/output.cpp src/share/vm/prims/jni.cpp src/share/vm/prims/methodHandles.cpp src/share/vm/runtime/arguments.cpp src/share/vm/runtime/globals.hpp src/share/vm/runtime/mutexLocker.cpp src/share/vm/runtime/mutexLocker.hpp src/share/vm/runtime/os.hpp src/share/vm/runtime/sweeper.cpp src/share/vm/runtime/thread.cpp src/share/vm/runtime/virtualspace.cpp src/share/vm/runtime/vmThread.cpp src/share/vm/runtime/vm_operations.cpp src/share/vm/utilities/globalDefinitions.hpp test/gc/TestVerifyBeforeGCDuringStartup.java
diffstat 193 files changed, 7595 insertions(+), 1900 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Thu May 08 16:16:21 2014 +0200
+++ b/.hgtags	Mon Jul 07 08:54:46 2014 +0200
@@ -599,6 +599,7 @@
 cc83359f5e5eb46dd9176b0a272390b1a0a51fdc hs24.60-b01
 c373a733d5d5147f99eaa2b91d6b937c28214fc9 jdk7u45-b33
 0bcb43482f2ac5615437541ffb8dc0f79ece3148 jdk7u45-b34
+12ea8d416f105f5971c808c89dddc1006bfc4c53 jdk7u45-b35
 429884602206fcf5314c8b953c06d54d337558ca jdk7u51-b00
 68f03ff066f2341b89b52a6d6e21ae09de008351 jdk7u51-b01
 67910a581eca113847c5320c49436a9816c5d5c6 jdk7u51-b02
@@ -613,3 +614,54 @@
 1f11dff734af98f5bf11d4fceeda221ab1416971 jdk7u51-b11
 dee2a38ef6b26534c44c550ef4da2c3146c612c2 jdk7u51-b12
 6c6a2299029ad02fa2820b8ff8c61c2bbcae799c jdk7u51-b13
+a398ddc79d2310ad37b131cc3794b3cf574f088e jdk7u51-b30
+cf4110c35afb10456d8264c47b7cde1c20150cab jdk7u51-b31
+208419914859dd77abdb5ec755b32c237ee6e4eb jdk7u51-b33
+f8457a75bdb5052f1d8c547027a926f9b755b808 jdk7u51-b34
+dee2a38ef6b26534c44c550ef4da2c3146c612c2 jdk7u55-b00
+ac0063b4452bc724e8648e64f4b2d495054bb308 jdk7u55-b01
+408028d410e316a99495c42df0031018890c22fe jdk7u55-b02
+50fb91504dd8cdf410eb956075442daf3aacf1db jdk7u55-b03
+3be3b8a032a5508646c1c5620cee18d3e69fc708 jdk7u55-b04
+b86119fa2748bd91ae4984ff2264da92b6626f8c jdk7u55-b05
+260d919d52e500a0b20f911fade2a7710474067a jdk7u55-b06
+8cf6e0a3a0651c4132ae034c2b68ddf4eb5c4d88 jdk7u55-b07
+049fd2cef85bf2d557dd7dd8a90a6831a8168ce4 jdk7u55-b08
+9b238ab164e6d1cf9cfb560827d88ef8a7d8c898 jdk7u55-b09
+573d8d080af9eff48aa3b8f0696d8874ce36fbb1 jdk7u55-b09
+36f8bd4dd467ae4183340842fd7158ac3309b826 jdk7u55-b10
+49cada8e39b9215b9fd8b9183743f92625587cfc jdk7u55-b11
+aadc864abd1ced3049bf59ce32786a07997ba190 jdk7u55-b12
+b021fd817a0177b31d1e3d65127a27458e85801e jdk7u55-b13
+d27b468d5f3be3329ff1ff342f3347e6b2e0303b jdk7u55-b30
+dff9147a781672f20bb0577a94233264ea4a95d1 jdk7u55-b14
+8175599864880938d68d0a515fa561043d7d5fd0 jdk7u55-b31
+ae4adc1492d1c90a70bd2d139a939fc0c8329be9 jdk7u60-b00
+af1fc2868a2b919727bfbb0858449bd991bbee4a jdk7u40-b60
+cc83359f5e5eb46dd9176b0a272390b1a0a51fdc hs24.60-b01
+b7d44793cd267b22352c688b0185466741bb7a89 hs24.60-b02
+90cfd4ad3c9263886d876792d72cb24ac0e03a85 hs24.60-b03
+8fd0e931efa57d1579fb1bc8a68ba3924244b99e jdk7u60-b01
+99e96aaac8afc14ce6f9f3d92ef7004cf505b35d hs24.60-b04
+0025a2a965c8f21376278245c2493d8861386fba jdk7u60-b02
+fa59add77d1a8f601a695f137248462fdc68cc2f hs24.60-b05
+a59134ccb1b704b2cd05e157970d425af43e5437 hs24.60-b06
+2c971ed884cec0a9293ccff3def696da81823225 jdk7u60-b03
+1afbeb8cb558429156d432f35e7582716053a9cb hs24.60-b07
+05fe7a87d14908eb3f21a0d29fc72cee2f996b7f jdk7u60-b04
+f52b5452d424545e3b101d808e6d7da763d6f0f3 hs24.60-b08
+462db155547e9bdd7ba26bead42808deb0b10d44 jdk7u60-b05
+0cc4550bd9c57ba3be343bfbfcaf46b9060d5e7d jdk7u60-b06
+2d053c4fd767155b2ac5e3e0a60b08a1bcc73cab jdk7u60-b07
+a198787e7b9bc7b831ad210b67732cdb2be9e46e jdk7u60-b08
+22cae361773d14b467328e8f90cf893550d1d610 jdk7u60-b09
+6f74afd8577eb4b6a0e6f7b25cfef7d6f7d92e5f jdk7u60-b10
+a2ac67a2c1cc867a8d6b525ab1df17204186e636 jdk7u60-b11
+cae50351dcece6e5bf215eabf958c5d669ffff1f jdk7u60-b12
+5853131ba4b448c5d89a3f0aa501fdf07f3b473c jdk7u60-b13
+b226be2040f971855626f5b88cb41a7d5299fea0 jdk7u60-b14
+2871f345b7e5585e20dc7aa91035967fe774cfba jdk7u60-b15
+ec76bacbb5b90efc7988dee5345c656126b97561 jdk7u60-b16
+617a6338e0c4f7699eed5061d7e8f576c3ace029 jdk7u60-b18
+617a6338e0c4f7699eed5061d7e8f576c3ace029 jdk7u60-b17
+361493c7cdb5f75b28efc63389d6cebaaaa43a2c jdk7u60-b19
--- a/agent/src/os/linux/ps_core.c	Thu May 08 16:16:21 2014 +0200
+++ b/agent/src/os/linux/ps_core.c	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, 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
@@ -700,29 +700,61 @@
 
 // read segments of a shared object
 static bool read_lib_segments(struct ps_prochandle* ph, int lib_fd, ELF_EHDR* lib_ehdr, uintptr_t lib_base) {
-   int i = 0;
-   ELF_PHDR* phbuf;
-   ELF_PHDR* lib_php = NULL;
+  int i = 0;
+  ELF_PHDR* phbuf;
+  ELF_PHDR* lib_php = NULL;
+
+  int page_size = sysconf(_SC_PAGE_SIZE);
+
+  if ((phbuf = read_program_header_table(lib_fd, lib_ehdr)) == NULL) {
+    return false;
+  }
 
-   if ((phbuf = read_program_header_table(lib_fd, lib_ehdr)) == NULL)
-      return false;
+  // we want to process only PT_LOAD segments that are not writable.
+  // i.e., text segments. The read/write/exec (data) segments would
+  // have been already added from core file segments.
+  for (lib_php = phbuf, i = 0; i < lib_ehdr->e_phnum; i++) {
+    if ((lib_php->p_type == PT_LOAD) && !(lib_php->p_flags & PF_W) && (lib_php->p_filesz != 0)) {
+
+      uintptr_t target_vaddr = lib_php->p_vaddr + lib_base;
+      map_info *existing_map = core_lookup(ph, target_vaddr);
+
+      if (existing_map == NULL){
+        if (add_map_info(ph, lib_fd, lib_php->p_offset,
+                          target_vaddr, lib_php->p_memsz) == NULL) {
+          goto err;
+        }
+      } else {
+        // Coredump stores value of p_memsz elf field
+        // rounded up to page boundary.
 
-   // we want to process only PT_LOAD segments that are not writable.
-   // i.e., text segments. The read/write/exec (data) segments would
-   // have been already added from core file segments.
-   for (lib_php = phbuf, i = 0; i < lib_ehdr->e_phnum; i++) {
-      if ((lib_php->p_type == PT_LOAD) && !(lib_php->p_flags & PF_W) && (lib_php->p_filesz != 0)) {
-         if (add_map_info(ph, lib_fd, lib_php->p_offset, lib_php->p_vaddr + lib_base, lib_php->p_filesz) == NULL)
-            goto err;
+        if ((existing_map->memsz != page_size) &&
+            (existing_map->fd != lib_fd) &&
+            (ROUNDUP(existing_map->memsz, page_size) != ROUNDUP(lib_php->p_memsz, page_size))) {
+
+          print_debug("address conflict @ 0x%lx (existing map size = %ld, size = %ld, flags = %d)\n",
+                        target_vaddr, existing_map->memsz, lib_php->p_memsz, lib_php->p_flags);
+          goto err;
+        }
+
+        /* replace PT_LOAD segment with library segment */
+        print_debug("overwrote with new address mapping (memsz %ld -> %ld)\n",
+                     existing_map->memsz, ROUNDUP(lib_php->p_memsz, page_size));
+
+        existing_map->fd = lib_fd;
+        existing_map->offset = lib_php->p_offset;
+        existing_map->memsz = ROUNDUP(lib_php->p_memsz, page_size);
       }
-      lib_php++;
-   }
+    }
+
+    lib_php++;
+  }
 
-   free(phbuf);
-   return true;
+  free(phbuf);
+  return true;
 err:
-   free(phbuf);
-   return false;
+  free(phbuf);
+  return false;
 }
 
 // process segments from interpreter (ld.so or ld-linux.so)
--- a/agent/src/share/classes/sun/jvm/hotspot/interpreter/Bytecodes.java	Thu May 08 16:16:21 2014 +0200
+++ b/agent/src/share/classes/sun/jvm/hotspot/interpreter/Bytecodes.java	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, 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
@@ -272,9 +272,10 @@
   public static final int _fast_aldc            = 229;
   public static final int _fast_aldc_w          = 230;
   public static final int _return_register_finalizer = 231;
-  public static final int _shouldnotreachhere   = 232; // For debugging
+  public static final int _invokehandle         = 232;
+  public static final int _shouldnotreachhere   = 233; // For debugging
 
-  public static final int number_of_codes       = 233;
+  public static final int number_of_codes       = 234;
 
   // Flag bits derived from format strings, can_trap, can_rewrite, etc.:
   // semantic flags:
@@ -798,6 +799,9 @@
 
     def(_return_register_finalizer, "return_register_finalizer", "b"    , null    , BasicType.getTVoid()   , 0, true, _return );
 
+    def(_invokehandle        , "invokehandle"        , "bJJ"  , null    , BasicType.getTIllegal(), -1, true, _invokevirtual   );
+
+
     def(_fast_aldc           , "fast_aldc"           , "bj"   , null    , BasicType.getTObject(),   1, true,  _ldc   );
     def(_fast_aldc_w         , "fast_aldc_w"         , "bJJ"  , null    , BasicType.getTObject(),   1, true,  _ldc_w );
 
--- a/make/bsd/makefiles/arm.make	Thu May 08 16:16:21 2014 +0200
+++ b/make/bsd/makefiles/arm.make	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2008, 2013, 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,6 +24,8 @@
 
 Obj_Files += bsd_arm.o
 
-LIBS += $(EXT_LIBS_PATH)/sflt_glibc.a 
+ifneq ($(EXT_LIBS_PATH),)
+  LIBS += $(EXT_LIBS_PATH)/sflt_glibc.a 
+endif
 
 CFLAGS += -DVM_LITTLE_ENDIAN
--- a/make/bsd/makefiles/buildtree.make	Thu May 08 16:16:21 2014 +0200
+++ b/make/bsd/makefiles/buildtree.make	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,6 @@
 #
 # Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013 Red Hat, Inc.
 # 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 +60,7 @@
 # needs to be set here since this Makefile doesn't include defs.make
 OS_VENDOR:=$(shell uname -s)
 
--include $(SPEC)
+include $(GAMMADIR)/make/defs.make
 include $(GAMMADIR)/make/scm.make
 include $(GAMMADIR)/make/altsrc.make
 
@@ -215,6 +216,7 @@
 	echo "HOTSPOT_BUILD_USER = $(HOTSPOT_BUILD_USER)"; \
 	echo "HOTSPOT_VM_DISTRO = $(HOTSPOT_VM_DISTRO)"; \
 	echo "OPENJDK = $(OPENJDK)"; \
+	echo "ZERO_BUILD = $(ZERO_BUILD)"; \
 	echo; \
 	echo "# Used for platform dispatching"; \
 	echo "TARGET_DEFINES  = -DTARGET_OS_FAMILY_\$$(Platform_os_family)"; \
--- a/make/bsd/makefiles/gcc.make	Thu May 08 16:16:21 2014 +0200
+++ b/make/bsd/makefiles/gcc.make	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,6 @@
 #
 # Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013 Red Hat, Inc.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -105,10 +106,10 @@
 VM_PICFLAG/AOUT   =
 VM_PICFLAG        = $(VM_PICFLAG/$(LINK_INTO))
 
-ifeq ($(JVM_VARIANT_ZERO), true)
+ifeq ($(TYPE),ZERO)
   CFLAGS += $(LIBFFI_CFLAGS)
 endif
-ifeq ($(JVM_VARIANT_ZEROSHARK), true)
+ifeq ($(TYPE),SHARK)
   CFLAGS += $(LIBFFI_CFLAGS)
   CFLAGS += $(LLVM_CFLAGS)
 endif
--- a/make/bsd/makefiles/vm.make	Thu May 08 16:16:21 2014 +0200
+++ b/make/bsd/makefiles/vm.make	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,6 @@
 #
 # Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013 Red Hat, Inc.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -42,7 +43,9 @@
 -include $(DEP_DIR)/*.d
 
 # read machine-specific adjustments (%%% should do this via buildtree.make?)
-ifeq ($(findstring true, $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
+ifeq ($(TYPE),ZERO)
+  include $(MAKEFILES_DIR)/zeroshark.make
+else ifeq ($(TYPE),SHARK)
   include $(MAKEFILES_DIR)/zeroshark.make
 else
   include $(MAKEFILES_DIR)/$(BUILDARCH).make
@@ -271,10 +274,10 @@
 
   LIBS_VM                  += $(LIBS)
 endif
-ifeq ($(JVM_VARIANT_ZERO), true)
+ifeq ($(TYPE),ZERO)
   LIBS_VM += $(LIBFFI_LIBS)
 endif
-ifeq ($(JVM_VARIANT_ZEROSHARK), true)
+ifeq ($(TYPE),SHARK)
   LIBS_VM   += $(LIBFFI_LIBS) $(LLVM_LIBS)
   LFLAGS_VM += $(LLVM_LDFLAGS)
 endif
--- a/make/hotspot_version	Thu May 08 16:16:21 2014 +0200
+++ b/make/hotspot_version	Mon Jul 07 08:54:46 2014 +0200
@@ -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
@@ -31,11 +31,11 @@
 #
 
 # Don't put quotes (fail windows build).
-HOTSPOT_VM_COPYRIGHT=Copyright 2013
+HOTSPOT_VM_COPYRIGHT=Copyright 2014
 
 HS_MAJOR_VER=24
-HS_MINOR_VER=51
-HS_BUILD_NUMBER=03
+HS_MINOR_VER=60
+HS_BUILD_NUMBER=09
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=7
--- a/make/linux/makefiles/arm.make	Thu May 08 16:16:21 2014 +0200
+++ b/make/linux/makefiles/arm.make	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2008, 2013, 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,6 +24,8 @@
 
 Obj_Files += linux_arm.o
 
-LIBS += $(EXT_LIBS_PATH)/sflt_glibc.a 
+ifneq ($(EXT_LIBS_PATH),)
+  LIBS += $(EXT_LIBS_PATH)/sflt_glibc.a 
+endif
 
 CFLAGS += -DVM_LITTLE_ENDIAN
--- a/make/linux/makefiles/buildtree.make	Thu May 08 16:16:21 2014 +0200
+++ b/make/linux/makefiles/buildtree.make	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,6 @@
 #
 # Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013 Red Hat, Inc.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -57,7 +58,7 @@
 # The makefiles are split this way so that "make foo" will run faster by not
 # having to read the dependency files for the vm.
 
--include $(SPEC)
+include $(GAMMADIR)/make/defs.make
 include $(GAMMADIR)/make/scm.make
 include $(GAMMADIR)/make/altsrc.make
 
@@ -211,6 +212,7 @@
 	echo "HOTSPOT_VM_DISTRO = $(HOTSPOT_VM_DISTRO)"; \
 	echo "OPENJDK = $(OPENJDK)"; \
 	echo "OPENJDK_TARGET_CPU_ENDIAN = $(OPENJDK_TARGET_CPU_ENDIAN)"; \
+	echo "ZERO_BUILD = $(ZERO_BUILD)"; \
 	echo; \
 	echo "# Used for platform dispatching"; \
 	echo "TARGET_DEFINES  = -DTARGET_OS_FAMILY_\$$(Platform_os_family)"; \
--- a/make/linux/makefiles/gcc.make	Thu May 08 16:16:21 2014 +0200
+++ b/make/linux/makefiles/gcc.make	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,6 @@
 #
 # Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013 Red Hat, Inc.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -72,10 +73,10 @@
 VM_PICFLAG/AOUT   =
 VM_PICFLAG        = $(VM_PICFLAG/$(LINK_INTO))
 
-ifeq ($(JVM_VARIANT_ZERO), true)
+ifeq ($(TYPE),ZERO)
 CFLAGS += $(LIBFFI_CFLAGS)
 endif
-ifeq ($(JVM_VARIANT_ZEROSHARK), true)
+ifeq ($(TYPE),SHARK)
 CFLAGS += $(LIBFFI_CFLAGS)
 CFLAGS += $(LLVM_CFLAGS)
 endif
--- a/make/linux/makefiles/vm.make	Thu May 08 16:16:21 2014 +0200
+++ b/make/linux/makefiles/vm.make	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,6 @@
 #
 # Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013 Red Hat, Inc.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -42,7 +43,9 @@
 -include $(DEP_DIR)/*.d
 
 # read machine-specific adjustments (%%% should do this via buildtree.make?)
-ifeq ($(findstring true, $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
+ifeq ($(TYPE),ZERO)
+  include $(MAKEFILES_DIR)/zeroshark.make
+else ifeq ($(TYPE),SHARK)
   include $(MAKEFILES_DIR)/zeroshark.make
 else
   include $(MAKEFILES_DIR)/$(BUILDARCH).make
@@ -244,7 +247,7 @@
 vm.def: $(Res_Files) $(Obj_Files)
 	sh $(GAMMADIR)/make/linux/makefiles/build_vm_def.sh *.o > $@
 
-ifeq ($(JVM_VARIANT_ZEROSHARK), true)
+ifeq ($(TYPE),SHARK)
   STATIC_CXX = false
 else
   ifeq ($(ZERO_LIBARCH), ppc64)
@@ -276,10 +279,10 @@
 
   LIBS_VM                  += $(LIBS)
 endif
-ifeq ($(JVM_VARIANT_ZERO), true)
+ifeq ($(TYPE),ZERO)
   LIBS_VM += $(LIBFFI_LIBS)
 endif
-ifeq ($(JVM_VARIANT_ZEROSHARK), true)
+ifeq ($(TYPE),SHARK)
   LIBS_VM   += $(LIBFFI_LIBS) $(LLVM_LIBS)
   LFLAGS_VM += $(LLVM_LDFLAGS)
 endif
--- a/src/cpu/sparc/vm/assembler_sparc.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/cpu/sparc/vm/assembler_sparc.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -4512,7 +4512,7 @@
 #define __ masm.
   address start = __ pc();
 
-  Label not_already_dirty, restart, refill;
+  Label not_already_dirty, restart, refill, young_card;
 
 #ifdef _LP64
   __ srlx(O0, CardTableModRefBS::card_shift, O0);
@@ -4523,9 +4523,15 @@
   __ set(addrlit, O1); // O1 := <card table base>
   __ ldub(O0, O1, O2); // O2 := [O0 + O1]
 
+  __ cmp_and_br_short(O2, G1SATBCardTableModRefBS::g1_young_card_val(), Assembler::equal, Assembler::pt, young_card);
+
+  __ membar(Assembler::Membar_mask_bits(Assembler::StoreLoad));
+  __ ldub(O0, O1, O2); // O2 := [O0 + O1]
+
   assert(CardTableModRefBS::dirty_card_val() == 0, "otherwise check this code");
   __ cmp_and_br_short(O2, G0, Assembler::notEqual, Assembler::pt, not_already_dirty);
 
+  __ bind(young_card);
   // We didn't take the branch, so we're already dirty: return.
   // Use return-from-leaf
   __ retl();
--- a/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -36,6 +36,9 @@
 #include "runtime/signature.hpp"
 #include "runtime/vframeArray.hpp"
 #include "vmreg_sparc.inline.hpp"
+#ifndef SERIALGC
+#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
+#endif
 
 // Implementation of StubAssembler
 
@@ -898,7 +901,7 @@
         Register tmp2 = G3_scratch;
         jbyte* byte_map_base = ((CardTableModRefBS*)bs)->byte_map_base;
 
-        Label not_already_dirty, restart, refill;
+        Label not_already_dirty, restart, refill, young_card;
 
 #ifdef _LP64
         __ srlx(addr, CardTableModRefBS::card_shift, addr);
@@ -910,9 +913,15 @@
         __ set(rs, cardtable);         // cardtable := <card table base>
         __ ldub(addr, cardtable, tmp); // tmp := [addr + cardtable]
 
+        __ cmp_and_br_short(tmp, G1SATBCardTableModRefBS::g1_young_card_val(), Assembler::equal, Assembler::pt, young_card);
+
+        __ membar(Assembler::Membar_mask_bits(Assembler::StoreLoad));
+        __ ldub(addr, cardtable, tmp); // tmp := [addr + cardtable]
+
         assert(CardTableModRefBS::dirty_card_val() == 0, "otherwise check this code");
         __ cmp_and_br_short(tmp, G0, Assembler::notEqual, Assembler::pt, not_already_dirty);
 
+        __ bind(young_card);
         // We didn't take the branch, so we're already dirty: return.
         // Use return-from-leaf
         __ retl();
--- a/src/cpu/sparc/vm/sparc.ad	Thu May 08 16:16:21 2014 +0200
+++ b/src/cpu/sparc/vm/sparc.ad	Mon Jul 07 08:54:46 2014 +0200
@@ -3411,8 +3411,8 @@
   interface(CONST_INTER);
 %}
 
-// Unsigned (positive) Integer Immediate: 13-bit
-operand immU13() %{
+// Unsigned Integer Immediate: 12-bit (non-negative that fits in simm13)
+operand immU12() %{
   predicate((0 <= n->get_int()) && Assembler::is_simm13(n->get_int()));
   match(ConI);
   op_cost(0);
@@ -3448,6 +3448,17 @@
   interface(CONST_INTER);
 %}
 
+// Int Immediate non-negative
+operand immU31()
+%{
+  predicate(n->get_int() >= 0);
+  match(ConI);
+
+  op_cost(0);
+  format %{ %}
+  interface(CONST_INTER);
+%}
+
 // Integer Immediate: 0-bit
 operand immI0() %{
   predicate(n->get_int() == 0);
@@ -5744,7 +5755,6 @@
   effect(TEMP dst, TEMP tmp);
   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
 
-  size((3+1)*4);  // set may use two instructions.
   format %{ "LDUH   $mem,$dst\t! ushort/char & 16-bit mask -> long\n\t"
             "SET    $mask,$tmp\n\t"
             "AND    $dst,$tmp,$dst" %}
@@ -5866,13 +5876,13 @@
   ins_pipe(iload_mem);
 %}
 
-// Load Integer with a 13-bit mask into a Long Register
-instruct loadI2L_immI13(iRegL dst, memory mem, immI13 mask) %{
+// Load Integer with a 12-bit mask into a Long Register
+instruct loadI2L_immU12(iRegL dst, memory mem, immU12 mask) %{
   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
   ins_cost(MEMORY_REF_COST + DEFAULT_COST);
 
   size(2*4);
-  format %{ "LDUW   $mem,$dst\t! int & 13-bit mask -> long\n\t"
+  format %{ "LDUW   $mem,$dst\t! int & 12-bit mask -> long\n\t"
             "AND    $dst,$mask,$dst" %}
   ins_encode %{
     Register Rdst = $dst$$Register;
@@ -5882,14 +5892,13 @@
   ins_pipe(iload_mem);
 %}
 
-// Load Integer with a 32-bit mask into a Long Register
-instruct loadI2L_immI(iRegL dst, memory mem, immI mask, iRegL tmp) %{
+// Load Integer with a 31-bit mask into a Long Register
+instruct loadI2L_immU31(iRegL dst, memory mem, immU31 mask, iRegL tmp) %{
   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
   effect(TEMP dst, TEMP tmp);
   ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
 
-  size((3+1)*4);  // set may use two instructions.
-  format %{ "LDUW   $mem,$dst\t! int & 32-bit mask -> long\n\t"
+  format %{ "LDUW   $mem,$dst\t! int & 31-bit mask -> long\n\t"
             "SET    $mask,$tmp\n\t"
             "AND    $dst,$tmp,$dst" %}
   ins_encode %{
@@ -8931,7 +8940,7 @@
   ins_pipe(ialu_cconly_reg_reg);
 %}
 
-instruct compU_iReg_imm13(flagsRegU icc, iRegI op1, immU13 op2 ) %{
+instruct compU_iReg_imm13(flagsRegU icc, iRegI op1, immU12 op2 ) %{
   match(Set icc (CmpU op1 op2));
 
   size(4);
--- a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -1873,6 +1873,25 @@
   if (ProfileInterpreter) {
     __ set_method_data_pointer_for_bcp();
   }
+
+  if (EnableInvokeDynamic) {
+    Label L_done;
+
+    __ ldub(Address(Lbcp, 0), G1_scratch);  // Load current bytecode
+    __ cmp_and_br_short(G1_scratch, Bytecodes::_invokestatic, Assembler::notEqual, Assembler::pn, L_done);
+
+    // The member name argument must be restored if _invokestatic is re-executed after a PopFrame call.
+    // Detect such a case in the InterpreterRuntime function and return the member name argument, or NULL.
+
+    __ call_VM(G1_scratch, CAST_FROM_FN_PTR(address, InterpreterRuntime::member_name_arg_or_null), I0, Lmethod, Lbcp);
+
+    __ br_null(G1_scratch, false, Assembler::pn, L_done);
+    __ delayed()->nop();
+
+    __ st_ptr(G1_scratch, Lesp, wordSize);
+    __ bind(L_done);
+  }
+
   // Resume bytecode interpretation at the current bcp
   __ dispatch_next(vtos);
   // end of JVMTI PopFrame support
--- a/src/cpu/x86/vm/assembler_x86.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/cpu/x86/vm/assembler_x86.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -8754,13 +8754,18 @@
   const Register card_addr = tmp;
   lea(card_addr, as_Address(ArrayAddress(cardtable, index)));
 #endif
-  cmpb(Address(card_addr, 0), 0);
+  cmpb(Address(card_addr, 0), (int)G1SATBCardTableModRefBS::g1_young_card_val());
   jcc(Assembler::equal, done);
 
+  membar(Assembler::Membar_mask_bits(Assembler::StoreLoad));
+  cmpb(Address(card_addr, 0), (int)CardTableModRefBS::dirty_card_val());
+  jcc(Assembler::equal, done);
+
+
   // storing a region crossing, non-NULL oop, card is clean.
   // dirty card and log.
 
-  movb(Address(card_addr, 0), 0);
+  movb(Address(card_addr, 0), (int)CardTableModRefBS::dirty_card_val());
 
   cmpl(queue_index, 0);
   jcc(Assembler::equal, runtime);
--- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1686,14 +1686,6 @@
   }
 
   assert_different_registers(obj, k_RInfo, klass_RInfo);
-  if (!k->is_loaded()) {
-    jobject2reg_with_patching(k_RInfo, op->info_for_patch());
-  } else {
-#ifdef _LP64
-    __ movoop(k_RInfo, k->constant_encoding());
-#endif // _LP64
-  }
-  assert(obj != k_RInfo, "must be different");
 
   __ cmpptr(obj, (int32_t)NULL_WORD);
   if (op->should_profile()) {
@@ -1710,6 +1702,14 @@
   } else {
     __ jcc(Assembler::equal, *obj_is_null);
   }
+
+  if (!k->is_loaded()) {
+    jobject2reg_with_patching(k_RInfo, op->info_for_patch());
+  } else {
+#ifdef _LP64
+    __ movoop(k_RInfo, k->constant_encoding());
+#endif // _LP64
+  }
   __ verify_oop(obj);
 
   if (op->fast_check()) {
--- a/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1395,19 +1395,18 @@
     addr = new LIR_Address(src.result(), offset, type);
   }
 
-  if (data != dst) {
-    __ move(data, dst);
-    data = dst;
-  }
+  // Because we want a 2-arg form of xchg and xadd
+  __ move(data, dst);
+
   if (x->is_add()) {
-    __ xadd(LIR_OprFact::address(addr), data, dst, LIR_OprFact::illegalOpr);
+    __ xadd(LIR_OprFact::address(addr), dst, dst, LIR_OprFact::illegalOpr);
   } else {
     if (is_obj) {
       // Do the pre-write barrier, if any.
       pre_barrier(LIR_OprFact::address(addr), LIR_OprFact::illegalOpr /* pre_val */,
                   true /* do_load */, false /* patch */, NULL);
     }
-    __ xchg(LIR_OprFact::address(addr), data, dst, LIR_OprFact::illegalOpr);
+    __ xchg(LIR_OprFact::address(addr), dst, dst, LIR_OprFact::illegalOpr);
     if (is_obj) {
       // Seems to be a precise address
       post_barrier(LIR_OprFact::address(addr), data);
--- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -37,6 +37,9 @@
 #include "runtime/signature.hpp"
 #include "runtime/vframeArray.hpp"
 #include "vmreg_x86.inline.hpp"
+#ifndef SERIALGC
+#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
+#endif
 
 
 // Implementation of StubAssembler
@@ -1743,13 +1746,17 @@
         __ leal(card_addr, __ as_Address(ArrayAddress(cardtable, index)));
 #endif
 
-        __ cmpb(Address(card_addr, 0), 0);
+        __ cmpb(Address(card_addr, 0), (int)G1SATBCardTableModRefBS::g1_young_card_val());
+        __ jcc(Assembler::equal, done);
+
+        __ membar(Assembler::Membar_mask_bits(Assembler::StoreLoad));
+        __ cmpb(Address(card_addr, 0), (int)CardTableModRefBS::dirty_card_val());
         __ jcc(Assembler::equal, done);
 
         // storing region crossing non-NULL, card is clean.
         // dirty card and log.
 
-        __ movb(Address(card_addr, 0), 0);
+        __ movb(Address(card_addr, 0), (int)CardTableModRefBS::dirty_card_val());
 
         __ cmpl(queue_index, 0);
         __ jcc(Assembler::equal, runtime);
--- a/src/cpu/x86/vm/frame_x86.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/cpu/x86/vm/frame_x86.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -94,12 +94,6 @@
     // other generic buffer blobs are more problematic so we just assume they are
     // ok. adapter blobs never have a frame complete and are never ok.
 
-    // check for a valid frame_size, otherwise we are unlikely to get a valid sender_pc
-
-    if (!Interpreter::contains(_pc) && _cb->frame_size() <= 0) {
-      return false;
-    }
-
     if (!_cb->is_frame_complete_at(_pc)) {
       if (_cb->is_nmethod() || _cb->is_adapter_blob() || _cb->is_runtime_stub()) {
         return false;
@@ -139,6 +133,11 @@
       // must be some sort of compiled/runtime frame
       // fp does not have to be safe (although it could be check for c1?)
 
+      // check for a valid frame_size, otherwise we are unlikely to get a valid sender_pc
+      if (_cb->frame_size() <= 0) {
+        return false;
+      }
+
       sender_sp = _unextended_sp + _cb->frame_size();
       // On Intel the return_address is always the word on the stack
       sender_pc = (address) *(sender_sp-1);
--- a/src/cpu/x86/vm/globals_x86.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/cpu/x86/vm/globals_x86.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -62,7 +62,7 @@
 // due to lack of optimization caused by C++ compiler bugs
 define_pd_global(intx, StackShadowPages, NOT_WIN64(20) WIN64_ONLY(6) DEBUG_ONLY(+2));
 #else
-define_pd_global(intx, StackShadowPages, 4 DEBUG_ONLY(+5));
+define_pd_global(intx, StackShadowPages, 6 DEBUG_ONLY(+5));
 #endif // AMD64
 
 define_pd_global(intx, PreInflateSpin,           10);
--- a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -1789,6 +1789,27 @@
   __ get_thread(thread);
   __ movl(Address(thread, JavaThread::popframe_condition_offset()), JavaThread::popframe_inactive);
 
+  if (EnableInvokeDynamic) {
+    Label L_done;
+    const Register local0 = rdi;
+
+    __ cmpb(Address(rsi, 0), Bytecodes::_invokestatic);
+    __ jcc(Assembler::notEqual, L_done);
+
+    // The member name argument must be restored if _invokestatic is re-executed after a PopFrame call.
+    // Detect such a case in the InterpreterRuntime function and return the member name argument, or NULL.
+
+    __ get_method(rdx);
+    __ movptr(rax, Address(local0, 0));
+    __ call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::member_name_arg_or_null), rax, rdx, rsi);
+
+    __ testptr(rax, rax);
+    __ jcc(Assembler::zero, L_done);
+
+    __ movptr(Address(rbx, 0), rax);
+    __ bind(L_done);
+  }
+
   __ dispatch_next(vtos);
   // end of PopFrame support
 
--- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -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
@@ -1815,6 +1815,27 @@
   __ movl(Address(r15_thread, JavaThread::popframe_condition_offset()),
           JavaThread::popframe_inactive);
 
+  if (EnableInvokeDynamic) {
+    Label L_done;
+    const Register local0 = r14;
+
+    __ cmpb(Address(r13, 0), Bytecodes::_invokestatic);
+    __ jcc(Assembler::notEqual, L_done);
+
+    // The member name argument must be restored if _invokestatic is re-executed after a PopFrame call.
+    // Detect such a case in the InterpreterRuntime function and return the member name argument, or NULL.
+
+    __ get_method(rdx);
+    __ movptr(rax, Address(local0, 0));
+    __ call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::member_name_arg_or_null), rax, rdx, r13);
+
+    __ testptr(rax, rax);
+    __ jcc(Assembler::zero, L_done);
+
+    __ movptr(Address(rbx, 0), rax);
+    __ bind(L_done);
+  }
+
   __ dispatch_next(vtos);
   // end of PopFrame support
 
--- a/src/cpu/x86/vm/x86_32.ad	Thu May 08 16:16:21 2014 +0200
+++ b/src/cpu/x86/vm/x86_32.ad	Mon Jul 07 08:54:46 2014 +0200
@@ -3931,6 +3931,17 @@
   interface(CONST_INTER);
 %}
 
+// Int Immediate non-negative
+operand immU31()
+%{
+  predicate(n->get_int() >= 0);
+  match(ConI);
+
+  op_cost(0);
+  format %{ %}
+  interface(CONST_INTER);
+%}
+
 // Constant for long shifts
 operand immI_32() %{
   predicate( n->get_int() == 32 );
@@ -6147,12 +6158,12 @@
   ins_pipe(ialu_reg_mem);
 %}
 
-// Load Integer with 32-bit mask into Long Register
-instruct loadI2L_immI(eRegL dst, memory mem, immI mask, eFlagsReg cr) %{
+// Load Integer with 31-bit mask into Long Register
+instruct loadI2L_immU31(eRegL dst, memory mem, immU31 mask, eFlagsReg cr) %{
   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
   effect(KILL cr);
 
-  format %{ "MOV    $dst.lo,$mem\t# int & 32-bit mask -> long\n\t"
+  format %{ "MOV    $dst.lo,$mem\t# int & 31-bit mask -> long\n\t"
             "XOR    $dst.hi,$dst.hi\n\t"
             "AND    $dst.lo,$mask" %}
   ins_encode %{
--- a/src/cpu/x86/vm/x86_64.ad	Thu May 08 16:16:21 2014 +0200
+++ b/src/cpu/x86/vm/x86_64.ad	Mon Jul 07 08:54:46 2014 +0200
@@ -3154,6 +3154,17 @@
   interface(CONST_INTER);
 %}
 
+// Int Immediate non-negative
+operand immU31()
+%{
+  predicate(n->get_int() >= 0);
+  match(ConI);
+
+  op_cost(0);
+  format %{ %}
+  interface(CONST_INTER);
+%}
+
 // Constant for long shifts
 operand immI_32()
 %{
@@ -5095,12 +5106,12 @@
   ins_pipe(ialu_reg_mem);
 %}
 
-// Load Integer with a 32-bit mask into Long Register
-instruct loadI2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{
+// Load Integer with a 31-bit mask into Long Register
+instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{
   match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
   effect(KILL cr);
 
-  format %{ "movl    $dst, $mem\t# int & 32-bit mask -> long\n\t"
+  format %{ "movl    $dst, $mem\t# int & 31-bit mask -> long\n\t"
             "andl    $dst, $mask" %}
   ins_encode %{
     Register Rdst = $dst$$Register;
--- a/src/cpu/zero/vm/entryFrame_zero.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/cpu/zero/vm/entryFrame_zero.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2008, 2010 Red Hat, Inc.
+ * Copyright (c) 2013 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -58,8 +58,8 @@
                            JavaCallWrapper* call_wrapper,
                            TRAPS);
  public:
-  JavaCallWrapper *call_wrapper() const {
-    return (JavaCallWrapper *) value_of_word(call_wrapper_off);
+  JavaCallWrapper **call_wrapper() const {
+    return (JavaCallWrapper **) addr_of_word(call_wrapper_off);
   }
 
  public:
--- a/src/cpu/zero/vm/frame_zero.inline.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/cpu/zero/vm/frame_zero.inline.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2007, 2013, Red Hat, Inc.
+ * Copyright (c) 2013 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -132,7 +132,7 @@
   return fp();
 }
 
-inline JavaCallWrapper* frame::entry_frame_call_wrapper() const {
+inline JavaCallWrapper** frame::entry_frame_call_wrapper_addr() const {
   return zero_entryframe()->call_wrapper();
 }
 
--- a/src/os/bsd/vm/attachListener_bsd.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/os/bsd/vm/attachListener_bsd.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -460,14 +460,14 @@
 
 void AttachListener::vm_start() {
   char fn[UNIX_PATH_MAX];
-  struct stat64 st;
+  struct stat st;
   int ret;
 
   int n = snprintf(fn, UNIX_PATH_MAX, "%s/.java_pid%d",
            os::get_temp_directory(), os::current_process_id());
   assert(n < (int)UNIX_PATH_MAX, "java_pid file name buffer overflow");
 
-  RESTARTABLE(::stat64(fn, &st), ret);
+  RESTARTABLE(::stat(fn, &st), ret);
   if (ret == 0) {
     ret = ::unlink(fn);
     if (ret == -1) {
--- a/src/os/bsd/vm/os_bsd.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/os/bsd/vm/os_bsd.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1582,10 +1582,10 @@
   return (1000 * 1000);
 }
 
-// XXX: For now, code this as if BSD does not support vtime.
-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();
@@ -3434,7 +3434,9 @@
 #endif
 #endif
 
-char* os::reserve_memory_special(size_t bytes, char* req_addr, bool exec) {
+char* os::reserve_memory_special(size_t bytes, size_t alignment, char* req_addr, bool exec) {
+  fatal("This code is not used or maintained.");
+
   // "exec" is passed in but not used.  Creating the shared image for
   // the code cache doesn't have an SHM_X executable permission to check.
   assert(UseLargePages && UseSHM, "only for SHM large pages");
@@ -6105,3 +6107,9 @@
   return n;
 }
 
+#ifndef PRODUCT
+void TestReserveMemorySpecial_test() {
+  // No tests available for this platform
+}
+#endif
+
--- a/src/os/linux/vm/globals_linux.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/os/linux/vm/globals_linux.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -40,6 +40,9 @@
   product(bool, UseHugeTLBFS, false,                                    \
           "Use MAP_HUGETLB for large pages")                            \
                                                                         \
+  product(bool, UseTransparentHugePages, false,                         \
+          "Use MADV_HUGEPAGE for large pages")                          \
+                                                                        \
   product(bool, LoadExecStackDllInVMThread, true,                       \
           "Load DLLs with executable-stack attribute in the VM Thread") \
                                                                         \
@@ -50,7 +53,7 @@
 // Defines Linux-specific default values. The flags are available on all
 // platforms, but they may have different default values on other platforms.
 //
-define_pd_global(bool, UseLargePages, true);
+define_pd_global(bool, UseLargePages, false);
 define_pd_global(bool, UseLargePagesIndividualAllocation, false);
 define_pd_global(bool, UseOSErrorReporting, false);
 define_pd_global(bool, UseThreadPriorities, true) ;
--- a/src/os/linux/vm/jsig.c	Thu May 08 16:16:21 2014 +0200
+++ b/src/os/linux/vm/jsig.c	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, 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 @@
 
   signal_lock();
 
-  sigused = (MASK(sig) & jvmsigs) != 0;
+  sigused = (sig < MAXSIGNUM) && ((MASK(sig) & jvmsigs) != 0);
   if (jvm_signal_installed && sigused) {
     /* jvm has installed its signal handler for this signal. */
     /* Save the handler. Don't really install it. */
@@ -116,7 +116,7 @@
 
     signal_unlock();
     return oldhandler;
-  } else if (jvm_signal_installing) {
+  } else if (sig < MAXSIGNUM && jvm_signal_installing) {
     /* jvm is installing its signal handlers. Install the new
      * handlers and save the old ones. jvm uses sigaction().
      * Leave the piece here just in case. */
@@ -165,7 +165,7 @@
 
   signal_lock();
 
-  sigused = (MASK(sig) & jvmsigs) != 0;
+  sigused = (sig < MAXSIGNUM) && ((MASK(sig) & jvmsigs) != 0);
   if (jvm_signal_installed && sigused) {
     /* jvm has installed its signal handler for this signal. */
     /* Save the handler. Don't really install it. */
@@ -178,7 +178,7 @@
 
     signal_unlock();
     return 0;
-  } else if (jvm_signal_installing) {
+  } else if (sig < MAXSIGNUM && jvm_signal_installing) {
     /* jvm is installing its signal handlers. Install the new
      * handlers and save the old ones. */
     res = call_os_sigaction(sig, act, &oldAct);
--- a/src/os/linux/vm/os_linux.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/os/linux/vm/os_linux.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -120,8 +120,16 @@
 # include <inttypes.h>
 # include <sys/ioctl.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
+
 #define MAX_PATH    (2 * K)
 
+#define MAX_SECS 100000000
+
 // for timer info max values which include all bits
 #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
 
@@ -1383,15 +1391,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 (double) (usage.ru_utime.tv_sec + usage.ru_stime.tv_sec) + (double) (usage.ru_utime.tv_usec + usage.ru_stime.tv_usec) / (1000 * 1000);
+  } else {
+    // better than nothing, but not much
+    return elapsedTime();
+  }
 }
 
 jlong os::javaTimeMillis() {
@@ -2482,7 +2494,6 @@
     sem_t _semaphore;
 };
 
-
 Semaphore::Semaphore() {
   sem_init(&_semaphore, 0, 0);
 }
@@ -2504,8 +2515,22 @@
 }
 
 bool Semaphore::timedwait(unsigned int sec, int nsec) {
+
   struct timespec ts;
-  unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec);
+  // Semaphore's are always associated with CLOCK_REALTIME
+  os::Linux::clock_gettime(CLOCK_REALTIME, &ts);
+  // see unpackTime for discussion on overflow checking
+  if (sec >= MAX_SECS) {
+    ts.tv_sec += MAX_SECS;
+    ts.tv_nsec = 0;
+  } else {
+    ts.tv_sec += sec;
+    ts.tv_nsec += nsec;
+    if (ts.tv_nsec >= NANOSECS_PER_SEC) {
+      ts.tv_nsec -= NANOSECS_PER_SEC;
+      ++ts.tv_sec; // note: this must be <= max_secs
+    }
+  }
 
   while (1) {
     int result = sem_timedwait(&_semaphore, &ts);
@@ -2710,14 +2735,6 @@
           alignment_hint, exec, strerror(err), err);
 }
 
-static void warn_fail_commit_memory(char* addr, size_t size,
-                                    size_t alignment_hint, bool exec,
-                                    int err, const char* msg) {
-  warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
-          ", " SIZE_FORMAT ", %d) failed; error='%s' (errno=%d); %s", addr, size,
-          alignment_hint, exec, strerror(err), err, msg);
-}
-
 // NOTE: Linux kernel does not really reserve the pages for us.
 //       All it does is to check if there are enough free pages
 //       left at the time of mmap(). This could be a potential
@@ -2768,41 +2785,9 @@
 #define MADV_HUGEPAGE 14
 #endif
 
-volatile jint os::Linux::num_largepage_commit_fails = 0;
-
 int os::Linux::commit_memory_impl(char* addr, size_t size,
                                   size_t alignment_hint, bool exec) {
-  int err;
-  if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) {
-    int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
-    uintptr_t res =
-      (uintptr_t) ::mmap(addr, size, prot,
-                         MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_HUGETLB,
-                         -1, 0);
-    if (res != (uintptr_t) MAP_FAILED) {
-      if (UseNUMAInterleaving) {
-        numa_make_global(addr, size);
-      }
-      return 0;
-    }
-
-    err = errno;  // save errno from mmap() call above
-
-    if (!recoverable_mmap_error(err)) {
-      // However, it is not clear that this loss of our reserved mapping
-      // happens with large pages on Linux or that we cannot recover
-      // from the loss. For now, we just issue a warning and we don't
-      // call vm_exit_out_of_memory(). This issue is being tracked by
-      // JBS-8007074.
-      Atomic::inc(&os::Linux::num_largepage_commit_fails);
-      warn_fail_commit_memory(addr, size, alignment_hint, exec, err,
-        "Cannot allocate large pages, falling back to regular pages");
-//    vm_exit_out_of_memory(size, "committing reserved memory.");
-    }
-    // Fall through and try to use small pages
-  }
-
-  err = os::Linux::commit_memory_impl(addr, size, exec);
+  int err = os::Linux::commit_memory_impl(addr, size, exec);
   if (err == 0) {
     realign_memory(addr, size, alignment_hint);
   }
@@ -2827,7 +2812,7 @@
 }
 
 void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
-  if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) {
+  if (UseTransparentHugePages && alignment_hint > (size_t)vm_page_size()) {
     // We don't check the return value: madvise(MADV_HUGEPAGE) may not
     // be supported or the memory may already be backed by huge pages.
     ::madvise(addr, bytes, MADV_HUGEPAGE);
@@ -2840,7 +2825,7 @@
   // uncommitted at all. We don't do anything in this case to avoid creating a segment with
   // small pages on top of the SHM segment. This method always works for small pages, so we
   // allow that in any case.
-  if (alignment_hint <= (size_t)os::vm_page_size() || !UseSHM) {
+  if (alignment_hint <= (size_t)os::vm_page_size() || can_commit_large_page_memory()) {
     commit_memory(addr, bytes, alignment_hint, !ExecMem);
   }
 }
@@ -3209,11 +3194,31 @@
   return linux_mprotect(addr, size, PROT_READ|PROT_WRITE);
 }
 
+bool os::Linux::transparent_huge_pages_sanity_check(bool warn, size_t page_size) {
+  bool result = false;
+  void *p = mmap(NULL, page_size * 2, PROT_READ|PROT_WRITE,
+                 MAP_ANONYMOUS|MAP_PRIVATE,
+                 -1, 0);
+  if (p != MAP_FAILED) {
+    void *aligned_p = align_ptr_up(p, page_size);
+
+    result = madvise(aligned_p, page_size, MADV_HUGEPAGE) == 0;
+
+    munmap(p, page_size * 2);
+  }
+
+  if (warn && !result) {
+    warning("TransparentHugePages is not supported by the operating system.");
+  }
+
+  return result;
+}
+
 bool os::Linux::hugetlbfs_sanity_check(bool warn, size_t page_size) {
   bool result = false;
-  void *p = mmap (NULL, page_size, PROT_READ|PROT_WRITE,
-                  MAP_ANONYMOUS|MAP_PRIVATE|MAP_HUGETLB,
-                  -1, 0);
+  void *p = mmap(NULL, page_size, PROT_READ|PROT_WRITE,
+                 MAP_ANONYMOUS|MAP_PRIVATE|MAP_HUGETLB,
+                 -1, 0);
 
   if (p != MAP_FAILED) {
     // We don't know if this really is a huge page or not.
@@ -3234,12 +3239,10 @@
       }
       fclose(fp);
     }
-    munmap (p, page_size);
-    if (result)
-      return true;
-  }
-
-  if (warn) {
+    munmap(p, page_size);
+  }
+
+  if (warn && !result) {
     warning("HugeTLBFS is not supported by the operating system.");
   }
 
@@ -3287,82 +3290,126 @@
 
 static size_t _large_page_size = 0;
 
-void os::large_page_init() {
-  if (!UseLargePages) {
-    UseHugeTLBFS = false;
-    UseSHM = false;
-    return;
-  }
-
-  if (FLAG_IS_DEFAULT(UseHugeTLBFS) && FLAG_IS_DEFAULT(UseSHM)) {
-    // If UseLargePages is specified on the command line try both methods,
-    // if it's default, then try only HugeTLBFS.
-    if (FLAG_IS_DEFAULT(UseLargePages)) {
-      UseHugeTLBFS = true;
-    } else {
-      UseHugeTLBFS = UseSHM = true;
-    }
-  }
-
-  if (LargePageSizeInBytes) {
-    _large_page_size = LargePageSizeInBytes;
-  } else {
-    // large_page_size on Linux is used to round up heap size. x86 uses either
-    // 2M or 4M page, depending on whether PAE (Physical Address Extensions)
-    // mode is enabled. AMD64/EM64T uses 2M page in 64bit mode. IA64 can use
-    // page as large as 256M.
-    //
-    // Here we try to figure out page size by parsing /proc/meminfo and looking
-    // for a line with the following format:
-    //    Hugepagesize:     2048 kB
-    //
-    // If we can't determine the value (e.g. /proc is not mounted, or the text
-    // format has been changed), we'll use the largest page size supported by
-    // the processor.
+size_t os::Linux::find_large_page_size() {
+  size_t large_page_size = 0;
+
+  // large_page_size on Linux is used to round up heap size. x86 uses either
+  // 2M or 4M page, depending on whether PAE (Physical Address Extensions)
+  // mode is enabled. AMD64/EM64T uses 2M page in 64bit mode. IA64 can use
+  // page as large as 256M.
+  //
+  // Here we try to figure out page size by parsing /proc/meminfo and looking
+  // for a line with the following format:
+  //    Hugepagesize:     2048 kB
+  //
+  // If we can't determine the value (e.g. /proc is not mounted, or the text
+  // format has been changed), we'll use the largest page size supported by
+  // the processor.
 
 #ifndef ZERO
-    _large_page_size = IA32_ONLY(4 * M) AMD64_ONLY(2 * M) IA64_ONLY(256 * M) SPARC_ONLY(4 * M)
-                       ARM_ONLY(2 * M) PPC_ONLY(4 * M);
+  large_page_size = IA32_ONLY(4 * M) AMD64_ONLY(2 * M) IA64_ONLY(256 * M) SPARC_ONLY(4 * M)
+                     ARM_ONLY(2 * M) PPC_ONLY(4 * M);
 #endif // ZERO
 
-    FILE *fp = fopen("/proc/meminfo", "r");
-    if (fp) {
-      while (!feof(fp)) {
-        int x = 0;
-        char buf[16];
-        if (fscanf(fp, "Hugepagesize: %d", &x) == 1) {
-          if (x && fgets(buf, sizeof(buf), fp) && strcmp(buf, " kB\n") == 0) {
-            _large_page_size = x * K;
-            break;
-          }
-        } else {
-          // skip to next line
-          for (;;) {
-            int ch = fgetc(fp);
-            if (ch == EOF || ch == (int)'\n') break;
-          }
+  FILE *fp = fopen("/proc/meminfo", "r");
+  if (fp) {
+    while (!feof(fp)) {
+      int x = 0;
+      char buf[16];
+      if (fscanf(fp, "Hugepagesize: %d", &x) == 1) {
+        if (x && fgets(buf, sizeof(buf), fp) && strcmp(buf, " kB\n") == 0) {
+          large_page_size = x * K;
+          break;
+        }
+      } else {
+        // skip to next line
+        for (;;) {
+          int ch = fgetc(fp);
+          if (ch == EOF || ch == (int)'\n') break;
         }
       }
-      fclose(fp);
     }
-  }
-
-  // print a warning if any large page related flag is specified on command line
-  bool warn_on_failure = !FLAG_IS_DEFAULT(UseHugeTLBFS);
-
+    fclose(fp);
+  }
+
+  if (!FLAG_IS_DEFAULT(LargePageSizeInBytes) && LargePageSizeInBytes != large_page_size) {
+    warning("Setting LargePageSizeInBytes has no effect on this OS. Large page size is "
+        SIZE_FORMAT "%s.", byte_size_in_proper_unit(large_page_size),
+        proper_unit_for_byte_size(large_page_size));
+  }
+
+  return large_page_size;
+}
+
+size_t os::Linux::setup_large_page_size() {
+  _large_page_size = Linux::find_large_page_size();
   const size_t default_page_size = (size_t)Linux::page_size();
   if (_large_page_size > default_page_size) {
     _page_sizes[0] = _large_page_size;
     _page_sizes[1] = default_page_size;
     _page_sizes[2] = 0;
   }
-  UseHugeTLBFS = UseHugeTLBFS &&
-                 Linux::hugetlbfs_sanity_check(warn_on_failure, _large_page_size);
-
-  if (UseHugeTLBFS)
+
+  return _large_page_size;
+}
+
+bool os::Linux::setup_large_page_type(size_t page_size) {
+  if (FLAG_IS_DEFAULT(UseHugeTLBFS) &&
+      FLAG_IS_DEFAULT(UseSHM) &&
+      FLAG_IS_DEFAULT(UseTransparentHugePages)) {
+
+    // The type of large pages has not been specified by the user.
+
+    // Try UseHugeTLBFS and then UseSHM.
+    UseHugeTLBFS = UseSHM = true;
+
+    // Don't try UseTransparentHugePages since there are known
+    // performance issues with it turned on. This might change in the future.
+    UseTransparentHugePages = false;
+  }
+
+  if (UseTransparentHugePages) {
+    bool warn_on_failure = !FLAG_IS_DEFAULT(UseTransparentHugePages);
+    if (transparent_huge_pages_sanity_check(warn_on_failure, page_size)) {
+      UseHugeTLBFS = false;
+      UseSHM = false;
+      return true;
+    }
+    UseTransparentHugePages = false;
+  }
+
+  if (UseHugeTLBFS) {
+    bool warn_on_failure = !FLAG_IS_DEFAULT(UseHugeTLBFS);
+    if (hugetlbfs_sanity_check(warn_on_failure, page_size)) {
+      UseSHM = false;
+      return true;
+    }
+    UseHugeTLBFS = false;
+  }
+
+  return UseSHM;
+}
+
+void os::large_page_init() {
+  if (!UseLargePages &&
+      !UseTransparentHugePages &&
+      !UseHugeTLBFS &&
+      !UseSHM) {
+    // Not using large pages.
+    return;
+  }
+
+  if (!FLAG_IS_DEFAULT(UseLargePages) && !UseLargePages) {
+    // The user explicitly turned off large pages.
+    // Ignore the rest of the large pages flags.
+    UseTransparentHugePages = false;
+    UseHugeTLBFS = false;
     UseSHM = false;
-
-  UseLargePages = UseHugeTLBFS || UseSHM;
+    return;
+  }
+
+  size_t large_page_size = Linux::setup_large_page_size();
+  UseLargePages          = Linux::setup_large_page_type(large_page_size);
 
   set_coredump_filter();
 }
@@ -3371,16 +3418,22 @@
 #define SHM_HUGETLB 04000
 #endif
 
-char* os::reserve_memory_special(size_t bytes, char* req_addr, bool exec) {
+char* os::Linux::reserve_memory_special_shm(size_t bytes, size_t alignment, char* req_addr, bool exec) {
   // "exec" is passed in but not used.  Creating the shared image for
   // the code cache doesn't have an SHM_X executable permission to check.
   assert(UseLargePages && UseSHM, "only for SHM large pages");
+  assert(is_ptr_aligned(req_addr, os::large_page_size()), "Unaligned address");
+
+  if (!is_size_aligned(bytes, os::large_page_size()) || alignment > os::large_page_size()) {
+    return NULL; // Fallback to small pages.
+  }
 
   key_t key = IPC_PRIVATE;
   char *addr;
 
   bool warn_on_failure = UseLargePages &&
                         (!FLAG_IS_DEFAULT(UseLargePages) ||
+                         !FLAG_IS_DEFAULT(UseSHM) ||
                          !FLAG_IS_DEFAULT(LargePageSizeInBytes)
                         );
   char msg[128];
@@ -3428,42 +3481,220 @@
      return NULL;
   }
 
-  if ((addr != NULL) && UseNUMAInterleaving) {
-    numa_make_global(addr, bytes);
-  }
-
-  // The memory is committed
-  MemTracker::record_virtual_memory_reserve_and_commit((address)addr, bytes, mtNone, CALLER_PC);
+  return addr;
+}
+
+static void warn_on_large_pages_failure(char* req_addr, size_t bytes, int error) {
+  assert(error == ENOMEM, "Only expect to fail if no memory is available");
+
+  bool warn_on_failure = UseLargePages &&
+      (!FLAG_IS_DEFAULT(UseLargePages) ||
+       !FLAG_IS_DEFAULT(UseHugeTLBFS) ||
+       !FLAG_IS_DEFAULT(LargePageSizeInBytes));
+
+  if (warn_on_failure) {
+    char msg[128];
+    jio_snprintf(msg, sizeof(msg), "Failed to reserve large pages memory req_addr: "
+        PTR_FORMAT " bytes: " SIZE_FORMAT " (errno = %d).", req_addr, bytes, error);
+    warning(msg);
+  }
+}
+
+char* os::Linux::reserve_memory_special_huge_tlbfs_only(size_t bytes, char* req_addr, bool exec) {
+  assert(UseLargePages && UseHugeTLBFS, "only for Huge TLBFS large pages");
+  assert(is_size_aligned(bytes, os::large_page_size()), "Unaligned size");
+  assert(is_ptr_aligned(req_addr, os::large_page_size()), "Unaligned address");
+
+  int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
+  char* addr = (char*)::mmap(req_addr, bytes, prot,
+                             MAP_PRIVATE|MAP_ANONYMOUS|MAP_HUGETLB,
+                             -1, 0);
+
+  if (addr == MAP_FAILED) {
+    warn_on_large_pages_failure(req_addr, bytes, errno);
+    return NULL;
+  }
+
+  assert(is_ptr_aligned(addr, os::large_page_size()), "Must be");
 
   return addr;
 }
 
+char* os::Linux::reserve_memory_special_huge_tlbfs_mixed(size_t bytes, size_t alignment, char* req_addr, bool exec) {
+  size_t large_page_size = os::large_page_size();
+
+  assert(bytes >= large_page_size, "Shouldn't allocate large pages for small sizes");
+
+  // Allocate small pages.
+
+  char* start;
+  if (req_addr != NULL) {
+    assert(is_ptr_aligned(req_addr, alignment), "Must be");
+    assert(is_size_aligned(bytes, alignment), "Must be");
+    start = os::reserve_memory(bytes, req_addr);
+    assert(start == NULL || start == req_addr, "Must be");
+  } else {
+    start = os::reserve_memory_aligned(bytes, alignment);
+  }
+
+  if (start == NULL) {
+    return NULL;
+  }
+
+  assert(is_ptr_aligned(start, alignment), "Must be");
+
+  // os::reserve_memory_special will record this memory area.
+  // Need to release it here to prevent overlapping reservations.
+  MemTracker::record_virtual_memory_release((address)start, bytes);
+
+  char* end = start + bytes;
+
+  // Find the regions of the allocated chunk that can be promoted to large pages.
+  char* lp_start = (char*)align_ptr_up(start, large_page_size);
+  char* lp_end   = (char*)align_ptr_down(end, large_page_size);
+
+  size_t lp_bytes = lp_end - lp_start;
+
+  assert(is_size_aligned(lp_bytes, large_page_size), "Must be");
+
+  if (lp_bytes == 0) {
+    // The mapped region doesn't even span the start and the end of a large page.
+    // Fall back to allocate a non-special area.
+    ::munmap(start, end - start);
+    return NULL;
+  }
+
+  int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
+
+
+  void* result;
+
+  if (start != lp_start) {
+    result = ::mmap(start, lp_start - start, prot,
+                    MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED,
+                    -1, 0);
+    if (result == MAP_FAILED) {
+      ::munmap(lp_start, end - lp_start);
+      return NULL;
+    }
+  }
+
+  result = ::mmap(lp_start, lp_bytes, prot,
+                  MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED|MAP_HUGETLB,
+                  -1, 0);
+  if (result == MAP_FAILED) {
+    warn_on_large_pages_failure(req_addr, bytes, errno);
+    // If the mmap above fails, the large pages region will be unmapped and we
+    // have regions before and after with small pages. Release these regions.
+    //
+    // |  mapped  |  unmapped  |  mapped  |
+    // ^          ^            ^          ^
+    // start      lp_start     lp_end     end
+    //
+    ::munmap(start, lp_start - start);
+    ::munmap(lp_end, end - lp_end);
+    return NULL;
+  }
+
+  if (lp_end != end) {
+      result = ::mmap(lp_end, end - lp_end, prot,
+                      MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED,
+                      -1, 0);
+    if (result == MAP_FAILED) {
+      ::munmap(start, lp_end - start);
+      return NULL;
+    }
+  }
+
+  return start;
+}
+
+char* os::Linux::reserve_memory_special_huge_tlbfs(size_t bytes, size_t alignment, char* req_addr, bool exec) {
+  assert(UseLargePages && UseHugeTLBFS, "only for Huge TLBFS large pages");
+  assert(is_ptr_aligned(req_addr, alignment), "Must be");
+  assert(is_power_of_2(alignment), "Must be");
+  assert(is_power_of_2(os::large_page_size()), "Must be");
+  assert(bytes >= os::large_page_size(), "Shouldn't allocate large pages for small sizes");
+
+  if (is_size_aligned(bytes, os::large_page_size()) && alignment <= os::large_page_size()) {
+    return reserve_memory_special_huge_tlbfs_only(bytes, req_addr, exec);
+  } else {
+    return reserve_memory_special_huge_tlbfs_mixed(bytes, alignment, req_addr, exec);
+  }
+}
+
+char* os::reserve_memory_special(size_t bytes, size_t alignment, char* req_addr, bool exec) {
+  assert(UseLargePages, "only for large pages");
+
+  char* addr;
+  if (UseSHM) {
+    addr = os::Linux::reserve_memory_special_shm(bytes, alignment, req_addr, exec);
+  } else {
+    assert(UseHugeTLBFS, "must be");
+    addr = os::Linux::reserve_memory_special_huge_tlbfs(bytes, alignment, req_addr, exec);
+  }
+
+  if (addr != NULL) {
+    if (UseNUMAInterleaving) {
+      numa_make_global(addr, bytes);
+    }
+
+    // The memory is committed
+    MemTracker::record_virtual_memory_reserve_and_commit((address)addr, bytes, mtNone, CALLER_PC);
+  }
+
+  return addr;
+}
+
+bool os::Linux::release_memory_special_shm(char* base, size_t bytes) {
+  // detaching the SHM segment will also delete it, see reserve_memory_special_shm()
+  return shmdt(base) == 0;
+}
+
+bool os::Linux::release_memory_special_huge_tlbfs(char* base, size_t bytes) {
+  return pd_release_memory(base, bytes);
+}
+
 bool os::release_memory_special(char* base, size_t bytes) {
+  assert(UseLargePages, "only for large pages");
+
   MemTracker::Tracker tkr = MemTracker::get_virtual_memory_release_tracker();
-  // detaching the SHM segment will also delete it, see reserve_memory_special()
-  int rslt = shmdt(base);
-  if (rslt == 0) {
+
+  bool res;
+  if (UseSHM) {
+    res = os::Linux::release_memory_special_shm(base, bytes);
+  } else {
+    assert(UseHugeTLBFS, "must be");
+    res = os::Linux::release_memory_special_huge_tlbfs(base, bytes);
+  }
+
+  if (res) {
     tkr.record((address)base, bytes);
-    return true;
   } else {
     tkr.discard();
-   return false;
-  }
-}
+  }
+
+  return res;
+}
+
 
 size_t os::large_page_size() {
   return _large_page_size;
 }
 
-// HugeTLBFS allows application to commit large page memory on demand;
-// with SysV SHM the entire memory region must be allocated as shared
+// With SysV SHM the entire memory region must be allocated as shared
 // memory.
+// HugeTLBFS allows application to commit large page memory on demand.
+// However, when committing memory with HugeTLBFS fails, the region
+// that was supposed to be committed will lose the old reservation
+// and allow other threads to steal that memory region. Because of this
+// behavior we can't commit HugeTLBFS memory.
 bool os::can_commit_large_page_memory() {
-  return UseHugeTLBFS;
+  return UseTransparentHugePages;
 }
 
 bool os::can_execute_large_page_memory() {
-  return UseHugeTLBFS;
+  return UseTransparentHugePages || UseHugeTLBFS;
 }
 
 // Reserve memory at an arbitrary address, only if that area is
@@ -4626,6 +4857,10 @@
 
   Linux::capture_initial_stack(JavaThread::stack_size_at_create());
 
+#if defined(IA32)
+  workaround_expand_exec_shield_cs_limit();
+#endif
+
   Linux::libpthread_init();
   if (PrintMiscellaneous && (Verbose || WizardMode)) {
      tty->print_cr("[HotSpot is running with %s, %s(%s)]\n",
@@ -4642,21 +4877,23 @@
         UseNUMA = false;
       }
     }
-    // With SHM large pages we cannot uncommit a page, so there's not way
+    // With SHM and HugeTLBFS large pages we cannot uncommit a page, so there's no way
     // we can make the adaptive lgrp chunk resizing work. If the user specified
-    // both UseNUMA and UseLargePages (or UseSHM) on the command line - warn and
+    // both UseNUMA and UseLargePages (or UseSHM/UseHugeTLBFS) on the command line - warn and
     // disable adaptive resizing.
-    if (UseNUMA && UseLargePages && UseSHM) {
-      if (!FLAG_IS_DEFAULT(UseNUMA)) {
-        if (FLAG_IS_DEFAULT(UseLargePages) && FLAG_IS_DEFAULT(UseSHM)) {
+    if (UseNUMA && UseLargePages && !can_commit_large_page_memory()) {
+      if (FLAG_IS_DEFAULT(UseNUMA)) {
+        UseNUMA = false;
+      } else {
+        if (FLAG_IS_DEFAULT(UseLargePages) &&
+            FLAG_IS_DEFAULT(UseSHM) &&
+            FLAG_IS_DEFAULT(UseHugeTLBFS)) {
           UseLargePages = false;
         } else {
-          warning("UseNUMA is not fully compatible with SHM large pages, disabling adaptive resizing");
+          warning("UseNUMA is not fully compatible with SHM/HugeTLBFS large pages, disabling adaptive resizing");
           UseAdaptiveSizePolicy = false;
           UseAdaptiveNUMAChunkSizing = false;
         }
-      } else {
-        UseNUMA = false;
       }
     }
     if (!UseNUMA && ForceNUMA) {
@@ -5589,7 +5826,6 @@
  * is no need to track notifications.
  */
 
-#define MAX_SECS 100000000
 /*
  * This code is common to linux and solaris and will be moved to a
  * common place in dolphin.
@@ -6008,3 +6244,149 @@
 }
 
 #endif // JAVASE_EMBEDDED
+
+
+/////////////// Unit tests ///////////////
+
+#ifndef PRODUCT
+
+#define test_log(...) \
+  do {\
+    if (VerboseInternalVMTests) { \
+      tty->print_cr(__VA_ARGS__); \
+      tty->flush(); \
+    }\
+  } while (false)
+
+class TestReserveMemorySpecial : AllStatic {
+ public:
+  static void small_page_write(void* addr, size_t size) {
+    size_t page_size = os::vm_page_size();
+
+    char* end = (char*)addr + size;
+    for (char* p = (char*)addr; p < end; p += page_size) {
+      *p = 1;
+    }
+  }
+
+  static void test_reserve_memory_special_huge_tlbfs_only(size_t size) {
+    if (!UseHugeTLBFS) {
+      return;
+    }
+
+    test_log("test_reserve_memory_special_huge_tlbfs_only(" SIZE_FORMAT ")", size);
+
+    char* addr = os::Linux::reserve_memory_special_huge_tlbfs_only(size, NULL, false);
+
+    if (addr != NULL) {
+      small_page_write(addr, size);
+
+      os::Linux::release_memory_special_huge_tlbfs(addr, size);
+    }
+  }
+
+  static void test_reserve_memory_special_huge_tlbfs_only() {
+    if (!UseHugeTLBFS) {
+      return;
+    }
+
+    size_t lp = os::large_page_size();
+
+    for (size_t size = lp; size <= lp * 10; size += lp) {
+      test_reserve_memory_special_huge_tlbfs_only(size);
+    }
+  }
+
+  static void test_reserve_memory_special_huge_tlbfs_mixed(size_t size, size_t alignment) {
+    if (!UseHugeTLBFS) {
+        return;
+    }
+
+    test_log("test_reserve_memory_special_huge_tlbfs_mixed(" SIZE_FORMAT ", " SIZE_FORMAT ")",
+        size, alignment);
+
+    assert(size >= os::large_page_size(), "Incorrect input to test");
+
+    char* addr = os::Linux::reserve_memory_special_huge_tlbfs_mixed(size, alignment, NULL, false);
+
+    if (addr != NULL) {
+      small_page_write(addr, size);
+
+      os::Linux::release_memory_special_huge_tlbfs(addr, size);
+    }
+  }
+
+  static void test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(size_t size) {
+    size_t lp = os::large_page_size();
+    size_t ag = os::vm_allocation_granularity();
+
+    for (size_t alignment = ag; is_size_aligned(size, alignment); alignment *= 2) {
+      test_reserve_memory_special_huge_tlbfs_mixed(size, alignment);
+    }
+  }
+
+  static void test_reserve_memory_special_huge_tlbfs_mixed() {
+    size_t lp = os::large_page_size();
+    size_t ag = os::vm_allocation_granularity();
+
+    test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp);
+    test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp + ag);
+    test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp + lp / 2);
+    test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 2);
+    test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 2 + ag);
+    test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 2 - ag);
+    test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 2 + lp / 2);
+    test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 10);
+    test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 10 + lp / 2);
+  }
+
+  static void test_reserve_memory_special_huge_tlbfs() {
+    if (!UseHugeTLBFS) {
+      return;
+    }
+
+    test_reserve_memory_special_huge_tlbfs_only();
+    test_reserve_memory_special_huge_tlbfs_mixed();
+  }
+
+  static void test_reserve_memory_special_shm(size_t size, size_t alignment) {
+    if (!UseSHM) {
+      return;
+    }
+
+    test_log("test_reserve_memory_special_shm(" SIZE_FORMAT ", " SIZE_FORMAT ")", size, alignment);
+
+    char* addr = os::Linux::reserve_memory_special_shm(size, alignment, NULL, false);
+
+    if (addr != NULL) {
+      assert(is_ptr_aligned(addr, alignment), "Check");
+      assert(is_ptr_aligned(addr, os::large_page_size()), "Check");
+
+      small_page_write(addr, size);
+
+      os::Linux::release_memory_special_shm(addr, size);
+    }
+  }
+
+  static void test_reserve_memory_special_shm() {
+    size_t lp = os::large_page_size();
+    size_t ag = os::vm_allocation_granularity();
+
+    for (size_t size = ag; size < lp * 3; size += ag) {
+      for (size_t alignment = ag; is_size_aligned(size, alignment); alignment *= 2) {
+        test_reserve_memory_special_shm(size, alignment);
+      }
+    }
+  }
+
+  static void test() {
+    test_reserve_memory_special_huge_tlbfs();
+    test_reserve_memory_special_shm();
+  }
+};
+
+void TestReserveMemorySpecial_test() {
+  TestReserveMemorySpecial::test();
+}
+
+#endif
--- a/src/os/linux/vm/os_linux.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/os/linux/vm/os_linux.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -35,6 +35,7 @@
 
 class Linux {
   friend class os;
+  friend class TestReserveMemorySpecial;
 
   // For signal-chaining
 #define MAXSIGNUM 32
@@ -95,15 +96,27 @@
   static void rebuild_cpu_to_node_map();
   static GrowableArray<int>* cpu_to_node()    { return _cpu_to_node; }
 
+  static size_t find_large_page_size();
+  static size_t setup_large_page_size();
+
+  static bool setup_large_page_type(size_t page_size);
+  static bool transparent_huge_pages_sanity_check(bool warn, size_t pages_size);
   static bool hugetlbfs_sanity_check(bool warn, size_t page_size);
 
+  static char* reserve_memory_special_shm(size_t bytes, size_t alignment, char* req_addr, bool exec);
+  static char* reserve_memory_special_huge_tlbfs(size_t bytes, size_t alignment, char* req_addr, bool exec);
+  static char* reserve_memory_special_huge_tlbfs_only(size_t bytes, char* req_addr, bool exec);
+  static char* reserve_memory_special_huge_tlbfs_mixed(size_t bytes, size_t alignment, char* req_addr, bool exec);
+
+  static bool release_memory_special_shm(char* base, size_t bytes);
+  static bool release_memory_special_huge_tlbfs(char* base, size_t bytes);
+
   static void print_full_memory_info(outputStream* st);
   static void print_distro_info(outputStream* st);
   static void print_libversion_info(outputStream* st);
 
  public:
   static bool _stack_is_executable;
-  static volatile jint num_largepage_commit_fails;
   static void *dlopen_helper(const char *name, char *ebuf, int ebuflen);
   static void *dll_load_in_vmthread(const char *name, char *ebuf, int ebuflen);
 
--- a/src/os/solaris/vm/os_solaris.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/os/solaris/vm/os_solaris.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -3530,11 +3530,15 @@
   return true;
 }
 
-char* os::reserve_memory_special(size_t size, char* addr, bool exec) {
+char* os::reserve_memory_special(size_t size, size_t alignment, char* addr, bool exec) {
   // "exec" is passed in but not used.  Creating the shared image for
   // the code cache doesn't have an SHM_X executable permission to check.
   assert(UseLargePages && UseISM, "only for ISM large pages");
 
+  if (!is_size_aligned(size, os::large_page_size()) || alignment > os::large_page_size()) {
+    return NULL; // Fallback to small pages.
+  }
+
   char* retAddr = NULL;
   int shmid;
   key_t ismKey;
@@ -6862,3 +6866,9 @@
 
   return strlen(buffer);
 }
+
+#ifndef PRODUCT
+void TestReserveMemorySpecial_test() {
+  // No tests available for this platform
+}
+#endif
--- a/src/os/windows/vm/os_windows.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/os/windows/vm/os_windows.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -800,15 +800,21 @@
   return result;
 }
 
-// For now, we say that Windows 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();
+  FILETIME created;
+  FILETIME exited;
+  FILETIME kernel;
+  FILETIME user;
+  if (GetThreadTimes(GetCurrentThread(), &created, &exited, &kernel, &user) != 0) {
+    // the resolution of windows_to_java_time() should be sufficient (ms)
+    return (double) (windows_to_java_time(kernel) + windows_to_java_time(user)) / MILLIUNITS;
+  } else {
+    return elapsedTime();
+  }
 }
 
 jlong os::javaTimeMillis() {
@@ -1591,6 +1597,7 @@
 
 void os::win32::print_windows_version(outputStream* st) {
   OSVERSIONINFOEX osvi;
+  SYSTEM_INFO si;
   ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
   osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
 
@@ -1600,6 +1607,18 @@
   }
 
   int os_vers = osvi.dwMajorVersion * 1000 + osvi.dwMinorVersion;
+
+  ZeroMemory(&si, sizeof(SYSTEM_INFO));
+  if (os_vers >= 5002) {
+    // Retrieve SYSTEM_INFO from GetNativeSystemInfo call so that we could
+    // find out whether we are running on 64 bit processor or not.
+    if (os::Kernel32Dll::GetNativeSystemInfoAvailable()) {
+      os::Kernel32Dll::GetNativeSystemInfo(&si);
+    } else {
+      GetSystemInfo(&si);
+    }
+  }
+
   if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
     switch (os_vers) {
     case 3051: st->print(" Windows NT 3.51"); break;
@@ -1607,57 +1626,48 @@
     case 5000: st->print(" Windows 2000"); break;
     case 5001: st->print(" Windows XP"); break;
     case 5002:
-    case 6000:
-    case 6001:
-    case 6002: {
-      // Retrieve SYSTEM_INFO from GetNativeSystemInfo call so that we could
-      // find out whether we are running on 64 bit processor or not.
-      SYSTEM_INFO si;
-      ZeroMemory(&si, sizeof(SYSTEM_INFO));
-        if (!os::Kernel32Dll::GetNativeSystemInfoAvailable()){
-          GetSystemInfo(&si);
-      } else {
-        os::Kernel32Dll::GetNativeSystemInfo(&si);
-      }
-      if (os_vers == 5002) {
-        if (osvi.wProductType == VER_NT_WORKSTATION &&
-            si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
+      if (osvi.wProductType == VER_NT_WORKSTATION &&
+          si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {
           st->print(" Windows XP x64 Edition");
-        else
-            st->print(" Windows Server 2003 family");
-      } else if (os_vers == 6000) {
-        if (osvi.wProductType == VER_NT_WORKSTATION)
-            st->print(" Windows Vista");
-        else
-            st->print(" Windows Server 2008");
-        if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
-            st->print(" , 64 bit");
-      } else if (os_vers == 6001) {
-        if (osvi.wProductType == VER_NT_WORKSTATION) {
-            st->print(" Windows 7");
-        } else {
-            // Unrecognized windows, print out its major and minor versions
-            st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion);
-        }
-        if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
-            st->print(" , 64 bit");
-      } else if (os_vers == 6002) {
-        if (osvi.wProductType == VER_NT_WORKSTATION) {
-            st->print(" Windows 8");
-        } else {
-            st->print(" Windows Server 2012");
-        }
-        if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
-            st->print(" , 64 bit");
-      } else { // future os
-        // Unrecognized windows, print out its major and minor versions
-        st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion);
-        if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
-            st->print(" , 64 bit");
+      } else {
+          st->print(" Windows Server 2003 family");
+      }
+      break;
+
+    case 6000:
+      if (osvi.wProductType == VER_NT_WORKSTATION) {
+        st->print(" Windows Vista");
+      } else {
+        st->print(" Windows Server 2008");
       }
       break;
-    }
-    default: // future windows, print out its major and minor versions
+
+    case 6001:
+      if (osvi.wProductType == VER_NT_WORKSTATION) {
+        st->print(" Windows 7");
+      } else {
+        st->print(" Windows Server 2008 R2");
+      }
+      break;
+
+    case 6002:
+      if (osvi.wProductType == VER_NT_WORKSTATION) {
+        st->print(" Windows 8");
+      } else {
+        st->print(" Windows Server 2012");
+      }
+      break;
+
+    case 6003:
+      if (osvi.wProductType == VER_NT_WORKSTATION) {
+        st->print(" Windows 8.1");
+      } else {
+        st->print(" Windows Server 2012 R2");
+      }
+      break;
+
+    default: // future os
+      // Unrecognized windows, print out its major and minor versions
       st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion);
     }
   } else {
@@ -1669,6 +1679,11 @@
       st->print(" Windows %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion);
     }
   }
+
+  if (os_vers >= 6000 && si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {
+    st->print(" , 64 bit");
+  }
+
   st->print(" Build %d", osvi.dwBuildNumber);
   st->print(" %s", osvi.szCSDVersion);           // service pack
   st->cr();
@@ -3079,7 +3094,12 @@
   return true;
 }
 
-char* os::reserve_memory_special(size_t bytes, char* addr, bool exec) {
+char* os::reserve_memory_special(size_t bytes, size_t alignment, char* addr, bool exec) {
+  assert(UseLargePages, "only for large pages");
+
+  if (!is_size_aligned(bytes, os::large_page_size()) || alignment > os::large_page_size()) {
+    return NULL; // Fallback to small pages.
+  }
 
   const DWORD prot = exec ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
   const DWORD flags = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES;
@@ -5584,3 +5604,9 @@
 }
 
 #endif
+
+#ifndef PRODUCT
+void TestReserveMemorySpecial_test() {
+  // No tests available for this platform
+}
+#endif
--- a/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -873,3 +873,46 @@
 #endif
 }
 #endif
+
+
+/*
+ * IA32 only: execute code at a high address in case buggy NX emulation is present. I.e. avoid CS limit
+ * updates (JDK-8023956).
+ */
+void os::workaround_expand_exec_shield_cs_limit() {
+#if defined(IA32)
+  size_t page_size = os::vm_page_size();
+  /*
+   * Take the highest VA the OS will give us and exec
+   *
+   * Although using -(pagesz) as mmap hint works on newer kernel as you would
+   * think, older variants affected by this work-around don't (search forward only).
+   *
+   * On the affected distributions, we understand the memory layout to be:
+   *
+   *   TASK_LIMIT= 3G, main stack base close to TASK_LIMT.
+   *
+   * A few pages south main stack will do it.
+   *
+   * If we are embedded in an app other than launcher (initial != main stack),
+   * we don't have much control or understanding of the address space, just let it slide.
+   */
+  char* hint = (char*) (Linux::initial_thread_stack_bottom() -
+                        ((StackYellowPages + StackRedPages + 1) * page_size));
+  char* codebuf = os::reserve_memory(page_size, hint);
+  if ( (codebuf == NULL) || (!os::commit_memory(codebuf, page_size, true)) ) {
+    return; // No matter, we tried, best effort.
+  }
+  if (PrintMiscellaneous && (Verbose || WizardMode)) {
+     tty->print_cr("[CS limit NX emulation work-around, exec code at: %p]", codebuf);
+  }
+
+  // Some code to exec: the 'ret' instruction
+  codebuf[0] = 0xC3;
+
+  // Call the code in the codebuf
+  __asm__ volatile("call *%0" : : "r"(codebuf));
+
+  // keep the page mapped so CS limit isn't reduced.
+#endif
+}
--- a/src/os_cpu/linux_x86/vm/os_linux_x86.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/os_cpu/linux_x86/vm/os_linux_x86.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -36,4 +36,17 @@
   // Note: Currently only used in 64 bit Windows implementations
   static bool register_code_area(char *low, char *high) { return true; }
 
+  /*
+   * Work-around for broken NX emulation using CS limit, Red Hat patch "Exec-Shield"
+   * (IA32 only).
+   *
+   * Map and execute at a high VA to prevent CS lazy updates race with SMP MM
+   * invalidation.Further code generation by the JVM will no longer cause CS limit
+   * updates.
+   *
+   * Affects IA32: RHEL 5 & 6, Ubuntu 10.04 (LTS), 10.10, 11.04, 11.10, 12.04.
+   * @see JDK-8023956
+   */
+  static void workaround_expand_exec_shield_cs_limit();
+
 #endif // OS_CPU_LINUX_X86_VM_OS_LINUX_X86_HPP
--- a/src/share/vm/c1/c1_LinearScan.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/c1/c1_LinearScan.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1138,8 +1138,10 @@
         }
       }
     }
-
-  } else if (opr_type != T_LONG) {
+    // We want to sometimes use logical operations on pointers, in particular in GC barriers.
+    // Since 64bit logical operations do not current support operands on stack, we have to make sure
+    // T_OBJECT doesn't get spilled along with T_LONG.
+  } else if (opr_type != T_LONG LP64_ONLY(&& opr_type != T_OBJECT)) {
     // integer instruction (note: long operands must always be in register)
     switch (op->code()) {
       case lir_cmp:
--- a/src/share/vm/c1/c1_Runtime1.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/c1/c1_Runtime1.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -911,16 +911,6 @@
     // Return to the now deoptimized frame.
   }
 
-  // If we are patching in a non-perm oop, make sure the nmethod
-  // is on the right list.
-  if (ScavengeRootsInCode && load_klass.not_null() && load_klass->is_scavengable()) {
-    MutexLockerEx ml_code (CodeCache_lock, Mutex::_no_safepoint_check_flag);
-    nmethod* nm = CodeCache::find_nmethod(caller_frame.pc());
-    guarantee(nm != NULL, "only nmethods can contain non-perm oops");
-    if (!nm->on_scavenge_root_list())
-      CodeCache::add_scavenge_root_nmethod(nm);
-  }
-
   // Now copy code back
 
   {
@@ -1096,6 +1086,22 @@
       }
     }
   }
+
+
+  // If we are patching in a non-perm oop, make sure the nmethod
+  // is on the right list.
+  if (ScavengeRootsInCode && load_klass.not_null() && load_klass->is_scavengable()) {
+    MutexLockerEx ml_code (CodeCache_lock, Mutex::_no_safepoint_check_flag);
+    nmethod* nm = CodeCache::find_nmethod(caller_frame.pc());
+    guarantee(nm != NULL, "only nmethods can contain non-perm oops");
+    if (!nm->on_scavenge_root_list()) {
+      CodeCache::add_scavenge_root_nmethod(nm);
+    }
+
+    // Since we've patched some oops in the nmethod,
+    // (re)register it with the heap.
+    Universe::heap()->register_nmethod(nm);
+  }
 JRT_END
 
 //
--- a/src/share/vm/classfile/classFileParser.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/classfile/classFileParser.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -2661,6 +2661,11 @@
                      "Short length on BootstrapMethods in class file %s",
                      CHECK);
 
+  guarantee_property(attribute_byte_length > sizeof(u2),
+                     "Invalid BootstrapMethods attribute length %u in class file %s",
+                     attribute_byte_length,
+                     CHECK);
+
   // The attribute contains a counted array of counted tuples of shorts,
   // represending bootstrap specifiers:
   //    length*{bootstrap_method_index, argument_count*{argument_index}}
@@ -4051,8 +4056,8 @@
   for (int index = 0; index < num_methods; index++) {
     methodOop m = (methodOop)methods->obj_at(index);
 
-    // skip static and <init> methods
-    if ((!m->is_static()) &&
+    // skip private, static, and <init> methods
+    if ((!m->is_private() && !m->is_static()) &&
         (m->name() != vmSymbols::object_initializer_name())) {
 
       Symbol* name = m->name();
--- a/src/share/vm/classfile/javaClasses.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/classfile/javaClasses.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -2391,6 +2391,26 @@
   *offset = value;
 }
 
+// Support for java_lang_invoke_DirectMethodHandle
+
+int java_lang_invoke_DirectMethodHandle::_member_offset;
+
+oop java_lang_invoke_DirectMethodHandle::member(oop dmh) {
+  oop member_name = NULL;
+  bool is_dmh = dmh->is_oop() && java_lang_invoke_DirectMethodHandle::is_instance(dmh);
+  assert(is_dmh, "a DirectMethodHandle oop is expected");
+  if (is_dmh) {
+    member_name = dmh->obj_field(member_offset_in_bytes());
+  }
+  return member_name;
+}
+
+void java_lang_invoke_DirectMethodHandle::compute_offsets() {
+  klassOop klass_oop = SystemDictionary::DirectMethodHandle_klass();
+  if (klass_oop != NULL && EnableInvokeDynamic) {
+    compute_offset(_member_offset, klass_oop, vmSymbols::member_name(), vmSymbols::java_lang_invoke_MemberName_signature());
+  }
+}
 
 // Support for java_lang_invoke_MethodHandle
 
@@ -2500,6 +2520,13 @@
   return mname->obj_field(_vmtarget_offset);
 }
 
+// Can be executed on VM thread only
+void java_lang_invoke_MemberName::adjust_vmtarget(oop mname, oop ref) {
+  assert((is_instance(mname) && (flags(mname) & (MN_IS_METHOD | MN_IS_CONSTRUCTOR)) > 0), "wrong type");
+  assert(Thread::current()->is_VM_thread(), "not VM thread");
+  mname->address_field_put(_vmtarget_offset, (address)ref);
+}
+
 void java_lang_invoke_MemberName::set_vmtarget(oop mname, oop ref) {
   assert(is_instance(mname), "wrong type");
 #ifdef ASSERT
@@ -3003,6 +3030,7 @@
   java_lang_ThreadGroup::compute_offsets();
   if (EnableInvokeDynamic) {
     java_lang_invoke_MethodHandle::compute_offsets();
+    java_lang_invoke_DirectMethodHandle::compute_offsets();
     java_lang_invoke_MemberName::compute_offsets();
     java_lang_invoke_LambdaForm::compute_offsets();
     java_lang_invoke_MethodType::compute_offsets();
--- a/src/share/vm/classfile/javaClasses.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/classfile/javaClasses.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -915,6 +915,32 @@
   static int form_offset_in_bytes()             { return _form_offset; }
 };
 
+// Interface to java.lang.invoke.DirectMethodHandle objects
+
+class java_lang_invoke_DirectMethodHandle: AllStatic {
+  friend class JavaClasses;
+
+ private:
+  static int _member_offset;               // the MemberName of this DMH
+
+  static void compute_offsets();
+
+ public:
+  // Accessors
+  static oop  member(oop mh);
+
+  // Testers
+  static bool is_subclass(klassOop klass) {
+    return Klass::cast(klass)->is_subclass_of(SystemDictionary::DirectMethodHandle_klass());
+  }
+  static bool is_instance(oop obj) {
+    return obj != NULL && is_subclass(obj->klass());
+  }
+
+  // Accessors for code generation:
+  static int member_offset_in_bytes() { return _member_offset; }
+};
+
 // Interface to java.lang.invoke.LambdaForm objects
 // (These are a private interface for managing adapter code generation.)
 
@@ -988,6 +1014,7 @@
 
   static oop            vmtarget(oop mname);
   static void       set_vmtarget(oop mname, oop target);
+  static void       adjust_vmtarget(oop mname, oop target);
 
   static intptr_t       vmindex(oop mname);
   static void       set_vmindex(oop mname, intptr_t index);
--- a/src/share/vm/classfile/symbolTable.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/classfile/symbolTable.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -39,6 +39,9 @@
 
 // --------------------------------------------------------------------------
 
+// the number of buckets a thread claims
+const int ClaimChunkSize = 32;
+
 SymbolTable* SymbolTable::_the_table = NULL;
 // Static arena for symbols that are not deallocated
 Arena* SymbolTable::_arena = NULL;
@@ -81,16 +84,12 @@
   }
 }
 
-int SymbolTable::symbols_removed = 0;
-int SymbolTable::symbols_counted = 0;
+int SymbolTable::_symbols_removed = 0;
+int SymbolTable::_symbols_counted = 0;
+volatile int SymbolTable::_parallel_claimed_idx = 0;
 
-// Remove unreferenced symbols from the symbol table
-// This is done late during GC.
-void SymbolTable::unlink() {
-  int removed = 0;
-  int total = 0;
-  size_t memory_total = 0;
-  for (int i = 0; i < the_table()->table_size(); ++i) {
+void SymbolTable::buckets_unlink(int start_idx, int end_idx, int* processed, int* removed, size_t* memory_total) {
+  for (int i = start_idx; i < end_idx; ++i) {
     HashtableEntry<Symbol*, mtSymbol>** p = the_table()->bucket_addr(i);
     HashtableEntry<Symbol*, mtSymbol>* entry = the_table()->bucket(i);
     while (entry != NULL) {
@@ -102,14 +101,14 @@
         break;
       }
       Symbol* s = entry->literal();
-      memory_total += s->object_size();
-      total++;
+      (*memory_total) += s->object_size();
+      (*processed)++;
       assert(s != NULL, "just checking");
       // If reference count is zero, remove.
       if (s->refcount() == 0) {
         assert(!entry->is_shared(), "shared entries should be kept live");
         delete s;
-        removed++;
+        (*removed)++;
         *p = entry->next();
         the_table()->free_entry(entry);
       } else {
@@ -119,12 +118,45 @@
       entry = (HashtableEntry<Symbol*, mtSymbol>*)HashtableEntry<Symbol*, mtSymbol>::make_ptr(*p);
     }
   }
-  symbols_removed += removed;
-  symbols_counted += total;
+}
+
+// Remove unreferenced symbols from the symbol table
+// This is done late during GC.
+void SymbolTable::unlink(int* processed, int* removed) {
+  size_t memory_total = 0;
+  buckets_unlink(0, the_table()->table_size(), processed, removed, &memory_total);
+  _symbols_removed += *removed;
+  _symbols_counted += *processed;
   // Exclude printing for normal PrintGCDetails because people parse
   // this output.
   if (PrintGCDetails && Verbose && WizardMode) {
-    gclog_or_tty->print(" [Symbols=%d size=" SIZE_FORMAT "K] ", total,
+    gclog_or_tty->print(" [Symbols=%d size=" SIZE_FORMAT "K] ", *processed,
+                        (memory_total*HeapWordSize)/1024);
+  }
+}
+
+void SymbolTable::possibly_parallel_unlink(int* processed, int* removed) {
+  const int limit = the_table()->table_size();
+
+  size_t memory_total = 0;
+
+  for (;;) {
+    // Grab next set of buckets to scan
+    int start_idx = Atomic::add(ClaimChunkSize, &_parallel_claimed_idx) - ClaimChunkSize;
+    if (start_idx >= limit) {
+      // End of table
+      break;
+    }
+
+    int end_idx = MIN2(limit, start_idx + ClaimChunkSize);
+    buckets_unlink(start_idx, end_idx, processed, removed, &memory_total);
+  }
+  Atomic::add(*processed, &_symbols_counted);
+  Atomic::add(*removed, &_symbols_removed);
+  // Exclude printing for normal PrintGCDetails because people parse
+  // this output.
+  if (PrintGCDetails && Verbose && WizardMode) {
+    gclog_or_tty->print(" [Symbols: scanned=%d removed=%d size=" SIZE_FORMAT "K] ", *processed, *removed,
                         (memory_total*HeapWordSize)/1024);
   }
 }
@@ -503,21 +535,21 @@
     }
   }
   tty->print_cr("Symbol Table:");
-  tty->print_cr("Total number of symbols  %5d", count);
-  tty->print_cr("Total size in memory     %5dK",
+  tty->print_cr("Total number of symbols  "INT32_FORMAT, count);
+  tty->print_cr("Total size in memory     "INT32_FORMAT"K",
           (memory_total*HeapWordSize)/1024);
-  tty->print_cr("Total counted            %5d", symbols_counted);
-  tty->print_cr("Total removed            %5d", symbols_removed);
-  if (symbols_counted > 0) {
+  tty->print_cr("Total counted            "INT32_FORMAT, _symbols_counted);
+  tty->print_cr("Total removed            "INT32_FORMAT, _symbols_removed);
+  if (_symbols_counted > 0) {
     tty->print_cr("Percent removed          %3.2f",
-          ((float)symbols_removed/(float)symbols_counted)* 100);
+          ((float)_symbols_removed/(float)_symbols_counted)* 100);
   }
-  tty->print_cr("Reference counts         %5d", Symbol::_total_count);
-  tty->print_cr("Symbol arena size        %5d used %5d",
+  tty->print_cr("Reference counts         "INT32_FORMAT, Symbol::_total_count);
+  tty->print_cr("Symbol arena size        "SIZE_FORMAT" used "SIZE_FORMAT,
                  arena()->size_in_bytes(), arena()->used());
   tty->print_cr("Histogram of symbol length:");
-  tty->print_cr("%8s %5d", "Total  ", total);
-  tty->print_cr("%8s %5d", "Maximum", max_symbols);
+  tty->print_cr("%8s "INT32_FORMAT, "Total  ", total);
+  tty->print_cr("%8s "INT32_FORMAT, "Maximum", max_symbols);
   tty->print_cr("%8s %3.2f", "Average",
           ((float) total / (float) the_table()->table_size()));
   tty->print_cr("%s", "Histogram:");
@@ -746,11 +778,41 @@
   return result;
 }
 
-void StringTable::unlink(BoolObjectClosure* is_alive) {
+void StringTable::unlink(BoolObjectClosure* is_alive, int* processed, int* removed) {
+    buckets_unlink(is_alive, 0, the_table()->table_size(), processed, removed);
+}
+
+void StringTable::possibly_parallel_unlink(BoolObjectClosure* is_alive, int* processed, int* removed) {
   // Readers of the table are unlocked, so we should only be removing
   // entries at a safepoint.
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
-  for (int i = 0; i < the_table()->table_size(); ++i) {
+  const int limit = the_table()->table_size();
+
+  for (;;) {
+    // Grab next set of buckets to scan
+    int start_idx = Atomic::add(ClaimChunkSize, &_parallel_claimed_idx) - ClaimChunkSize;
+    if (start_idx >= limit) {
+      // End of table
+      break;
+    }
+
+    int end_idx = MIN2(limit, start_idx + ClaimChunkSize);
+    buckets_unlink(is_alive, start_idx, end_idx, processed, removed);
+  }
+}
+
+void StringTable::buckets_unlink(BoolObjectClosure* is_alive, int start_idx, int end_idx, int* processed, int* removed) {
+  const int limit = the_table()->table_size();
+
+  assert(0 <= start_idx && start_idx <= limit,
+         err_msg("start_idx (" INT32_FORMAT ") is out of bounds", start_idx));
+  assert(0 <= end_idx && end_idx <= limit,
+         err_msg("end_idx (" INT32_FORMAT ") is out of bounds", end_idx));
+  assert(start_idx <= end_idx,
+         err_msg("Index ordering: start_idx=" INT32_FORMAT", end_idx=" INT32_FORMAT,
+                 start_idx, end_idx));
+
+  for (int i = start_idx; i < end_idx; ++i) {
     HashtableEntry<oop, mtSymbol>** p = the_table()->bucket_addr(i);
     HashtableEntry<oop, mtSymbol>* entry = the_table()->bucket(i);
     while (entry != NULL) {
@@ -767,24 +829,26 @@
       } else {
         *p = entry->next();
         the_table()->free_entry(entry);
+        (*removed)++;
       }
+      (*processed)++;
       entry = (HashtableEntry<oop, mtSymbol>*)HashtableEntry<oop, mtSymbol>::make_ptr(*p);
     }
   }
 }
 
-void StringTable::buckets_do(OopClosure* f, int start_idx, int end_idx) {
+void StringTable::buckets_oops_do(OopClosure* f, int start_idx, int end_idx) {
   const int limit = the_table()->table_size();
 
   assert(0 <= start_idx && start_idx <= limit,
-         err_msg("start_idx (" INT32_FORMAT ") oob?", start_idx));
+         err_msg("start_idx (" INT32_FORMAT ") is out of bounds", start_idx));
   assert(0 <= end_idx && end_idx <= limit,
-         err_msg("end_idx (" INT32_FORMAT ") oob?", end_idx));
+         err_msg("end_idx (" INT32_FORMAT ") is out of bounds", end_idx));
   assert(start_idx <= end_idx,
-         err_msg("Ordering: start_idx=" INT32_FORMAT", end_idx=" INT32_FORMAT,
+         err_msg("Index ordering: start_idx=" INT32_FORMAT", end_idx=" INT32_FORMAT,
                  start_idx, end_idx));
 
-  for (int i = start_idx; i < end_idx; i += 1) {
+  for (int i = start_idx; i < end_idx; i++) {
     HashtableEntry<oop, mtSymbol>** p = the_table()->bucket_addr(i);
     HashtableEntry<oop, mtSymbol>* entry = the_table()->bucket(i);
     while (entry != NULL) {
@@ -804,11 +868,10 @@
 }
 
 void StringTable::oops_do(OopClosure* f) {
-  buckets_do(f, 0, the_table()->table_size());
+  buckets_oops_do(f, 0, the_table()->table_size());
 }
 
 void StringTable::possibly_parallel_oops_do(OopClosure* f) {
-  const int ClaimChunkSize = 32;
   const int limit = the_table()->table_size();
 
   for (;;) {
@@ -820,7 +883,7 @@
     }
 
     int end_idx = MIN2(limit, start_idx + ClaimChunkSize);
-    buckets_do(f, start_idx, end_idx);
+    buckets_oops_do(f, start_idx, end_idx);
   }
 }
 
--- a/src/share/vm/classfile/symbolTable.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/classfile/symbolTable.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -86,8 +86,8 @@
   static bool _needs_rehashing;
 
   // For statistics
-  static int symbols_removed;
-  static int symbols_counted;
+  static int _symbols_removed;
+  static int _symbols_counted;
 
   Symbol* allocate_symbol(const u1* name, int len, bool c_heap, TRAPS); // Assumes no characters larger than 0x7F
 
@@ -126,6 +126,11 @@
   static Arena* arena() { return _arena; }  // called for statistics
 
   static void initialize_symbols(int arena_alloc_size = 0);
+
+  static volatile int _parallel_claimed_idx;
+
+  // Release any dead symbols
+  static void buckets_unlink(int start_idx, int end_idx, int* processed, int* removed, size_t* memory_total);
 public:
   enum {
     symbol_alloc_batch_size = 8,
@@ -175,7 +180,19 @@
                   unsigned int* hashValues, TRAPS);
 
   // Release any dead symbols
-  static void unlink();
+  static void unlink() {
+    int processed = 0;
+    int removed = 0;
+    unlink(&processed, &removed);
+  }
+  static void unlink(int* processed, int* removed);
+  // Release any dead symbols, possibly parallel version
+  static void possibly_parallel_unlink() {
+    int processed = 0;
+    int removed = 0;
+    possibly_parallel_unlink(&processed, &removed);
+  }
+  static void possibly_parallel_unlink(int* processed, int* removed);
 
   // iterate over symbols
   static void symbols_do(SymbolClosure *cl);
@@ -233,6 +250,9 @@
   // Rehash the symbol table if it gets out of balance
   static void rehash_table();
   static bool needs_rehashing()         { return _needs_rehashing; }
+  // Parallel chunked scanning
+  static void clear_parallel_claimed_index() { _parallel_claimed_idx = 0; }
+  static int parallel_claimed_index() { return _parallel_claimed_idx; }
 };
 
 class StringTable : public Hashtable<oop, mtSymbol> {
@@ -256,7 +276,9 @@
 
   // Apply the give oop closure to the entries to the buckets
   // in the range [start_idx, end_idx).
-  static void buckets_do(OopClosure* f, int start_idx, int end_idx);
+  static void buckets_oops_do(OopClosure* f, int start_idx, int end_idx);
+  // Unlink the entries to the buckets in the range [start_idx, end_idx).
+  static void buckets_unlink(BoolObjectClosure* is_alive, int start_idx, int end_idx, int* processed, int* removed);
 
   StringTable() : Hashtable<oop, mtSymbol>((int)StringTableSize,
                               sizeof (HashtableEntry<oop, mtSymbol>)) {}
@@ -283,7 +305,13 @@
 
   // GC support
   //   Delete pointers to otherwise-unreachable objects.
-  static void unlink(BoolObjectClosure* cl);
+  static void unlink(BoolObjectClosure* cl) {
+    int processed = 0;
+    int removed = 0;
+    unlink(cl, &processed, &removed);
+  }
+
+  static void unlink(BoolObjectClosure* cl, int* processed, int* removed);
 
   // Serially invoke "f->do_oop" on the locations of all oops in the table.
   static void oops_do(OopClosure* f);
@@ -291,6 +319,8 @@
   // Possibly parallel version of the above
   static void possibly_parallel_oops_do(OopClosure* f);
 
+  static void possibly_parallel_unlink(BoolObjectClosure* cl, int* processed, int* removed);
+
   // Hashing algorithm, used as the hash value used by the
   //     StringTable for bucket selection and comparison (stored in the
   //     HashtableEntry structures).  This is used in the String.intern() method.
@@ -328,5 +358,6 @@
 
   // Parallel chunked scanning
   static void clear_parallel_claimed_index() { _parallel_claimed_idx = 0; }
+  static int parallel_claimed_index() { return _parallel_claimed_idx; }
 };
 #endif // SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP
--- a/src/share/vm/classfile/systemDictionary.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/classfile/systemDictionary.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -585,7 +585,7 @@
   assert(name != NULL && !FieldType::is_array(name) &&
          !FieldType::is_obj(name), "invalid class name");
 
-  TracingTime class_load_start_time = Tracing::time();
+  const Ticks class_load_start_time = Ticks::now();
 
   // UseNewReflection
   // Fix for 4474172; see evaluation for more details
@@ -946,7 +946,7 @@
                                         TRAPS) {
   TempNewSymbol parsed_name = NULL;
 
-  TracingTime class_load_start_time = Tracing::time();
+  const Ticks class_load_start_time = Ticks::now();
 
   // Parse the stream. Note that we do this even though this klass might
   // already be present in the SystemDictionary, otherwise we would not
@@ -1572,9 +1572,10 @@
 // Used for assertions and verification only
 klassOop SystemDictionary::find_class(Symbol* class_name, Handle class_loader) {
   #ifndef ASSERT
-  guarantee(VerifyBeforeGC   ||
-            VerifyDuringGC   ||
-            VerifyBeforeExit ||
+  guarantee(VerifyBeforeGC      ||
+            VerifyDuringGC      ||
+            VerifyBeforeExit    ||
+            VerifyDuringStartup ||
             VerifyAfterGC, "too expensive");
   #endif
   assert_locked_or_safepoint(SystemDictionary_lock);
@@ -2314,6 +2315,11 @@
   objArrayHandle appendix_box = oopFactory::new_objArray(SystemDictionary::Object_klass(), 1, CHECK_(empty));
   assert(appendix_box->obj_at(0) == NULL, "");
 
+  // This should not happen.  JDK code should take care of that.
+  if (accessing_klass.is_null() || method_type.is_null()) {
+    THROW_MSG_(vmSymbols::java_lang_InternalError(), "bad invokehandle", empty);
+  }
+
   // call java.lang.invoke.MethodHandleNatives::linkMethod(... String, MethodType) -> MemberName
   JavaCallArguments args;
   args.push_oop(accessing_klass()->java_mirror());
@@ -2439,6 +2445,9 @@
   Handle type;
   if (signature->utf8_length() > 0 && signature->byte_at(0) == '(') {
     type = find_method_handle_type(signature, caller, CHECK_(empty));
+  } else if (caller.is_null()) {
+    // This should not happen.  JDK code should take care of that.
+    THROW_MSG_(vmSymbols::java_lang_InternalError(), "bad MH constant", empty);
   } else {
     ResourceMark rm(THREAD);
     SignatureStream ss(signature, false);
@@ -2502,6 +2511,11 @@
   Handle method_name = java_lang_String::create_from_symbol(name, CHECK_(empty));
   Handle method_type = find_method_handle_type(type, caller, CHECK_(empty));
 
+  // This should not happen.  JDK code should take care of that.
+  if (caller.is_null() || method_type.is_null()) {
+    THROW_MSG_(vmSymbols::java_lang_InternalError(), "bad invokedynamic", empty);
+  }
+
   objArrayHandle appendix_box = oopFactory::new_objArray(SystemDictionary::Object_klass(), 1, CHECK_(empty));
   assert(appendix_box->obj_at(0) == NULL, "");
 
@@ -2607,13 +2621,12 @@
 }
 
 // utility function for posting class load event
-void SystemDictionary::post_class_load_event(TracingTime start_time,
+void SystemDictionary::post_class_load_event(const Ticks& start_time,
                                              instanceKlassHandle k,
                                              Handle initiating_loader) {
 #if INCLUDE_TRACE
   EventClassLoad event(UNTIMED);
   if (event.should_commit()) {
-    event.set_endtime(Tracing::time());
     event.set_starttime(start_time);
     event.set_loadedClass(k());
     oop defining_class_loader = k->class_loader();
@@ -2632,7 +2645,7 @@
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint!");
   if (Tracing::enabled()) {
     _should_write_unload_events = Tracing::is_event_enabled(TraceClassUnloadEvent);
-    _class_unload_time = Tracing::time();
+    _class_unload_time = Ticks::now();
     _is_alive = is_alive;
     classes_do(&class_unload_event);
 
@@ -2648,7 +2661,7 @@
 
 #if INCLUDE_TRACE
 
-TracingTime SystemDictionary::_class_unload_time;
+Ticks SystemDictionary::_class_unload_time;
 BoolObjectClosure* SystemDictionary::_is_alive = NULL;
 int SystemDictionary::_no_of_classes_unloading = 0;
 bool SystemDictionary::_should_write_unload_events = false;
--- a/src/share/vm/classfile/systemDictionary.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/classfile/systemDictionary.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -33,7 +33,7 @@
 #include "runtime/reflectionUtils.hpp"
 #include "utilities/hashtable.hpp"
 #include "utilities/hashtable.inline.hpp"
-#include "trace/traceTime.hpp"
+#include "utilities/ticks.hpp"
 
 // The system dictionary stores all loaded classes and maps:
 //
@@ -151,6 +151,7 @@
   do_klass(MemberName_klass,                            java_lang_invoke_MemberName,               Pre_JSR292          ) \
   do_klass(MethodHandleNatives_klass,                   java_lang_invoke_MethodHandleNatives,      Pre_JSR292          ) \
   do_klass(LambdaForm_klass,                            java_lang_invoke_LambdaForm,               Opt                 ) \
+  do_klass(DirectMethodHandle_klass,                    java_lang_invoke_DirectMethodHandle,       Opt                 ) \
   do_klass(MethodType_klass,                            java_lang_invoke_MethodType,               Pre_JSR292          ) \
   do_klass(BootstrapMethodError_klass,                  java_lang_BootstrapMethodError,            Pre_JSR292          ) \
   do_klass(CallSite_klass,                              java_lang_invoke_CallSite,                 Pre_JSR292          ) \
@@ -616,7 +617,7 @@
   static void add_to_hierarchy(instanceKlassHandle k, TRAPS);
 
   // event based tracing
-  static void post_class_load_event(TracingTime start_time, instanceKlassHandle k,
+  static void post_class_load_event(const Ticks& start_time, instanceKlassHandle k,
                                     Handle initiating_loader);
   static void post_class_unload_events(BoolObjectClosure* is_alive);
 
@@ -678,7 +679,7 @@
   static bool _has_checkPackageAccess;
 
 #if INCLUDE_TRACE
-  static TracingTime _class_unload_time;
+  static Ticks _class_unload_time;
   static BoolObjectClosure* _is_alive;
   static int _no_of_classes_unloading;
   static bool _should_write_unload_events;
--- a/src/share/vm/classfile/vmSymbols.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/classfile/vmSymbols.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -243,6 +243,7 @@
   /* Support for JSR 292 & invokedynamic (JDK 1.7 and above) */                                   \
   template(java_lang_invoke_CallSite,                 "java/lang/invoke/CallSite")                \
   template(java_lang_invoke_ConstantCallSite,         "java/lang/invoke/ConstantCallSite")        \
+  template(java_lang_invoke_DirectMethodHandle,       "java/lang/invoke/DirectMethodHandle")      \
   template(java_lang_invoke_MutableCallSite,          "java/lang/invoke/MutableCallSite")         \
   template(java_lang_invoke_VolatileCallSite,         "java/lang/invoke/VolatileCallSite")        \
   template(java_lang_invoke_MethodHandle,             "java/lang/invoke/MethodHandle")            \
@@ -338,6 +339,7 @@
   template(thread_id_name,                            "tid")                                      \
   template(newInstance0_name,                         "newInstance0")                             \
   template(limit_name,                                "limit")                                    \
+  template(member_name,                               "member")                                   \
   template(forName_name,                              "forName")                                  \
   template(forName0_name,                             "forName0")                                 \
   template(isJavaIdentifierStart_name,                "isJavaIdentifierStart")                    \
--- a/src/share/vm/code/nmethod.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/code/nmethod.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -676,6 +676,7 @@
     code_buffer->copy_oops_to(this);
     if (ScavengeRootsInCode && detect_scavenge_root_oops()) {
       CodeCache::add_scavenge_root_nmethod(this);
+      Universe::heap()->register_nmethod(this);
     }
     debug_only(verify_scavenge_root_oops());
     CodeCache::commit(this);
@@ -869,6 +870,7 @@
     dependencies->copy_to(this);
     if (ScavengeRootsInCode && detect_scavenge_root_oops()) {
       CodeCache::add_scavenge_root_nmethod(this);
+      Universe::heap()->register_nmethod(this);
     }
     debug_only(verify_scavenge_root_oops());
 
@@ -1282,6 +1284,13 @@
   methodHandle the_method(method());
   No_Safepoint_Verifier nsv;
 
+  // during patching, depending on the nmethod state we must notify the GC that
+  // code has been unloaded, unregistering it. We cannot do this right while
+  // holding the Patching_lock because we need to use the CodeCache_lock. This
+  // would be prone to deadlocks.
+  // This flag is used to remember whether we need to later lock and unregister.
+  bool nmethod_needs_unregister = false;
+
   {
     // invalidate osr nmethod before acquiring the patching lock since
     // they both acquire leaf locks and we don't want a deadlock.
@@ -1314,6 +1323,13 @@
       inc_decompile_count();
     }
 
+    // If the state is becoming a zombie, signal to unregister the nmethod with
+    // the heap.
+    // This nmethod may have already been unloaded during a full GC.
+    if ((state == zombie) && !is_unloaded()) {
+      nmethod_needs_unregister = true;
+    }
+
     // Change state
     // We must ensure that state transition normal -> not_entrant is
     // visible before VEP patch becomes visible. We must complete
@@ -1354,6 +1370,9 @@
       // safepoint can sneak in, otherwise the oops used by the
       // dependency logic could have become stale.
       MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+      if (nmethod_needs_unregister) {
+        Universe::heap()->unregister_nmethod(this);
+      }
       flush_dependencies(NULL);
     }
 
@@ -1701,20 +1720,10 @@
 #endif // !PRODUCT
 }
 
-// This method is called twice during GC -- once while
-// tracing the "active" nmethods on thread stacks during
-// the (strong) marking phase, and then again when walking
-// the code cache contents during the weak roots processing
-// phase. The two uses are distinguished by means of the
-// 'do_strong_roots_only' flag, which is true in the first
-// case. We want to walk the weak roots in the nmethod
-// only in the second case. The weak roots in the nmethod
-// are the oops in the ExceptionCache and the InlineCache
-// oops.
-void nmethod::oops_do(OopClosure* f, bool do_strong_roots_only) {
-  // make sure the oops ready to receive visitors
-  assert(!is_zombie() && !is_unloaded(),
-         "should not call follow on zombie or unloaded nmethod");
+void nmethod::oops_do(OopClosure* f, bool do_strong_roots_only, bool allow_zombie) {
+   // make sure the oops ready to receive visitors
+  assert(allow_zombie || !is_zombie(), "should not call follow on zombie nmethod");
+  assert(!is_unloaded(), "should not call follow on unloaded nmethod");
 
   // If the method is not entrant or zombie then a JMP is plastered over the
   // first few bytes.  If an oop in the old code was there, that oop
--- a/src/share/vm/code/nmethod.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/code/nmethod.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -548,8 +548,8 @@
 
   void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map,
                                      OopClosure* f);
-  void oops_do(OopClosure* f) { oops_do(f, false); }
-  void oops_do(OopClosure* f, bool do_strong_roots_only);
+  void oops_do(OopClosure* f) { oops_do(f, false, false); }
+  void oops_do(OopClosure* f, bool do_strong_roots_only, bool allow_zombie);
   bool detect_scavenge_root_oops();
   void verify_scavenge_root_oops() PRODUCT_RETURN;
 
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -58,8 +58,22 @@
   MarkRefsIntoClosure(MemRegion span, CMSBitMap* bitMap);
   virtual void do_oop(oop* p);
   virtual void do_oop(narrowOop* p);
-  inline void do_oop_nv(oop* p)       { MarkRefsIntoClosure::do_oop_work(p); }
-  inline void do_oop_nv(narrowOop* p) { MarkRefsIntoClosure::do_oop_work(p); }
+
+  Prefetch::style prefetch_style() {
+    return Prefetch::do_read;
+  }
+};
+
+class Par_MarkRefsIntoClosure: public OopsInGenClosure {
+ private:
+  const MemRegion _span;
+  CMSBitMap*      _bitMap;
+ protected:
+  DO_OOP_WORK_DEFN
+ public:
+  Par_MarkRefsIntoClosure(MemRegion span, CMSBitMap* bitMap);
+  virtual void do_oop(oop* p);
+  virtual void do_oop(narrowOop* p);
   bool do_header() { return true; }
   Prefetch::style prefetch_style() {
     return Prefetch::do_read;
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -575,6 +575,7 @@
   _restart_addr(NULL),
   _overflow_list(NULL),
   _stats(cmsGen),
+  _eden_chunk_lock(new Mutex(Mutex::leaf + 1, "CMS_eden_chunk_lock", true)),
   _eden_chunk_array(NULL),     // may be set in ctor body
   _eden_chunk_capacity(0),     // -- ditto --
   _eden_chunk_index(0),        // -- ditto --
@@ -754,7 +755,7 @@
   assert(_eden_chunk_array != NULL || _eden_chunk_capacity == 0, "Error");
 
   // Support for parallelizing survivor space rescan
-  if (CMSParallelRemarkEnabled && CMSParallelSurvivorRemarkEnabled) {
+  if ((CMSParallelRemarkEnabled && CMSParallelSurvivorRemarkEnabled) || CMSParallelInitialMarkEnabled) {
     const size_t max_plab_samples =
       ((DefNewGeneration*)_young_gen)->max_survivor_size()/MinTLABSize;
 
@@ -1997,7 +1998,7 @@
   GenCollectedHeap* gch = GenCollectedHeap::heap();
 
   STWGCTimer* gc_timer = GenMarkSweep::gc_timer();
-  gc_timer->register_gc_start(os::elapsed_counter());
+  gc_timer->register_gc_start();
 
   SerialOldTracer* gc_tracer = GenMarkSweep::gc_tracer();
   gc_tracer->report_gc_start(gch->gc_cause(), gc_timer->gc_start());
@@ -2094,7 +2095,7 @@
     size_policy()->msc_collection_end(gch->gc_cause());
   }
 
-  gc_timer->register_gc_end(os::elapsed_counter());
+  gc_timer->register_gc_end();
 
   gc_tracer->report_gc_end(gc_timer->gc_end(), gc_timer->time_partitions());
 
@@ -2136,6 +2137,39 @@
 }
 
 
+void CMSCollector::print_eden_and_survivor_chunk_arrays() {
+  DefNewGeneration* dng = _young_gen->as_DefNewGeneration();
+  EdenSpace* eden_space = dng->eden();
+  ContiguousSpace* from_space = dng->from();
+  ContiguousSpace* to_space   = dng->to();
+  // Eden
+  if (_eden_chunk_array != NULL) {
+    gclog_or_tty->print_cr("eden " PTR_FORMAT "-" PTR_FORMAT "-" PTR_FORMAT "(" SIZE_FORMAT ")",
+                           eden_space->bottom(), eden_space->top(),
+                           eden_space->end(), eden_space->capacity());
+    gclog_or_tty->print_cr("_eden_chunk_index=" SIZE_FORMAT ", "
+                           "_eden_chunk_capacity=" SIZE_FORMAT,
+                           _eden_chunk_index, _eden_chunk_capacity);
+    for (size_t i = 0; i < _eden_chunk_index; i++) {
+      gclog_or_tty->print_cr("_eden_chunk_array[" SIZE_FORMAT "]=" PTR_FORMAT,
+                             i, _eden_chunk_array[i]);
+    }
+  }
+  // Survivor
+  if (_survivor_chunk_array != NULL) {
+    gclog_or_tty->print_cr("survivor " PTR_FORMAT "-" PTR_FORMAT "-" PTR_FORMAT "(" SIZE_FORMAT ")",
+                           from_space->bottom(), from_space->top(),
+                           from_space->end(), from_space->capacity());
+    gclog_or_tty->print_cr("_survivor_chunk_index=" SIZE_FORMAT ", "
+                           "_survivor_chunk_capacity=" SIZE_FORMAT,
+                           _survivor_chunk_index, _survivor_chunk_capacity);
+    for (size_t i = 0; i < _survivor_chunk_index; i++) {
+      gclog_or_tty->print_cr("_survivor_chunk_array[" SIZE_FORMAT "]=" PTR_FORMAT,
+                             i, _survivor_chunk_array[i]);
+    }
+  }
+}
+
 void CMSCollector::getFreelistLocks() const {
   // Get locks for all free lists in all generations that this
   // collector is responsible for
@@ -2443,7 +2477,7 @@
 
 void CMSCollector::register_gc_start(GCCause::Cause cause) {
   _cms_start_registered = true;
-  _gc_timer_cm->register_gc_start(os::elapsed_counter());
+  _gc_timer_cm->register_gc_start();
   _gc_tracer_cm->report_gc_start(cause, _gc_timer_cm->gc_start());
 }
 
@@ -2451,7 +2485,7 @@
   if (_cms_start_registered) {
     report_heap_summary(GCWhen::AfterGC);
 
-    _gc_timer_cm->register_gc_end(os::elapsed_counter());
+    _gc_timer_cm->register_gc_end();
     _gc_tracer_cm->report_gc_end(_gc_timer_cm->gc_end(), _gc_timer_cm->time_partitions());
     _cms_start_registered = false;
   }
@@ -2510,8 +2544,7 @@
         // initial marking in checkpointRootsInitialWork has been completed
         if (VerifyDuringGC &&
             GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
-          gclog_or_tty->print("Verify before initial mark: ");
-          Universe::verify();
+          Universe::verify("Verify before initial mark: ");
         }
         {
           bool res = markFromRoots(false);
@@ -2522,8 +2555,7 @@
       case FinalMarking:
         if (VerifyDuringGC &&
             GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
-          gclog_or_tty->print("Verify before re-mark: ");
-          Universe::verify();
+          Universe::verify("Verify before re-mark: ");
         }
         checkpointRootsFinal(false, clear_all_soft_refs,
                              init_mark_was_synchronous);
@@ -2534,8 +2566,7 @@
         // final marking in checkpointRootsFinal has been completed
         if (VerifyDuringGC &&
             GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
-          gclog_or_tty->print("Verify before sweep: ");
-          Universe::verify();
+          Universe::verify("Verify before sweep: ");
         }
         sweep(false);
         assert(_collectorState == Resizing, "Incorrect state");
@@ -2550,8 +2581,7 @@
         // The heap has been resized.
         if (VerifyDuringGC &&
             GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
-          gclog_or_tty->print("Verify before reset: ");
-          Universe::verify();
+          Universe::verify("Verify before reset: ");
         }
         save_heap_summary();
         reset(false);
@@ -2890,8 +2920,8 @@
   bool failed() { return _failed; }
 };
 
-bool CMSCollector::verify_after_remark() {
-  gclog_or_tty->print(" [Verifying CMS Marking... ");
+bool CMSCollector::verify_after_remark(bool silent) {
+  if (!silent) gclog_or_tty->print(" [Verifying CMS Marking... ");
   MutexLockerEx ml(verification_mark_bm()->lock(), Mutex::_no_safepoint_check_flag);
   static bool init = false;
 
@@ -2952,7 +2982,7 @@
     warning("Unrecognized value %d for CMSRemarkVerifyVariant",
             CMSRemarkVerifyVariant);
   }
-  gclog_or_tty->print(" done] ");
+  if (!silent) gclog_or_tty->print(" done] ");
   return true;
 }
 
@@ -3530,6 +3560,31 @@
 
 // CMS work
 
+// The common parts of CMSParInitialMarkTask and CMSParRemarkTask.
+class CMSParMarkTask : public AbstractGangTask {
+ protected:
+  CMSCollector*     _collector;
+  int               _n_workers;
+  CMSParMarkTask(const char* name, CMSCollector* collector, int n_workers) :
+      AbstractGangTask(name),
+      _collector(collector),
+      _n_workers(n_workers) {}
+  // Work method in support of parallel rescan ... of young gen spaces
+  void do_young_space_rescan(uint worker_id, OopsInGenClosure* cl,
+                             ContiguousSpace* space,
+                             HeapWord** chunk_array, size_t chunk_top);
+  void work_on_young_gen_roots(uint worker_id, OopsInGenClosure* cl);
+};
+
+// Parallel initial mark task
+class CMSParInitialMarkTask: public CMSParMarkTask {
+ public:
+  CMSParInitialMarkTask(CMSCollector* collector, int n_workers) :
+      CMSParMarkTask("Scan roots and young gen for initial mark in parallel",
+                     collector, n_workers) {}
+  void work(uint worker_id);
+};
+
 // Checkpoint the roots into this generation from outside
 // this generation. [Note this initial checkpoint need only
 // be approximate -- we'll do a catch up phase subsequently.]
@@ -3619,20 +3674,42 @@
   // weak reference processing has not started yet.
   ref_processor()->set_enqueuing_is_done(false);
 
+  if (CMSPrintEdenSurvivorChunks) {
+    print_eden_and_survivor_chunk_arrays();
+  }
+
   {
     // This is not needed. DEBUG_ONLY(RememberKlassesChecker imx(true);)
     COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;)
-    gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
-    gch->gen_process_strong_roots(_cmsGen->level(),
-                                  true,   // younger gens are roots
-                                  true,   // activate StrongRootsScope
-                                  true,   // collecting perm gen
-                                  SharedHeap::ScanningOption(roots_scanning_options()),
-                                  &notOlder,
-                                  true,   // walk all of code cache if (so & SO_CodeCache)
-                                  NULL);
-  }
-
+    if (CMSParallelInitialMarkEnabled && CollectedHeap::use_parallel_gc_threads()) {
+      // The parallel version.
+      FlexibleWorkGang* workers = gch->workers();
+      assert(workers != NULL, "Need parallel worker threads.");
+      int n_workers = workers->active_workers();
+      CMSParInitialMarkTask tsk(this, n_workers);
+      gch->set_par_threads(n_workers);
+      initialize_sequential_subtasks_for_young_gen_rescan(n_workers);
+      if (n_workers > 1) {
+        GenCollectedHeap::StrongRootsScope srs(gch);
+        workers->run_task(&tsk);
+      } else {
+        GenCollectedHeap::StrongRootsScope srs(gch);
+        tsk.work(0);
+      }
+      gch->set_par_threads(0);
+    } else {
+      // The serial version.
+      gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
+      gch->gen_process_strong_roots(_cmsGen->level(),
+                                    true,   // younger gens are roots
+                                    true,   // activate StrongRootsScope
+                                    true,   // collecting perm gen
+                                    SharedHeap::ScanningOption(roots_scanning_options()),
+                                    &notOlder,
+                                    true,   // walk all of code cache if (so & SO_CodeCache)
+                                    NULL);
+    }
+  }
   // Clear mod-union table; it will be dirtied in the prologue of
   // CMS generation per each younger generation collection.
 
@@ -4414,7 +4491,9 @@
   verify_overflow_empty();
   _abort_preclean = false;
   if (CMSPrecleaningEnabled) {
-    _eden_chunk_index = 0;
+    if (!CMSEdenChunksRecordAlways) {
+      _eden_chunk_index = 0;
+    }
     size_t used = get_eden_used();
     size_t capacity = get_eden_capacity();
     // Don't start sampling unless we will get sufficiently
@@ -4523,7 +4602,9 @@
   if (!_start_sampling) {
     return;
   }
-  if (_eden_chunk_array) {
+  // When CMSEdenChunksRecordAlways is true, the eden chunk array
+  // is populated by the young generation.
+  if (_eden_chunk_array != NULL && !CMSEdenChunksRecordAlways) {
     if (_eden_chunk_index < _eden_chunk_capacity) {
       _eden_chunk_array[_eden_chunk_index] = *_top_addr;   // take sample
       assert(_eden_chunk_array[_eden_chunk_index] <= *_end_addr,
@@ -5000,6 +5081,10 @@
     // Update the saved marks which may affect the root scans.
     gch->save_marks();
 
+    if (CMSPrintEdenSurvivorChunks) {
+      print_eden_and_survivor_chunk_arrays();
+    }
+
     {
       COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;)
 
@@ -5107,10 +5192,51 @@
   }
 }
 
+void CMSParInitialMarkTask::work(uint worker_id) {
+  elapsedTimer _timer;
+  ResourceMark rm;
+  HandleMark   hm;
+
+  // ---------- scan from roots --------------
+  _timer.start();
+  GenCollectedHeap* gch = GenCollectedHeap::heap();
+  Par_MarkRefsIntoClosure par_mri_cl(_collector->_span, &(_collector->_markBitMap));
+
+  // ---------- young gen roots --------------
+  {
+    work_on_young_gen_roots(worker_id, &par_mri_cl);
+    _timer.stop();
+    if (PrintCMSStatistics != 0) {
+      gclog_or_tty->print_cr(
+        "Finished young gen initial mark scan work in %dth thread: %3.3f sec",
+        worker_id, _timer.seconds());
+    }
+  }
+
+  // ---------- remaining roots --------------
+  _timer.reset();
+  _timer.start();
+  gch->gen_process_strong_roots(_collector->_cmsGen->level(),
+                                false,     // yg was scanned above
+                                false,     // this is parallel code
+                                true,      // collecting perm gen
+                                SharedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()),
+                                &par_mri_cl,
+                                true,   // walk all of code cache if (so & SO_CodeCache)
+                                NULL);
+  assert(_collector->should_unload_classes()
+         || (_collector->CMSCollector::roots_scanning_options() & SharedHeap::SO_CodeCache),
+         "if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops");
+  _timer.stop();
+  if (PrintCMSStatistics != 0) {
+    gclog_or_tty->print_cr(
+      "Finished remaining root initial mark scan work in %dth thread: %3.3f sec",
+      worker_id, _timer.seconds());
+  }
+}
+
 // Parallel remark task
-class CMSParRemarkTask: public AbstractGangTask {
-  CMSCollector* _collector;
-  int           _n_workers;
+class CMSParRemarkTask: public CMSParMarkTask {
   CompactibleFreeListSpace* _cms_space;
   CompactibleFreeListSpace* _perm_space;
 
@@ -5126,10 +5252,9 @@
                    CompactibleFreeListSpace* perm_space,
                    int n_workers, FlexibleWorkGang* workers,
                    OopTaskQueueSet* task_queues):
-    AbstractGangTask("Rescan roots and grey objects in parallel"),
-    _collector(collector),
+    CMSParMarkTask("Rescan roots and grey objects in parallel",
+                   collector, n_workers),
     _cms_space(cms_space), _perm_space(perm_space),
-    _n_workers(n_workers),
     _task_queues(task_queues),
     _term(n_workers, task_queues) { }
 
@@ -5143,11 +5268,6 @@
   void work(uint worker_id);
 
  private:
-  // Work method in support of parallel rescan ... of young gen spaces
-  void do_young_space_rescan(int i, Par_MarkRefsIntoAndScanClosure* cl,
-                             ContiguousSpace* space,
-                             HeapWord** chunk_array, size_t chunk_top);
-
   // ... of  dirty cards in old space
   void do_dirty_card_rescan_tasks(CompactibleFreeListSpace* sp, int i,
                                   Par_MarkRefsIntoAndScanClosure* cl);
@@ -5156,6 +5276,25 @@
   void do_work_steal(int i, Par_MarkRefsIntoAndScanClosure* cl, int* seed);
 };
 
+void CMSParMarkTask::work_on_young_gen_roots(uint worker_id, OopsInGenClosure* cl) {
+  DefNewGeneration* dng = _collector->_young_gen->as_DefNewGeneration();
+  EdenSpace* eden_space = dng->eden();
+  ContiguousSpace* from_space = dng->from();
+  ContiguousSpace* to_space   = dng->to();
+
+  HeapWord** eca = _collector->_eden_chunk_array;
+  size_t     ect = _collector->_eden_chunk_index;
+  HeapWord** sca = _collector->_survivor_chunk_array;
+  size_t     sct = _collector->_survivor_chunk_index;
+
+  assert(ect <= _collector->_eden_chunk_capacity, "out of bounds");
+  assert(sct <= _collector->_survivor_chunk_capacity, "out of bounds");
+
+  do_young_space_rescan(worker_id, cl, to_space, NULL, 0);
+  do_young_space_rescan(worker_id, cl, from_space, sca, sct);
+  do_young_space_rescan(worker_id, cl, eden_space, eca, ect);
+}
+
 // work_queue(i) is passed to the closure
 // Par_MarkRefsIntoAndScanClosure.  The "i" parameter
 // also is passed to do_dirty_card_rescan_tasks() and to
@@ -5180,23 +5319,7 @@
   // work first.
   // ---------- young gen roots --------------
   {
-    DefNewGeneration* dng = _collector->_young_gen->as_DefNewGeneration();
-    EdenSpace* eden_space = dng->eden();
-    ContiguousSpace* from_space = dng->from();
-    ContiguousSpace* to_space   = dng->to();
-
-    HeapWord** eca = _collector->_eden_chunk_array;
-    size_t     ect = _collector->_eden_chunk_index;
-    HeapWord** sca = _collector->_survivor_chunk_array;
-    size_t     sct = _collector->_survivor_chunk_index;
-
-    assert(ect <= _collector->_eden_chunk_capacity, "out of bounds");
-    assert(sct <= _collector->_survivor_chunk_capacity, "out of bounds");
-
-    do_young_space_rescan(worker_id, &par_mrias_cl, to_space, NULL, 0);
-    do_young_space_rescan(worker_id, &par_mrias_cl, from_space, sca, sct);
-    do_young_space_rescan(worker_id, &par_mrias_cl, eden_space, eca, ect);
-
+    work_on_young_gen_roots(worker_id, &par_mrias_cl);
     _timer.stop();
     if (PrintCMSStatistics != 0) {
       gclog_or_tty->print_cr(
@@ -5257,8 +5380,8 @@
 
 // Note that parameter "i" is not used.
 void
-CMSParRemarkTask::do_young_space_rescan(int i,
-  Par_MarkRefsIntoAndScanClosure* cl, ContiguousSpace* space,
+CMSParMarkTask::do_young_space_rescan(uint worker_id,
+  OopsInGenClosure* cl, ContiguousSpace* space,
   HeapWord** chunk_array, size_t chunk_top) {
   // Until all tasks completed:
   // . claim an unclaimed task
@@ -5454,6 +5577,32 @@
          "Else our work is not yet done");
 }
 
+// Record object boundaries in _eden_chunk_array by sampling the eden
+// top in the slow-path eden object allocation code path and record
+// the boundaries, if CMSEdenChunksRecordAlways is true. If
+// CMSEdenChunksRecordAlways is false, we use the other asynchronous
+// sampling in sample_eden() that activates during the part of the
+// preclean phase.
+void CMSCollector::sample_eden_chunk() {
+  if (CMSEdenChunksRecordAlways && _eden_chunk_array != NULL) {
+    if (_eden_chunk_lock->try_lock()) {
+      // Record a sample. This is the critical section. The contents
+      // of the _eden_chunk_array have to be non-decreasing in the
+      // address order.
+      _eden_chunk_array[_eden_chunk_index] = *_top_addr;
+      assert(_eden_chunk_array[_eden_chunk_index] <= *_end_addr,
+             "Unexpected state of Eden");
+      if (_eden_chunk_index == 0 ||
+          ((_eden_chunk_array[_eden_chunk_index] > _eden_chunk_array[_eden_chunk_index-1]) &&
+           (pointer_delta(_eden_chunk_array[_eden_chunk_index],
+                          _eden_chunk_array[_eden_chunk_index-1]) >= CMSSamplingGrain))) {
+        _eden_chunk_index++;  // commit sample
+      }
+      _eden_chunk_lock->unlock();
+    }
+  }
+}
+
 // Return a thread-local PLAB recording array, as appropriate.
 void* CMSCollector::get_data_recorder(int thr_num) {
   if (_survivor_plab_array != NULL &&
@@ -5477,12 +5626,13 @@
 
 // Merge the per-thread plab arrays into the global survivor chunk
 // array which will provide the partitioning of the survivor space
-// for CMS rescan.
+// for CMS initial scan and rescan.
 void CMSCollector::merge_survivor_plab_arrays(ContiguousSpace* surv,
                                               int no_of_gc_threads) {
   assert(_survivor_plab_array  != NULL, "Error");
   assert(_survivor_chunk_array != NULL, "Error");
-  assert(_collectorState == FinalMarking, "Error");
+  assert(_collectorState == FinalMarking ||
+         (CMSParallelInitialMarkEnabled && _collectorState == InitialMarking), "Error");
   for (int j = 0; j < no_of_gc_threads; j++) {
     _cursor[j] = 0;
   }
@@ -5545,7 +5695,7 @@
 }
 
 // Set up the space's par_seq_tasks structure for work claiming
-// for parallel rescan of young gen.
+// for parallel initial scan and rescan of young gen.
 // See ParRescanTask where this is currently used.
 void
 CMSCollector::
@@ -6695,6 +6845,28 @@
 void MarkRefsIntoClosure::do_oop(oop* p)       { MarkRefsIntoClosure::do_oop_work(p); }
 void MarkRefsIntoClosure::do_oop(narrowOop* p) { MarkRefsIntoClosure::do_oop_work(p); }
 
+Par_MarkRefsIntoClosure::Par_MarkRefsIntoClosure(
+  MemRegion span, CMSBitMap* bitMap):
+    _span(span),
+    _bitMap(bitMap)
+{
+    assert(_ref_processor == NULL, "deliberately left NULL");
+    assert(_bitMap->covers(_span), "_bitMap/_span mismatch");
+}
+
+void Par_MarkRefsIntoClosure::do_oop(oop obj) {
+  // if p points into _span, then mark corresponding bit in _markBitMap
+  assert(obj->is_oop(), "expected an oop");
+  HeapWord* addr = (HeapWord*)obj;
+  if (_span.contains(addr)) {
+    // this should be made more efficient
+    _bitMap->par_mark(addr);
+  }
+}
+
+void Par_MarkRefsIntoClosure::do_oop(oop* p)       { Par_MarkRefsIntoClosure::do_oop_work(p); }
+void Par_MarkRefsIntoClosure::do_oop(narrowOop* p) { Par_MarkRefsIntoClosure::do_oop_work(p); }
+
 // A variant of the above, used for CMS marking verification.
 MarkRefsIntoVerifyClosure::MarkRefsIntoVerifyClosure(
   MemRegion span, CMSBitMap* verification_bm, CMSBitMap* cms_bm):
@@ -9360,7 +9532,6 @@
     return;
   }
 }
-
 // Transfer some number of overflown objects to usual marking
 // stack. Return true if some objects were transferred.
 bool MarkRefsIntoAndScanClosure::take_from_overflow_list() {
@@ -9432,4 +9603,3 @@
       ShouldNotReachHere();
   }
 }
-
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -516,6 +516,8 @@
   friend class ConcurrentMarkSweepThread;
   friend class ConcurrentMarkSweepGeneration;
   friend class CompactibleFreeListSpace;
+  friend class CMSParMarkTask;
+  friend class CMSParInitialMarkTask;
   friend class CMSParRemarkTask;
   friend class CMSConcMarkingTask;
   friend class CMSRefProcTaskProxy;
@@ -752,6 +754,7 @@
   Generation* _young_gen;  // the younger gen
   HeapWord** _top_addr;    // ... Top of Eden
   HeapWord** _end_addr;    // ... End of Eden
+  Mutex*     _eden_chunk_lock;
   HeapWord** _eden_chunk_array; // ... Eden partitioning array
   size_t     _eden_chunk_index; // ... top (exclusive) of array
   size_t     _eden_chunk_capacity;  // ... max entries in array
@@ -953,6 +956,7 @@
 
   // Support for parallel remark of survivor space
   void* get_data_recorder(int thr_num);
+  void sample_eden_chunk();
 
   CMSBitMap* markBitMap()  { return &_markBitMap; }
   void directAllocated(HeapWord* start, size_t size);
@@ -1013,7 +1017,7 @@
 
   // debugging
   void verify();
-  bool verify_after_remark();
+  bool verify_after_remark(bool silent = VerifySilently);
   void verify_ok_to_terminate() const PRODUCT_RETURN;
   void verify_work_stacks_empty() const PRODUCT_RETURN;
   void verify_overflow_empty() const PRODUCT_RETURN;
@@ -1031,6 +1035,8 @@
 
   // Initialization errors
   bool completed_initialization() { return _completed_initialization; }
+
+  void print_eden_and_survivor_chunk_arrays();
 };
 
 class CMSExpansionCause : public AllStatic  {
@@ -1317,6 +1323,10 @@
     //Delegate to collector
     return collector()->get_data_recorder(thr_num);
   }
+  void sample_eden_chunk() {
+    //Delegate to collector
+    return collector()->sample_eden_chunk();
+  }
 
   // Printing
   const char* name() const;
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, 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
@@ -145,7 +145,7 @@
                                 );
 #endif /* USDT2 */
 
-  _collector->_gc_timer_cm->register_gc_pause_start("Initial Mark", os::elapsed_counter());
+  _collector->_gc_timer_cm->register_gc_pause_start("Initial Mark");
 
   GenCollectedHeap* gch = GenCollectedHeap::heap();
   GCCauseSetter gccs(gch, GCCause::_cms_initial_mark);
@@ -157,7 +157,7 @@
 
   VM_CMS_Operation::verify_after_gc();
 
-  _collector->_gc_timer_cm->register_gc_pause_end(os::elapsed_counter());
+  _collector->_gc_timer_cm->register_gc_pause_end();
 
 #ifndef USDT2
   HS_DTRACE_PROBE(hs_private, cms__initmark__end);
@@ -182,7 +182,7 @@
                                 );
 #endif /* USDT2 */
 
-  _collector->_gc_timer_cm->register_gc_pause_start("Final Mark", os::elapsed_counter());
+  _collector->_gc_timer_cm->register_gc_pause_start("Final Mark");
 
   GenCollectedHeap* gch = GenCollectedHeap::heap();
   GCCauseSetter gccs(gch, GCCause::_cms_final_remark);
@@ -195,7 +195,7 @@
   VM_CMS_Operation::verify_after_gc();
 
   _collector->save_heap_summary();
-  _collector->_gc_timer_cm->register_gc_pause_end(os::elapsed_counter());
+  _collector->_gc_timer_cm->register_gc_pause_end();
 
 #ifndef USDT2
   HS_DTRACE_PROBE(hs_private, cms__remark__end);
--- a/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -114,6 +114,14 @@
   }
 }
 
+void ConcurrentG1Refine::worker_threads_do(ThreadClosure * tc) {
+  if (_threads != NULL) {
+    for (int i = 0; i < worker_thread_num(); i++) {
+      tc->do_thread(_threads[i]);
+    }
+  }
+}
+
 int ConcurrentG1Refine::thread_num() {
   int n_threads = (G1ConcRefinementThreads > 0) ? G1ConcRefinementThreads
                                                 : ParallelGCThreads;
@@ -126,3 +134,7 @@
     st->cr();
   }
 }
+
+ConcurrentG1RefineThread * ConcurrentG1Refine::sampling_thread() const {
+  return _threads[worker_thread_num()];
+}
--- a/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -35,6 +35,7 @@
 class G1CollectedHeap;
 class G1HotCardCache;
 class G1RemSet;
+class DirtyCardQueue;
 
 class ConcurrentG1Refine: public CHeapObj<mtGC> {
   ConcurrentG1RefineThread** _threads;
@@ -78,9 +79,15 @@
 
   void reinitialize_threads();
 
-  // Iterate over the conc refine threads
+  // Iterate over all concurrent refinement threads
   void threads_do(ThreadClosure *tc);
 
+  // Iterate over all worker refinement threads
+  void worker_threads_do(ThreadClosure * tc);
+
+  // The RS sampling thread
+  ConcurrentG1RefineThread * sampling_thread() const;
+
   static int thread_num();
 
   void print_worker_threads_on(outputStream* st) const;
--- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1154,10 +1154,9 @@
 
   if (VerifyDuringGC) {
     HandleMark hm;  // handle scope
-    gclog_or_tty->print(" VerifyDuringGC:(before)");
     Universe::heap()->prepare_for_verify();
-    Universe::verify(/* silent */ false,
-                     /* option */ VerifyOption_G1UsePrevMarking);
+    Universe::verify(VerifyOption_G1UsePrevMarking,
+                     " VerifyDuringGC:(before)");
   }
 
   G1CollectorPolicy* g1p = g1h->g1_policy();
@@ -1181,10 +1180,9 @@
     // Verify the heap w.r.t. the previous marking bitmap.
     if (VerifyDuringGC) {
       HandleMark hm;  // handle scope
-      gclog_or_tty->print(" VerifyDuringGC:(overflow)");
       Universe::heap()->prepare_for_verify();
-      Universe::verify(/* silent */ false,
-                       /* option */ VerifyOption_G1UsePrevMarking);
+      Universe::verify(VerifyOption_G1UsePrevMarking,
+                       " VerifyDuringGC:(overflow)");
     }
 
     // Clear the marking state because we will be restarting
@@ -1204,10 +1202,9 @@
 
     if (VerifyDuringGC) {
       HandleMark hm;  // handle scope
-      gclog_or_tty->print(" VerifyDuringGC:(after)");
       Universe::heap()->prepare_for_verify();
-      Universe::verify(/* silent */ false,
-                       /* option */ VerifyOption_G1UseNextMarking);
+      Universe::verify(VerifyOption_G1UseNextMarking,
+                       " VerifyDuringGC:(after)");
     }
     assert(!restart_for_overflow(), "sanity");
     // Completely reset the marking state since marking completed
@@ -1498,7 +1495,6 @@
   }
 };
 
-
 class G1ParVerifyFinalCountTask: public AbstractGangTask {
 protected:
   G1CollectedHeap* _g1h;
@@ -1856,10 +1852,9 @@
 
   if (VerifyDuringGC) {
     HandleMark hm;  // handle scope
-    gclog_or_tty->print(" VerifyDuringGC:(before)");
     Universe::heap()->prepare_for_verify();
-    Universe::verify(/* silent */ false,
-                     /* option */ VerifyOption_G1UsePrevMarking);
+    Universe::verify(VerifyOption_G1UsePrevMarking,
+                     " VerifyDuringGC:(before)");
   }
 
   G1CollectorPolicy* g1p = G1CollectedHeap::heap()->g1_policy();
@@ -2011,10 +2006,9 @@
 
   if (VerifyDuringGC) {
     HandleMark hm;  // handle scope
-    gclog_or_tty->print(" VerifyDuringGC:(after)");
     Universe::heap()->prepare_for_verify();
-    Universe::verify(/* silent */ false,
-                     /* option */ VerifyOption_G1UsePrevMarking);
+    Universe::verify(VerifyOption_G1UsePrevMarking,
+                     " VerifyDuringGC:(after)");
   }
 
   g1h->verify_region_sets_optional();
@@ -2412,10 +2406,9 @@
     assert(!rp->discovery_enabled(), "Post condition");
   }
 
-  // Now clean up stale oops in StringTable
-  StringTable::unlink(&g1_is_alive);
-  // Clean up unreferenced symbols in symbol table.
-  SymbolTable::unlink();
+  g1h->unlink_string_and_symbol_table(&g1_is_alive,
+                                      /* process_strings */ false, // currently strings are always roots
+                                      /* process_symbols */ true);
 }
 
 void ConcurrentMark::swapMarkBitMaps() {
@@ -4396,7 +4389,8 @@
     _total_used_bytes(0), _total_capacity_bytes(0),
     _total_prev_live_bytes(0), _total_next_live_bytes(0),
     _hum_used_bytes(0), _hum_capacity_bytes(0),
-    _hum_prev_live_bytes(0), _hum_next_live_bytes(0) {
+    _hum_prev_live_bytes(0), _hum_next_live_bytes(0),
+    _total_remset_bytes(0), _total_strong_code_roots_bytes(0) {
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
   MemRegion g1_committed = g1h->g1_committed();
   MemRegion g1_reserved = g1h->g1_reserved();
@@ -4414,23 +4408,29 @@
                  HeapRegion::GrainBytes);
   _out->print_cr(G1PPRL_LINE_PREFIX);
   _out->print_cr(G1PPRL_LINE_PREFIX
-                 G1PPRL_TYPE_H_FORMAT
-                 G1PPRL_ADDR_BASE_H_FORMAT
-                 G1PPRL_BYTE_H_FORMAT
-                 G1PPRL_BYTE_H_FORMAT
-                 G1PPRL_BYTE_H_FORMAT
-                 G1PPRL_DOUBLE_H_FORMAT,
-                 "type", "address-range",
-                 "used", "prev-live", "next-live", "gc-eff");
+                G1PPRL_TYPE_H_FORMAT
+                G1PPRL_ADDR_BASE_H_FORMAT
+                G1PPRL_BYTE_H_FORMAT
+                G1PPRL_BYTE_H_FORMAT
+                G1PPRL_BYTE_H_FORMAT
+                G1PPRL_DOUBLE_H_FORMAT
+                G1PPRL_BYTE_H_FORMAT
+                G1PPRL_BYTE_H_FORMAT,
+                "type", "address-range",
+                "used", "prev-live", "next-live", "gc-eff",
+                "remset", "code-roots");
   _out->print_cr(G1PPRL_LINE_PREFIX
-                 G1PPRL_TYPE_H_FORMAT
-                 G1PPRL_ADDR_BASE_H_FORMAT
-                 G1PPRL_BYTE_H_FORMAT
-                 G1PPRL_BYTE_H_FORMAT
-                 G1PPRL_BYTE_H_FORMAT
-                 G1PPRL_DOUBLE_H_FORMAT,
-                 "", "",
-                 "(bytes)", "(bytes)", "(bytes)", "(bytes/ms)");
+                G1PPRL_TYPE_H_FORMAT
+                G1PPRL_ADDR_BASE_H_FORMAT
+                G1PPRL_BYTE_H_FORMAT
+                G1PPRL_BYTE_H_FORMAT
+                G1PPRL_BYTE_H_FORMAT
+                G1PPRL_DOUBLE_H_FORMAT
+                G1PPRL_BYTE_H_FORMAT
+                G1PPRL_BYTE_H_FORMAT,
+                "", "",
+                "(bytes)", "(bytes)", "(bytes)", "(bytes/ms)",
+                "(bytes)", "(bytes)");
 }
 
 // It takes as a parameter a reference to one of the _hum_* fields, it
@@ -4472,6 +4472,9 @@
   size_t prev_live_bytes = r->live_bytes();
   size_t next_live_bytes = r->next_live_bytes();
   double gc_eff          = r->gc_efficiency();
+  size_t remset_bytes    = r->rem_set()->mem_size();
+  size_t strong_code_roots_bytes = r->rem_set()->strong_code_roots_mem_size();
+
   if (r->used() == 0) {
     type = "FREE";
   } else if (r->is_survivor()) {
@@ -4505,6 +4508,8 @@
   _total_capacity_bytes  += capacity_bytes;
   _total_prev_live_bytes += prev_live_bytes;
   _total_next_live_bytes += next_live_bytes;
+  _total_remset_bytes    += remset_bytes;
+  _total_strong_code_roots_bytes += strong_code_roots_bytes;
 
   // Print a line for this particular region.
   _out->print_cr(G1PPRL_LINE_PREFIX
@@ -4513,14 +4518,19 @@
                  G1PPRL_BYTE_FORMAT
                  G1PPRL_BYTE_FORMAT
                  G1PPRL_BYTE_FORMAT
-                 G1PPRL_DOUBLE_FORMAT,
+                 G1PPRL_DOUBLE_FORMAT
+                 G1PPRL_BYTE_FORMAT
+                 G1PPRL_BYTE_FORMAT,
                  type, bottom, end,
-                 used_bytes, prev_live_bytes, next_live_bytes, gc_eff);
+                 used_bytes, prev_live_bytes, next_live_bytes, gc_eff,
+                 remset_bytes, strong_code_roots_bytes);
 
   return false;
 }
 
 G1PrintRegionLivenessInfoClosure::~G1PrintRegionLivenessInfoClosure() {
+  // add static memory usages to remembered set sizes
+  _total_remset_bytes += HeapRegionRemSet::fl_mem_size() + HeapRegionRemSet::static_mem_size();
   // Print the footer of the output.
   _out->print_cr(G1PPRL_LINE_PREFIX);
   _out->print_cr(G1PPRL_LINE_PREFIX
@@ -4528,13 +4538,17 @@
                  G1PPRL_SUM_MB_FORMAT("capacity")
                  G1PPRL_SUM_MB_PERC_FORMAT("used")
                  G1PPRL_SUM_MB_PERC_FORMAT("prev-live")
-                 G1PPRL_SUM_MB_PERC_FORMAT("next-live"),
+                 G1PPRL_SUM_MB_PERC_FORMAT("next-live")
+                 G1PPRL_SUM_MB_FORMAT("remset")
+                 G1PPRL_SUM_MB_FORMAT("code-roots"),
                  bytes_to_mb(_total_capacity_bytes),
                  bytes_to_mb(_total_used_bytes),
                  perc(_total_used_bytes, _total_capacity_bytes),
                  bytes_to_mb(_total_prev_live_bytes),
                  perc(_total_prev_live_bytes, _total_capacity_bytes),
                  bytes_to_mb(_total_next_live_bytes),
-                 perc(_total_next_live_bytes, _total_capacity_bytes));
+                 perc(_total_next_live_bytes, _total_capacity_bytes),
+                 bytes_to_mb(_total_remset_bytes),
+                 bytes_to_mb(_total_strong_code_roots_bytes));
   _out->cr();
 }
--- a/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1224,6 +1224,12 @@
   size_t _hum_prev_live_bytes;
   size_t _hum_next_live_bytes;
 
+  // Accumulator for the remembered set size
+  size_t _total_remset_bytes;
+
+  // Accumulator for strong code roots memory size
+  size_t _total_strong_code_roots_bytes;
+
   static double perc(size_t val, size_t total) {
     if (total == 0) {
       return 0.0;
--- a/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -81,7 +81,7 @@
                                          size_t* marked_bytes_array,
                                          BitMap* task_card_bm) {
   G1CollectedHeap* g1h = _g1h;
-  CardTableModRefBS* ct_bs = (CardTableModRefBS*) (g1h->barrier_set());
+  CardTableModRefBS* ct_bs = g1h->g1_barrier_set();
 
   HeapWord* start = mr.start();
   HeapWord* end = mr.end();
--- a/src/share/vm/gc_implementation/g1/g1CardCounts.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/g1CardCounts.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -65,9 +65,7 @@
     // threshold limit is no more than this.
     guarantee(G1ConcRSHotCardLimit <= max_jubyte, "sanity");
 
-    ModRefBarrierSet* bs = _g1h->mr_bs();
-    guarantee(bs->is_a(BarrierSet::CardTableModRef), "Precondition");
-    _ct_bs = (CardTableModRefBS*)bs;
+    _ct_bs = _g1h->g1_barrier_set();
     _ct_bot = _ct_bs->byte_for_const(_g1h->reserved_region().start());
 
     // Allocate/Reserve the counts table
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "code/codeCache.hpp"
 #include "code/icBuffer.hpp"
 #include "gc_implementation/g1/bufferingOopClosure.hpp"
 #include "gc_implementation/g1/concurrentG1Refine.hpp"
@@ -56,6 +57,7 @@
 #include "oops/oop.pcgc.inline.hpp"
 #include "runtime/aprofiler.hpp"
 #include "runtime/vmThread.hpp"
+#include "utilities/ticks.hpp"
 
 size_t G1CollectedHeap::_humongous_object_threshold_in_words = 0;
 
@@ -125,10 +127,8 @@
   int _histo[256];
 public:
   ClearLoggedCardTableEntryClosure() :
-    _calls(0)
+    _calls(0), _g1h(G1CollectedHeap::heap()), _ctbs(_g1h->g1_barrier_set())
   {
-    _g1h = G1CollectedHeap::heap();
-    _ctbs = (CardTableModRefBS*)_g1h->barrier_set();
     for (int i = 0; i < 256; i++) _histo[i] = 0;
   }
   bool do_card_ptr(jbyte* card_ptr, int worker_i) {
@@ -158,11 +158,8 @@
   CardTableModRefBS* _ctbs;
 public:
   RedirtyLoggedCardTableEntryClosure() :
-    _calls(0)
-  {
-    _g1h = G1CollectedHeap::heap();
-    _ctbs = (CardTableModRefBS*)_g1h->barrier_set();
-  }
+    _calls(0), _g1h(G1CollectedHeap::heap()), _ctbs(_g1h->g1_barrier_set()) {}
+
   bool do_card_ptr(jbyte* card_ptr, int worker_i) {
     if (_g1h->is_in_reserved(_ctbs->addr_for(card_ptr))) {
       _calls++;
@@ -477,7 +474,7 @@
 
 void G1CollectedHeap::check_ct_logs_at_safepoint() {
   DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
-  CardTableModRefBS* ct_bs = (CardTableModRefBS*)barrier_set();
+  CardTableModRefBS* ct_bs = g1_barrier_set();
 
   // Count the dirty cards at the start.
   CountNonCleanMemRegionClosure count1(this);
@@ -1158,26 +1155,33 @@
   ModRefBarrierSet* _mr_bs;
 public:
   PostMCRemSetClearClosure(G1CollectedHeap* g1h, ModRefBarrierSet* mr_bs) :
-    _g1h(g1h), _mr_bs(mr_bs) { }
+    _g1h(g1h), _mr_bs(mr_bs) {}
+
   bool doHeapRegion(HeapRegion* r) {
+    HeapRegionRemSet* hrrs = r->rem_set();
+
     if (r->continuesHumongous()) {
+      // We'll assert that the strong code root list and RSet is empty
+      assert(hrrs->strong_code_roots_list_length() == 0, "sanity");
+      assert(hrrs->occupied() == 0, "RSet should be empty");
       return false;
     }
+
     _g1h->reset_gc_time_stamps(r);
-    HeapRegionRemSet* hrrs = r->rem_set();
-    if (hrrs != NULL) hrrs->clear();
+    hrrs->clear();
     // You might think here that we could clear just the cards
     // corresponding to the used region.  But no: if we leave a dirty card
     // in a region we might allocate into, then it would prevent that card
     // from being enqueued, and cause it to be missed.
     // Re: the performance cost: we shouldn't be doing full GC anyway!
     _mr_bs->clear(MemRegion(r->bottom(), r->end()));
+
     return false;
   }
 };
 
 void G1CollectedHeap::clear_rsets_post_compaction() {
-  PostMCRemSetClearClosure rs_clear(this, mr_bs());
+  PostMCRemSetClearClosure rs_clear(this, g1_barrier_set());
   heap_region_iterate(&rs_clear);
 }
 
@@ -1251,31 +1255,6 @@
   heap_region_iterate(&cl);
 }
 
-double G1CollectedHeap::verify(bool guard, const char* msg) {
-  double verify_time_ms = 0.0;
-
-  if (guard && total_collections() >= VerifyGCStartAt) {
-    double verify_start = os::elapsedTime();
-    HandleMark hm;  // Discard invalid handles created during verification
-    gclog_or_tty->print(msg);
-    prepare_for_verify();
-    Universe::verify(false /* silent */, VerifyOption_G1UsePrevMarking);
-    verify_time_ms = (os::elapsedTime() - verify_start) * 1000;
-  }
-
-  return verify_time_ms;
-}
-
-void G1CollectedHeap::verify_before_gc() {
-  double verify_time_ms = verify(VerifyBeforeGC, " VerifyBeforeGC:");
-  g1_policy()->phase_times()->record_verify_before_time_ms(verify_time_ms);
-}
-
-void G1CollectedHeap::verify_after_gc() {
-  double verify_time_ms = verify(VerifyAfterGC, " VerifyAfterGC:");
-  g1_policy()->phase_times()->record_verify_after_time_ms(verify_time_ms);
-}
-
 bool G1CollectedHeap::do_collection(bool explicit_gc,
                                     bool clear_all_soft_refs,
                                     size_t word_size) {
@@ -1286,7 +1265,7 @@
   }
 
   STWGCTimer* gc_timer = G1MarkSweep::gc_timer();
-  gc_timer->register_gc_start(os::elapsed_counter());
+  gc_timer->register_gc_start();
 
   SerialOldTracer* gc_tracer = G1MarkSweep::gc_tracer();
   gc_tracer->report_gc_start(gc_cause(), gc_timer->gc_start());
@@ -1408,8 +1387,6 @@
 
       MemoryService::track_memory_usage();
 
-      verify_after_gc();
-
       assert(!ref_processor_stw()->discovery_enabled(), "Postcondition");
       ref_processor_stw()->verify_no_references_recorded();
 
@@ -1482,6 +1459,9 @@
         heap_region_iterate(&rebuild_rs);
       }
 
+      // Rebuild the strong code root lists for each region
+      rebuild_strong_code_roots();
+
       if (true) { // FIXME
         // Ask the permanent generation to adjust size for full collections
         perm()->compute_new_size();
@@ -1509,6 +1489,8 @@
       _hrs.verify_optional();
       verify_region_sets_optional();
 
+      verify_after_gc();
+
       // Start a new incremental collection set for the next pause
       assert(g1_policy()->collection_set() == NULL, "must be");
       g1_policy()->start_incremental_cset_building();
@@ -1546,8 +1528,7 @@
     post_full_gc_dump(gc_timer);
   }
 
-  gc_timer->register_gc_end(os::elapsed_counter());
-
+  gc_timer->register_gc_end();
   gc_tracer->report_gc_end(gc_timer->gc_end(), gc_timer->time_partitions());
 
   return true;
@@ -1568,8 +1549,6 @@
 void
 G1CollectedHeap::
 resize_if_necessary_after_full_collection(size_t word_size) {
-  assert(MinHeapFreeRatio <= MaxHeapFreeRatio, "sanity check");
-
   // Include the current allocation, if any, and bytes that will be
   // pre-allocated to support collections, as "used".
   const size_t used_after_gc = used();
@@ -2002,10 +1981,12 @@
 
   size_t init_byte_size = collector_policy()->initial_heap_byte_size();
   size_t max_byte_size = collector_policy()->max_heap_byte_size();
+  size_t heap_alignment = collector_policy()->max_alignment();
 
   // Ensure that the sizes are properly aligned.
   Universe::check_alignment(init_byte_size, HeapRegion::GrainBytes, "g1 heap");
   Universe::check_alignment(max_byte_size, HeapRegion::GrainBytes, "g1 heap");
+  Universe::check_alignment(max_byte_size, heap_alignment, "g1 heap");
 
   _cg1r = new ConcurrentG1Refine(this);
 
@@ -2029,14 +2010,14 @@
   size_t total_reserved = 0;
 
   total_reserved = add_and_check_overflow(total_reserved, max_byte_size);
-  size_t pg_max_size = (size_t) align_size_up(pgs->max_size(), HeapRegion::GrainBytes);
+  size_t pg_max_size = (size_t) align_size_up(pgs->max_size(), heap_alignment);
   total_reserved = add_and_check_overflow(total_reserved, pg_max_size);
 
   Universe::check_alignment(total_reserved, HeapRegion::GrainBytes, "g1 heap and perm");
 
-  char* addr = Universe::preferred_heap_base(total_reserved, Universe::UnscaledNarrowOop);
-
-  ReservedHeapSpace heap_rs(total_reserved, HeapRegion::GrainBytes,
+  char* addr = Universe::preferred_heap_base(total_reserved, heap_alignment, Universe::UnscaledNarrowOop);
+
+  ReservedHeapSpace heap_rs(total_reserved, heap_alignment,
                             UseLargePages, addr);
 
   if (UseCompressedOops) {
@@ -2044,17 +2025,17 @@
       // Failed to reserve at specified address - the requested memory
       // region is taken already, for example, by 'java' launcher.
       // Try again to reserver heap higher.
-      addr = Universe::preferred_heap_base(total_reserved, Universe::ZeroBasedNarrowOop);
-
-      ReservedHeapSpace heap_rs0(total_reserved, HeapRegion::GrainBytes,
+      addr = Universe::preferred_heap_base(total_reserved, heap_alignment, Universe::ZeroBasedNarrowOop);
+
+      ReservedHeapSpace heap_rs0(total_reserved, heap_alignment,
                                  UseLargePages, addr);
 
       if (addr != NULL && !heap_rs0.is_reserved()) {
         // Failed to reserve at specified address again - give up.
-        addr = Universe::preferred_heap_base(total_reserved, Universe::HeapBasedNarrowOop);
+        addr = Universe::preferred_heap_base(total_reserved, heap_alignment, Universe::HeapBasedNarrowOop);
         assert(addr == NULL, "");
 
-        ReservedHeapSpace heap_rs1(total_reserved, HeapRegion::GrainBytes,
+        ReservedHeapSpace heap_rs1(total_reserved, heap_alignment,
                                    UseLargePages, addr);
         heap_rs = heap_rs1;
       } else {
@@ -2080,20 +2061,13 @@
   // Create the gen rem set (and barrier set) for the entire reserved region.
   _rem_set = collector_policy()->create_rem_set(_reserved, 2);
   set_barrier_set(rem_set()->bs());
-  if (barrier_set()->is_a(BarrierSet::ModRef)) {
-    _mr_bs = (ModRefBarrierSet*)_barrier_set;
-  } else {
-    vm_exit_during_initialization("G1 requires a mod ref bs.");
+  if (!barrier_set()->is_a(BarrierSet::G1SATBCTLogging)) {
+    vm_exit_during_initialization("G1 requires a G1SATBLoggingCardTableModRefBS");
     return JNI_ENOMEM;
   }
 
   // Also create a G1 rem set.
-  if (mr_bs()->is_a(BarrierSet::CardTableModRef)) {
-    _g1_rem_set = new G1RemSet(this, (CardTableModRefBS*)mr_bs());
-  } else {
-    vm_exit_during_initialization("G1 requires a cardtable mod ref bs.");
-    return JNI_ENOMEM;
-  }
+  _g1_rem_set = new G1RemSet(this, g1_barrier_set());
 
   // Carve out the G1 part of the heap.
 
@@ -2517,7 +2491,7 @@
   FullGCCount_lock->notify_all();
 }
 
-void G1CollectedHeap::register_concurrent_cycle_start(jlong start_time) {
+void G1CollectedHeap::register_concurrent_cycle_start(const Ticks& start_time) {
   _concurrent_cycle_started = true;
   _gc_timer_cm->register_gc_start(start_time);
 
@@ -2527,7 +2501,7 @@
 
 void G1CollectedHeap::register_concurrent_cycle_end() {
   if (_concurrent_cycle_started) {
-    _gc_timer_cm->register_gc_end(os::elapsed_counter());
+    _gc_timer_cm->register_gc_end();
 
     if (_cm->has_aborted()) {
       _gc_tracer_cm->report_concurrent_mode_failure();
@@ -3161,6 +3135,119 @@
   return NULL; // keep some compilers happy
 }
 
+// TODO: VerifyRootsClosure extends OopsInGenClosure so that we can
+//       pass it as the perm_blk to SharedHeap::process_strong_roots.
+//       When process_strong_roots stop calling perm_blk->younger_refs_iterate
+//       we can change this closure to extend the simpler OopClosure.
+class VerifyRootsClosure: public OopsInGenClosure {
+private:
+  G1CollectedHeap* _g1h;
+  VerifyOption     _vo;
+  bool             _failures;
+public:
+  // _vo == UsePrevMarking -> use "prev" marking information,
+  // _vo == UseNextMarking -> use "next" marking information,
+  // _vo == UseMarkWord    -> use mark word from object header.
+  VerifyRootsClosure(VerifyOption vo) :
+    _g1h(G1CollectedHeap::heap()),
+    _vo(vo),
+    _failures(false) { }
+
+  bool failures() { return _failures; }
+
+  template <class T> void do_oop_nv(T* p) {
+    T heap_oop = oopDesc::load_heap_oop(p);
+    if (!oopDesc::is_null(heap_oop)) {
+      oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+      if (_g1h->is_obj_dead_cond(obj, _vo)) {
+        gclog_or_tty->print_cr("Root location "PTR_FORMAT" "
+                              "points to dead obj "PTR_FORMAT, p, (void*) obj);
+        if (_vo == VerifyOption_G1UseMarkWord) {
+          gclog_or_tty->print_cr("  Mark word: "PTR_FORMAT, (void*)(obj->mark()));
+        }
+        obj->print_on(gclog_or_tty);
+        _failures = true;
+      }
+    }
+  }
+
+  void do_oop(oop* p)       { do_oop_nv(p); }
+  void do_oop(narrowOop* p) { do_oop_nv(p); }
+};
+
+class G1VerifyCodeRootOopClosure: public OopsInGenClosure {
+  G1CollectedHeap* _g1h;
+  OopClosure* _root_cl;
+  nmethod* _nm;
+  VerifyOption _vo;
+  bool _failures;
+
+  template <class T> void do_oop_work(T* p) {
+    // First verify that this root is live
+    _root_cl->do_oop(p);
+
+    if (!G1VerifyHeapRegionCodeRoots) {
+      // We're not verifying the code roots attached to heap region.
+      return;
+    }
+
+    // Don't check the code roots during marking verification in a full GC
+    if (_vo == VerifyOption_G1UseMarkWord) {
+      return;
+    }
+
+    // Now verify that the current nmethod (which contains p) is
+    // in the code root list of the heap region containing the
+    // object referenced by p.
+
+    T heap_oop = oopDesc::load_heap_oop(p);
+    if (!oopDesc::is_null(heap_oop)) {
+      oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+
+      if (_g1h->is_in_g1_reserved(obj)) {
+        // Now fetch the region containing the object
+        HeapRegion* hr = _g1h->heap_region_containing(obj);
+        HeapRegionRemSet* hrrs = hr->rem_set();
+        // Verify that the strong code root list for this region
+        // contains the nmethod
+        if (!hrrs->strong_code_roots_list_contains(_nm)) {
+          gclog_or_tty->print_cr("Code root location "PTR_FORMAT" "
+                                "from nmethod "PTR_FORMAT" not in strong "
+                                "code roots for region ["PTR_FORMAT","PTR_FORMAT")",
+                                p, _nm, hr->bottom(), hr->end());
+          _failures = true;
+        }
+      }
+    }
+  }
+
+public:
+  G1VerifyCodeRootOopClosure(G1CollectedHeap* g1h, OopClosure* root_cl, VerifyOption vo):
+    _g1h(g1h), _root_cl(root_cl), _vo(vo), _nm(NULL), _failures(false) {}
+
+  void do_oop(oop* p) { do_oop_work(p); }
+  void do_oop(narrowOop* p) { do_oop_work(p); }
+
+  void set_nmethod(nmethod* nm) { _nm = nm; }
+  bool failures() { return _failures; }
+};
+
+class G1VerifyCodeRootBlobClosure: public CodeBlobClosure {
+  G1VerifyCodeRootOopClosure* _oop_cl;
+
+public:
+  G1VerifyCodeRootBlobClosure(G1VerifyCodeRootOopClosure* oop_cl):
+    _oop_cl(oop_cl) {}
+
+  void do_code_blob(CodeBlob* cb) {
+    nmethod* nm = cb->as_nmethod_or_null();
+    if (nm != NULL) {
+      _oop_cl->set_nmethod(nm);
+      nm->oops_do(_oop_cl);
+    }
+  }
+};
+
 class VerifyLivenessOopClosure: public OopClosure {
   G1CollectedHeap* _g1h;
   VerifyOption _vo;
@@ -3294,42 +3381,6 @@
   }
 };
 
-class VerifyRootsClosure: public OopsInGenClosure {
-private:
-  G1CollectedHeap* _g1h;
-  VerifyOption     _vo;
-  bool             _failures;
-public:
-  // _vo == UsePrevMarking -> use "prev" marking information,
-  // _vo == UseNextMarking -> use "next" marking information,
-  // _vo == UseMarkWord    -> use mark word from object header.
-  VerifyRootsClosure(VerifyOption vo) :
-    _g1h(G1CollectedHeap::heap()),
-    _vo(vo),
-    _failures(false) { }
-
-  bool failures() { return _failures; }
-
-  template <class T> void do_oop_nv(T* p) {
-    T heap_oop = oopDesc::load_heap_oop(p);
-    if (!oopDesc::is_null(heap_oop)) {
-      oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
-      if (_g1h->is_obj_dead_cond(obj, _vo)) {
-        gclog_or_tty->print_cr("Root location "PTR_FORMAT" "
-                              "points to dead obj "PTR_FORMAT, p, (void*) obj);
-        if (_vo == VerifyOption_G1UseMarkWord) {
-          gclog_or_tty->print_cr("  Mark word: "PTR_FORMAT, (void*)(obj->mark()));
-        }
-        obj->print_on(gclog_or_tty);
-        _failures = true;
-      }
-    }
-  }
-
-  void do_oop(oop* p)       { do_oop_nv(p); }
-  void do_oop(narrowOop* p) { do_oop_nv(p); }
-};
-
 // This is the task used for parallel heap verification.
 
 class G1ParVerifyTask: public AbstractGangTask {
@@ -3364,21 +3415,16 @@
   }
 };
 
-void G1CollectedHeap::verify(bool silent) {
-  verify(silent, VerifyOption_G1UsePrevMarking);
-}
-
-void G1CollectedHeap::verify(bool silent,
-                             VerifyOption vo) {
+void G1CollectedHeap::verify(bool silent, VerifyOption vo) {
   if (SafepointSynchronize::is_at_safepoint()) {
+    assert(Thread::current()->is_VM_thread(),
+           "Expected to be executed serially by the VM thread at this point");
+
     if (!silent) { gclog_or_tty->print("Roots (excluding permgen) "); }
     VerifyRootsClosure rootsCl(vo);
 
-    assert(Thread::current()->is_VM_thread(),
-           "Expected to be executed serially by the VM thread at this point");
-
-    CodeBlobToOopClosure blobsCl(&rootsCl, /*do_marking=*/ false);
-
+    G1VerifyCodeRootOopClosure codeRootsCl(this, &rootsCl, vo);
+    G1VerifyCodeRootBlobClosure blobsCl(&codeRootsCl);
     // We apply the relevant closures to all the oops in the
     // system dictionary, the string table and the code cache.
     const int so = SO_AllClasses | SO_Strings | SO_CodeCache;
@@ -3473,6 +3519,34 @@
   }
 }
 
+void G1CollectedHeap::verify(bool silent) {
+  verify(silent, VerifyOption_G1UsePrevMarking);
+}
+
+double G1CollectedHeap::verify(bool guard, const char* msg) {
+  double verify_time_ms = 0.0;
+
+  if (guard && total_collections() >= VerifyGCStartAt) {
+    double verify_start = os::elapsedTime();
+    HandleMark hm;  // Discard invalid handles created during verification
+    prepare_for_verify();
+    Universe::verify(VerifyOption_G1UsePrevMarking, msg);
+    verify_time_ms = (os::elapsedTime() - verify_start) * 1000;
+  }
+
+  return verify_time_ms;
+}
+
+void G1CollectedHeap::verify_before_gc() {
+  double verify_time_ms = verify(VerifyBeforeGC, " VerifyBeforeGC:");
+  g1_policy()->phase_times()->record_verify_before_time_ms(verify_time_ms);
+}
+
+void G1CollectedHeap::verify_after_gc() {
+  double verify_time_ms = verify(VerifyAfterGC, " VerifyAfterGC:");
+  g1_policy()->phase_times()->record_verify_after_time_ms(verify_time_ms);
+}
+
 class PrintRegionClosure: public HeapRegionClosure {
   outputStream* _st;
 public:
@@ -3616,9 +3690,22 @@
   AllocationProfiler::iterate_since_last_gc();
   // Fill TLAB's and such
   ensure_parsability(true);
+
+  if (G1SummarizeRSetStats && (G1SummarizeRSetStatsPeriod > 0) &&
+      (total_collections() % G1SummarizeRSetStatsPeriod == 0)) {
+    g1_rem_set()->print_periodic_summary_info("Before GC RS summary");
+  }
 }
 
 void G1CollectedHeap::gc_epilogue(bool full /* Ignored */) {
+
+  if (G1SummarizeRSetStats &&
+      (G1SummarizeRSetStatsPeriod > 0) &&
+      // we are at the end of the GC. Total collections has already been increased.
+      ((total_collections() - 1) % G1SummarizeRSetStatsPeriod == 0)) {
+    g1_rem_set()->print_periodic_summary_info("After GC RS summary");
+  }
+
   // FIXME: what is this about?
   // I'm ignoring the "fill_newgen()" call if "alloc_event_enabled"
   // is set.
@@ -3815,7 +3902,7 @@
     return false;
   }
 
-  _gc_timer_stw->register_gc_start(os::elapsed_counter());
+  _gc_timer_stw->register_gc_start();
 
   _gc_tracer_stw->report_gc_start(gc_cause(), _gc_timer_stw->gc_start());
 
@@ -3880,8 +3967,9 @@
       append_secondary_free_list_if_not_empty_with_lock();
     }
 
-    assert(check_young_list_well_formed(),
-      "young list should be well formed");
+    assert(check_young_list_well_formed(), "young list should be well formed");
+    assert(check_heap_region_claim_values(HeapRegion::InitialClaimValue),
+           "sanity check");
 
     // Don't dynamically change the number of GC threads this early.  A value of
     // 0 is used to indicate serial work.  When parallel work is done,
@@ -4193,15 +4281,10 @@
 
     _gc_tracer_stw->report_evacuation_info(&evacuation_info);
     _gc_tracer_stw->report_tenuring_threshold(_g1_policy->tenuring_threshold());
-    _gc_timer_stw->register_gc_end(os::elapsed_counter());
+    _gc_timer_stw->register_gc_end();
     _gc_tracer_stw->report_gc_end(_gc_timer_stw->gc_end(), _gc_timer_stw->time_partitions());
   }
 
-  if (G1SummarizeRSetStats &&
-      (G1SummarizeRSetStatsPeriod > 0) &&
-      (total_collections() % G1SummarizeRSetStatsPeriod == 0)) {
-    g1_rem_set()->print_summary_info();
-  }
   // It should now be safe to tell the concurrent mark thread to start
   // without its logging output interfering with the logging output
   // that came from the pause.
@@ -4482,7 +4565,7 @@
   : _g1h(g1h),
     _refs(g1h->task_queue(queue_num)),
     _dcq(&g1h->dirty_card_queue_set()),
-    _ct_bs((CardTableModRefBS*)_g1h->barrier_set()),
+    _ct_bs(g1h->g1_barrier_set()),
     _g1_rem(g1h->g1_rem_set()),
     _hash_seed(17), _queue_num(queue_num),
     _term_attempts(0),
@@ -4975,7 +5058,8 @@
                                     scan_root_cl,
                                     &push_heap_rs_cl,
                                     scan_perm_cl,
-                                    worker_id);
+                                    worker_id,
+                                    /* manages_code_roots */ true);
       pss.end_strong_roots();
 
       {
@@ -5009,67 +5093,6 @@
 
 // *** Common G1 Evacuation Stuff
 
-// Closures that support the filtering of CodeBlobs scanned during
-// external root scanning.
-
-// Closure applied to reference fields in code blobs (specifically nmethods)
-// to determine whether an nmethod contains references that point into
-// the collection set. Used as a predicate when walking code roots so
-// that only nmethods that point into the collection set are added to the
-// 'marked' list.
-
-class G1FilteredCodeBlobToOopClosure : public CodeBlobToOopClosure {
-
-  class G1PointsIntoCSOopClosure : public OopClosure {
-    G1CollectedHeap* _g1;
-    bool _points_into_cs;
-  public:
-    G1PointsIntoCSOopClosure(G1CollectedHeap* g1) :
-      _g1(g1), _points_into_cs(false) { }
-
-    bool points_into_cs() const { return _points_into_cs; }
-
-    template <class T>
-    void do_oop_nv(T* p) {
-      if (!_points_into_cs) {
-        T heap_oop = oopDesc::load_heap_oop(p);
-        if (!oopDesc::is_null(heap_oop) &&
-            _g1->in_cset_fast_test(oopDesc::decode_heap_oop_not_null(heap_oop))) {
-          _points_into_cs = true;
-        }
-      }
-    }
-
-    virtual void do_oop(oop* p)        { do_oop_nv(p); }
-    virtual void do_oop(narrowOop* p)  { do_oop_nv(p); }
-  };
-
-  G1CollectedHeap* _g1;
-
-public:
-  G1FilteredCodeBlobToOopClosure(G1CollectedHeap* g1, OopClosure* cl) :
-    CodeBlobToOopClosure(cl, true), _g1(g1) { }
-
-  virtual void do_code_blob(CodeBlob* cb) {
-    nmethod* nm = cb->as_nmethod_or_null();
-    if (nm != NULL && !(nm->test_oops_do_mark())) {
-      G1PointsIntoCSOopClosure predicate_cl(_g1);
-      nm->oops_do(&predicate_cl);
-
-      if (predicate_cl.points_into_cs()) {
-        // At least one of the reference fields or the oop relocations
-        // in the nmethod points into the collection set. We have to
-        // 'mark' this nmethod.
-        // Note: Revisit the following if CodeBlobToOopClosure::do_code_blob()
-        // or MarkingCodeBlobClosure::do_code_blob() change.
-        if (!nm->test_set_oops_do_mark()) {
-          do_newly_marked_nmethod(nm);
-        }
-      }
-    }
-  }
-};
-
 // This method is run in a GC worker.
 
 void
@@ -5079,7 +5102,8 @@
                         OopClosure* scan_non_heap_roots,
                         OopsInHeapRegionClosure* scan_rs,
                         OopsInGenClosure* scan_perm,
-                        int worker_i) {
+                        int worker_i,
+                        bool manages_code_roots) {
 
   // First scan the strong roots, including the perm gen.
   double ext_roots_start = os::elapsedTime();
@@ -5089,15 +5113,17 @@
   BufferingOopsInGenClosure buf_scan_perm(scan_perm);
   buf_scan_perm.set_generation(perm_gen());
 
-  // Walk the code cache w/o buffering, because StarTask cannot handle
-  // unaligned oop locations.
-  G1FilteredCodeBlobToOopClosure eager_scan_code_roots(this, scan_non_heap_roots);
+  assert(so & SO_CodeCache || scan_rs != NULL, "must scan code roots somehow");
+  // Walk the code cache/strong code roots w/o buffering, because StarTask
+  // cannot handle unaligned oop locations.
+  CodeBlobToOopClosure eager_scan_code_roots(scan_non_heap_roots, true /* do_marking */);
 
   process_strong_roots(false, // no scoping; this is parallel code
                        collecting_perm_gen, so,
                        &buf_scan_non_heap_roots,
                        &eager_scan_code_roots,
-                       &buf_scan_perm);
+                       &buf_scan_perm,
+                       manages_code_roots);
 
   // Now the CM ref_processor roots.
   if (!_process_strong_tasks->is_task_claimed(G1H_PS_refProcessor_oops_do)) {
@@ -5136,9 +5162,22 @@
   }
   g1_policy()->phase_times()->record_satb_filtering_time(worker_i, satb_filtering_ms);
 
+  // If this is an initial mark pause, and we're not scanning
+  // the entire code cache, we need to mark the oops in the
+  // strong code root lists for the regions that are not in
+  // the collection set.
+  // Note all threads participate in this set of root tasks.
+  double mark_strong_code_roots_ms = 0.0;
+  if (g1_policy()->during_initial_mark_pause() && !(so & SO_CodeCache)) {
+    double mark_strong_roots_start = os::elapsedTime();
+    mark_strong_code_roots(worker_i);
+    mark_strong_code_roots_ms = (os::elapsedTime() - mark_strong_roots_start) * 1000.0;
+  }
+  g1_policy()->phase_times()->record_strong_code_root_mark_time(worker_i, mark_strong_code_roots_ms);
+
   // Now scan the complement of the collection set.
   if (scan_rs != NULL) {
-    g1_rem_set()->oops_into_collection_set_do(scan_rs, worker_i);
+    g1_rem_set()->oops_into_collection_set_do(scan_rs, &eager_scan_code_roots, worker_i);
   }
 
   _process_strong_tasks->all_tasks_completed();
@@ -5151,6 +5190,102 @@
   SharedHeap::process_weak_roots(root_closure, &roots_in_blobs, non_root_closure);
 }
 
+class G1StringSymbolTableUnlinkTask : public AbstractGangTask {
+private:
+  BoolObjectClosure* _is_alive;
+  int _initial_string_table_size;
+  int _initial_symbol_table_size;
+
+  bool  _process_strings;
+  int _strings_processed;
+  int _strings_removed;
+
+  bool  _process_symbols;
+  int _symbols_processed;
+  int _symbols_removed;
+
+  bool _do_in_parallel;
+public:
+  G1StringSymbolTableUnlinkTask(BoolObjectClosure* is_alive, bool process_strings, bool process_symbols) :
+    AbstractGangTask("Par String/Symbol table unlink"), _is_alive(is_alive),
+    _do_in_parallel(G1CollectedHeap::use_parallel_gc_threads()),
+    _process_strings(process_strings), _strings_processed(0), _strings_removed(0),
+    _process_symbols(process_symbols), _symbols_processed(0), _symbols_removed(0) {
+
+    _initial_string_table_size = StringTable::the_table()->table_size();
+    _initial_symbol_table_size = SymbolTable::the_table()->table_size();
+    if (process_strings) {
+      StringTable::clear_parallel_claimed_index();
+    }
+    if (process_symbols) {
+      SymbolTable::clear_parallel_claimed_index();
+    }
+  }
+
+  ~G1StringSymbolTableUnlinkTask() {
+    guarantee(!_process_strings || !_do_in_parallel || StringTable::parallel_claimed_index() >= _initial_string_table_size,
+              err_msg("claim value "INT32_FORMAT" after unlink less than initial string table size "INT32_FORMAT,
+                      StringTable::parallel_claimed_index(), _initial_string_table_size));
+    guarantee(!_process_symbols || !_do_in_parallel || SymbolTable::parallel_claimed_index() >= _initial_symbol_table_size,
+              err_msg("claim value "INT32_FORMAT" after unlink less than initial symbol table size "INT32_FORMAT,
+                      SymbolTable::parallel_claimed_index(), _initial_symbol_table_size));
+  }
+
+  void work(uint worker_id) {
+    if (_do_in_parallel) {
+      int strings_processed = 0;
+      int strings_removed = 0;
+      int symbols_processed = 0;
+      int symbols_removed = 0;
+      if (_process_strings) {
+        StringTable::possibly_parallel_unlink(_is_alive, &strings_processed, &strings_removed);
+        Atomic::add(strings_processed, &_strings_processed);
+        Atomic::add(strings_removed, &_strings_removed);
+      }
+      if (_process_symbols) {
+        SymbolTable::possibly_parallel_unlink(&symbols_processed, &symbols_removed);
+        Atomic::add(symbols_processed, &_symbols_processed);
+        Atomic::add(symbols_removed, &_symbols_removed);
+      }
+    } else {
+      if (_process_strings) {
+        StringTable::unlink(_is_alive, &_strings_processed, &_strings_removed);
+      }
+      if (_process_symbols) {
+        SymbolTable::unlink(&_symbols_processed, &_symbols_removed);
+      }
+    }
+  }
+
+  size_t strings_processed() const { return (size_t)_strings_processed; }
+  size_t strings_removed()   const { return (size_t)_strings_removed; }
+
+  size_t symbols_processed() const { return (size_t)_symbols_processed; }
+  size_t symbols_removed()   const { return (size_t)_symbols_removed; }
+};
+
+void G1CollectedHeap::unlink_string_and_symbol_table(BoolObjectClosure* is_alive,
+                                                     bool process_strings, bool process_symbols) {
+  uint n_workers = (G1CollectedHeap::use_parallel_gc_threads() ?
+                   _g1h->workers()->active_workers() : 1);
+
+  G1StringSymbolTableUnlinkTask g1_unlink_task(is_alive, process_strings, process_symbols);
+  if (G1CollectedHeap::use_parallel_gc_threads()) {
+    set_par_threads(n_workers);
+    workers()->run_task(&g1_unlink_task);
+    set_par_threads(0);
+  } else {
+    g1_unlink_task.work(0);
+  }
+  if (G1TraceStringSymbolTableScrubbing) {
+    gclog_or_tty->print_cr("Cleaned string and symbol table, "
+                           "strings: "SIZE_FORMAT" processed, "SIZE_FORMAT" removed, "
+                           "symbols: "SIZE_FORMAT" processed, "SIZE_FORMAT" removed",
+                           g1_unlink_task.strings_processed(), g1_unlink_task.strings_removed(),
+                           g1_unlink_task.symbols_processed(), g1_unlink_task.symbols_removed());
+  }
+}
+
 // Weak Reference Processing support
 
 // An always "is_alive" closure that is used to preserve referents.
@@ -5761,9 +5896,6 @@
   process_discovered_references(n_workers);
 
   // Weak root processing.
-  // Note: when JSR 292 is enabled and code blobs can contain
-  // non-perm oops then we will need to process the code blobs
-  // here too.
   {
     G1STWIsAliveClosure is_alive(this);
     G1KeepAliveClosure keep_alive(this);
@@ -5779,6 +5911,17 @@
   hot_card_cache->reset_hot_cache();
   hot_card_cache->set_use_cache(true);
 
+  // Migrate the strong code roots attached to each region in
+  // the collection set. Ideally we would like to do this
+  // after we have finished the scanning/evacuation of the
+  // strong code roots for a particular heap region.
+  migrate_strong_code_roots();
+
+  if (g1_policy()->during_initial_mark_pause()) {
+    // Reset the claim values set during marking the strong code roots
+    reset_heap_region_claim_values();
+  }
+
   finalize_for_evac_failure();
 
   if (evacuation_failed()) {
@@ -5912,11 +6055,11 @@
 }
 
 class G1ParCleanupCTTask : public AbstractGangTask {
-  CardTableModRefBS* _ct_bs;
+  G1SATBCardTableModRefBS* _ct_bs;
   G1CollectedHeap* _g1h;
   HeapRegion* volatile _su_head;
 public:
-  G1ParCleanupCTTask(CardTableModRefBS* ct_bs,
+  G1ParCleanupCTTask(G1SATBCardTableModRefBS* ct_bs,
                      G1CollectedHeap* g1h) :
     AbstractGangTask("G1 Par Cleanup CT Task"),
     _ct_bs(ct_bs), _g1h(g1h) { }
@@ -5939,9 +6082,9 @@
 #ifndef PRODUCT
 class G1VerifyCardTableCleanup: public HeapRegionClosure {
   G1CollectedHeap* _g1h;
-  CardTableModRefBS* _ct_bs;
+  G1SATBCardTableModRefBS* _ct_bs;
 public:
-  G1VerifyCardTableCleanup(G1CollectedHeap* g1h, CardTableModRefBS* ct_bs)
+  G1VerifyCardTableCleanup(G1CollectedHeap* g1h, G1SATBCardTableModRefBS* ct_bs)
     : _g1h(g1h), _ct_bs(ct_bs) { }
   virtual bool doHeapRegion(HeapRegion* r) {
     if (r->is_survivor()) {
@@ -5955,7 +6098,7 @@
 
 void G1CollectedHeap::verify_not_dirty_region(HeapRegion* hr) {
   // All of the region should be clean.
-  CardTableModRefBS* ct_bs = (CardTableModRefBS*)barrier_set();
+  G1SATBCardTableModRefBS* ct_bs = g1_barrier_set();
   MemRegion mr(hr->bottom(), hr->end());
   ct_bs->verify_not_dirty_region(mr);
 }
@@ -5968,13 +6111,17 @@
   // not dirty that area (one less thing to have to do while holding
   // a lock). So we can only verify that [bottom(),pre_dummy_top()]
   // is dirty.
-  CardTableModRefBS* ct_bs = (CardTableModRefBS*) barrier_set();
+  G1SATBCardTableModRefBS* ct_bs = g1_barrier_set();
   MemRegion mr(hr->bottom(), hr->pre_dummy_top());
-  ct_bs->verify_dirty_region(mr);
+  if (hr->is_young()) {
+    ct_bs->verify_g1_young_region(mr);
+  } else {
+    ct_bs->verify_dirty_region(mr);
+  }
 }
 
 void G1CollectedHeap::verify_dirty_young_list(HeapRegion* head) {
-  CardTableModRefBS* ct_bs = (CardTableModRefBS*) barrier_set();
+  G1SATBCardTableModRefBS* ct_bs = g1_barrier_set();
   for (HeapRegion* hr = head; hr != NULL; hr = hr->get_next_young_region()) {
     verify_dirty_region(hr);
   }
@@ -5986,7 +6133,7 @@
 #endif
 
 void G1CollectedHeap::cleanUpCardTable() {
-  CardTableModRefBS* ct_bs = (CardTableModRefBS*) (barrier_set());
+  G1SATBCardTableModRefBS* ct_bs = g1_barrier_set();
   double start = os::elapsedTime();
 
   {
@@ -6575,3 +6722,234 @@
   _humongous_set.verify_end();
   _free_list.verify_end();
 }
+
+// Optimized nmethod scanning
+
+class RegisterNMethodOopClosure: public OopClosure {
+  G1CollectedHeap* _g1h;
+  nmethod* _nm;
+
+  template <class T> void do_oop_work(T* p) {
+    T heap_oop = oopDesc::load_heap_oop(p);
+    if (!oopDesc::is_null(heap_oop)) {
+      oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+      HeapRegion* hr = _g1h->heap_region_containing(obj);
+      if (hr == NULL) {
+        // reference into perm gen - ignore.
+        assert(_g1h->is_in_permanent(obj), "must be a reference into perm gen");
+        return;
+      }
+      assert(!hr->continuesHumongous(),
+             err_msg("trying to add code root "PTR_FORMAT" in continuation of humongous region "HR_FORMAT
+                     " starting at "HR_FORMAT,
+                     _nm, HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region())));
+
+      // HeapRegion::add_strong_code_root() avoids adding duplicate
+      // entries but having duplicates is  OK since we "mark" nmethods
+      // as visited when we scan the strong code root lists during the GC.
+      hr->add_strong_code_root(_nm);
+      assert(hr->rem_set()->strong_code_roots_list_contains(_nm),
+             err_msg("failed to add code root "PTR_FORMAT" to remembered set of region "HR_FORMAT,
+                     _nm, HR_FORMAT_PARAMS(hr)));
+    }
+  }
+
+public:
+  RegisterNMethodOopClosure(G1CollectedHeap* g1h, nmethod* nm) :
+    _g1h(g1h), _nm(nm) {}
+
+  void do_oop(oop* p)       { do_oop_work(p); }
+  void do_oop(narrowOop* p) { do_oop_work(p); }
+};
+
+class UnregisterNMethodOopClosure: public OopClosure {
+  G1CollectedHeap* _g1h;
+  nmethod* _nm;
+
+  template <class T> void do_oop_work(T* p) {
+    T heap_oop = oopDesc::load_heap_oop(p);
+    if (!oopDesc::is_null(heap_oop)) {
+      oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+      HeapRegion* hr = _g1h->heap_region_containing(obj);
+      if (hr == NULL) {
+        // reference into perm gen - ignore.
+        assert(_g1h->is_in_permanent(obj), "must be a reference into perm gen");
+        return;
+      }
+      assert(!hr->continuesHumongous(),
+             err_msg("trying to remove code root "PTR_FORMAT" in continuation of humongous region "HR_FORMAT
+                     " starting at "HR_FORMAT,
+                     _nm, HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region())));
+
+      hr->remove_strong_code_root(_nm);
+      assert(!hr->rem_set()->strong_code_roots_list_contains(_nm),
+             err_msg("failed to remove code root "PTR_FORMAT" of region "HR_FORMAT,
+                     _nm, HR_FORMAT_PARAMS(hr)));    }
+  }
+
+public:
+  UnregisterNMethodOopClosure(G1CollectedHeap* g1h, nmethod* nm) :
+    _g1h(g1h), _nm(nm) {}
+
+  void do_oop(oop* p)       { do_oop_work(p); }
+  void do_oop(narrowOop* p) { do_oop_work(p); }
+};
+
+void G1CollectedHeap::register_nmethod(nmethod* nm) {
+  CollectedHeap::register_nmethod(nm);
+
+  guarantee(nm != NULL, "sanity");
+  RegisterNMethodOopClosure reg_cl(this, nm);
+  nm->oops_do(&reg_cl);
+}
+
+void G1CollectedHeap::unregister_nmethod(nmethod* nm) {
+  CollectedHeap::unregister_nmethod(nm);
+
+  guarantee(nm != NULL, "sanity");
+  UnregisterNMethodOopClosure reg_cl(this, nm);
+  nm->oops_do(&reg_cl, false, true);
+}
+
+class MigrateCodeRootsHeapRegionClosure: public HeapRegionClosure {
+public:
+  bool doHeapRegion(HeapRegion *hr) {
+    assert(!hr->isHumongous(),
+           err_msg("humongous region "HR_FORMAT" should not have been added to collection set",
+                   HR_FORMAT_PARAMS(hr)));
+    hr->migrate_strong_code_roots();
+    return false;
+  }
+};
+
+void G1CollectedHeap::migrate_strong_code_roots() {
+  MigrateCodeRootsHeapRegionClosure cl;
+  double migrate_start = os::elapsedTime();
+  collection_set_iterate(&cl);
+  double migration_time_ms = (os::elapsedTime() - migrate_start) * 1000.0;
+  g1_policy()->phase_times()->record_strong_code_root_migration_time(migration_time_ms);
+}
+
+// Mark all the code roots that point into regions *not* in the
+// collection set.
+//
+// Note we do not want to use a "marking" CodeBlobToOopClosure while
+// walking the the code roots lists of regions not in the collection
+// set. Suppose we have an nmethod (M) that points to objects in two
+// separate regions - one in the collection set (R1) and one not (R2).
+// Using a "marking" CodeBlobToOopClosure here would result in "marking"
+// nmethod M when walking the code roots for R1. When we come to scan
+// the code roots for R2, we would see that M is already marked and it
+// would be skipped and the objects in R2 that are referenced from M
+// would not be evacuated.
+
+class MarkStrongCodeRootCodeBlobClosure: public CodeBlobClosure {
+
+  class MarkStrongCodeRootOopClosure: public OopClosure {
+    ConcurrentMark* _cm;
+    HeapRegion* _hr;
+    uint _worker_id;
+
+    template <class T> void do_oop_work(T* p) {
+      T heap_oop = oopDesc::load_heap_oop(p);
+      if (!oopDesc::is_null(heap_oop)) {
+        oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+        // Only mark objects in the region (which is assumed
+        // to be not in the collection set).
+        if (_hr->is_in(obj)) {
+          _cm->grayRoot(obj, (size_t) obj->size(), _worker_id);
+        }
+      }
+    }
+
+  public:
+    MarkStrongCodeRootOopClosure(ConcurrentMark* cm, HeapRegion* hr, uint worker_id) :
+      _cm(cm), _hr(hr), _worker_id(worker_id) {
+      assert(!_hr->in_collection_set(), "sanity");
+    }
+
+    void do_oop(narrowOop* p) { do_oop_work(p); }
+    void do_oop(oop* p)       { do_oop_work(p); }
+  };
+
+  MarkStrongCodeRootOopClosure _oop_cl;
+
+public:
+  MarkStrongCodeRootCodeBlobClosure(ConcurrentMark* cm, HeapRegion* hr, uint worker_id):
+    _oop_cl(cm, hr, worker_id) {}
+
+  void do_code_blob(CodeBlob* cb) {
+    nmethod* nm = (cb == NULL) ? NULL : cb->as_nmethod_or_null();
+    if (nm != NULL) {
+      nm->oops_do(&_oop_cl);
+    }
+  }
+};
+
+class MarkStrongCodeRootsHRClosure: public HeapRegionClosure {
+  G1CollectedHeap* _g1h;
+  uint _worker_id;
+
+public:
+  MarkStrongCodeRootsHRClosure(G1CollectedHeap* g1h, uint worker_id) :
+    _g1h(g1h), _worker_id(worker_id) {}
+
+  bool doHeapRegion(HeapRegion *hr) {
+    HeapRegionRemSet* hrrs = hr->rem_set();
+    if (hr->continuesHumongous()) {
+      // Code roots should never be attached to a continuation of a humongous region
+      assert(hrrs->strong_code_roots_list_length() == 0,
+             err_msg("code roots should never be attached to continuations of humongous region "HR_FORMAT
+                     " starting at "HR_FORMAT", but has "INT32_FORMAT,
+                     HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region()),
+                     hrrs->strong_code_roots_list_length()));
+      return false;
+    }
+
+    if (hr->in_collection_set()) {
+      // Don't mark code roots into regions in the collection set here.
+      // They will be marked when we scan them.
+      return false;
+    }
+
+    MarkStrongCodeRootCodeBlobClosure cb_cl(_g1h->concurrent_mark(), hr, _worker_id);
+    hr->strong_code_roots_do(&cb_cl);
+    return false;
+  }
+};
+
+void G1CollectedHeap::mark_strong_code_roots(uint worker_id) {
+  MarkStrongCodeRootsHRClosure cl(this, worker_id);
+  if (G1CollectedHeap::use_parallel_gc_threads()) {
+    heap_region_par_iterate_chunked(&cl,
+                                    worker_id,
+                                    workers()->active_workers(),
+                                    HeapRegion::ParMarkRootClaimValue);
+  } else {
+    heap_region_iterate(&cl);
+  }
+}
+
+class RebuildStrongCodeRootClosure: public CodeBlobClosure {
+  G1CollectedHeap* _g1h;
+
+public:
+  RebuildStrongCodeRootClosure(G1CollectedHeap* g1h) :
+    _g1h(g1h) {}
+
+  void do_code_blob(CodeBlob* cb) {
+    nmethod* nm = (cb != NULL) ? cb->as_nmethod_or_null() : NULL;
+    if (nm == NULL) {
+      return;
+    }
+
+    if (ScavengeRootsInCode && nm->detect_scavenge_root_oops()) {
+      _g1h->register_nmethod(nm);
+    }
+  }
+};
+
+void G1CollectedHeap::rebuild_strong_code_roots() {
+  RebuildStrongCodeRootClosure blob_cl(this);
+  CodeCache::blobs_do(&blob_cl);
+}
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -31,6 +31,7 @@
 #include "gc_implementation/g1/g1HRPrinter.hpp"
 #include "gc_implementation/g1/g1MonitoringSupport.hpp"
 #include "gc_implementation/g1/g1RemSet.hpp"
+#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
 #include "gc_implementation/g1/g1YCTypes.hpp"
 #include "gc_implementation/g1/heapRegionSeq.hpp"
 #include "gc_implementation/g1/heapRegionSets.hpp"
@@ -46,6 +47,7 @@
 // may combine concurrent marking with parallel, incremental compaction of
 // heap subsets that will yield large amounts of garbage.
 
+// Forward declarations
 class HeapRegion;
 class HRRSCleanupTask;
 class PermanentGenerationSpec;
@@ -69,6 +71,8 @@
 class G1NewTracer;
 class G1OldTracer;
 class EvacuationFailedInfo;
+class nmethod;
+class Ticks;
 
 typedef OverflowTaskQueue<StarTask, mtGC>         RefToScanQueue;
 typedef GenericTaskQueueSet<RefToScanQueue, mtGC> RefToScanQueueSet;
@@ -163,19 +167,6 @@
     : G1AllocRegion("Mutator Alloc Region", false /* bot_updates */) { }
 };
 
-// The G1 STW is alive closure.
-// An instance is embedded into the G1CH and used as the
-// (optional) _is_alive_non_header closure in the STW
-// reference processor. It is also extensively used during
-// reference processing during STW evacuation pauses.
-class G1STWIsAliveClosure: public BoolObjectClosure {
-  G1CollectedHeap* _g1;
-public:
-  G1STWIsAliveClosure(G1CollectedHeap* g1) : _g1(g1) {}
-  void do_object(oop p) { assert(false, "Do not call."); }
-  bool do_object_b(oop p);
-};
-
 class SurvivorGCAllocRegion : public G1AllocRegion {
 protected:
   virtual HeapRegion* allocate_new_region(size_t word_size, bool force);
@@ -194,6 +185,19 @@
   : G1AllocRegion("Old GC Alloc Region", true /* bot_updates */) { }
 };
 
+// The G1 STW is alive closure.
+// An instance is embedded into the G1CH and used as the
+// (optional) _is_alive_non_header closure in the STW
+// reference processor. It is also extensively used during
+// reference processing during STW evacuation pauses.
+class G1STWIsAliveClosure: public BoolObjectClosure {
+  G1CollectedHeap* _g1;
+public:
+  G1STWIsAliveClosure(G1CollectedHeap* g1) : _g1(g1) {}
+  void do_object(oop p) { assert(false, "Do not call."); }
+  bool do_object_b(oop p);
+};
+
 class RefineCardTableEntryClosure;
 
 class G1CollectedHeap : public SharedHeap {
@@ -747,7 +751,7 @@
     return _old_marking_cycles_completed;
   }
 
-  void register_concurrent_cycle_start(jlong start_time);
+  void register_concurrent_cycle_start(const Ticks& start_time);
   void register_concurrent_cycle_end();
   void trace_heap_after_concurrent_cycle();
 
@@ -792,8 +796,6 @@
 
   // The g1 remembered set of the heap.
   G1RemSet* _g1_rem_set;
-  // And it's mod ref barrier set, used to track updates for the above.
-  ModRefBarrierSet* _mr_bs;
 
   // A set of cards that cover the objects for which the Rsets should be updated
   // concurrently after the collection.
@@ -835,7 +837,8 @@
                                OopClosure* scan_non_heap_roots,
                                OopsInHeapRegionClosure* scan_rs,
                                OopsInGenClosure* scan_perm,
-                               int worker_i);
+                               int worker_i,
+                               bool manages_code_roots = false);
 
   // Apply "blk" to all the weak roots of the system.  These include
   // JNI weak roots, the code cache, system dictionary, symbol table,
@@ -1127,7 +1130,6 @@
 
   // The rem set and barrier set.
   G1RemSet* g1_rem_set() const { return _g1_rem_set; }
-  ModRefBarrierSet* mr_bs() const { return _mr_bs; }
 
   // The rem set iterator.
   HeapRegionRemSetIterator* rem_set_iterator(int i) {
@@ -1361,6 +1363,10 @@
 
   virtual bool is_in_closed_subset(const void* p) const;
 
+  G1SATBCardTableModRefBS* g1_barrier_set() {
+    return (G1SATBCardTableModRefBS*) barrier_set();
+  }
+
   // This resets the card table to all zeros.  It is used after
   // a collection pause which used the card table to claim cards.
   void cleanUpCardTable();
@@ -1592,41 +1598,6 @@
 
   virtual jlong millis_since_last_gc();
 
-  // Perform any cleanup actions necessary before allowing a verification.
-  virtual void prepare_for_verify();
-
-  // Perform verification.
-
-  // vo == UsePrevMarking  -> use "prev" marking information,
-  // vo == UseNextMarking -> use "next" marking information
-  // vo == UseMarkWord    -> use the mark word in the object header
-  //
-  // NOTE: Only the "prev" marking information is guaranteed to be
-  // consistent most of the time, so most calls to this should use
-  // vo == UsePrevMarking.
-  // Currently, there is only one case where this is called with
-  // vo == UseNextMarking, which is to verify the "next" marking
-  // information at the end of remark.
-  // Currently there is only one place where this is called with
-  // vo == UseMarkWord, which is to verify the marking during a
-  // full GC.
-  void verify(bool silent, VerifyOption vo);
-
-  // Override; it uses the "prev" marking information
-  virtual void verify(bool silent);
-
-  virtual void print_on(outputStream* st) const;
-  virtual void print_extended_on(outputStream* st) const;
-
-  virtual void print_gc_threads_on(outputStream* st) const;
-  virtual void gc_threads_do(ThreadClosure* tc) const;
-
-  // Override
-  void print_tracing_info() const;
-
-  // The following two methods are helpful for debugging RSet issues.
-  void print_cset_rsets() PRODUCT_RETURN;
-  void print_all_rsets() PRODUCT_RETURN;
 
   // Convenience function to be used in situations where the heap type can be
   // asserted to be this type.
@@ -1684,7 +1655,6 @@
   // then call the region version of the same function.
 
   // Added if it is in permanent gen it isn't dead.
-  // Added if it is NULL it isn't dead.
 
   bool is_obj_dead(const oop obj) const {
     const HeapRegion* hr = heap_region_containing(obj);
@@ -1708,13 +1678,90 @@
     else return is_obj_ill(obj, hr);
   }
 
+  bool allocated_since_marking(oop obj, HeapRegion* hr, VerifyOption vo);
+  HeapWord* top_at_mark_start(HeapRegion* hr, VerifyOption vo);
+  bool is_marked(oop obj, VerifyOption vo);
+  const char* top_at_mark_start_str(VerifyOption vo);
+
+  ConcurrentMark* concurrent_mark() const { return _cm; }
+
+  // Refinement
+
+  ConcurrentG1Refine* concurrent_g1_refine() const { return _cg1r; }
+
+  // The dirty cards region list is used to record a subset of regions
+  // whose cards need clearing. The list if populated during the
+  // remembered set scanning and drained during the card table
+  // cleanup. Although the methods are reentrant, population/draining
+  // phases must not overlap. For synchronization purposes the last
+  // element on the list points to itself.
+  HeapRegion* _dirty_cards_region_list;
+  void push_dirty_cards_region(HeapRegion* hr);
+  HeapRegion* pop_dirty_cards_region();
+
+  // Optimized nmethod scanning support routines
+
+  // Register the given nmethod with the G1 heap
+  virtual void register_nmethod(nmethod* nm);
+
+  // Unregister the given nmethod from the G1 heap
+  virtual void unregister_nmethod(nmethod* nm);
+
+  // Migrate the nmethods in the code root lists of the regions
+  // in the collection set to regions in to-space. In the event
+  // of an evacuation failure, nmethods that reference objects
+  // that were not successfullly evacuated are not migrated.
+  void migrate_strong_code_roots();
+
+  // During an initial mark pause, mark all the code roots that
+  // point into regions *not* in the collection set.
+  void mark_strong_code_roots(uint worker_id);
+
+  // Rebuild the stong code root lists for each region
+  // after a full GC
+  void rebuild_strong_code_roots();
+
+  // Delete entries for dead interned string and clean up unreferenced symbols
+  // in symbol table, possibly in parallel.
+  void unlink_string_and_symbol_table(BoolObjectClosure* is_alive, bool unlink_strings = true, bool unlink_symbols = true);
+
+  // Verification
+
+  // The following is just to alert the verification code
+  // that a full collection has occurred and that the
+  // remembered sets are no longer up to date.
+  bool _full_collection;
+  void set_full_collection() { _full_collection = true;}
+  void clear_full_collection() {_full_collection = false;}
+  bool full_collection() {return _full_collection;}
+
+  // Perform any cleanup actions necessary before allowing a verification.
+  virtual void prepare_for_verify();
+
+  // Perform verification.
+
+  // vo == UsePrevMarking  -> use "prev" marking information,
+  // vo == UseNextMarking -> use "next" marking information
+  // vo == UseMarkWord    -> use the mark word in the object header
+  //
+  // NOTE: Only the "prev" marking information is guaranteed to be
+  // consistent most of the time, so most calls to this should use
+  // vo == UsePrevMarking.
+  // Currently, there is only one case where this is called with
+  // vo == UseNextMarking, which is to verify the "next" marking
+  // information at the end of remark.
+  // Currently there is only one place where this is called with
+  // vo == UseMarkWord, which is to verify the marking during a
+  // full GC.
+  void verify(bool silent, VerifyOption vo);
+
+  // Override; it uses the "prev" marking information
+  virtual void verify(bool silent);
+
   // The methods below are here for convenience and dispatch the
   // appropriate method depending on value of the given VerifyOption
-  // parameter. The options for that parameter are:
-  //
-  // vo == UsePrevMarking -> use "prev" marking information,
-  // vo == UseNextMarking -> use "next" marking information,
-  // vo == UseMarkWord    -> use mark word from object header
+  // parameter. The values for that parameter, and their meanings,
+  // are the same as those above.
 
   bool is_obj_dead_cond(const oop obj,
                         const HeapRegion* hr,
@@ -1739,31 +1786,20 @@
     return false; // keep some compilers happy
   }
 
-  bool allocated_since_marking(oop obj, HeapRegion* hr, VerifyOption vo);
-  HeapWord* top_at_mark_start(HeapRegion* hr, VerifyOption vo);
-  bool is_marked(oop obj, VerifyOption vo);
-  const char* top_at_mark_start_str(VerifyOption vo);
+  // Printing
 
-  // The following is just to alert the verification code
-  // that a full collection has occurred and that the
-  // remembered sets are no longer up to date.
-  bool _full_collection;
-  void set_full_collection() { _full_collection = true;}
-  void clear_full_collection() {_full_collection = false;}
-  bool full_collection() {return _full_collection;}
+  virtual void print_on(outputStream* st) const;
+  virtual void print_extended_on(outputStream* st) const;
 
-  ConcurrentMark* concurrent_mark() const { return _cm; }
-  ConcurrentG1Refine* concurrent_g1_refine() const { return _cg1r; }
+  virtual void print_gc_threads_on(outputStream* st) const;
+  virtual void gc_threads_do(ThreadClosure* tc) const;
 
-  // The dirty cards region list is used to record a subset of regions
-  // whose cards need clearing. The list if populated during the
-  // remembered set scanning and drained during the card table
-  // cleanup. Although the methods are reentrant, population/draining
-  // phases must not overlap. For synchronization purposes the last
-  // element on the list points to itself.
-  HeapRegion* _dirty_cards_region_list;
-  void push_dirty_cards_region(HeapRegion* hr);
-  HeapRegion* pop_dirty_cards_region();
+  // Override
+  void print_tracing_info() const;
+
+  // The following two methods are helpful for debugging RSet issues.
+  void print_cset_rsets() PRODUCT_RETURN;
+  void print_all_rsets() PRODUCT_RETURN;
 
 public:
   void stop_conc_gc_threads();
@@ -1800,7 +1836,7 @@
   G1CollectedHeap* _g1h;
   RefToScanQueue*  _refs;
   DirtyCardQueue   _dcq;
-  CardTableModRefBS* _ct_bs;
+  G1SATBCardTableModRefBS* _ct_bs;
   G1RemSet* _g1_rem;
 
   G1ParGCAllocBuffer  _surviving_alloc_buffer;
@@ -1839,7 +1875,7 @@
   void   add_to_undo_waste(size_t waste)         { _undo_waste += waste; }
 
   DirtyCardQueue& dirty_card_queue()             { return _dcq;  }
-  CardTableModRefBS* ctbs()                      { return _ct_bs; }
+  G1SATBCardTableModRefBS* ctbs()                { return _ct_bs; }
 
   template <class T> void immediate_rs_update(HeapRegion* from, T* p, int tid) {
     if (!from->is_survivor()) {
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -29,6 +29,7 @@
 #include "gc_implementation/g1/g1CollectedHeap.hpp"
 #include "gc_implementation/g1/g1AllocRegion.inline.hpp"
 #include "gc_implementation/g1/g1CollectorPolicy.hpp"
+#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
 #include "gc_implementation/g1/heapRegionSeq.inline.hpp"
 #include "utilities/taskqueue.hpp"
 
@@ -131,7 +132,7 @@
   assert(containing_hr->is_in(end - 1), "it should also contain end - 1");
 
   MemRegion mr(start, end);
-  ((CardTableModRefBS*)_g1h->barrier_set())->dirty(mr);
+  g1_barrier_set()->g1_mark_as_young(mr);
 }
 
 inline RefToScanQueue* G1CollectedHeap::task_queue(int i) const {
--- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -310,7 +310,8 @@
 void G1CollectorPolicy::initialize_flags() {
   set_min_alignment(HeapRegion::GrainBytes);
   size_t card_table_alignment = GenRemSet::max_alignment_constraint(rem_set_name());
-  set_max_alignment(MAX2(card_table_alignment, min_alignment()));
+  size_t page_size = UseLargePages ? os::large_page_size() : os::vm_page_size();
+  set_max_alignment(MAX3(card_table_alignment, min_alignment(), page_size));
   if (SurvivorRatio < 1) {
     vm_exit_during_initialization("Invalid survivor ratio specified");
   }
--- a/src/share/vm/gc_implementation/g1/g1EvacFailure.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/g1EvacFailure.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -41,11 +41,11 @@
 private:
   G1CollectedHeap* _g1;
   DirtyCardQueue *_dcq;
-  CardTableModRefBS* _ct_bs;
+  G1SATBCardTableModRefBS* _ct_bs;
 
 public:
   UpdateRSetDeferred(G1CollectedHeap* g1, DirtyCardQueue* dcq) :
-    _g1(g1), _ct_bs((CardTableModRefBS*)_g1->barrier_set()), _dcq(dcq) {}
+    _g1(g1), _ct_bs(_g1->g1_barrier_set()), _dcq(dcq) {}
 
   virtual void do_oop(narrowOop* p) { do_oop_work(p); }
   virtual void do_oop(      oop* p) { do_oop_work(p); }
--- a/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -161,6 +161,8 @@
   _last_update_rs_times_ms(_max_gc_threads, "%.1lf"),
   _last_update_rs_processed_buffers(_max_gc_threads, "%d"),
   _last_scan_rs_times_ms(_max_gc_threads, "%.1lf"),
+  _last_strong_code_root_scan_times_ms(_max_gc_threads, "%.1lf"),
+  _last_strong_code_root_mark_times_ms(_max_gc_threads, "%.1lf"),
   _last_obj_copy_times_ms(_max_gc_threads, "%.1lf"),
   _last_termination_times_ms(_max_gc_threads, "%.1lf"),
   _last_termination_attempts(_max_gc_threads, SIZE_FORMAT),
@@ -182,6 +184,8 @@
   _last_update_rs_times_ms.reset();
   _last_update_rs_processed_buffers.reset();
   _last_scan_rs_times_ms.reset();
+  _last_strong_code_root_scan_times_ms.reset();
+  _last_strong_code_root_mark_times_ms.reset();
   _last_obj_copy_times_ms.reset();
   _last_termination_times_ms.reset();
   _last_termination_attempts.reset();
@@ -197,6 +201,8 @@
   _last_update_rs_times_ms.verify();
   _last_update_rs_processed_buffers.verify();
   _last_scan_rs_times_ms.verify();
+  _last_strong_code_root_scan_times_ms.verify();
+  _last_strong_code_root_mark_times_ms.verify();
   _last_obj_copy_times_ms.verify();
   _last_termination_times_ms.verify();
   _last_termination_attempts.verify();
@@ -210,6 +216,8 @@
                                _last_satb_filtering_times_ms.get(i) +
                                _last_update_rs_times_ms.get(i) +
                                _last_scan_rs_times_ms.get(i) +
+                               _last_strong_code_root_scan_times_ms.get(i) +
+                               _last_strong_code_root_mark_times_ms.get(i) +
                                _last_obj_copy_times_ms.get(i) +
                                _last_termination_times_ms.get(i);
 
@@ -239,6 +247,9 @@
     // Now subtract the time taken to fix up roots in generated code
     misc_time_ms += _cur_collection_code_root_fixup_time_ms;
 
+    // Strong code root migration time
+    misc_time_ms += _cur_strong_code_root_migration_time_ms;
+
     // Subtract the time taken to clean the card table from the
     // current value of "other time"
     misc_time_ms += _cur_clear_ct_time_ms;
@@ -257,9 +268,13 @@
     if (_last_satb_filtering_times_ms.sum() > 0.0) {
       _last_satb_filtering_times_ms.print(2, "SATB Filtering (ms)");
     }
+    if (_last_strong_code_root_mark_times_ms.sum() > 0.0) {
+     _last_strong_code_root_mark_times_ms.print(2, "Code Root Marking (ms)");
+    }
     _last_update_rs_times_ms.print(2, "Update RS (ms)");
       _last_update_rs_processed_buffers.print(3, "Processed Buffers");
     _last_scan_rs_times_ms.print(2, "Scan RS (ms)");
+    _last_strong_code_root_scan_times_ms.print(2, "Code Root Scanning (ms)");
     _last_obj_copy_times_ms.print(2, "Object Copy (ms)");
     _last_termination_times_ms.print(2, "Termination (ms)");
     if (G1Log::finest()) {
@@ -273,12 +288,17 @@
     if (_last_satb_filtering_times_ms.sum() > 0.0) {
       _last_satb_filtering_times_ms.print(1, "SATB Filtering (ms)");
     }
+    if (_last_strong_code_root_mark_times_ms.sum() > 0.0) {
+      _last_strong_code_root_mark_times_ms.print(1, "Code Root Marking (ms)");
+    }
     _last_update_rs_times_ms.print(1, "Update RS (ms)");
       _last_update_rs_processed_buffers.print(2, "Processed Buffers");
     _last_scan_rs_times_ms.print(1, "Scan RS (ms)");
+    _last_strong_code_root_scan_times_ms.print(1, "Code Root Scanning (ms)");
     _last_obj_copy_times_ms.print(1, "Object Copy (ms)");
   }
   print_stats(1, "Code Root Fixup", _cur_collection_code_root_fixup_time_ms);
+  print_stats(1, "Code Root Migration", _cur_strong_code_root_migration_time_ms);
   print_stats(1, "Clear CT", _cur_clear_ct_time_ms);
   double misc_time_ms = pause_time_sec * MILLIUNITS - accounted_time_ms();
   print_stats(1, "Other", misc_time_ms);
--- a/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -119,6 +119,8 @@
   WorkerDataArray<double> _last_update_rs_times_ms;
   WorkerDataArray<int>    _last_update_rs_processed_buffers;
   WorkerDataArray<double> _last_scan_rs_times_ms;
+  WorkerDataArray<double> _last_strong_code_root_scan_times_ms;
+  WorkerDataArray<double> _last_strong_code_root_mark_times_ms;
   WorkerDataArray<double> _last_obj_copy_times_ms;
   WorkerDataArray<double> _last_termination_times_ms;
   WorkerDataArray<size_t> _last_termination_attempts;
@@ -128,6 +130,7 @@
 
   double _cur_collection_par_time_ms;
   double _cur_collection_code_root_fixup_time_ms;
+  double _cur_strong_code_root_migration_time_ms;
 
   double _cur_clear_ct_time_ms;
   double _cur_ref_proc_time_ms;
@@ -179,6 +182,14 @@
     _last_scan_rs_times_ms.set(worker_i, ms);
   }
 
+  void record_strong_code_root_scan_time(uint worker_i, double ms) {
+    _last_strong_code_root_scan_times_ms.set(worker_i, ms);
+  }
+
+  void record_strong_code_root_mark_time(uint worker_i, double ms) {
+    _last_strong_code_root_mark_times_ms.set(worker_i, ms);
+  }
+
   void record_obj_copy_time(uint worker_i, double ms) {
     _last_obj_copy_times_ms.set(worker_i, ms);
   }
@@ -208,6 +219,10 @@
     _cur_collection_code_root_fixup_time_ms = ms;
   }
 
+  void record_strong_code_root_migration_time(double ms) {
+    _cur_strong_code_root_migration_time_ms = ms;
+  }
+
   void record_ref_proc_time(double ms) {
     _cur_ref_proc_time_ms = ms;
   }
@@ -294,6 +309,14 @@
     return _last_scan_rs_times_ms.average();
   }
 
+  double average_last_strong_code_root_scan_time(){
+    return _last_strong_code_root_scan_times_ms.average();
+  }
+
+  double average_last_strong_code_root_mark_time(){
+    return _last_strong_code_root_mark_times_ms.average();
+  }
+
   double average_last_obj_copy_time() {
     return _last_obj_copy_times_ms.average();
   }
--- a/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -177,10 +177,8 @@
   GenMarkSweep::follow_mdo_weak_refs();
   assert(GenMarkSweep::_marking_stack.is_empty(), "just drained");
 
-  // Visit interned string tables and delete unmarked oops
-  StringTable::unlink(&GenMarkSweep::is_alive);
-  // Clean up unreferenced symbols in symbol table.
-  SymbolTable::unlink();
+  // Delete entries for dead interned string and clean up unreferenced symbols in symbol table.
+  G1CollectedHeap::heap()->unlink_string_and_symbol_table(&GenMarkSweep::is_alive);
 
   assert(GenMarkSweep::_marking_stack.is_empty(),
          "stack should be empty by now");
@@ -188,7 +186,6 @@
   if (VerifyDuringGC) {
     HandleMark hm;  // handle scope
     COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact);
-    gclog_or_tty->print(" VerifyDuringGC:(full)[Verifying ");
     Universe::heap()->prepare_for_verify();
     // Note: we can verify only the heap here. When an object is
     // marked, the previous value of the mark word (including
@@ -200,11 +197,13 @@
     // fail. At the end of the GC, the orginal mark word values
     // (including hash values) are restored to the appropriate
     // objects.
-    Universe::heap()->verify(/* silent      */ false,
-                             /* option      */ VerifyOption_G1UseMarkWord);
-
-    G1CollectedHeap* g1h = G1CollectedHeap::heap();
-    gclog_or_tty->print_cr("]");
+    if (!VerifySilently) {
+      gclog_or_tty->print(" VerifyDuringGC:(full)[Verifying ");
+    }
+    Universe::heap()->verify(VerifySilently, VerifyOption_G1UseMarkWord);
+    if (!VerifySilently) {
+      gclog_or_tty->print_cr("]");
+    }
   }
 
   gc_tracer()->report_object_count_after_gc(&GenMarkSweep::is_alive);
@@ -235,7 +234,7 @@
 public:
   G1PrepareCompactClosure(CompactibleSpace* cs)
   : _g1h(G1CollectedHeap::heap()),
-    _mrbs(G1CollectedHeap::heap()->mr_bs()),
+    _mrbs(_g1h->g1_barrier_set()),
     _cp(NULL, cs, cs->initialize_threshold()),
     _humongous_proxy_set("G1MarkSweep Humongous Proxy Set") { }
 
--- a/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -34,6 +34,7 @@
 #include "gc_implementation/g1/g1OopClosures.inline.hpp"
 #include "gc_implementation/g1/g1RemSet.inline.hpp"
 #include "gc_implementation/g1/heapRegionSeq.inline.hpp"
+#include "gc_implementation/g1/heapRegionRemSet.hpp"
 #include "memory/iterator.hpp"
 #include "oops/oop.inline.hpp"
 #include "utilities/intHisto.hpp"
@@ -73,7 +74,8 @@
     _ct_bs(ct_bs), _g1p(_g1->g1_policy()),
     _cg1r(g1->concurrent_g1_refine()),
     _cset_rs_update_cl(NULL),
-    _cards_scanned(NULL), _total_cards_scanned(0)
+    _cards_scanned(NULL), _total_cards_scanned(0),
+    _prev_period_summary()
 {
   _seq_task = new SubTasksDone(NumSeqTasks);
   guarantee(n_workers() > 0, "There should be some workers");
@@ -81,6 +83,9 @@
   for (uint i = 0; i < n_workers(); i++) {
     _cset_rs_update_cl[i] = NULL;
   }
+  if (G1SummarizeRSetStats) {
+    _prev_period_summary.initialize(this);
+  }
 }
 
 G1RemSet::~G1RemSet() {
@@ -101,15 +106,25 @@
 class ScanRSClosure : public HeapRegionClosure {
   size_t _cards_done, _cards;
   G1CollectedHeap* _g1h;
+
   OopsInHeapRegionClosure* _oc;
+  CodeBlobToOopClosure* _code_root_cl;
+
   G1BlockOffsetSharedArray* _bot_shared;
-  CardTableModRefBS *_ct_bs;
-  int _worker_i;
-  int _block_size;
-  bool _try_claimed;
+  G1SATBCardTableModRefBS *_ct_bs;
+
+  double _strong_code_root_scan_time_sec;
+  int    _worker_i;
+  int    _block_size;
+  bool   _try_claimed;
+
 public:
-  ScanRSClosure(OopsInHeapRegionClosure* oc, int worker_i) :
+  ScanRSClosure(OopsInHeapRegionClosure* oc,
+                CodeBlobToOopClosure* code_root_cl,
+                int worker_i) :
     _oc(oc),
+    _code_root_cl(code_root_cl),
+    _strong_code_root_scan_time_sec(0.0),
     _cards(0),
     _cards_done(0),
     _worker_i(worker_i),
@@ -117,7 +132,7 @@
   {
     _g1h = G1CollectedHeap::heap();
     _bot_shared = _g1h->bot_shared();
-    _ct_bs = (CardTableModRefBS*) (_g1h->barrier_set());
+    _ct_bs = _g1h->g1_barrier_set();
     _block_size = MAX2<int>(G1RSetScanBlockSize, 1);
   }
 
@@ -157,6 +172,12 @@
                            card_start, card_start + G1BlockOffsetSharedArray::N_words);
   }
 
+  void scan_strong_code_roots(HeapRegion* r) {
+    double scan_start = os::elapsedTime();
+    r->strong_code_roots_do(_code_root_cl);
+    _strong_code_root_scan_time_sec += (os::elapsedTime() - scan_start);
+  }
+
   bool doHeapRegion(HeapRegion* r) {
     assert(r->in_collection_set(), "should only be called on elements of CS.");
     HeapRegionRemSet* hrrs = r->rem_set();
@@ -170,6 +191,7 @@
     //   _try_claimed || r->claim_iter()
     // is true: either we're supposed to work on claimed-but-not-complete
     // regions, or we successfully claimed the region.
+
     HeapRegionRemSetIterator* iter = _g1h->rem_set_iterator(_worker_i);
     hrrs->init_iterator(iter);
     size_t card_index;
@@ -203,30 +225,43 @@
       }
     }
     if (!_try_claimed) {
+      // Scan the strong code root list attached to the current region
+      scan_strong_code_roots(r);
+
       hrrs->set_iter_complete();
     }
     return false;
   }
+
+  double strong_code_root_scan_time_sec() {
+    return _strong_code_root_scan_time_sec;
+  }
+
   size_t cards_done() { return _cards_done;}
   size_t cards_looked_up() { return _cards;}
 };
 
-void G1RemSet::scanRS(OopsInHeapRegionClosure* oc, int worker_i) {
+void G1RemSet::scanRS(OopsInHeapRegionClosure* oc,
+                      CodeBlobToOopClosure* code_root_cl,
+                      int worker_i) {
   double rs_time_start = os::elapsedTime();
   HeapRegion *startRegion = _g1->start_cset_region_for_worker(worker_i);
 
-  ScanRSClosure scanRScl(oc, worker_i);
+  ScanRSClosure scanRScl(oc, code_root_cl, worker_i);
 
   _g1->collection_set_iterate_from(startRegion, &scanRScl);
   scanRScl.set_try_claimed();
   _g1->collection_set_iterate_from(startRegion, &scanRScl);
 
-  double scan_rs_time_sec = os::elapsedTime() - rs_time_start;
+  double scan_rs_time_sec = (os::elapsedTime() - rs_time_start)
+                            - scanRScl.strong_code_root_scan_time_sec();
 
-  assert( _cards_scanned != NULL, "invariant" );
+  assert(_cards_scanned != NULL, "invariant");
   _cards_scanned[worker_i] = scanRScl.cards_done();
 
   _g1p->phase_times()->record_scan_rs_time(worker_i, scan_rs_time_sec * 1000.0);
+  _g1p->phase_times()->record_strong_code_root_scan_time(worker_i,
+                                                         scanRScl.strong_code_root_scan_time_sec() * 1000.0);
 }
 
 // Closure used for updating RSets and recording references that
@@ -286,7 +321,8 @@
 }
 
 void G1RemSet::oops_into_collection_set_do(OopsInHeapRegionClosure* oc,
-                                             int worker_i) {
+                                           CodeBlobToOopClosure* code_root_cl,
+                                           int worker_i) {
 #if CARD_REPEAT_HISTO
   ct_freq_update_histo_and_reset();
 #endif
@@ -326,7 +362,7 @@
     _g1p->phase_times()->record_update_rs_time(worker_i, 0.0);
   }
   if (G1UseParallelRSetScanning || (worker_i == 0)) {
-    scanRS(oc, worker_i);
+    scanRS(oc, code_root_cl, worker_i);
   } else {
     _g1p->phase_times()->record_scan_rs_time(worker_i, 0.0);
   }
@@ -472,12 +508,7 @@
   ScrubRSClosure(BitMap* region_bm, BitMap* card_bm) :
     _g1h(G1CollectedHeap::heap()),
     _region_bm(region_bm), _card_bm(card_bm),
-    _ctbs(NULL)
-  {
-    ModRefBarrierSet* bs = _g1h->mr_bs();
-    guarantee(bs->is_a(BarrierSet::CardTableModRef), "Precondition");
-    _ctbs = (CardTableModRefBS*)bs;
-  }
+    _ctbs(_g1h->g1_barrier_set()) {}
 
   bool doHeapRegion(HeapRegion* r) {
     if (!r->continuesHumongous()) {
@@ -700,47 +731,29 @@
   return has_refs_into_cset;
 }
 
-class HRRSStatsIter: public HeapRegionClosure {
-  size_t _occupied;
-  size_t _total_mem_sz;
-  size_t _max_mem_sz;
-  HeapRegion* _max_mem_sz_region;
-public:
-  HRRSStatsIter() :
-    _occupied(0),
-    _total_mem_sz(0),
-    _max_mem_sz(0),
-    _max_mem_sz_region(NULL)
-  {}
+void G1RemSet::print_periodic_summary_info(const char* header) {
+  G1RemSetSummary current;
+  current.initialize(this);
 
-  bool doHeapRegion(HeapRegion* r) {
-    if (r->continuesHumongous()) return false;
-    size_t mem_sz = r->rem_set()->mem_size();
-    if (mem_sz > _max_mem_sz) {
-      _max_mem_sz = mem_sz;
-      _max_mem_sz_region = r;
-    }
-    _total_mem_sz += mem_sz;
-    size_t occ = r->rem_set()->occupied();
-    _occupied += occ;
-    return false;
-  }
-  size_t total_mem_sz() { return _total_mem_sz; }
-  size_t max_mem_sz() { return _max_mem_sz; }
-  size_t occupied() { return _occupied; }
-  HeapRegion* max_mem_sz_region() { return _max_mem_sz_region; }
-};
+  _prev_period_summary.subtract_from(&current);
+  print_summary_info(&_prev_period_summary, header);
 
-class PrintRSThreadVTimeClosure : public ThreadClosure {
-public:
-  virtual void do_thread(Thread *t) {
-    ConcurrentG1RefineThread* crt = (ConcurrentG1RefineThread*) t;
-    gclog_or_tty->print("    %5.2f", crt->vtime_accum());
-  }
-};
+  _prev_period_summary.set(&current);
+}
 
 void G1RemSet::print_summary_info() {
-  G1CollectedHeap* g1 = G1CollectedHeap::heap();
+  G1RemSetSummary current;
+  current.initialize(this);
+
+  print_summary_info(&current, " Cumulative RS summary");
+}
+
+void G1RemSet::print_summary_info(G1RemSetSummary * summary, const char * header) {
+  assert(summary != NULL, "just checking");
+
+  if (header != NULL) {
+    gclog_or_tty->print_cr("%s", header);
+  }
 
 #if CARD_REPEAT_HISTO
   gclog_or_tty->print_cr("\nG1 card_repeat count histogram: ");
@@ -748,52 +761,13 @@
   card_repeat_count.print_on(gclog_or_tty);
 #endif
 
-  gclog_or_tty->print_cr("\n Concurrent RS processed %d cards",
-                         _conc_refine_cards);
-  DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
-  jint tot_processed_buffers =
-    dcqs.processed_buffers_mut() + dcqs.processed_buffers_rs_thread();
-  gclog_or_tty->print_cr("  Of %d completed buffers:", tot_processed_buffers);
-  gclog_or_tty->print_cr("     %8d (%5.1f%%) by conc RS threads.",
-                dcqs.processed_buffers_rs_thread(),
-                100.0*(float)dcqs.processed_buffers_rs_thread()/
-                (float)tot_processed_buffers);
-  gclog_or_tty->print_cr("     %8d (%5.1f%%) by mutator threads.",
-                dcqs.processed_buffers_mut(),
-                100.0*(float)dcqs.processed_buffers_mut()/
-                (float)tot_processed_buffers);
-  gclog_or_tty->print_cr("  Conc RS threads times(s)");
-  PrintRSThreadVTimeClosure p;
-  gclog_or_tty->print("     ");
-  g1->concurrent_g1_refine()->threads_do(&p);
-  gclog_or_tty->print_cr("");
-
-  HRRSStatsIter blk;
-  g1->heap_region_iterate(&blk);
-  gclog_or_tty->print_cr("  Total heap region rem set sizes = "SIZE_FORMAT"K."
-                         "  Max = "SIZE_FORMAT"K.",
-                         blk.total_mem_sz()/K, blk.max_mem_sz()/K);
-  gclog_or_tty->print_cr("  Static structures = "SIZE_FORMAT"K,"
-                         " free_lists = "SIZE_FORMAT"K.",
-                         HeapRegionRemSet::static_mem_size() / K,
-                         HeapRegionRemSet::fl_mem_size() / K);
-  gclog_or_tty->print_cr("    "SIZE_FORMAT" occupied cards represented.",
-                         blk.occupied());
-  HeapRegion* max_mem_sz_region = blk.max_mem_sz_region();
-  HeapRegionRemSet* rem_set = max_mem_sz_region->rem_set();
-  gclog_or_tty->print_cr("    Max size region = "HR_FORMAT", "
-                         "size = "SIZE_FORMAT "K, occupied = "SIZE_FORMAT"K.",
-                         HR_FORMAT_PARAMS(max_mem_sz_region),
-                         (rem_set->mem_size() + K - 1)/K,
-                         (rem_set->occupied() + K - 1)/K);
-  gclog_or_tty->print_cr("    Did %d coarsenings.",
-                         HeapRegionRemSet::n_coarsenings());
+  summary->print_on(gclog_or_tty);
 }
 
 void G1RemSet::prepare_for_verify() {
   if (G1HRRSFlushLogBuffersOnVerify &&
       (VerifyBeforeGC || VerifyAfterGC)
-      &&  !_g1->full_collection()) {
+      &&  (!_g1->full_collection() || G1VerifyRSetsDuringFullGC)) {
     cleanupHRRS();
     _g1->set_refine_cte_cl_concurrency(false);
     if (SafepointSynchronize::is_at_safepoint()) {
--- a/src/share/vm/gc_implementation/g1/g1RemSet.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/g1RemSet.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -25,6 +25,8 @@
 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1REMSET_HPP
 #define SHARE_VM_GC_IMPLEMENTATION_G1_G1REMSET_HPP
 
+#include "gc_implementation/g1/g1RemSetSummary.hpp"
+
 // A G1RemSet provides ways of iterating over pointers into a selected
 // collection set.
 
@@ -37,9 +39,11 @@
 // so that they can be used to update the individual region remsets.
 
 class G1RemSet: public CHeapObj<mtGC> {
+private:
+  G1RemSetSummary _prev_period_summary;
 protected:
   G1CollectedHeap* _g1;
-  unsigned _conc_refine_cards;
+  size_t _conc_refine_cards;
   uint n_workers();
 
 protected:
@@ -66,6 +70,8 @@
   // references into the collection set.
   OopsInHeapRegionClosure** _cset_rs_update_cl;
 
+  // Print the given summary info
+  virtual void print_summary_info(G1RemSetSummary * summary, const char * header = NULL);
 public:
   // This is called to reset dual hash tables after the gc pause
   // is finished and the initial hash table is no longer being
@@ -75,14 +81,23 @@
   G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs);
   ~G1RemSet();
 
-  // Invoke "blk->do_oop" on all pointers into the CS in objects in regions
-  // outside the CS (having invoked "blk->set_region" to set the "from"
-  // region correctly beforehand.) The "worker_i" param is for the
-  // parallel case where the number of the worker thread calling this
-  // function can be helpful in partitioning the work to be done. It
-  // should be the same as the "i" passed to the calling thread's
-  // work(i) function. In the sequential case this param will be ingored.
-  void oops_into_collection_set_do(OopsInHeapRegionClosure* blk, int worker_i);
+  // Invoke "blk->do_oop" on all pointers into the collection set
+  // from objects in regions outside the collection set (having
+  // invoked "blk->set_region" to set the "from" region correctly
+  // beforehand.)
+  //
+  // Invoke code_root_cl->do_code_blob on the unmarked nmethods
+  // on the strong code roots list for each region in the
+  // collection set.
+  //
+  // The "worker_i" param is for the parallel case where the id
+  // of the worker thread calling this function can be helpful in
+  // partitioning the work to be done. It should be the same as
+  // the "i" passed to the calling thread's work(i) function.
+  // In the sequential case this param will be ignored.
+  void oops_into_collection_set_do(OopsInHeapRegionClosure* blk,
+                                   CodeBlobToOopClosure* code_root_cl,
+                                   int worker_i);
 
   // Prepare for and cleanup after an oops_into_collection_set_do
   // call.  Must call each of these once before and after (in sequential
@@ -92,7 +107,10 @@
   void prepare_for_oops_into_collection_set_do();
   void cleanup_after_oops_into_collection_set_do();
 
-  void scanRS(OopsInHeapRegionClosure* oc, int worker_i);
+  void scanRS(OopsInHeapRegionClosure* oc,
+              CodeBlobToOopClosure* code_root_cl,
+              int worker_i);
+
   void updateRS(DirtyCardQueue* into_cset_dcq, int worker_i);
 
   CardTableModRefBS* ct_bs() { return _ct_bs; }
@@ -123,11 +141,18 @@
                            int worker_i,
                            bool check_for_refs_into_cset);
 
-  // Print any relevant summary info.
+  // Print accumulated summary info from the start of the VM.
   virtual void print_summary_info();
 
+  // Print accumulated summary info from the last time called.
+  virtual void print_periodic_summary_info(const char* header);
+
   // Prepare remembered set for verification.
   virtual void prepare_for_verify();
+
+  size_t conc_refine_cards() const {
+    return _conc_refine_cards;
+  }
 };
 
 class CountNonCleanMemRegionClosure: public MemRegionClosure {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -0,0 +1,354 @@
+/*
+ * Copyright (c) 2013, 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 "gc_implementation/g1/concurrentG1Refine.hpp"
+#include "gc_implementation/g1/concurrentG1RefineThread.hpp"
+#include "gc_implementation/g1/heapRegion.hpp"
+#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
+#include "gc_implementation/g1/g1RemSet.inline.hpp"
+#include "gc_implementation/g1/g1RemSetSummary.hpp"
+#include "gc_implementation/g1/heapRegionRemSet.hpp"
+#include "runtime/thread.hpp"
+
+class GetRSThreadVTimeClosure : public ThreadClosure {
+private:
+  G1RemSetSummary* _summary;
+  uint _counter;
+
+public:
+  GetRSThreadVTimeClosure(G1RemSetSummary * summary) : ThreadClosure(), _summary(summary), _counter(0) {
+    assert(_summary != NULL, "just checking");
+  }
+
+  virtual void do_thread(Thread* t) {
+    ConcurrentG1RefineThread* crt = (ConcurrentG1RefineThread*) t;
+    _summary->set_rs_thread_vtime(_counter, crt->vtime_accum());
+    _counter++;
+  }
+};
+
+void G1RemSetSummary::update() {
+  _num_refined_cards = remset()->conc_refine_cards();
+  DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
+  _num_processed_buf_mutator = dcqs.processed_buffers_mut();
+  _num_processed_buf_rs_threads = dcqs.processed_buffers_rs_thread();
+
+  _num_coarsenings = HeapRegionRemSet::n_coarsenings();
+
+  ConcurrentG1Refine * cg1r = G1CollectedHeap::heap()->concurrent_g1_refine();
+  if (_rs_threads_vtimes != NULL) {
+    GetRSThreadVTimeClosure p(this);
+    cg1r->worker_threads_do(&p);
+  }
+  set_sampling_thread_vtime(cg1r->sampling_thread()->vtime_accum());
+}
+
+void G1RemSetSummary::set_rs_thread_vtime(uint thread, double value) {
+  assert(_rs_threads_vtimes != NULL, "just checking");
+  assert(thread < _num_vtimes, "just checking");
+  _rs_threads_vtimes[thread] = value;
+}
+
+double G1RemSetSummary::rs_thread_vtime(uint thread) const {
+  assert(_rs_threads_vtimes != NULL, "just checking");
+  assert(thread < _num_vtimes, "just checking");
+  return _rs_threads_vtimes[thread];
+}
+
+void G1RemSetSummary::initialize(G1RemSet* remset) {
+  assert(_rs_threads_vtimes == NULL, "just checking");
+  assert(remset != NULL, "just checking");
+
+  _remset = remset;
+  _num_vtimes = ConcurrentG1Refine::thread_num();
+  _rs_threads_vtimes = NEW_C_HEAP_ARRAY(double, _num_vtimes, mtGC);
+  memset(_rs_threads_vtimes, 0, sizeof(double) * _num_vtimes);
+
+  update();
+}
+
+void G1RemSetSummary::set(G1RemSetSummary* other) {
+  assert(other != NULL, "just checking");
+  assert(remset() == other->remset(), "just checking");
+  assert(_num_vtimes == other->_num_vtimes, "just checking");
+
+  _num_refined_cards = other->num_concurrent_refined_cards();
+
+  _num_processed_buf_mutator = other->num_processed_buf_mutator();
+  _num_processed_buf_rs_threads = other->num_processed_buf_rs_threads();
+
+  _num_coarsenings = other->_num_coarsenings;
+
+  memcpy(_rs_threads_vtimes, other->_rs_threads_vtimes, sizeof(double) * _num_vtimes);
+
+  set_sampling_thread_vtime(other->sampling_thread_vtime());
+}
+
+void G1RemSetSummary::subtract_from(G1RemSetSummary* other) {
+  assert(other != NULL, "just checking");
+  assert(remset() == other->remset(), "just checking");
+  assert(_num_vtimes == other->_num_vtimes, "just checking");
+
+  _num_refined_cards = other->num_concurrent_refined_cards() - _num_refined_cards;
+
+  _num_processed_buf_mutator = other->num_processed_buf_mutator() - _num_processed_buf_mutator;
+  _num_processed_buf_rs_threads = other->num_processed_buf_rs_threads() - _num_processed_buf_rs_threads;
+
+  _num_coarsenings = other->num_coarsenings() - _num_coarsenings;
+
+  for (uint i = 0; i < _num_vtimes; i++) {
+    set_rs_thread_vtime(i, other->rs_thread_vtime(i) - rs_thread_vtime(i));
+  }
+
+  _sampling_thread_vtime = other->sampling_thread_vtime() - _sampling_thread_vtime;
+}
+
+static double percent_of(size_t numerator, size_t denominator) {
+  if (denominator != 0) {
+    return (double)numerator / denominator * 100.0f;
+  } else {
+    return 0.0f;
+  }
+}
+
+static size_t round_to_K(size_t value) {
+  return value / K;
+}
+
+class RegionTypeCounter VALUE_OBJ_CLASS_SPEC {
+private:
+  const char* _name;
+
+  size_t _rs_mem_size;
+  size_t _cards_occupied;
+  size_t _amount;
+
+  size_t _code_root_mem_size;
+  size_t _code_root_elems;
+
+  double rs_mem_size_percent_of(size_t total) {
+    return percent_of(_rs_mem_size, total);
+  }
+
+  double cards_occupied_percent_of(size_t total) {
+    return percent_of(_cards_occupied, total);
+  }
+
+  double code_root_mem_size_percent_of(size_t total) {
+    return percent_of(_code_root_mem_size, total);
+  }
+
+  double code_root_elems_percent_of(size_t total) {
+    return percent_of(_code_root_elems, total);
+  }
+
+  size_t amount() const { return _amount; }
+
+public:
+
+  RegionTypeCounter(const char* name) : _name(name), _rs_mem_size(0), _cards_occupied(0),
+    _amount(0), _code_root_mem_size(0), _code_root_elems(0) { }
+
+  void add(size_t rs_mem_size, size_t cards_occupied, size_t code_root_mem_size,
+    size_t code_root_elems) {
+    _rs_mem_size += rs_mem_size;
+    _cards_occupied += cards_occupied;
+    _code_root_mem_size += code_root_mem_size;
+    _code_root_elems += code_root_elems;
+    _amount++;
+  }
+
+  size_t rs_mem_size() const { return _rs_mem_size; }
+  size_t cards_occupied() const { return _cards_occupied; }
+
+  size_t code_root_mem_size() const { return _code_root_mem_size; }
+  size_t code_root_elems() const { return _code_root_elems; }
+
+  void print_rs_mem_info_on(outputStream * out, size_t total) {
+    out->print_cr("    "SIZE_FORMAT_W(8)"K (%5.1f%%) by "SIZE_FORMAT" %s regions",
+        round_to_K(rs_mem_size()), rs_mem_size_percent_of(total), amount(), _name);
+  }
+
+  void print_cards_occupied_info_on(outputStream * out, size_t total) {
+    out->print_cr("     "SIZE_FORMAT_W(8)" (%5.1f%%) entries by "SIZE_FORMAT" %s regions",
+        cards_occupied(), cards_occupied_percent_of(total), amount(), _name);
+  }
+
+  void print_code_root_mem_info_on(outputStream * out, size_t total) {
+    out->print_cr("    "SIZE_FORMAT_W(8)"K (%5.1f%%) by "SIZE_FORMAT" %s regions",
+        round_to_K(code_root_mem_size()), code_root_mem_size_percent_of(total), amount(), _name);
+  }
+
+  void print_code_root_elems_info_on(outputStream * out, size_t total) {
+    out->print_cr("     "SIZE_FORMAT_W(8)" (%5.1f%%) elements by "SIZE_FORMAT" %s regions",
+        code_root_elems(), code_root_elems_percent_of(total), amount(), _name);
+  }
+};
+
+
+class HRRSStatsIter: public HeapRegionClosure {
+private:
+  RegionTypeCounter _young;
+  RegionTypeCounter _humonguous;
+  RegionTypeCounter _free;
+  RegionTypeCounter _old;
+  RegionTypeCounter _all;
+
+  size_t _max_rs_mem_sz;
+  HeapRegion* _max_rs_mem_sz_region;
+
+  size_t total_rs_mem_sz() const            { return _all.rs_mem_size(); }
+  size_t total_cards_occupied() const       { return _all.cards_occupied(); }
+
+  size_t max_rs_mem_sz() const              { return _max_rs_mem_sz; }
+  HeapRegion* max_rs_mem_sz_region() const  { return _max_rs_mem_sz_region; }
+
+  size_t _max_code_root_mem_sz;
+  HeapRegion* _max_code_root_mem_sz_region;
+
+  size_t total_code_root_mem_sz() const     { return _all.code_root_mem_size(); }
+  size_t total_code_root_elems() const      { return _all.code_root_elems(); }
+
+  size_t max_code_root_mem_sz() const       { return _max_code_root_mem_sz; }
+  HeapRegion* max_code_root_mem_sz_region() const { return _max_code_root_mem_sz_region; }
+
+public:
+  HRRSStatsIter() : _all("All"), _young("Young"), _humonguous("Humonguous"),
+    _free("Free"), _old("Old"), _max_code_root_mem_sz_region(NULL), _max_rs_mem_sz_region(NULL),
+    _max_rs_mem_sz(0), _max_code_root_mem_sz(0)
+  {}
+
+  bool doHeapRegion(HeapRegion* r) {
+    HeapRegionRemSet* hrrs = r->rem_set();
+
+    // HeapRegionRemSet::mem_size() includes the
+    // size of the strong code roots
+    size_t rs_mem_sz = hrrs->mem_size();
+    if (rs_mem_sz > _max_rs_mem_sz) {
+      _max_rs_mem_sz = rs_mem_sz;
+      _max_rs_mem_sz_region = r;
+    }
+    size_t occupied_cards = hrrs->occupied();
+    size_t code_root_mem_sz = hrrs->strong_code_roots_mem_size();
+    if (code_root_mem_sz > max_code_root_mem_sz()) {
+      _max_code_root_mem_sz_region = r;
+    }
+    size_t code_root_elems = hrrs->strong_code_roots_list_length();
+
+    RegionTypeCounter* current = NULL;
+    if (r->is_young()) {
+      current = &_young;
+    } else if (r->isHumongous()) {
+      current = &_humonguous;
+    } else if (r->is_empty()) {
+      current = &_free;
+    } else {
+      current = &_old;
+    }
+    current->add(rs_mem_sz, occupied_cards, code_root_mem_sz, code_root_elems);
+    _all.add(rs_mem_sz, occupied_cards, code_root_mem_sz, code_root_elems);
+
+    return false;
+  }
+
+  void print_summary_on(outputStream* out) {
+    RegionTypeCounter* counters[] = { &_young, &_humonguous, &_free, &_old, NULL };
+
+    out->print_cr("\n Current rem set statistics");
+    out->print_cr("  Total per region rem sets sizes = "SIZE_FORMAT"K."
+                  " Max = "SIZE_FORMAT"K.",
+                  round_to_K(total_rs_mem_sz()), round_to_K(max_rs_mem_sz()));
+    for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) {
+      (*current)->print_rs_mem_info_on(out, total_rs_mem_sz());
+    }
+
+    out->print_cr("   Static structures = "SIZE_FORMAT"K,"
+                  " free_lists = "SIZE_FORMAT"K.",
+                  round_to_K(HeapRegionRemSet::static_mem_size()),
+                  round_to_K(HeapRegionRemSet::fl_mem_size()));
+
+    out->print_cr("    "SIZE_FORMAT" occupied cards represented.",
+                  total_cards_occupied());
+    for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) {
+      (*current)->print_cards_occupied_info_on(out, total_cards_occupied());
+    }
+
+    // Largest sized rem set region statistics
+    HeapRegionRemSet* rem_set = max_rs_mem_sz_region()->rem_set();
+    out->print_cr("    Region with largest rem set = "HR_FORMAT", "
+                  "size = "SIZE_FORMAT "K, occupied = "SIZE_FORMAT"K.",
+                  HR_FORMAT_PARAMS(max_rs_mem_sz_region()),
+                  round_to_K(rem_set->mem_size()),
+                  round_to_K(rem_set->occupied()));
+
+    // Strong code root statistics
+    HeapRegionRemSet* max_code_root_rem_set = max_code_root_mem_sz_region()->rem_set();
+    out->print_cr("  Total heap region code root sets sizes = "SIZE_FORMAT"K."
+                  "  Max = "SIZE_FORMAT"K.",
+                  round_to_K(total_code_root_mem_sz()),
+                  round_to_K(max_code_root_rem_set->strong_code_roots_mem_size()));
+    for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) {
+      (*current)->print_code_root_mem_info_on(out, total_code_root_mem_sz());
+    }
+
+    out->print_cr("    "SIZE_FORMAT" code roots represented.",
+                  total_code_root_elems());
+    for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) {
+      (*current)->print_code_root_elems_info_on(out, total_code_root_elems());
+    }
+
+    out->print_cr("    Region with largest amount of code roots = "HR_FORMAT", "
+                  "size = "SIZE_FORMAT "K, num_elems = "SIZE_FORMAT".",
+                  HR_FORMAT_PARAMS(max_code_root_mem_sz_region()),
+                  round_to_K(max_code_root_rem_set->strong_code_roots_mem_size()),
+                  round_to_K(max_code_root_rem_set->strong_code_roots_list_length()));
+  }
+};
+
+void G1RemSetSummary::print_on(outputStream* out) {
+  out->print_cr("\n Recent concurrent refinement statistics");
+  out->print_cr("  Processed "SIZE_FORMAT" cards",
+                num_concurrent_refined_cards());
+  out->print_cr("  Of "SIZE_FORMAT" completed buffers:", num_processed_buf_total());
+  out->print_cr("     "SIZE_FORMAT_W(8)" (%5.1f%%) by concurrent RS threads.",
+                num_processed_buf_total(),
+                percent_of(num_processed_buf_rs_threads(), num_processed_buf_total()));
+  out->print_cr("     "SIZE_FORMAT_W(8)" (%5.1f%%) by mutator threads.",
+                num_processed_buf_mutator(),
+                percent_of(num_processed_buf_mutator(), num_processed_buf_total()));
+  out->print_cr("  Did "SIZE_FORMAT" coarsenings.", num_coarsenings());
+  out->print_cr("  Concurrent RS threads times (s)");
+  out->print("     ");
+  for (uint i = 0; i < _num_vtimes; i++) {
+    out->print("    %5.2f", rs_thread_vtime(i));
+  }
+  out->cr();
+  out->print_cr("  Concurrent sampling threads times (s)");
+  out->print_cr("         %5.2f", sampling_thread_vtime());
+
+  HRRSStatsIter blk;
+  G1CollectedHeap::heap()->heap_region_iterate(&blk);
+  blk.print_summary_on(out);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc_implementation/g1/g1RemSetSummary.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2013, 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_G1REMSETSUMMARY_HPP
+#define SHARE_VM_GC_IMPLEMENTATION_G1_G1REMSETSUMMARY_HPP
+
+#include "utilities/ostream.hpp"
+
+class G1RemSet;
+
+// A G1RemSetSummary manages statistical information about the G1RemSet
+
+class G1RemSetSummary VALUE_OBJ_CLASS_SPEC {
+private:
+  friend class GetRSThreadVTimeClosure;
+
+  G1RemSet* _remset;
+
+  G1RemSet* remset() const {
+    return _remset;
+  }
+
+  size_t _num_refined_cards;
+  size_t _num_processed_buf_mutator;
+  size_t _num_processed_buf_rs_threads;
+
+  size_t _num_coarsenings;
+
+  double* _rs_threads_vtimes;
+  size_t _num_vtimes;
+
+  double _sampling_thread_vtime;
+
+  void set_rs_thread_vtime(uint thread, double value);
+  void set_sampling_thread_vtime(double value) {
+    _sampling_thread_vtime = value;
+  }
+
+  void free_and_null() {
+    if (_rs_threads_vtimes) {
+      FREE_C_HEAP_ARRAY(double, _rs_threads_vtimes, mtGC);
+      _rs_threads_vtimes = NULL;
+      _num_vtimes = 0;
+    }
+  }
+
+  // update this summary with current data from various places
+  void update();
+
+public:
+  G1RemSetSummary() : _remset(NULL), _num_refined_cards(0),
+    _num_processed_buf_mutator(0), _num_processed_buf_rs_threads(0), _num_coarsenings(0),
+    _rs_threads_vtimes(NULL), _num_vtimes(0), _sampling_thread_vtime(0.0f) {
+  }
+
+  ~G1RemSetSummary() {
+    free_and_null();
+  }
+
+  // set the counters in this summary to the values of the others
+  void set(G1RemSetSummary* other);
+  // subtract all counters from the other summary, and set them in the current
+  void subtract_from(G1RemSetSummary* other);
+
+  // initialize and get the first sampling
+  void initialize(G1RemSet* remset);
+
+  void print_on(outputStream* out);
+
+  double rs_thread_vtime(uint thread) const;
+
+  double sampling_thread_vtime() const {
+    return _sampling_thread_vtime;
+  }
+
+  size_t num_concurrent_refined_cards() const {
+    return _num_refined_cards;
+  }
+
+  size_t num_processed_buf_mutator() const {
+    return _num_processed_buf_mutator;
+  }
+
+  size_t num_processed_buf_rs_threads() const {
+    return _num_processed_buf_rs_threads;
+  }
+
+  size_t num_processed_buf_total() const {
+    return num_processed_buf_mutator() + num_processed_buf_rs_threads();
+  }
+
+  size_t num_coarsenings() const {
+    return _num_coarsenings;
+  }
+};
+
+#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1REMSETSUMMARY_HPP
--- a/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -79,6 +79,46 @@
   }
 }
 
+bool G1SATBCardTableModRefBS::mark_card_deferred(size_t card_index) {
+  jbyte val = _byte_map[card_index];
+  // It's already processed
+  if ((val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val()) {
+    return false;
+  }
+
+  if  (val == g1_young_gen) {
+    // the card is for a young gen region. We don't need to keep track of all pointers into young
+    return false;
+  }
+
+  // Cached bit can be installed either on a clean card or on a claimed card.
+  jbyte new_val = val;
+  if (val == clean_card_val()) {
+    new_val = (jbyte)deferred_card_val();
+  } else {
+    if (val & claimed_card_val()) {
+      new_val = val | (jbyte)deferred_card_val();
+    }
+  }
+  if (new_val != val) {
+    Atomic::cmpxchg(new_val, &_byte_map[card_index], val);
+  }
+  return true;
+}
+
+void G1SATBCardTableModRefBS::g1_mark_as_young(const MemRegion& mr) {
+  jbyte *const first = byte_for(mr.start());
+  jbyte *const last = byte_after(mr.last());
+
+  memset(first, g1_young_gen, last - first);
+}
+
+#ifndef PRODUCT
+void G1SATBCardTableModRefBS::verify_g1_young_region(MemRegion mr) {
+  verify_region(mr, g1_young_gen,  true);
+}
+#endif
+
 G1SATBCardTableLoggingModRefBS::
 G1SATBCardTableLoggingModRefBS(MemRegion whole_heap,
                                int max_covered_regions) :
@@ -92,7 +132,11 @@
 G1SATBCardTableLoggingModRefBS::write_ref_field_work(void* field,
                                                      oop new_val,
                                                      bool release) {
-  jbyte* byte = byte_for(field);
+  volatile jbyte* byte = byte_for(field);
+  if (*byte == g1_young_gen) {
+    return;
+  }
+  OrderAccess::storeload();
   if (*byte != dirty_card) {
     // Perform a releasing store if requested.
     if (release) {
@@ -129,7 +173,7 @@
 
 void
 G1SATBCardTableLoggingModRefBS::invalidate(MemRegion mr, bool whole_heap) {
-  jbyte* byte = byte_for(mr.start());
+  volatile jbyte* byte = byte_for(mr.start());
   jbyte* last_byte = byte_for(mr.last());
   Thread* thr = Thread::current();
   if (whole_heap) {
@@ -138,25 +182,35 @@
       byte++;
     }
   } else {
-    // Enqueue if necessary.
-    if (thr->is_Java_thread()) {
-      JavaThread* jt = (JavaThread*)thr;
-      while (byte <= last_byte) {
-        if (*byte != dirty_card) {
-          *byte = dirty_card;
-          jt->dirty_card_queue().enqueue(byte);
+    // skip all consecutive young cards
+    for (; byte <= last_byte && *byte == g1_young_gen; byte++);
+
+    if (byte <= last_byte) {
+      OrderAccess::storeload();
+      // Enqueue if necessary.
+      if (thr->is_Java_thread()) {
+        JavaThread* jt = (JavaThread*)thr;
+        for (; byte <= last_byte; byte++) {
+          if (*byte == g1_young_gen) {
+            continue;
+          }
+          if (*byte != dirty_card) {
+            *byte = dirty_card;
+            jt->dirty_card_queue().enqueue(byte);
+          }
         }
-        byte++;
-      }
-    } else {
-      MutexLockerEx x(Shared_DirtyCardQ_lock,
-                      Mutex::_no_safepoint_check_flag);
-      while (byte <= last_byte) {
-        if (*byte != dirty_card) {
-          *byte = dirty_card;
-          _dcqs.shared_dirty_card_queue()->enqueue(byte);
+      } else {
+        MutexLockerEx x(Shared_DirtyCardQ_lock,
+                        Mutex::_no_safepoint_check_flag);
+        for (; byte <= last_byte; byte++) {
+          if (*byte == g1_young_gen) {
+            continue;
+          }
+          if (*byte != dirty_card) {
+            *byte = dirty_card;
+            _dcqs.shared_dirty_card_queue()->enqueue(byte);
+          }
         }
-        byte++;
       }
     }
   }
--- a/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -37,7 +37,14 @@
 // snapshot-at-the-beginning marking.
 
 class G1SATBCardTableModRefBS: public CardTableModRefBSForCTRS {
+protected:
+  enum G1CardValues {
+    g1_young_gen = CT_MR_BS_last_reserved << 1
+  };
+
 public:
+  static int g1_young_card_val()   { return g1_young_gen; }
+
   // Add "pre_val" to a set of objects that may have been disconnected from the
   // pre-marking object graph.
   static void enqueue(oop pre_val);
@@ -88,6 +95,45 @@
       write_ref_array_pre_work(dst, count);
     }
   }
+
+/*
+   Claimed and deferred bits are used together in G1 during the evacuation
+   pause. These bits can have the following state transitions:
+   1. The claimed bit can be put over any other card state. Except that
+      the "dirty -> dirty and claimed" transition is checked for in
+      G1 code and is not used.
+   2. Deferred bit can be set only if the previous state of the card
+      was either clean or claimed. mark_card_deferred() is wait-free.
+      We do not care if the operation is be successful because if
+      it does not it will only result in duplicate entry in the update
+      buffer because of the "cache-miss". So it's not worth spinning.
+ */
+
+  bool is_card_claimed(size_t card_index) {
+    jbyte val = _byte_map[card_index];
+    return (val & (clean_card_mask_val() | claimed_card_val())) == claimed_card_val();
+  }
+
+  void set_card_claimed(size_t card_index) {
+      jbyte val = _byte_map[card_index];
+      if (val == clean_card_val()) {
+        val = (jbyte)claimed_card_val();
+      } else {
+        val |= (jbyte)claimed_card_val();
+      }
+      _byte_map[card_index] = val;
+  }
+
+  void verify_g1_young_region(MemRegion mr) PRODUCT_RETURN;
+  void g1_mark_as_young(const MemRegion& mr);
+
+  bool mark_card_deferred(size_t card_index);
+
+  bool is_card_deferred(size_t card_index) {
+    jbyte val = _byte_map[card_index];
+    return (val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val();
+  }
+
 };
 
 // Adds card-table logging to the post-barrier.
--- a/src/share/vm/gc_implementation/g1/g1_globals.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/g1_globals.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -71,6 +71,9 @@
   diagnostic(bool, G1TraceConcRefinement, false,                            \
           "Trace G1 concurrent refinement")                                 \
                                                                             \
+  experimental(bool, G1TraceStringSymbolTableScrubbing, false,              \
+          "Trace information string and symbol table scrubbing.")           \
+                                                                            \
   product(double, G1ConcMarkStepDurationMillis, 10.0,                       \
           "Target duration of individual concurrent marking steps "         \
           "in milliseconds.")                                               \
@@ -332,7 +335,14 @@
                                                                             \
   develop(bool, G1EvacuationFailureALotDuringMixedGC, true,                 \
           "Force use of evacuation failure handling during mixed "          \
-          "evacuation pauses")
+          "evacuation pauses")                                              \
+                                                                            \
+  diagnostic(bool, G1VerifyRSetsDuringFullGC, false,                        \
+             "If true, perform verification of each heap region's "         \
+             "remembered set when verifying the heap during a full GC.")    \
+                                                                            \
+  diagnostic(bool, G1VerifyHeapRegionCodeRoots, false,                      \
+             "Verify the code root lists attached to each heap region.")
 
 G1_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_EXPERIMENTAL_FLAG, DECLARE_NOTPRODUCT_FLAG, DECLARE_MANAGEABLE_FLAG, DECLARE_PRODUCT_RW_FLAG)
 
--- a/src/share/vm/gc_implementation/g1/heapRegion.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/heapRegion.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "code/nmethod.hpp"
 #include "gc_implementation/g1/g1BlockOffsetTable.inline.hpp"
 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
 #include "gc_implementation/g1/g1OopClosures.inline.hpp"
@@ -50,144 +51,6 @@
                                                    OopClosure* oc) :
   _r_bottom(r->bottom()), _r_end(r->end()), _oc(oc) { }
 
-class VerifyLiveClosure: public OopClosure {
-private:
-  G1CollectedHeap* _g1h;
-  CardTableModRefBS* _bs;
-  oop _containing_obj;
-  bool _failures;
-  int _n_failures;
-  VerifyOption _vo;
-public:
-  // _vo == UsePrevMarking -> use "prev" marking information,
-  // _vo == UseNextMarking -> use "next" marking information,
-  // _vo == UseMarkWord    -> use mark word from object header.
-  VerifyLiveClosure(G1CollectedHeap* g1h, VerifyOption vo) :
-    _g1h(g1h), _bs(NULL), _containing_obj(NULL),
-    _failures(false), _n_failures(0), _vo(vo)
-  {
-    BarrierSet* bs = _g1h->barrier_set();
-    if (bs->is_a(BarrierSet::CardTableModRef))
-      _bs = (CardTableModRefBS*)bs;
-  }
-
-  void set_containing_obj(oop obj) {
-    _containing_obj = obj;
-  }
-
-  bool failures() { return _failures; }
-  int n_failures() { return _n_failures; }
-
-  virtual void do_oop(narrowOop* p) { do_oop_work(p); }
-  virtual void do_oop(      oop* p) { do_oop_work(p); }
-
-  void print_object(outputStream* out, oop obj) {
-#ifdef PRODUCT
-    klassOop k = obj->klass();
-    const char* class_name = instanceKlass::cast(k)->external_name();
-    out->print_cr("class name %s", class_name);
-#else // PRODUCT
-    obj->print_on(out);
-#endif // PRODUCT
-  }
-
-  template <class T>
-  void do_oop_work(T* p) {
-    assert(_containing_obj != NULL, "Precondition");
-    assert(!_g1h->is_obj_dead_cond(_containing_obj, _vo),
-           "Precondition");
-    T heap_oop = oopDesc::load_heap_oop(p);
-    if (!oopDesc::is_null(heap_oop)) {
-      oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
-      bool failed = false;
-      if (!_g1h->is_in_closed_subset(obj) || _g1h->is_obj_dead_cond(obj, _vo)) {
-        MutexLockerEx x(ParGCRareEvent_lock,
-                        Mutex::_no_safepoint_check_flag);
-
-        if (!_failures) {
-          gclog_or_tty->print_cr("");
-          gclog_or_tty->print_cr("----------");
-        }
-        if (!_g1h->is_in_closed_subset(obj)) {
-          HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
-          gclog_or_tty->print_cr("Field "PTR_FORMAT
-                                 " of live obj "PTR_FORMAT" in region "
-                                 "["PTR_FORMAT", "PTR_FORMAT")",
-                                 p, (void*) _containing_obj,
-                                 from->bottom(), from->end());
-          print_object(gclog_or_tty, _containing_obj);
-          gclog_or_tty->print_cr("points to obj "PTR_FORMAT" not in the heap",
-                                 (void*) obj);
-        } else {
-          HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
-          HeapRegion* to   = _g1h->heap_region_containing((HeapWord*)obj);
-          gclog_or_tty->print_cr("Field "PTR_FORMAT
-                                 " of live obj "PTR_FORMAT" in region "
-                                 "["PTR_FORMAT", "PTR_FORMAT")",
-                                 p, (void*) _containing_obj,
-                                 from->bottom(), from->end());
-          print_object(gclog_or_tty, _containing_obj);
-          gclog_or_tty->print_cr("points to dead obj "PTR_FORMAT" in region "
-                                 "["PTR_FORMAT", "PTR_FORMAT")",
-                                 (void*) obj, to->bottom(), to->end());
-          print_object(gclog_or_tty, obj);
-        }
-        gclog_or_tty->print_cr("----------");
-        gclog_or_tty->flush();
-        _failures = true;
-        failed = true;
-        _n_failures++;
-      }
-
-      if (!_g1h->full_collection()) {
-        HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
-        HeapRegion* to   = _g1h->heap_region_containing(obj);
-        if (from != NULL && to != NULL &&
-            from != to &&
-            !to->isHumongous()) {
-          jbyte cv_obj = *_bs->byte_for_const(_containing_obj);
-          jbyte cv_field = *_bs->byte_for_const(p);
-          const jbyte dirty = CardTableModRefBS::dirty_card_val();
-
-          bool is_bad = !(from->is_young()
-                          || to->rem_set()->contains_reference(p)
-                          || !G1HRRSFlushLogBuffersOnVerify && // buffers were not flushed
-                              (_containing_obj->is_objArray() ?
-                                  cv_field == dirty
-                               : cv_obj == dirty || cv_field == dirty));
-          if (is_bad) {
-            MutexLockerEx x(ParGCRareEvent_lock,
-                            Mutex::_no_safepoint_check_flag);
-
-            if (!_failures) {
-              gclog_or_tty->print_cr("");
-              gclog_or_tty->print_cr("----------");
-            }
-            gclog_or_tty->print_cr("Missing rem set entry:");
-            gclog_or_tty->print_cr("Field "PTR_FORMAT" "
-                                   "of obj "PTR_FORMAT", "
-                                   "in region "HR_FORMAT,
-                                   p, (void*) _containing_obj,
-                                   HR_FORMAT_PARAMS(from));
-            _containing_obj->print_on(gclog_or_tty);
-            gclog_or_tty->print_cr("points to obj "PTR_FORMAT" "
-                                   "in region "HR_FORMAT,
-                                   (void*) obj,
-                                   HR_FORMAT_PARAMS(to));
-            obj->print_on(gclog_or_tty);
-            gclog_or_tty->print_cr("Obj head CTE = %d, field CTE = %d.",
-                          cv_obj, cv_field);
-            gclog_or_tty->print_cr("----------");
-            gclog_or_tty->flush();
-            _failures = true;
-            if (!failed) _n_failures++;
-          }
-        }
-      }
-    }
-  }
-};
-
 template<class ClosureType>
 HeapWord* walk_mem_region_loop(ClosureType* cl, G1CollectedHeap* g1h,
                                HeapRegion* hr,
@@ -314,6 +177,11 @@
     region_size = MAX_REGION_SIZE;
   }
 
+  if (region_size != G1HeapRegionSize) {
+    // Update the flag to make sure that PrintFlagsFinal logs the correct value
+    FLAG_SET_ERGO(uintx, G1HeapRegionSize, region_size);
+  }
+
   // And recalculate the log.
   region_size_log = log2_long((jlong) region_size);
 
@@ -363,7 +231,7 @@
   if (!par) {
     // If this is parallel, this will be done later.
     HeapRegionRemSet* hrrs = rem_set();
-    if (hrrs != NULL) hrrs->clear();
+    hrrs->clear();
     _claimed = InitialClaimValue;
   }
   zero_marked_bytes();
@@ -504,6 +372,7 @@
     _rem_set(NULL), _recorded_rs_length(0), _predicted_elapsed_time_ms(0),
     _predicted_bytes_to_copy(0)
 {
+  _rem_set = new HeapRegionRemSet(sharedOffsetArray, this);
   _orig_end = mr.end();
   // Note that initialize() will set the start of the unmarked area of the
   // region.
@@ -511,8 +380,6 @@
   set_top(bottom());
   set_saved_mark();
 
-  _rem_set =  new HeapRegionRemSet(sharedOffsetArray, this);
-
   assert(HeapRegionRemSet::num_par_rem_sets() > 0, "Invariant.");
 }
 
@@ -732,6 +599,161 @@
   return NULL;
 }
 
+// Code roots support
+
+void HeapRegion::add_strong_code_root(nmethod* nm) {
+  HeapRegionRemSet* hrrs = rem_set();
+  hrrs->add_strong_code_root(nm);
+}
+
+void HeapRegion::remove_strong_code_root(nmethod* nm) {
+  HeapRegionRemSet* hrrs = rem_set();
+  hrrs->remove_strong_code_root(nm);
+}
+
+void HeapRegion::migrate_strong_code_roots() {
+  assert(in_collection_set(), "only collection set regions");
+  assert(!isHumongous(),
+          err_msg("humongous region "HR_FORMAT" should not have been added to collection set",
+                  HR_FORMAT_PARAMS(this)));
+
+  HeapRegionRemSet* hrrs = rem_set();
+  hrrs->migrate_strong_code_roots();
+}
+
+void HeapRegion::strong_code_roots_do(CodeBlobClosure* blk) const {
+  HeapRegionRemSet* hrrs = rem_set();
+  hrrs->strong_code_roots_do(blk);
+}
+
+class VerifyStrongCodeRootOopClosure: public OopClosure {
+  const HeapRegion* _hr;
+  nmethod* _nm;
+  bool _failures;
+  bool _has_oops_in_region;
+
+  template <class T> void do_oop_work(T* p) {
+    T heap_oop = oopDesc::load_heap_oop(p);
+    if (!oopDesc::is_null(heap_oop)) {
+      oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+
+      // Note: not all the oops embedded in the nmethod are in the
+      // current region. We only look at those which are.
+      if (_hr->is_in(obj)) {
+        // Object is in the region. Check that its less than top
+        if (_hr->top() <= (HeapWord*)obj) {
+          // Object is above top
+          gclog_or_tty->print_cr("Object "PTR_FORMAT" in region "
+                                 "["PTR_FORMAT", "PTR_FORMAT") is above "
+                                 "top "PTR_FORMAT,
+                                 obj, _hr->bottom(), _hr->end(), _hr->top());
+          _failures = true;
+          return;
+        }
+        // Nmethod has at least one oop in the current region
+        _has_oops_in_region = true;
+      }
+    }
+  }
+
+public:
+  VerifyStrongCodeRootOopClosure(const HeapRegion* hr, nmethod* nm):
+    _hr(hr), _failures(false), _has_oops_in_region(false) {}
+
+  void do_oop(narrowOop* p) { do_oop_work(p); }
+  void do_oop(oop* p)       { do_oop_work(p); }
+
+  bool failures()           { return _failures; }
+  bool has_oops_in_region() { return _has_oops_in_region; }
+};
+
+class VerifyStrongCodeRootCodeBlobClosure: public CodeBlobClosure {
+  const HeapRegion* _hr;
+  bool _failures;
+public:
+  VerifyStrongCodeRootCodeBlobClosure(const HeapRegion* hr) :
+    _hr(hr), _failures(false) {}
+
+  void do_code_blob(CodeBlob* cb) {
+    nmethod* nm = (cb == NULL) ? NULL : cb->as_nmethod_or_null();
+    if (nm != NULL) {
+      // Verify that the nemthod is live
+      if (!nm->is_alive()) {
+        gclog_or_tty->print_cr("region ["PTR_FORMAT","PTR_FORMAT"] has dead nmethod "
+                               PTR_FORMAT" in its strong code roots",
+                               _hr->bottom(), _hr->end(), nm);
+        _failures = true;
+      } else {
+        VerifyStrongCodeRootOopClosure oop_cl(_hr, nm);
+        nm->oops_do(&oop_cl);
+        if (!oop_cl.has_oops_in_region()) {
+          gclog_or_tty->print_cr("region ["PTR_FORMAT","PTR_FORMAT"] has nmethod "
+                                 PTR_FORMAT" in its strong code roots "
+                                 "with no pointers into region",
+                                 _hr->bottom(), _hr->end(), nm);
+          _failures = true;
+        } else if (oop_cl.failures()) {
+          gclog_or_tty->print_cr("region ["PTR_FORMAT","PTR_FORMAT"] has other "
+                                 "failures for nmethod "PTR_FORMAT,
+                                 _hr->bottom(), _hr->end(), nm);
+          _failures = true;
+        }
+      }
+    }
+  }
+
+  bool failures()       { return _failures; }
+};
+
+void HeapRegion::verify_strong_code_roots(VerifyOption vo, bool* failures) const {
+  if (!G1VerifyHeapRegionCodeRoots) {
+    // We're not verifying code roots.
+    return;
+  }
+  if (vo == VerifyOption_G1UseMarkWord) {
+    // Marking verification during a full GC is performed after class
+    // unloading, code cache unloading, etc so the strong code roots
+    // attached to each heap region are in an inconsistent state. They won't
+    // be consistent until the strong code roots are rebuilt after the
+    // actual GC. Skip verifying the strong code roots in this particular
+    // time.
+    assert(VerifyDuringGC, "only way to get here");
+    return;
+  }
+
+  HeapRegionRemSet* hrrs = rem_set();
+  int strong_code_roots_length = hrrs->strong_code_roots_list_length();
+
+  // if this region is empty then there should be no entries
+  // on its strong code root list
+  if (is_empty()) {
+    if (strong_code_roots_length > 0) {
+      gclog_or_tty->print_cr("region ["PTR_FORMAT","PTR_FORMAT"] is empty "
+                             "but has "INT32_FORMAT" code root entries",
+                             bottom(), end(), strong_code_roots_length);
+      *failures = true;
+    }
+    return;
+  }
+
+  if (continuesHumongous()) {
+    if (strong_code_roots_length > 0) {
+      gclog_or_tty->print_cr("region "HR_FORMAT" is a continuation of a humongous "
+                             "region but has "INT32_FORMAT" code root entries",
+                             HR_FORMAT_PARAMS(this), strong_code_roots_length);
+      *failures = true;
+    }
+    return;
+  }
+
+  VerifyStrongCodeRootCodeBlobClosure cb_cl(this);
+  strong_code_roots_do(&cb_cl);
+
+  if (cb_cl.failures()) {
+    *failures = true;
+  }
+}
+
 void HeapRegion::print() const { print_on(gclog_or_tty); }
 void HeapRegion::print_on(outputStream* st) const {
   if (isHumongous()) {
@@ -760,10 +782,143 @@
   G1OffsetTableContigSpace::print_on(st);
 }
 
-void HeapRegion::verify() const {
-  bool dummy = false;
-  verify(VerifyOption_G1UsePrevMarking, /* failures */ &dummy);
-}
+class VerifyLiveClosure: public OopClosure {
+private:
+  G1CollectedHeap* _g1h;
+  CardTableModRefBS* _bs;
+  oop _containing_obj;
+  bool _failures;
+  int _n_failures;
+  VerifyOption _vo;
+public:
+  // _vo == UsePrevMarking -> use "prev" marking information,
+  // _vo == UseNextMarking -> use "next" marking information,
+  // _vo == UseMarkWord    -> use mark word from object header.
+  VerifyLiveClosure(G1CollectedHeap* g1h, VerifyOption vo) :
+    _g1h(g1h), _bs(NULL), _containing_obj(NULL),
+    _failures(false), _n_failures(0), _vo(vo)
+  {
+    BarrierSet* bs = _g1h->barrier_set();
+    if (bs->is_a(BarrierSet::CardTableModRef))
+      _bs = (CardTableModRefBS*)bs;
+  }
+
+  void set_containing_obj(oop obj) {
+    _containing_obj = obj;
+  }
+
+  bool failures() { return _failures; }
+  int n_failures() { return _n_failures; }
+
+  virtual void do_oop(narrowOop* p) { do_oop_work(p); }
+  virtual void do_oop(      oop* p) { do_oop_work(p); }
+
+  void print_object(outputStream* out, oop obj) {
+#ifdef PRODUCT
+    klassOop k = obj->klass();
+    const char* class_name = instanceKlass::cast(k)->external_name();
+    out->print_cr("class name %s", class_name);
+#else // PRODUCT
+    obj->print_on(out);
+#endif // PRODUCT
+  }
+
+  template <class T>
+  void do_oop_work(T* p) {
+    assert(_containing_obj != NULL, "Precondition");
+    assert(!_g1h->is_obj_dead_cond(_containing_obj, _vo),
+           "Precondition");
+    T heap_oop = oopDesc::load_heap_oop(p);
+    if (!oopDesc::is_null(heap_oop)) {
+      oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+      bool failed = false;
+      if (!_g1h->is_in_closed_subset(obj) || _g1h->is_obj_dead_cond(obj, _vo)) {
+        MutexLockerEx x(ParGCRareEvent_lock,
+                        Mutex::_no_safepoint_check_flag);
+
+        if (!_failures) {
+          gclog_or_tty->print_cr("");
+          gclog_or_tty->print_cr("----------");
+        }
+        if (!_g1h->is_in_closed_subset(obj)) {
+          HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
+          gclog_or_tty->print_cr("Field "PTR_FORMAT
+                                 " of live obj "PTR_FORMAT" in region "
+                                 "["PTR_FORMAT", "PTR_FORMAT")",
+                                 p, (void*) _containing_obj,
+                                 from->bottom(), from->end());
+          print_object(gclog_or_tty, _containing_obj);
+          gclog_or_tty->print_cr("points to obj "PTR_FORMAT" not in the heap",
+                                 (void*) obj);
+        } else {
+          HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
+          HeapRegion* to   = _g1h->heap_region_containing((HeapWord*)obj);
+          gclog_or_tty->print_cr("Field "PTR_FORMAT
+                                 " of live obj "PTR_FORMAT" in region "
+                                 "["PTR_FORMAT", "PTR_FORMAT")",
+                                 p, (void*) _containing_obj,
+                                 from->bottom(), from->end());
+          print_object(gclog_or_tty, _containing_obj);
+          gclog_or_tty->print_cr("points to dead obj "PTR_FORMAT" in region "
+                                 "["PTR_FORMAT", "PTR_FORMAT")",
+                                 (void*) obj, to->bottom(), to->end());
+          print_object(gclog_or_tty, obj);
+        }
+        gclog_or_tty->print_cr("----------");
+        gclog_or_tty->flush();
+        _failures = true;
+        failed = true;
+        _n_failures++;
+      }
+
+      if (!_g1h->full_collection() || G1VerifyRSetsDuringFullGC) {
+        HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
+        HeapRegion* to   = _g1h->heap_region_containing(obj);
+        if (from != NULL && to != NULL &&
+            from != to &&
+            !to->isHumongous()) {
+          jbyte cv_obj = *_bs->byte_for_const(_containing_obj);
+          jbyte cv_field = *_bs->byte_for_const(p);
+          const jbyte dirty = CardTableModRefBS::dirty_card_val();
+
+          bool is_bad = !(from->is_young()
+                          || to->rem_set()->contains_reference(p)
+                          || !G1HRRSFlushLogBuffersOnVerify && // buffers were not flushed
+                              (_containing_obj->is_objArray() ?
+                                  cv_field == dirty
+                               : cv_obj == dirty || cv_field == dirty));
+          if (is_bad) {
+            MutexLockerEx x(ParGCRareEvent_lock,
+                            Mutex::_no_safepoint_check_flag);
+
+            if (!_failures) {
+              gclog_or_tty->print_cr("");
+              gclog_or_tty->print_cr("----------");
+            }
+            gclog_or_tty->print_cr("Missing rem set entry:");
+            gclog_or_tty->print_cr("Field "PTR_FORMAT" "
+                                   "of obj "PTR_FORMAT", "
+                                   "in region "HR_FORMAT,
+                                   p, (void*) _containing_obj,
+                                   HR_FORMAT_PARAMS(from));
+            _containing_obj->print_on(gclog_or_tty);
+            gclog_or_tty->print_cr("points to obj "PTR_FORMAT" "
+                                   "in region "HR_FORMAT,
+                                   (void*) obj,
+                                   HR_FORMAT_PARAMS(to));
+            obj->print_on(gclog_or_tty);
+            gclog_or_tty->print_cr("Obj head CTE = %d, field CTE = %d.",
+                          cv_obj, cv_field);
+            gclog_or_tty->print_cr("----------");
+            gclog_or_tty->flush();
+            _failures = true;
+            if (!failed) _n_failures++;
+          }
+        }
+      }
+    }
+  }
+};
 
 // This really ought to be commoned up into OffsetTableContigSpace somehow.
 // We would need a mechanism to make that code skip dead objects.
@@ -903,6 +1058,13 @@
     *failures = true;
     return;
   }
+
+  verify_strong_code_roots(vo, failures);
+}
+
+void HeapRegion::verify() const {
+  bool dummy = false;
+  verify(VerifyOption_G1UsePrevMarking, /* failures */ &dummy);
 }
 
 // G1OffsetTableContigSpace code; copied from space.cpp.  Hope this can go
--- a/src/share/vm/gc_implementation/g1/heapRegion.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/heapRegion.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -51,6 +51,7 @@
 class HeapRegionRemSetIterator;
 class HeapRegion;
 class HeapRegionSetBase;
+class nmethod;
 
 #define HR_FORMAT "%u:(%s)["PTR_FORMAT","PTR_FORMAT","PTR_FORMAT"]"
 #define HR_FORMAT_PARAMS(_hr_) \
@@ -374,7 +375,8 @@
     RebuildRSClaimValue        = 5,
     ParEvacFailureClaimValue   = 6,
     AggregateCountClaimValue   = 7,
-    VerifyCountClaimValue      = 8
+    VerifyCountClaimValue      = 8,
+    ParMarkRootClaimValue      = 9
   };
 
   inline HeapWord* par_allocate_no_bot_updates(size_t word_size) {
@@ -801,6 +803,25 @@
 
   virtual void reset_after_compaction();
 
+  // Routines for managing a list of code roots (attached to the
+  // this region's RSet) that point into this heap region.
+  void add_strong_code_root(nmethod* nm);
+  void remove_strong_code_root(nmethod* nm);
+
+  // During a collection, migrate the successfully evacuated
+  // strong code roots that referenced into this region to the
+  // new regions that they now point into. Unsuccessfully
+  // evacuated code roots are not migrated.
+  void migrate_strong_code_roots();
+
+  // Applies blk->do_code_blob() to each of the entries in
+  // the strong code roots list for this region
+  void strong_code_roots_do(CodeBlobClosure* blk) const;
+
+  // Verify that the entries on the strong code root list for this
+  // region are live and include at least one pointer into this region.
+  void verify_strong_code_roots(VerifyOption vo, bool* failures) const;
+
   void print() const;
   void print_on(outputStream* st) const;
 
--- a/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -33,6 +33,7 @@
 #include "oops/oop.inline.hpp"
 #include "utilities/bitMap.inline.hpp"
 #include "utilities/globalDefinitions.hpp"
+#include "utilities/growableArray.hpp"
 
 class PerRegionTable: public CHeapObj<mtGC> {
   friend class OtherRegionsTable;
@@ -706,10 +707,11 @@
   // Cast away const in this case.
   MutexLockerEx x((Mutex*)&_m, Mutex::_no_safepoint_check_flag);
   size_t sum = 0;
-  PerRegionTable * cur = _first_all_fine_prts;
-  while (cur != NULL) {
-    sum += cur->mem_size();
-    cur = cur->next();
+  // all PRTs are of the same size so it is sufficient to query only one of them.
+  if (_first_all_fine_prts != NULL) {
+    assert(_last_all_fine_prts != NULL &&
+      _first_all_fine_prts->mem_size() == _last_all_fine_prts->mem_size(), "check that mem_size() is constant");
+    sum += _first_all_fine_prts->mem_size() * _n_fine_entries;
   }
   sum += (sizeof(PerRegionTable*) * _max_fine_entries);
   sum += (_coarse_map.size_in_words() * HeapWordSize);
@@ -845,7 +847,7 @@
 
 HeapRegionRemSet::HeapRegionRemSet(G1BlockOffsetSharedArray* bosa,
                                    HeapRegion* hr)
-  : _bosa(bosa), _other_regions(hr) {
+  : _bosa(bosa), _strong_code_roots_list(NULL), _other_regions(hr) {
   reset_for_par_iteration();
 }
 
@@ -909,6 +911,12 @@
 }
 
 void HeapRegionRemSet::clear() {
+  if (_strong_code_roots_list != NULL) {
+    delete _strong_code_roots_list;
+  }
+  _strong_code_roots_list = new (ResourceObj::C_HEAP, mtGC)
+                                GrowableArray<nmethod*>(10, 0, NULL, true);
+
   _other_regions.clear();
   assert(occupied() == 0, "Should be clear.");
   reset_for_par_iteration();
@@ -926,6 +934,126 @@
   _other_regions.scrub(ctbs, region_bm, card_bm);
 }
 
+
+// Code roots support
+
+void HeapRegionRemSet::add_strong_code_root(nmethod* nm) {
+  assert(nm != NULL, "sanity");
+  // Search for the code blob from the RHS to avoid
+  // duplicate entries as much as possible
+  if (_strong_code_roots_list->find_from_end(nm) < 0) {
+    // Code blob isn't already in the list
+    _strong_code_roots_list->push(nm);
+  }
+}
+
+void HeapRegionRemSet::remove_strong_code_root(nmethod* nm) {
+  assert(nm != NULL, "sanity");
+  int idx = _strong_code_roots_list->find(nm);
+  if (idx >= 0) {
+    _strong_code_roots_list->remove_at(idx);
+  }
+  // Check that there were no duplicates
+  guarantee(_strong_code_roots_list->find(nm) < 0, "duplicate entry found");
+}
+
+class NMethodMigrationOopClosure : public OopClosure {
+  G1CollectedHeap* _g1h;
+  HeapRegion* _from;
+  nmethod* _nm;
+
+  uint _num_self_forwarded;
+
+  template <class T> void do_oop_work(T* p) {
+    T heap_oop = oopDesc::load_heap_oop(p);
+    if (!oopDesc::is_null(heap_oop)) {
+      oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+      if (obj->is_perm()) {
+        // reference into perm gen - ignore.
+        return;
+      } else if (_from->is_in(obj)) {
+        // Reference still points into the source region.
+        // Since roots are immediately evacuated this means that
+        // we must have self forwarded the object
+        assert(obj->is_forwarded(),
+               err_msg("code roots should be immediately evacuated. "
+                       "Ref: "PTR_FORMAT", "
+                       "Obj: "PTR_FORMAT", "
+                       "Region: "HR_FORMAT,
+                       p, (void*) obj, HR_FORMAT_PARAMS(_from)));
+        assert(obj->forwardee() == obj,
+               err_msg("not self forwarded? obj = "PTR_FORMAT, (void*)obj));
+
+        // The object has been self forwarded.
+        // Note, if we're during an initial mark pause, there is
+        // no need to explicitly mark object. It will be marked
+        // during the regular evacuation failure handling code.
+        _num_self_forwarded++;
+      } else {
+        // The reference points into a promotion or to-space region
+        HeapRegion* to = _g1h->heap_region_containing(obj);
+        to->rem_set()->add_strong_code_root(_nm);
+      }
+    }
+  }
+
+public:
+  NMethodMigrationOopClosure(G1CollectedHeap* g1h, HeapRegion* from, nmethod* nm):
+    _g1h(g1h), _from(from), _nm(nm), _num_self_forwarded(0) {}
+
+  void do_oop(narrowOop* p) { do_oop_work(p); }
+  void do_oop(oop* p)       { do_oop_work(p); }
+
+  uint retain() { return _num_self_forwarded > 0; }
+};
+
+void HeapRegionRemSet::migrate_strong_code_roots() {
+  assert(hr()->in_collection_set(), "only collection set regions");
+  assert(!hr()->isHumongous(),
+         err_msg("humongous region "HR_FORMAT" should not have been added to the collection set",
+                 HR_FORMAT_PARAMS(hr())));
+
+  ResourceMark rm;
+
+  // List of code blobs to retain for this region
+  GrowableArray<nmethod*> to_be_retained(10);
+  G1CollectedHeap* g1h = G1CollectedHeap::heap();
+
+  while (_strong_code_roots_list->is_nonempty()) {
+    nmethod *nm = _strong_code_roots_list->pop();
+    if (nm != NULL) {
+      NMethodMigrationOopClosure oop_cl(g1h, hr(), nm);
+      nm->oops_do(&oop_cl);
+      if (oop_cl.retain()) {
+        to_be_retained.push(nm);
+      }
+    }
+  }
+
+  // Now push any code roots we need to retain
+  assert(to_be_retained.is_empty() || hr()->evacuation_failed(),
+         "Retained nmethod list must be empty or "
+         "evacuation of this region failed");
+
+  while (to_be_retained.is_nonempty()) {
+    nmethod* nm = to_be_retained.pop();
+    assert(nm != NULL, "sanity");
+    add_strong_code_root(nm);
+  }
+}
+
+void HeapRegionRemSet::strong_code_roots_do(CodeBlobClosure* blk) const {
+  for (int i = 0; i < _strong_code_roots_list->length(); i += 1) {
+    nmethod* nm = _strong_code_roots_list->at(i);
+    blk->do_code_blob(nm);
+  }
+}
+
+size_t HeapRegionRemSet::strong_code_roots_mem_size() {
+  return sizeof(GrowableArray<nmethod*>) +
+         _strong_code_roots_list->max_length() * sizeof(nmethod*);
+}
+
 //-------------------- Iteration --------------------
 
 HeapRegionRemSetIterator::
--- a/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -37,6 +37,7 @@
 class HeapRegionRemSetIterator;
 class PerRegionTable;
 class SparsePRT;
+class nmethod;
 
 // Essentially a wrapper around SparsePRTCleanupTask. See
 // sparsePRT.hpp for more details.
@@ -191,6 +192,10 @@
   G1BlockOffsetSharedArray* _bosa;
   G1BlockOffsetSharedArray* bosa() const { return _bosa; }
 
+  // A list of code blobs (nmethods) whose code contains pointers into
+  // the region that owns this RSet.
+  GrowableArray<nmethod*>* _strong_code_roots_list;
+
   OtherRegionsTable _other_regions;
 
   enum ParIterState { Unclaimed, Claimed, Complete };
@@ -285,11 +290,13 @@
   void init_iterator(HeapRegionRemSetIterator* iter) const;
 
   // The actual # of bytes this hr_remset takes up.
+  // Note also includes the strong code root set.
   size_t mem_size() {
     return _other_regions.mem_size()
       // This correction is necessary because the above includes the second
       // part.
-      + sizeof(this) - sizeof(OtherRegionsTable);
+      + (sizeof(this) - sizeof(OtherRegionsTable))
+      + strong_code_roots_mem_size();
   }
 
   // Returns the memory occupancy of all static data structures associated
@@ -307,6 +314,37 @@
   bool contains_reference(OopOrNarrowOopStar from) const {
     return _other_regions.contains_reference(from);
   }
+
+  // Routines for managing the list of code roots that point into
+  // the heap region that owns this RSet.
+  void add_strong_code_root(nmethod* nm);
+  void remove_strong_code_root(nmethod* nm);
+
+  // During a collection, migrate the successfully evacuated strong
+  // code roots that referenced into the region that owns this RSet
+  // to the RSets of the new regions that they now point into.
+  // Unsuccessfully evacuated code roots are not migrated.
+  void migrate_strong_code_roots();
+
+  // Applies blk->do_code_blob() to each of the entries in
+  // the strong code roots list
+  void strong_code_roots_do(CodeBlobClosure* blk) const;
+
+  // Returns the number of elements in the strong code roots list
+  int strong_code_roots_list_length() {
+    return _strong_code_roots_list->length();
+  }
+
+  // Returns true if the strong code roots contains the given
+  // nmethod.
+  bool strong_code_roots_list_contains(nmethod* nm) {
+    return _strong_code_roots_list->contains(nm);
+  }
+
+  // Returns the amount of memory, in bytes, currently
+  // consumed by the strong code roots.
+  size_t strong_code_roots_mem_size();
+
   void print() const;
 
   // Called during a stop-world phase to perform any deferred cleanups.
--- a/src/share/vm/gc_implementation/g1/ptrQueue.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/ptrQueue.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -79,6 +79,10 @@
 
   void reset() { if (_buf != NULL) _index = _sz; }
 
+  void enqueue(volatile void* ptr) {
+    enqueue((void*)(ptr));
+  }
+
   // Enqueues the given "obj".
   void enqueue(void* ptr) {
     if (!_active) return;
--- a/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -923,7 +923,7 @@
 
   GenCollectedHeap* gch = GenCollectedHeap::heap();
 
-  _gc_timer->register_gc_start(os::elapsed_counter());
+  _gc_timer->register_gc_start();
 
   assert(gch->kind() == CollectedHeap::GenCollectedHeap,
     "not a CMS generational heap");
@@ -1100,7 +1100,7 @@
   gch->trace_heap_after_gc(&gc_tracer);
   gc_tracer.report_tenuring_threshold(tenuring_threshold());
 
-  _gc_timer->register_gc_end(os::elapsed_counter());
+  _gc_timer->register_gc_end();
 
   gc_tracer.report_gc_end(_gc_timer->gc_end(), _gc_timer->time_partitions());
 }
--- a/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -90,14 +90,16 @@
                   og_min_size, og_max_size,
                   yg_min_size, yg_max_size);
 
-  // The ReservedSpace ctor used below requires that the page size for the perm
-  // gen is <= the page size for the rest of the heap (young + old gens).
   const size_t og_page_sz = os::page_size_for_region(yg_min_size + og_min_size,
                                                      yg_max_size + og_max_size,
                                                      8);
-  const size_t pg_page_sz = MIN2(os::page_size_for_region(pg_min_size,
-                                                          pg_max_size, 16),
-                                 og_page_sz);
+
+  // Use the same page size for both perm gen and old gen,
+  // to allow large pages to be allocated when the heap is reserved
+  // for the implementations that can't 'commit' large pages.
+  // NEEDS_CLEANUP. ReservedHeapSpace/ReservedSpace that takes both
+  // a prefix and a suffix alignment can now be removed.
+  const size_t pg_page_sz = og_page_sz;
 
   const size_t pg_align = set_alignment(_perm_gen_alignment,  pg_page_sz);
   const size_t og_align = set_alignment(_old_gen_alignment,   og_page_sz);
@@ -138,12 +140,9 @@
   total_reserved = add_and_check_overflow(total_reserved, og_max_size);
   total_reserved = add_and_check_overflow(total_reserved, yg_max_size);
 
-  char* addr = Universe::preferred_heap_base(total_reserved, Universe::UnscaledNarrowOop);
+  assert(is_size_aligned(total_reserved, og_align), "Must be");
 
-  // The main part of the heap (old gen + young gen) can often use a larger page
-  // size than is needed or wanted for the perm gen.  Use the "compound
-  // alignment" ReservedSpace ctor to avoid having to use the same page size for
-  // all gens.
+  char* addr = Universe::preferred_heap_base(total_reserved, og_align, Universe::UnscaledNarrowOop);
 
   ReservedHeapSpace heap_rs(pg_max_size, pg_align, og_max_size + yg_max_size,
                             og_align, addr);
@@ -153,12 +152,12 @@
       // Failed to reserve at specified address - the requested memory
       // region is taken already, for example, by 'java' launcher.
       // Try again to reserver heap higher.
-      addr = Universe::preferred_heap_base(total_reserved, Universe::ZeroBasedNarrowOop);
+      addr = Universe::preferred_heap_base(total_reserved, og_align, Universe::ZeroBasedNarrowOop);
       ReservedHeapSpace heap_rs0(pg_max_size, pg_align, og_max_size + yg_max_size,
                                  og_align, addr);
       if (addr != NULL && !heap_rs0.is_reserved()) {
         // Failed to reserve at specified address again - give up.
-        addr = Universe::preferred_heap_base(total_reserved, Universe::HeapBasedNarrowOop);
+        addr = Universe::preferred_heap_base(total_reserved, og_align, Universe::HeapBasedNarrowOop);
         assert(addr == NULL, "");
         ReservedHeapSpace heap_rs1(pg_max_size, pg_align, og_max_size + yg_max_size,
                                    og_align, addr);
--- a/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "gc_implementation/parallelScavenge/generationSizer.hpp"
+#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
 #include "gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp"
 #include "gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.hpp"
 #include "gc_implementation/parallelScavenge/psScavenge.hpp"
@@ -78,6 +79,38 @@
   _old_gen_policy_is_ready = false;
 }
 
+size_t PSAdaptiveSizePolicy::calculate_free_based_on_live(size_t live, uintx ratio_as_percentage) {
+  // We want to calculate how much free memory there can be based on the
+  // amount of live data currently in the old gen. Using the formula:
+  // ratio * (free + live) = free
+  // Some equation solving later we get:
+  // free = (live * ratio) / (1 - ratio)
+
+  const double ratio = ratio_as_percentage / 100.0;
+  const double ratio_inverse = 1.0 - ratio;
+  const double tmp = live * ratio;
+  size_t free = (size_t)(tmp / ratio_inverse);
+
+  return free;
+}
+
+size_t PSAdaptiveSizePolicy::calculated_old_free_size_in_bytes() const {
+  size_t free_size = (size_t)(_promo_size + avg_promoted()->padded_average());
+  size_t live = ParallelScavengeHeap::heap()->old_gen()->used_in_bytes();
+
+  if (MinHeapFreeRatio != 0) {
+    size_t min_free = calculate_free_based_on_live(live, MinHeapFreeRatio);
+    free_size = MAX2(free_size, min_free);
+  }
+
+  if (MaxHeapFreeRatio != 100) {
+    size_t max_free = calculate_free_based_on_live(live, MaxHeapFreeRatio);
+    free_size = MIN2(max_free, free_size);
+  }
+
+  return free_size;
+}
+
 void PSAdaptiveSizePolicy::major_collection_begin() {
   // Update the interval time
   _major_timer.stop();
@@ -1107,3 +1140,18 @@
                           st,
                           PSScavenge::tenuring_threshold());
 }
+
+#ifndef PRODUCT
+
+void TestOldFreeSpaceCalculation_test() {
+  assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(100, 20) == 25, "Calculation of free memory failed");
+  assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(100, 50) == 100, "Calculation of free memory failed");
+  assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(100, 60) == 150, "Calculation of free memory failed");
+  assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(100, 75) == 300, "Calculation of free memory failed");
+  assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(400, 20) == 100, "Calculation of free memory failed");
+  assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(400, 50) == 400, "Calculation of free memory failed");
+  assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(400, 60) == 600, "Calculation of free memory failed");
+  assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(400, 75) == 1200, "Calculation of free memory failed");
+}
+
+#endif /* !PRODUCT */
--- a/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -238,7 +238,6 @@
   void major_collection_begin();
   void major_collection_end(size_t amount_live, GCCause::Cause gc_cause);
 
-  //
   void tenured_allocation(size_t size) {
     _avg_pretenured->sample(size);
   }
@@ -246,9 +245,9 @@
   // Accessors
   // NEEDS_CLEANUP   should use sizes.hpp
 
-  size_t calculated_old_free_size_in_bytes() const {
-    return (size_t)(_promo_size + avg_promoted()->padded_average());
-  }
+  static size_t calculate_free_based_on_live(size_t live, uintx ratio_as_percentage);
+
+  size_t calculated_old_free_size_in_bytes() const;
 
   size_t average_old_live_in_bytes() const {
     return (size_t) avg_old_live()->average();
--- a/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -116,7 +116,7 @@
   assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
   GCCause::Cause gc_cause = heap->gc_cause();
 
-  _gc_timer->register_gc_start(os::elapsed_counter());
+  _gc_timer->register_gc_start();
   _gc_tracer->report_gc_start(gc_cause, _gc_timer->gc_start());
 
   PSAdaptiveSizePolicy* size_policy = heap->size_policy();
@@ -149,8 +149,7 @@
 
   if (VerifyBeforeGC && heap->total_collections() >= VerifyGCStartAt) {
     HandleMark hm;  // Discard invalid handles created during verification
-    gclog_or_tty->print(" VerifyBeforeGC:");
-    Universe::verify();
+    Universe::verify(" VerifyBeforeGC:");
   }
 
   // Verify object start arrays
@@ -359,8 +358,7 @@
 
   if (VerifyAfterGC && heap->total_collections() >= VerifyGCStartAt) {
     HandleMark hm;  // Discard invalid handles created during verification
-    gclog_or_tty->print(" VerifyAfterGC:");
-    Universe::verify();
+    Universe::verify(" VerifyAfterGC:");
   }
 
   // Re-verify object start arrays
@@ -386,7 +384,7 @@
   ParallelTaskTerminator::print_termination_counts();
 #endif
 
-  _gc_timer->register_gc_end(os::elapsed_counter());
+  _gc_timer->register_gc_end();
 
   _gc_tracer->report_gc_end(_gc_timer->gc_end(), _gc_timer->time_partitions());
 
--- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, 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
@@ -1034,8 +1034,7 @@
 
   if (VerifyBeforeGC && heap->total_collections() >= VerifyGCStartAt) {
     HandleMark hm;  // Discard invalid handles created during verification
-    gclog_or_tty->print(" VerifyBeforeGC:");
-    Universe::verify();
+    Universe::verify(" VerifyBeforeGC:");
   }
 
   // Verify object start arrays
@@ -2041,7 +2040,7 @@
 
   ParallelScavengeHeap* heap = gc_heap();
 
-  _gc_timer.register_gc_start(os::elapsed_counter());
+  _gc_timer.register_gc_start();
   _gc_tracer.report_gc_start(heap->gc_cause(), _gc_timer.gc_start());
 
   TimeStamp marking_start;
@@ -2248,8 +2247,7 @@
 
   if (VerifyAfterGC && heap->total_collections() >= VerifyGCStartAt) {
     HandleMark hm;  // Discard invalid handles created during verification
-    gclog_or_tty->print(" VerifyAfterGC:");
-    Universe::verify();
+    Universe::verify(" VerifyAfterGC:");
   }
 
   // Re-verify object start arrays
@@ -2285,7 +2283,7 @@
   ParallelTaskTerminator::print_termination_counts();
 #endif
 
-  _gc_timer.register_gc_end(os::elapsed_counter());
+  _gc_timer.register_gc_end();
 
   _gc_tracer.report_dense_prefix(dense_prefix(old_space_id));
   _gc_tracer.report_gc_end(_gc_timer.gc_end(), _gc_timer.time_partitions());
--- a/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -266,7 +266,7 @@
   assert(_preserved_mark_stack.is_empty(), "should be empty");
   assert(_preserved_oop_stack.is_empty(), "should be empty");
 
-  _gc_timer.register_gc_start(os::elapsed_counter());
+  _gc_timer.register_gc_start();
 
   TimeStamp scavenge_entry;
   TimeStamp scavenge_midpoint;
@@ -325,8 +325,7 @@
 
   if (VerifyBeforeGC && heap->total_collections() >= VerifyGCStartAt) {
     HandleMark hm;  // Discard invalid handles created during verification
-    gclog_or_tty->print(" VerifyBeforeGC:");
-    Universe::verify();
+    Universe::verify(" VerifyBeforeGC:");
   }
 
   {
@@ -536,8 +535,19 @@
           counters->update_survivor_overflowed(_survivor_overflow);
         }
 
+        size_t max_young_size = young_gen->max_size();
+
+        // Deciding a free ratio in the young generation is tricky, so if
+        // MinHeapFreeRatio or MaxHeapFreeRatio are in use (implicating
+        // that the old generation size may have been limited because of them) we
+        // should then limit our young generation size using NewRatio to have it
+        // follow the old generation size.
+        if (MinHeapFreeRatio != 0 || MaxHeapFreeRatio != 100) {
+          max_young_size = MIN2(old_gen->capacity_in_bytes() / NewRatio, young_gen->max_size());
+        }
+
         size_t survivor_limit =
-          size_policy->max_survivor_size(young_gen->max_size());
+          size_policy->max_survivor_size(max_young_size);
         _tenuring_threshold =
           size_policy->compute_survivor_space_size_and_threshold(
                                                            _survivor_overflow,
@@ -560,8 +570,7 @@
         // Do call at minor collections?
         // Don't check if the size_policy is ready at this
         // level.  Let the size_policy check that internally.
-        if (UseAdaptiveSizePolicy &&
-            UseAdaptiveGenerationSizePolicyAtMinorCollection &&
+        if (UseAdaptiveGenerationSizePolicyAtMinorCollection &&
             ((gc_cause != GCCause::_java_lang_system_gc) ||
               UseAdaptiveSizePolicyWithSystemGC)) {
 
@@ -570,7 +579,7 @@
             young_gen->from_space()->capacity_in_bytes() +
             young_gen->to_space()->capacity_in_bytes(),
             "Sizes of space in young gen are out-of-bounds");
-          size_t max_eden_size = young_gen->max_size() -
+          size_t max_eden_size = max_young_size -
             young_gen->from_space()->capacity_in_bytes() -
             young_gen->to_space()->capacity_in_bytes();
           size_policy->compute_generation_free_space(young_gen->used_in_bytes(),
@@ -661,8 +670,7 @@
 
   if (VerifyAfterGC && heap->total_collections() >= VerifyGCStartAt) {
     HandleMark hm;  // Discard invalid handles created during verification
-    gclog_or_tty->print(" VerifyAfterGC:");
-    Universe::verify();
+    Universe::verify(" VerifyAfterGC:");
   }
 
   heap->print_heap_after_gc();
@@ -689,7 +697,7 @@
 #endif
 
 
-  _gc_timer.register_gc_end(os::elapsed_counter());
+  _gc_timer.register_gc_end();
 
   _gc_tracer.report_gc_end(_gc_timer.gc_end(), _gc_timer.time_partitions());
 
--- a/src/share/vm/gc_implementation/shared/gcTimer.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/shared/gcTimer.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,52 +25,55 @@
 #include "precompiled.hpp"
 #include "gc_implementation/shared/gcTimer.hpp"
 #include "utilities/growableArray.hpp"
+#include "utilities/ticks.inline.hpp"
 
-void GCTimer::register_gc_start(jlong time) {
+// the "time" parameter for most functions
+// has a default value set by Ticks::now()
+
+void GCTimer::register_gc_start(const Ticks& time) {
   _time_partitions.clear();
   _gc_start = time;
 }
 
-void GCTimer::register_gc_end(jlong time) {
+void GCTimer::register_gc_end(const Ticks& time) {
   assert(!_time_partitions.has_active_phases(),
       "We should have ended all started phases, before ending the GC");
 
   _gc_end = time;
 }
 
-void GCTimer::register_gc_pause_start(const char* name, jlong time) {
+void GCTimer::register_gc_pause_start(const char* name, const Ticks& time) {
   _time_partitions.report_gc_phase_start(name, time);
 }
 
-void GCTimer::register_gc_pause_end(jlong time) {
+void GCTimer::register_gc_pause_end(const Ticks& time) {
   _time_partitions.report_gc_phase_end(time);
 }
 
-void GCTimer::register_gc_phase_start(const char* name, jlong time) {
+void GCTimer::register_gc_phase_start(const char* name, const Ticks& time) {
   _time_partitions.report_gc_phase_start(name, time);
 }
 
-void GCTimer::register_gc_phase_end(jlong time) {
+void GCTimer::register_gc_phase_end(const Ticks& time) {
   _time_partitions.report_gc_phase_end(time);
 }
 
-
-void STWGCTimer::register_gc_start(jlong time) {
+void STWGCTimer::register_gc_start(const Ticks& time) {
   GCTimer::register_gc_start(time);
   register_gc_pause_start("GC Pause", time);
 }
 
-void STWGCTimer::register_gc_end(jlong time) {
+void STWGCTimer::register_gc_end(const Ticks& time) {
   register_gc_pause_end(time);
   GCTimer::register_gc_end(time);
 }
 
-void ConcurrentGCTimer::register_gc_pause_start(const char* name, jlong time) {
-  GCTimer::register_gc_pause_start(name, time);
+void ConcurrentGCTimer::register_gc_pause_start(const char* name) {
+  GCTimer::register_gc_pause_start(name);
 }
 
-void ConcurrentGCTimer::register_gc_pause_end(jlong time) {
-  GCTimer::register_gc_pause_end(time);
+void ConcurrentGCTimer::register_gc_pause_end() {
+  GCTimer::register_gc_pause_end();
 }
 
 void PhasesStack::clear() {
@@ -111,11 +114,11 @@
 void TimePartitions::clear() {
   _phases->clear();
   _active_phases.clear();
-  _sum_of_pauses = 0;
-  _longest_pause = 0;
+  _sum_of_pauses = Tickspan();
+  _longest_pause = Tickspan();
 }
 
-void TimePartitions::report_gc_phase_start(const char* name, jlong time) {
+void TimePartitions::report_gc_phase_start(const char* name, const Ticks& time) {
   assert(_phases->length() <= 1000, "Too many recored phases?");
 
   int level = _active_phases.count();
@@ -133,13 +136,13 @@
 void TimePartitions::update_statistics(GCPhase* phase) {
   // FIXME: This should only be done for pause phases
   if (phase->level() == 0) {
-    jlong pause = phase->end() - phase->start();
+    const Tickspan pause = phase->end() - phase->start();
     _sum_of_pauses += pause;
     _longest_pause = MAX2(pause, _longest_pause);
   }
 }
 
-void TimePartitions::report_gc_phase_end(jlong time) {
+void TimePartitions::report_gc_phase_end(const Ticks& time) {
   int phase_index = _active_phases.pop();
   GCPhase* phase = _phases->adr_at(phase_index);
   phase->set_end(time);
@@ -157,14 +160,6 @@
   return _phases->adr_at(index);
 }
 
-jlong TimePartitions::sum_of_pauses() {
-  return _sum_of_pauses;
-}
-
-jlong TimePartitions::longest_pause() {
-  return _longest_pause;
-}
-
 bool TimePartitions::has_active_phases() {
   return _active_phases.count() > 0;
 }
@@ -194,7 +189,7 @@
     max_nested_pause_phases();
   }
 
-  static void validate_pause_phase(GCPhase* phase, int level, const char* name, jlong start, jlong end) {
+  static void validate_pause_phase(GCPhase* phase, int level, const char* name, const Ticks& start, const Ticks& end) {
     assert(phase->level() == level, "Incorrect level");
     assert(strcmp(phase->name(), name) == 0, "Incorrect name");
     assert(phase->start() == start, "Incorrect start");
@@ -209,8 +204,8 @@
     TimePartitionPhasesIterator iter(&time_partitions);
 
     validate_pause_phase(iter.next(), 0, "PausePhase", 2, 8);
-    assert(time_partitions.sum_of_pauses() == 8-2, "Incorrect");
-    assert(time_partitions.longest_pause() == 8-2, "Incorrect");
+    assert(time_partitions.sum_of_pauses() == Ticks(8) - Ticks(2), "Incorrect");
+    assert(time_partitions.longest_pause() == Ticks(8) - Ticks(2), "Incorrect");
 
     assert(!iter.has_next(), "Too many elements");
   }
@@ -227,8 +222,8 @@
     validate_pause_phase(iter.next(), 0, "PausePhase1", 2, 3);
     validate_pause_phase(iter.next(), 0, "PausePhase2", 4, 6);
 
-    assert(time_partitions.sum_of_pauses() == 3, "Incorrect");
-    assert(time_partitions.longest_pause() == 2, "Incorrect");
+    assert(time_partitions.sum_of_pauses() == Ticks(3) - Ticks(0), "Incorrect");
+    assert(time_partitions.longest_pause() == Ticks(2) - Ticks(0), "Incorrect");
 
     assert(!iter.has_next(), "Too many elements");
   }
@@ -245,8 +240,8 @@
     validate_pause_phase(iter.next(), 0, "PausePhase", 2, 5);
     validate_pause_phase(iter.next(), 1, "SubPhase", 3, 4);
 
-    assert(time_partitions.sum_of_pauses() == 3, "Incorrect");
-    assert(time_partitions.longest_pause() == 3, "Incorrect");
+    assert(time_partitions.sum_of_pauses() == Ticks(3) - Ticks(0), "Incorrect");
+    assert(time_partitions.longest_pause() == Ticks(3) - Ticks(0), "Incorrect");
 
     assert(!iter.has_next(), "Too many elements");
   }
@@ -269,8 +264,8 @@
     validate_pause_phase(iter.next(), 2, "SubPhase2", 4, 7);
     validate_pause_phase(iter.next(), 3, "SubPhase3", 5, 6);
 
-    assert(time_partitions.sum_of_pauses() == 7, "Incorrect");
-    assert(time_partitions.longest_pause() == 7, "Incorrect");
+    assert(time_partitions.sum_of_pauses() == Ticks(7) - Ticks(0), "Incorrect");
+    assert(time_partitions.longest_pause() == Ticks(7) - Ticks(0), "Incorrect");
 
     assert(!iter.has_next(), "Too many elements");
   }
@@ -298,8 +293,8 @@
     validate_pause_phase(iter.next(), 1, "SubPhase3", 7, 8);
     validate_pause_phase(iter.next(), 1, "SubPhase4", 9, 10);
 
-    assert(time_partitions.sum_of_pauses() == 9, "Incorrect");
-    assert(time_partitions.longest_pause() == 9, "Incorrect");
+    assert(time_partitions.sum_of_pauses() == Ticks(9) - Ticks(0), "Incorrect");
+    assert(time_partitions.longest_pause() == Ticks(9) - Ticks(0), "Incorrect");
 
     assert(!iter.has_next(), "Too many elements");
   }
@@ -336,8 +331,8 @@
     validate_pause_phase(iter.next(), 2, "SubPhase22", 12, 13);
     validate_pause_phase(iter.next(), 1, "SubPhase3", 15, 16);
 
-    assert(time_partitions.sum_of_pauses() == 15, "Incorrect");
-    assert(time_partitions.longest_pause() == 15, "Incorrect");
+    assert(time_partitions.sum_of_pauses() == Ticks(15) - Ticks(0), "Incorrect");
+    assert(time_partitions.longest_pause() == Ticks(15) - Ticks(0), "Incorrect");
 
     assert(!iter.has_next(), "Too many elements");
   }
--- a/src/share/vm/gc_implementation/shared/gcTimer.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/shared/gcTimer.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -28,6 +28,7 @@
 #include "memory/allocation.hpp"
 #include "prims/jni_md.h"
 #include "utilities/macros.hpp"
+#include "utilities/ticks.hpp"
 
 class ConcurrentPhase;
 class GCPhase;
@@ -45,21 +46,21 @@
 class GCPhase {
   const char* _name;
   int _level;
-  jlong _start;
-  jlong _end;
+  Ticks _start;
+  Ticks _end;
 
  public:
   void set_name(const char* name) { _name = name; }
-  const char* name() { return _name; }
+  const char* name() const { return _name; }
 
-  int level() { return _level; }
+  int level() const { return _level; }
   void set_level(int level) { _level = level; }
 
-  jlong start() { return _start; }
-  void set_start(jlong time) { _start = time; }
+  const Ticks start() const { return _start; }
+  void set_start(const Ticks& time) { _start = time; }
 
-  jlong end() { return _end; }
-  void set_end(jlong time) { _end = time; }
+  const Ticks end() const { return _end; }
+  void set_end(const Ticks& time) { _end = time; }
 
   virtual void accept(PhaseVisitor* visitor) = 0;
 };
@@ -102,22 +103,22 @@
   GrowableArray<PausePhase>* _phases;
   PhasesStack _active_phases;
 
-  jlong _sum_of_pauses;
-  jlong _longest_pause;
+  Tickspan _sum_of_pauses;
+  Tickspan _longest_pause;
 
  public:
   TimePartitions();
   ~TimePartitions();
   void clear();
 
-  void report_gc_phase_start(const char* name, jlong time);
-  void report_gc_phase_end(jlong time);
+  void report_gc_phase_start(const char* name, const Ticks& time);
+  void report_gc_phase_end(const Ticks& time);
 
   int num_phases() const;
   GCPhase* phase_at(int index) const;
 
-  jlong sum_of_pauses();
-  jlong longest_pause();
+  const Tickspan sum_of_pauses() const { return _sum_of_pauses; }
+  const Tickspan longest_pause() const { return _longest_pause; }
 
   bool has_active_phases();
  private:
@@ -133,40 +134,37 @@
 class GCTimer : public ResourceObj {
   NOT_PRODUCT(friend class GCTimerTest;)
  protected:
-  jlong _gc_start;
-  jlong _gc_end;
+  Ticks _gc_start;
+  Ticks _gc_end;
   TimePartitions _time_partitions;
 
  public:
-  virtual void register_gc_start(jlong time);
-  virtual void register_gc_end(jlong time);
+  virtual void register_gc_start(const Ticks& time = Ticks::now());
+  virtual void register_gc_end(const Ticks& time = Ticks::now());
 
-  void register_gc_phase_start(const char* name, jlong time);
-  void register_gc_phase_end(jlong time);
+  void register_gc_phase_start(const char* name, const Ticks& time);
+  void register_gc_phase_end(const Ticks& time);
 
-  jlong gc_start() { return _gc_start; }
-  jlong gc_end() { return _gc_end; }
+  const Ticks gc_start() const { return _gc_start; }
+  const Ticks gc_end() const { return _gc_end; }
 
   TimePartitions* time_partitions() { return &_time_partitions; }
 
-  long longest_pause();
-  long sum_of_pauses();
-
  protected:
-  void register_gc_pause_start(const char* name, jlong time);
-  void register_gc_pause_end(jlong time);
+  void register_gc_pause_start(const char* name, const Ticks& time = Ticks::now());
+  void register_gc_pause_end(const Ticks& time = Ticks::now());
 };
 
 class STWGCTimer : public GCTimer {
  public:
-  virtual void register_gc_start(jlong time);
-  virtual void register_gc_end(jlong time);
+  virtual void register_gc_start(const Ticks& time = Ticks::now());
+  virtual void register_gc_end(const Ticks& time = Ticks::now());
 };
 
 class ConcurrentGCTimer : public GCTimer {
  public:
-  void register_gc_pause_start(const char* name, jlong time);
-  void register_gc_pause_end(jlong time);
+  void register_gc_pause_start(const char* name);
+  void register_gc_pause_end();
 };
 
 class TimePartitionPhasesIterator {
--- a/src/share/vm/gc_implementation/shared/gcTrace.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/shared/gcTrace.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -33,6 +33,7 @@
 #include "memory/referenceProcessorStats.hpp"
 #include "runtime/os.hpp"
 #include "utilities/globalDefinitions.hpp"
+#include "utilities/ticks.inline.hpp"
 
 #ifndef SERIALGC
 #include "gc_implementation/g1/evacuationInfo.hpp"
@@ -46,7 +47,7 @@
   return GCTracer_next_gc_id++;
 }
 
-void GCTracer::report_gc_start_impl(GCCause::Cause cause, jlong timestamp) {
+void GCTracer::report_gc_start_impl(GCCause::Cause cause, const Ticks& timestamp) {
   assert_unset_gc_id();
 
   GCId gc_id = create_new_gc_id();
@@ -55,7 +56,7 @@
   _shared_gc_info.set_start_timestamp(timestamp);
 }
 
-void GCTracer::report_gc_start(GCCause::Cause cause, jlong timestamp) {
+void GCTracer::report_gc_start(GCCause::Cause cause, const Ticks& timestamp) {
   assert_unset_gc_id();
 
   report_gc_start_impl(cause, timestamp);
@@ -65,7 +66,7 @@
   return _shared_gc_info.id() != SharedGCInfo::UNSET_GCID;
 }
 
-void GCTracer::report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions) {
+void GCTracer::report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions) {
   assert_set_gc_id();
 
   _shared_gc_info.set_sum_of_pauses(time_partitions->sum_of_pauses());
@@ -76,7 +77,7 @@
   send_garbage_collection_event();
 }
 
-void GCTracer::report_gc_end(jlong timestamp, TimePartitions* time_partitions) {
+void GCTracer::report_gc_end(const Ticks& timestamp, TimePartitions* time_partitions) {
   assert_set_gc_id();
 
   report_gc_end_impl(timestamp, time_partitions);
@@ -97,10 +98,10 @@
   const GCId _gc_id;
   const double _size_threshold_percentage;
   const size_t _total_size_in_words;
-  const jlong _timestamp;
+  const Ticks _timestamp;
 
  public:
-  ObjectCountEventSenderClosure(GCId gc_id, size_t total_size_in_words, jlong timestamp) :
+  ObjectCountEventSenderClosure(GCId gc_id, size_t total_size_in_words, const Ticks& timestamp) :
     _gc_id(gc_id),
     _size_threshold_percentage(ObjectCountCutOffPercent / 100),
     _total_size_in_words(total_size_in_words),
@@ -154,8 +155,7 @@
       ObjectCountFilter object_filter(is_alive_cl);
       HeapInspection::populate_table(&cit, false, &object_filter);
 
-      jlong timestamp = os::elapsed_counter();
-      ObjectCountEventSenderClosure event_sender(_shared_gc_info.id(), cit.size_of_instances_in_words(), timestamp);
+      ObjectCountEventSenderClosure event_sender(_shared_gc_info.id(), cit.size_of_instances_in_words(), Ticks::now());
       cit.iterate(&event_sender);
     }
   }
@@ -168,7 +168,7 @@
   send_perm_gen_summary_event(when, perm_gen_summary);
 }
 
-void YoungGCTracer::report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions) {
+void YoungGCTracer::report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions) {
   assert_set_gc_id();
   assert(_tenuring_threshold != UNSET_TENURING_THRESHOLD, "Tenuring threshold has not been reported");
 
@@ -188,14 +188,14 @@
   _tenuring_threshold = tenuring_threshold;
 }
 
-void OldGCTracer::report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions) {
+void OldGCTracer::report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions) {
   assert_set_gc_id();
 
   GCTracer::report_gc_end_impl(timestamp, time_partitions);
   send_old_gc_event();
 }
 
-void ParallelOldTracer::report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions) {
+void ParallelOldTracer::report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions) {
   assert_set_gc_id();
 
   OldGCTracer::report_gc_end_impl(timestamp, time_partitions);
@@ -221,7 +221,7 @@
   _g1_young_gc_info.set_type(type);
 }
 
-void G1NewTracer::report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions) {
+void G1NewTracer::report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions) {
   assert_set_gc_id();
 
   YoungGCTracer::report_gc_end_impl(timestamp, time_partitions);
--- a/src/share/vm/gc_implementation/shared/gcTrace.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/shared/gcTrace.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -34,6 +34,7 @@
 #ifndef SERIALGC
 #include "gc_implementation/g1/g1YCTypes.hpp"
 #endif
+#include "utilities/ticks.hpp"
 
 typedef uint GCId;
 
@@ -46,8 +47,6 @@
 class BoolObjectClosure;
 
 class SharedGCInfo VALUE_OBJ_CLASS_SPEC {
-  static const jlong UNSET_TIMESTAMP = -1;
-
  public:
   static const GCId UNSET_GCID = (GCId)-1;
 
@@ -55,23 +54,30 @@
   GCId _id;
   GCName _name;
   GCCause::Cause _cause;
-  jlong _start_timestamp;
-  jlong _end_timestamp;
-  jlong _sum_of_pauses;
-  jlong _longest_pause;
+  Ticks     _start_timestamp;
+  Ticks     _end_timestamp;
+  Tickspan  _sum_of_pauses;
+  Tickspan  _longest_pause;
 
  public:
-  SharedGCInfo(GCName name) : _id(UNSET_GCID), _name(name), _cause(GCCause::_last_gc_cause),
-      _start_timestamp(UNSET_TIMESTAMP), _end_timestamp(UNSET_TIMESTAMP), _sum_of_pauses(0), _longest_pause(0) {}
+  SharedGCInfo(GCName name) :
+    _id(UNSET_GCID),
+    _name(name),
+    _cause(GCCause::_last_gc_cause),
+    _start_timestamp(),
+    _end_timestamp(),
+    _sum_of_pauses(),
+    _longest_pause() {
+  }
 
   void set_id(GCId id) { _id = id; }
   GCId id() const { return _id; }
 
-  void set_start_timestamp(jlong timestamp) { _start_timestamp = timestamp; }
-  jlong start_timestamp() const { return _start_timestamp; }
+  void set_start_timestamp(const Ticks& timestamp) { _start_timestamp = timestamp; }
+  const Ticks start_timestamp() const { return _start_timestamp; }
 
-  void set_end_timestamp(jlong timestamp) { _end_timestamp = timestamp; }
-  jlong end_timestamp() const { return _end_timestamp; }
+  void set_end_timestamp(const Ticks& timestamp) { _end_timestamp = timestamp; }
+  const Ticks end_timestamp() const { return _end_timestamp; }
 
   void set_name(GCName name) { _name = name; }
   GCName name() const { return _name; }
@@ -79,11 +85,11 @@
   void set_cause(GCCause::Cause cause) { _cause = cause; }
   GCCause::Cause cause() const { return _cause; }
 
-  void set_sum_of_pauses(jlong duration) { _sum_of_pauses = duration; }
-  jlong sum_of_pauses() const { return _sum_of_pauses; }
+  void set_sum_of_pauses(const Tickspan& duration) { _sum_of_pauses = duration; }
+  const Tickspan sum_of_pauses() const { return _sum_of_pauses; }
 
-  void set_longest_pause(jlong duration) { _longest_pause = duration; }
-  jlong longest_pause() const { return _longest_pause; }
+  void set_longest_pause(const Tickspan& duration) { _longest_pause = duration; }
+  const Tickspan longest_pause() const { return _longest_pause; }
 };
 
 class ParallelOldGCInfo VALUE_OBJ_CLASS_SPEC {
@@ -115,8 +121,8 @@
   SharedGCInfo _shared_gc_info;
 
  public:
-  void report_gc_start(GCCause::Cause cause, jlong timestamp);
-  void report_gc_end(jlong timestamp, TimePartitions* time_partitions);
+  void report_gc_start(GCCause::Cause cause, const Ticks& timestamp);
+  void report_gc_end(const Ticks& timestamp, TimePartitions* time_partitions);
   void report_gc_heap_summary(GCWhen::Type when, const GCHeapSummary& heap_summary, const PermGenSummary& perm_gen_summary) const;
   void report_gc_reference_stats(const ReferenceProcessorStats& rp) const;
   void report_object_count_after_gc(BoolObjectClosure* object_filter);
@@ -125,8 +131,8 @@
 
  protected:
   GCTracer(GCName name) : _shared_gc_info(name) {}
-  virtual void report_gc_start_impl(GCCause::Cause cause, jlong timestamp);
-  virtual void report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions);
+  virtual void report_gc_start_impl(GCCause::Cause cause, const Ticks& timestamp);
+  virtual void report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions);
 
  private:
   void send_garbage_collection_event() const;
@@ -143,7 +149,7 @@
 
  protected:
   YoungGCTracer(GCName name) : GCTracer(name), _tenuring_threshold(UNSET_TENURING_THRESHOLD) {}
-  virtual void report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions);
+  virtual void report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions);
 
  public:
   void report_promotion_failed(const PromotionFailedInfo& pf_info);
@@ -157,7 +163,7 @@
 class OldGCTracer : public GCTracer {
  protected:
   OldGCTracer(GCName name) : GCTracer(name) {}
-  virtual void report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions);
+  virtual void report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions);
 
  public:
   void report_concurrent_mode_failure();
@@ -175,7 +181,7 @@
   void report_dense_prefix(void* dense_prefix);
 
  protected:
-  void report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions);
+  void report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions);
 
  private:
   void send_parallel_old_event() const;
@@ -209,7 +215,7 @@
   G1NewTracer() : YoungGCTracer(G1New) {}
 
   void report_yc_type(G1YCType type);
-  void report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions);
+  void report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions);
   void report_evacuation_info(EvacuationInfo* info);
   void report_evacuation_failed(EvacuationFailedInfo& ef_info);
 
--- a/src/share/vm/gc_implementation/shared/gcTraceSend.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/shared/gcTraceSend.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -28,8 +28,10 @@
 #include "gc_implementation/shared/gcTrace.hpp"
 #include "gc_implementation/shared/gcWhen.hpp"
 #include "gc_implementation/shared/copyFailedInfo.hpp"
+#include "runtime/os.hpp"
 #include "trace/traceBackend.hpp"
 #include "trace/tracing.hpp"
+
 #ifndef SERIALGC
 #include "gc_implementation/g1/evacuationInfo.hpp"
 #include "gc_implementation/g1/g1YCTypes.hpp"
--- a/src/share/vm/gc_implementation/shared/gcTraceTime.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/shared/gcTraceTime.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -43,11 +43,13 @@
 # include "thread_bsd.inline.hpp"
 #endif
 
+#include "utilities/ticks.inline.hpp"
+
 
 GCTraceTime::GCTraceTime(const char* title, bool doit, bool print_cr, GCTimer* timer) :
-    _title(title), _doit(doit), _print_cr(print_cr), _timer(timer) {
+    _title(title), _doit(doit), _print_cr(print_cr), _timer(timer), _start_counter() {
   if (_doit || _timer != NULL) {
-    _start_counter = os::elapsed_counter();
+    _start_counter.stamp();
   }
 
   if (_timer != NULL) {
@@ -66,10 +68,10 @@
 }
 
 GCTraceTime::~GCTraceTime() {
-  jlong stop_counter = 0;
+  Ticks stop_counter;
 
   if (_doit || _timer != NULL) {
-    stop_counter = os::elapsed_counter();
+    stop_counter.stamp();
   }
 
   if (_timer != NULL) {
@@ -77,11 +79,12 @@
   }
 
   if (_doit) {
-    double seconds = TimeHelper::counter_to_seconds(stop_counter - _start_counter);
+    const Tickspan duration = stop_counter - _start_counter;
+    double duration_in_seconds = TicksToTimeHelper::seconds(duration);
     if (_print_cr) {
-      gclog_or_tty->print_cr(", %3.7f secs]", seconds);
+      gclog_or_tty->print_cr(", %3.7f secs]", duration_in_seconds);
     } else {
-      gclog_or_tty->print(", %3.7f secs]", seconds);
+      gclog_or_tty->print(", %3.7f secs]", duration_in_seconds);
     }
     gclog_or_tty->flush();
   }
--- a/src/share/vm/gc_implementation/shared/gcTraceTime.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/shared/gcTraceTime.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -26,6 +26,7 @@
 #define SHARE_VM_GC_IMPLEMENTATION_SHARED_GCTRACETIME_HPP
 
 #include "prims/jni_md.h"
+#include "utilities/ticks.hpp"
 
 class GCTimer;
 
@@ -34,7 +35,7 @@
   bool _doit;
   bool _print_cr;
   GCTimer* _timer;
-  jlong _start_counter;
+  Ticks _start_counter;
 
  public:
   GCTraceTime(const char* title, bool doit, bool print_cr, GCTimer* timer);
--- a/src/share/vm/gc_implementation/shared/objectCountEventSender.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/shared/objectCountEventSender.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -28,8 +28,10 @@
 #include "memory/heapInspection.hpp"
 #include "trace/tracing.hpp"
 #include "utilities/globalDefinitions.hpp"
+#include "utilities/ticks.hpp"
 
-void ObjectCountEventSender::send(const KlassInfoEntry* entry, GCId gc_id, jlong timestamp) {
+void ObjectCountEventSender::send(const KlassInfoEntry* entry, GCId gc_id, const Ticks& timestamp) {
+#if INCLUDE_TRACE
   assert(Tracing::is_event_enabled(EventObjectCountAfterGC::eventId),
          "Only call this method if the event is enabled");
 
@@ -40,6 +42,8 @@
   event.set_totalSize(entry->words() * BytesPerWord);
   event.set_endtime(timestamp);
   event.commit();
+
+#endif
 }
 
 bool ObjectCountEventSender::should_send_event() {
--- a/src/share/vm/gc_implementation/shared/objectCountEventSender.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_implementation/shared/objectCountEventSender.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -29,10 +29,11 @@
 #include "memory/allocation.hpp"
 
 class KlassInfoEntry;
+class Ticks;
 
 class ObjectCountEventSender : public AllStatic {
  public:
-  static void send(const KlassInfoEntry* entry, GCId gc_id, jlong timestamp);
+  static void send(const KlassInfoEntry* entry, GCId gc_id, const Ticks& timestamp);
   static bool should_send_event();
 };
 
--- a/src/share/vm/gc_interface/collectedHeap.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_interface/collectedHeap.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -124,6 +124,14 @@
   }
 }
 
+void CollectedHeap::register_nmethod(nmethod* nm) {
+  assert_locked_or_safepoint(CodeCache_lock);
+}
+
+void CollectedHeap::unregister_nmethod(nmethod* nm) {
+  assert_locked_or_safepoint(CodeCache_lock);
+}
+
 void CollectedHeap::trace_heap(GCWhen::Type when, GCTracer* gc_tracer) {
   const GCHeapSummary& heap_summary = create_heap_summary();
   const PermGenSummary& perm_summary = create_perm_gen_summary();
--- a/src/share/vm/gc_interface/collectedHeap.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/gc_interface/collectedHeap.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -49,6 +49,7 @@
 class Thread;
 class ThreadClosure;
 class VirtualSpaceSummary;
+class nmethod;
 
 class GCMessage : public FormatBuffer<1024> {
  public:
@@ -667,6 +668,11 @@
   void print_heap_before_gc();
   void print_heap_after_gc();
 
+  // Registering and unregistering an nmethod (compiled code) with the heap.
+  // Override with specific mechanism for each specialized heap type.
+  virtual void register_nmethod(nmethod* nm);
+  virtual void unregister_nmethod(nmethod* nm);
+
   void trace_heap_before_gc(GCTracer* gc_tracer);
   void trace_heap_after_gc(GCTracer* gc_tracer);
 
--- a/src/share/vm/interpreter/interpreterRuntime.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/interpreter/interpreterRuntime.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -1248,3 +1248,24 @@
                        size_of_arguments * Interpreter::stackElementSize);
 IRT_END
 #endif
+
+// This is a support of the JVMTI PopFrame interface.
+// Make sure it is an invokestatic of a polymorphic intrinsic that has a member_name argument
+// and return it as a vm_result so that it can be reloaded in the list of invokestatic parameters.
+// The dmh argument is a reference to a DirectMethoHandle that has a member name field.
+IRT_ENTRY(void, InterpreterRuntime::member_name_arg_or_null(JavaThread* thread, address dmh,
+                                                            methodOopDesc* method, address bcp))
+  Bytecodes::Code code = Bytecodes::code_at(method, bcp);
+  if (code != Bytecodes::_invokestatic) {
+    return;
+  }
+  constantPoolOopDesc* cpool = method->constants();
+  int cp_index = Bytes::get_native_u2(bcp + 1) + constantPoolOopDesc::CPCACHE_INDEX_TAG;
+  Symbol* cname = cpool->klass_name_at(cpool->klass_ref_index_at(cp_index));
+  Symbol* mname = cpool->name_ref_at(cp_index);
+
+  if (MethodHandles::has_member_arg(cname, mname)) {
+    oop member_name = java_lang_invoke_DirectMethodHandle::member((oop)dmh);
+    thread->set_vm_result(member_name);
+  }
+IRT_END
--- a/src/share/vm/interpreter/interpreterRuntime.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/interpreter/interpreterRuntime.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -115,6 +115,7 @@
   static void    create_exception(JavaThread* thread, char* name, char* message);
   static void    create_klass_exception(JavaThread* thread, char* name, oopDesc* obj);
   static address exception_handler_for_exception(JavaThread* thread, oopDesc* exception);
+  static void    member_name_arg_or_null(JavaThread* thread, address dmh, methodOopDesc* m, address bcp);
   static void    throw_pending_exception(JavaThread* thread);
 
 #ifdef CC_INTERP
--- a/src/share/vm/memory/cardTableModRefBS.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/memory/cardTableModRefBS.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -400,60 +400,6 @@
   inline_write_ref_field(field, newVal, release);
 }
 
-/*
-   Claimed and deferred bits are used together in G1 during the evacuation
-   pause. These bits can have the following state transitions:
-   1. The claimed bit can be put over any other card state. Except that
-      the "dirty -> dirty and claimed" transition is checked for in
-      G1 code and is not used.
-   2. Deferred bit can be set only if the previous state of the card
-      was either clean or claimed. mark_card_deferred() is wait-free.
-      We do not care if the operation is be successful because if
-      it does not it will only result in duplicate entry in the update
-      buffer because of the "cache-miss". So it's not worth spinning.
- */
-
-
-bool CardTableModRefBS::claim_card(size_t card_index) {
-  jbyte val = _byte_map[card_index];
-  assert(val != dirty_card_val(), "Shouldn't claim a dirty card");
-  while (val == clean_card_val() ||
-         (val & (clean_card_mask_val() | claimed_card_val())) != claimed_card_val()) {
-    jbyte new_val = val;
-    if (val == clean_card_val()) {
-      new_val = (jbyte)claimed_card_val();
-    } else {
-      new_val = val | (jbyte)claimed_card_val();
-    }
-    jbyte res = Atomic::cmpxchg(new_val, &_byte_map[card_index], val);
-    if (res == val) {
-      return true;
-    }
-    val = res;
-  }
-  return false;
-}
-
-bool CardTableModRefBS::mark_card_deferred(size_t card_index) {
-  jbyte val = _byte_map[card_index];
-  // It's already processed
-  if ((val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val()) {
-    return false;
-  }
-  // Cached bit can be installed either on a clean card or on a claimed card.
-  jbyte new_val = val;
-  if (val == clean_card_val()) {
-    new_val = (jbyte)deferred_card_val();
-  } else {
-    if (val & claimed_card_val()) {
-      new_val = val | (jbyte)deferred_card_val();
-    }
-  }
-  if (new_val != val) {
-    Atomic::cmpxchg(new_val, &_byte_map[card_index], val);
-  }
-  return true;
-}
 
 void CardTableModRefBS::non_clean_card_iterate_possibly_parallel(Space* sp,
                                                                  MemRegion mr,
--- a/src/share/vm/memory/cardTableModRefBS.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/memory/cardTableModRefBS.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -349,34 +349,10 @@
     _byte_map[card_index] = dirty_card_val();
   }
 
-  bool is_card_claimed(size_t card_index) {
-    jbyte val = _byte_map[card_index];
-    return (val & (clean_card_mask_val() | claimed_card_val())) == claimed_card_val();
-  }
-
-  void set_card_claimed(size_t card_index) {
-      jbyte val = _byte_map[card_index];
-      if (val == clean_card_val()) {
-        val = (jbyte)claimed_card_val();
-      } else {
-        val |= (jbyte)claimed_card_val();
-      }
-      _byte_map[card_index] = val;
-  }
-
-  bool claim_card(size_t card_index);
-
   bool is_card_clean(size_t card_index) {
     return _byte_map[card_index] == clean_card_val();
   }
 
-  bool is_card_deferred(size_t card_index) {
-    jbyte val = _byte_map[card_index];
-    return (val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val();
-  }
-
-  bool mark_card_deferred(size_t card_index);
-
   // Card marking array base (adjusted for heap low boundary)
   // This would be the 0th element of _byte_map, if the heap started at 0x0.
   // But since the heap starts at some higher address, this points to somewhere
--- a/src/share/vm/memory/collectorPolicy.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/memory/collectorPolicy.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -233,6 +233,8 @@
       alignment = lcm(os::large_page_size(), alignment);
   }
 
+  assert(alignment >= min_alignment(), "Must be");
+
   return alignment;
 }
 
--- a/src/share/vm/memory/defNewGeneration.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/memory/defNewGeneration.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, 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
@@ -541,7 +541,7 @@
 
   GenCollectedHeap* gch = GenCollectedHeap::heap();
 
-  _gc_timer->register_gc_start(os::elapsed_counter());
+  _gc_timer->register_gc_start();
   DefNewTracer gc_tracer;
   gc_tracer.report_gc_start(gch->gc_cause(), _gc_timer->gc_start());
 
@@ -685,7 +685,7 @@
   gch->trace_heap_after_gc(&gc_tracer);
   gc_tracer.report_tenuring_threshold(tenuring_threshold());
 
-  _gc_timer->register_gc_end(os::elapsed_counter());
+  _gc_timer->register_gc_end();
 
   gc_tracer.report_gc_end(_gc_timer->gc_end(), _gc_timer->time_partitions());
 }
@@ -1007,6 +1007,9 @@
   // have to use it here, as well.
   HeapWord* result = eden()->par_allocate(word_size);
   if (result != NULL) {
+    if (CMSEdenChunksRecordAlways && _next_gen != NULL) {
+      _next_gen->sample_eden_chunk();
+    }
     return result;
   }
   do {
@@ -1037,13 +1040,19 @@
   // circular dependency at compile time.
   if (result == NULL) {
     result = allocate_from_space(word_size);
+  } else if (CMSEdenChunksRecordAlways && _next_gen != NULL) {
+    _next_gen->sample_eden_chunk();
   }
   return result;
 }
 
 HeapWord* DefNewGeneration::par_allocate(size_t word_size,
                                          bool is_tlab) {
-  return eden()->par_allocate(word_size);
+  HeapWord* res = eden()->par_allocate(word_size);
+  if (CMSEdenChunksRecordAlways && _next_gen != NULL) {
+    _next_gen->sample_eden_chunk();
+  }
+  return res;
 }
 
 void DefNewGeneration::gc_prologue(bool full) {
--- a/src/share/vm/memory/genCollectedHeap.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/memory/genCollectedHeap.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -99,17 +99,19 @@
   guarantee(HeapWordSize == wordSize, "HeapWordSize must equal wordSize");
 
   // The heap must be at least as aligned as generations.
-  size_t alignment = Generation::GenGrain;
+  size_t gen_alignment = Generation::GenGrain;
 
   _gen_specs = gen_policy()->generations();
   PermanentGenerationSpec *perm_gen_spec =
                                 collector_policy()->permanent_generation();
 
+  size_t heap_alignment = collector_policy()->max_alignment();
+
   // Make sure the sizes are all aligned.
   for (i = 0; i < _n_gens; i++) {
-    _gen_specs[i]->align(alignment);
+    _gen_specs[i]->align(gen_alignment);
   }
-  perm_gen_spec->align(alignment);
+  perm_gen_spec->align(heap_alignment);
 
   // If we are dumping the heap, then allocate a wasted block of address
   // space in order to push the heap to a lower address.  This extra
@@ -130,9 +132,9 @@
   char* heap_address;
   size_t total_reserved = 0;
   int n_covered_regions = 0;
-  ReservedSpace heap_rs(0);
+  ReservedSpace heap_rs;
 
-  heap_address = allocate(alignment, perm_gen_spec, &total_reserved,
+  heap_address = allocate(heap_alignment, perm_gen_spec, &total_reserved,
                           &n_covered_regions, &heap_rs);
 
   if (UseSharedSpaces) {
@@ -142,7 +144,7 @@
       }
       FileMapInfo* mapinfo = FileMapInfo::current_info();
       mapinfo->fail_continue("Unable to reserve shared region.");
-      allocate(alignment, perm_gen_spec, &total_reserved, &n_covered_regions,
+      allocate(heap_alignment, perm_gen_spec, &total_reserved, &n_covered_regions,
                &heap_rs);
     }
   }
@@ -207,19 +209,21 @@
   const size_t pageSize = UseLargePages ?
       os::large_page_size() : os::vm_page_size();
 
+  assert(alignment % pageSize == 0, "Must be");
+
   for (int i = 0; i < _n_gens; i++) {
     total_reserved = add_and_check_overflow(total_reserved, _gen_specs[i]->max_size());
     n_covered_regions += _gen_specs[i]->n_covered_regions();
   }
 
-  assert(total_reserved % pageSize == 0,
-         err_msg("Gen size; total_reserved=" SIZE_FORMAT ", pageSize="
-                 SIZE_FORMAT, total_reserved, pageSize));
+  assert(total_reserved % alignment == 0,
+         err_msg("Gen size; total_reserved=" SIZE_FORMAT ", alignment="
+                 SIZE_FORMAT, total_reserved, alignment));
   total_reserved = add_and_check_overflow(total_reserved, perm_gen_spec->max_size());
-  assert(total_reserved % pageSize == 0,
-         err_msg("Perm size; total_reserved=" SIZE_FORMAT ", pageSize="
+  assert(total_reserved % alignment == 0,
+         err_msg("Perm size; total_reserved=" SIZE_FORMAT ", alignment="
                  SIZE_FORMAT ", perm gen max=" SIZE_FORMAT, total_reserved,
-                 pageSize, perm_gen_spec->max_size()));
+                 alignment, perm_gen_spec->max_size()));
 
   n_covered_regions += perm_gen_spec->n_covered_regions();
 
@@ -229,7 +233,9 @@
   total_reserved = add_and_check_overflow(total_reserved, misc);
 
   if (UseLargePages) {
+    assert(misc == 0, "CDS does not support Large Pages");
     assert(total_reserved != 0, "total_reserved cannot be 0");
+    assert(is_size_aligned(total_reserved, os::large_page_size()), "Must be");
     total_reserved = round_up_and_check_overflow(total_reserved, os::large_page_size());
   }
 
@@ -250,7 +256,7 @@
   } else {
     heap_address = NULL;  // any address will do.
     if (UseCompressedOops) {
-      heap_address = Universe::preferred_heap_base(total_reserved, Universe::UnscaledNarrowOop);
+      heap_address = Universe::preferred_heap_base(total_reserved, alignment, Universe::UnscaledNarrowOop);
       *_total_reserved = total_reserved;
       *_n_covered_regions = n_covered_regions;
       *heap_rs = ReservedHeapSpace(total_reserved, alignment,
@@ -260,13 +266,13 @@
         // Failed to reserve at specified address - the requested memory
         // region is taken already, for example, by 'java' launcher.
         // Try again to reserver heap higher.
-        heap_address = Universe::preferred_heap_base(total_reserved, Universe::ZeroBasedNarrowOop);
+        heap_address = Universe::preferred_heap_base(total_reserved, alignment, Universe::ZeroBasedNarrowOop);
         *heap_rs = ReservedHeapSpace(total_reserved, alignment,
                                      UseLargePages, heap_address);
 
         if (heap_address != NULL && !heap_rs->is_reserved()) {
           // Failed to reserve at specified address again - give up.
-          heap_address = Universe::preferred_heap_base(total_reserved, Universe::HeapBasedNarrowOop);
+          heap_address = Universe::preferred_heap_base(total_reserved, alignment, Universe::HeapBasedNarrowOop);
           assert(heap_address == NULL, "");
           *heap_rs = ReservedHeapSpace(total_reserved, alignment,
                                        UseLargePages, heap_address);
@@ -538,8 +544,7 @@
             prepare_for_verify();
             prepared_for_verification = true;
           }
-          gclog_or_tty->print(" VerifyBeforeGC:");
-          Universe::verify();
+          Universe::verify(" VerifyBeforeGC:");
         }
         COMPILER2_PRESENT(DerivedPointerTable::clear());
 
@@ -610,8 +615,7 @@
         if (VerifyAfterGC && i >= VerifyGCLevel &&
             total_collections() >= VerifyGCStartAt) {
           HandleMark hm;  // Discard invalid handles created during verification
-          gclog_or_tty->print(" VerifyAfterGC:");
-          Universe::verify();
+          Universe::verify(" VerifyAfterGC:");
         }
 
         if (PrintGCDetails) {
@@ -932,12 +936,13 @@
 // Returns "TRUE" iff "p" points into the committed areas of the heap.
 bool GenCollectedHeap::is_in(const void* p) const {
   #ifndef ASSERT
-  guarantee(VerifyBeforeGC   ||
-            VerifyDuringGC   ||
-            VerifyBeforeExit ||
-            PrintAssembly    ||
-            tty->count() != 0 ||   // already printing
-            VerifyAfterGC    ||
+  guarantee(VerifyBeforeGC      ||
+            VerifyDuringGC      ||
+            VerifyBeforeExit    ||
+            VerifyDuringStartup ||
+            PrintAssembly       ||
+            tty->count() != 0   ||   // already printing
+            VerifyAfterGC       ||
     VMError::fatal_error_in_progress(), "too expensive");
 
   #endif
--- a/src/share/vm/memory/generation.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/memory/generation.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, 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
@@ -476,16 +476,16 @@
     x(ref_processor(), gch->reserved_region());
 
   STWGCTimer* gc_timer = GenMarkSweep::gc_timer();
-  gc_timer->register_gc_start(os::elapsed_counter());
+  gc_timer->register_gc_start();
 
   SerialOldTracer* gc_tracer = GenMarkSweep::gc_tracer();
   gc_tracer->report_gc_start(gch->gc_cause(), gc_timer->gc_start());
 
   GenMarkSweep::invoke_at_safepoint(_level, ref_processor(), clear_all_soft_refs);
 
-  gc_timer->register_gc_end(os::elapsed_counter());
+  gc_timer->register_gc_end();
 
-  gc_tracer->report_gc_end(os::elapsed_counter(), gc_timer->time_partitions());
+  gc_tracer->report_gc_end(gc_timer->gc_end(), gc_timer->time_partitions());
 
   SpecializationStats::print();
 }
--- a/src/share/vm/memory/generation.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/memory/generation.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -457,6 +457,7 @@
   // expected to be GC worker thread-local, with the worker index
   // indicated by "thr_num".
   virtual void* get_data_recorder(int thr_num) { return NULL; }
+  virtual void sample_eden_chunk() {}
 
   // Some generations may require some cleanup actions before allowing
   // a verification.
--- a/src/share/vm/memory/iterator.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/memory/iterator.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -70,7 +70,7 @@
 }
 
 void CodeBlobToOopClosure::do_newly_marked_nmethod(nmethod* nm) {
-  nm->oops_do(_cl, /*do_strong_roots_only=*/ true);
+  nm->oops_do(_cl, /*do_strong_roots_only=*/ true, /*allow_zombie=*/ false);
 }
 
 void CodeBlobToOopClosure::do_code_blob(CodeBlob* cb) {
--- a/src/share/vm/memory/sharedHeap.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/memory/sharedHeap.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -64,7 +64,8 @@
   }
   _sh = this;  // ch is static, should be set only once.
   if ((UseParNewGC ||
-      (UseConcMarkSweepGC && CMSParallelRemarkEnabled) ||
+      (UseConcMarkSweepGC && (CMSParallelInitialMarkEnabled ||
+                              CMSParallelRemarkEnabled)) ||
        UseG1GC) &&
       ParallelGCThreads > 0) {
     _workers = new FlexibleWorkGang("Parallel GC Threads", ParallelGCThreads,
@@ -148,7 +149,8 @@
                                       ScanningOption so,
                                       OopClosure* roots,
                                       CodeBlobClosure* code_roots,
-                                      OopsInGenClosure* perm_blk) {
+                                      OopsInGenClosure* perm_blk,
+                                      bool manages_code_roots) {
   StrongRootsScope srs(this, activate_scope);
   // General strong roots.
   assert(_strong_roots_parity != 0, "must have called prologue code");
@@ -216,7 +218,7 @@
         CodeCache::blobs_do(code_roots);
       }
     } else if (so & (SO_SystemClasses|SO_AllClasses)) {
-      if (!collecting_perm_gen) {
+      if (!manages_code_roots && !collecting_perm_gen) {
         // If we are collecting from class statics, but we are not going to
         // visit all of the CodeCache, collect from the non-perm roots if any.
         // This makes the code cache function temporarily as a source of strong
--- a/src/share/vm/memory/sharedHeap.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/memory/sharedHeap.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -267,7 +267,8 @@
                             ScanningOption so,
                             OopClosure* roots,
                             CodeBlobClosure* code_roots,
-                            OopsInGenClosure* perm_blk);
+                            OopsInGenClosure* perm_blk,
+                            bool manages_code_roots = false);
 
   // Apply "blk" to all the weak roots of the system.  These include
   // JNI weak roots, the code cache, system dictionary, symbol table,
--- a/src/share/vm/memory/universe.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/memory/universe.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -829,17 +829,23 @@
 // 32Gb
 // OopEncodingHeapMax == NarrowOopHeapMax << LogMinObjAlignmentInBytes;
 
-char* Universe::preferred_heap_base(size_t heap_size, NARROW_OOP_MODE mode) {
+char* Universe::preferred_heap_base(size_t heap_size, size_t alignment, NARROW_OOP_MODE mode) {
+  assert(is_size_aligned((size_t)OopEncodingHeapMax, alignment), "Must be");
+  assert(is_size_aligned((size_t)NarrowOopHeapMax, alignment), "Must be");
+  assert(is_size_aligned(heap_size, alignment), "Must be");
+
+  uintx heap_base_min_address_aligned = align_size_up(HeapBaseMinAddress, alignment);
+
   size_t base = 0;
 #ifdef _LP64
   if (UseCompressedOops) {
     assert(mode == UnscaledNarrowOop  ||
            mode == ZeroBasedNarrowOop ||
            mode == HeapBasedNarrowOop, "mode is invalid");
-    const size_t total_size = heap_size + HeapBaseMinAddress;
+    const size_t total_size = heap_size + heap_base_min_address_aligned;
     // Return specified base for the first request.
     if (!FLAG_IS_DEFAULT(HeapBaseMinAddress) && (mode == UnscaledNarrowOop)) {
-      base = HeapBaseMinAddress;
+      base = heap_base_min_address_aligned;
     } else if (total_size <= OopEncodingHeapMax && (mode != HeapBasedNarrowOop)) {
       if (total_size <= NarrowOopHeapMax && (mode == UnscaledNarrowOop) &&
           (Universe::narrow_oop_shift() == 0)) {
@@ -885,6 +891,8 @@
     }
   }
 #endif
+
+  assert(is_ptr_aligned((char*)base, alignment), "Must be");
   return (char*)base; // also return NULL (don't care) for 32-bit VM
 }
 
@@ -1374,7 +1382,7 @@
   st->print_cr("}");
 }
 
-void Universe::verify(bool silent, VerifyOption option) {
+void Universe::verify(VerifyOption option, const char* prefix, bool silent) {
   if (SharedSkipVerify) {
     return;
   }
@@ -1395,11 +1403,12 @@
   HandleMark hm;  // Handles created during verification can be zapped
   _verify_count++;
 
+  if (!silent) gclog_or_tty->print(prefix);
   if (!silent) gclog_or_tty->print("[Verifying ");
   if (!silent) gclog_or_tty->print("threads ");
   Threads::verify();
+  if (!silent) gclog_or_tty->print("heap ");
   heap()->verify(silent, option);
-
   if (!silent) gclog_or_tty->print("syms ");
   SymbolTable::verify();
   if (!silent) gclog_or_tty->print("strs ");
--- a/src/share/vm/memory/universe.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/memory/universe.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -380,7 +380,7 @@
 
   static NARROW_OOP_MODE narrow_oop_mode();
 
-  static char* preferred_heap_base(size_t heap_size, NARROW_OOP_MODE mode);
+  static char* preferred_heap_base(size_t heap_size, size_t alignment, NARROW_OOP_MODE mode);
 
   // Historic gc information
   static size_t get_heap_capacity_at_last_gc()         { return _heap_capacity_at_last_gc; }
@@ -419,12 +419,12 @@
 
   // Debugging
   static bool verify_in_progress() { return _verify_in_progress; }
-  static void verify(bool silent, VerifyOption option);
-  static void verify(bool silent) {
-    verify(silent, VerifyOption_Default /* option */);
+  static void verify(VerifyOption option, const char* prefix, bool silent = VerifySilently);
+  static void verify(const char* prefix, bool silent = VerifySilently) {
+    verify(VerifyOption_Default, prefix, silent);
   }
-  static void verify() {
-    verify(false /* silent */);
+  static void verify(bool silent = VerifySilently) {
+    verify("", silent);
   }
 
   static int  verify_count()       { return _verify_count; }
--- a/src/share/vm/oops/constantPoolOop.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/oops/constantPoolOop.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, 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
@@ -1026,24 +1026,13 @@
 
   case JVM_CONSTANT_InvokeDynamic:
   {
-    int k1 = invoke_dynamic_bootstrap_method_ref_index_at(index1);
-    int k2 = cp2->invoke_dynamic_bootstrap_method_ref_index_at(index2);
-    bool match = compare_entry_to(k1, cp2, k2, CHECK_false);
-    if (!match)  return false;
-    k1 = invoke_dynamic_name_and_type_ref_index_at(index1);
-    k2 = cp2->invoke_dynamic_name_and_type_ref_index_at(index2);
-    match = compare_entry_to(k1, cp2, k2, CHECK_false);
-    if (!match)  return false;
-    int argc = invoke_dynamic_argument_count_at(index1);
-    if (argc == cp2->invoke_dynamic_argument_count_at(index2)) {
-      for (int j = 0; j < argc; j++) {
-        k1 = invoke_dynamic_argument_index_at(index1, j);
-        k2 = cp2->invoke_dynamic_argument_index_at(index2, j);
-        match = compare_entry_to(k1, cp2, k2, CHECK_false);
-        if (!match)  return false;
-      }
-      return true;           // got through loop; all elements equal
-    }
+    int k1 = invoke_dynamic_name_and_type_ref_index_at(index1);
+    int k2 = cp2->invoke_dynamic_name_and_type_ref_index_at(index2);
+    int i1 = invoke_dynamic_bootstrap_specifier_index(index1);
+    int i2 = cp2->invoke_dynamic_bootstrap_specifier_index(index2);
+    bool match = compare_entry_to(k1, cp2, k2, CHECK_false) &&
+                 compare_operand_to(i1, cp2, i2, CHECK_false);
+    return match;
   } break;
 
   case JVM_CONSTANT_UnresolvedString:
@@ -1078,12 +1067,135 @@
 } // end compare_entry_to()
 
 
+// Resize the operands array with delta_len and delta_size.
+// Used in RedefineClasses for CP merge.
+void constantPoolOopDesc::resize_operands(int delta_len, int delta_size, TRAPS) {
+  int old_len  = operand_array_length(operands());
+  int new_len  = old_len + delta_len;
+  int min_len  = (delta_len > 0) ? old_len : new_len;
+
+  int old_size = operands()->length();
+  int new_size = old_size + delta_size;
+  int min_size = (delta_size > 0) ? old_size : new_size;
+
+  typeArrayHandle new_ops = oopFactory::new_permanent_intArray(new_size, CHECK);
+
+  // Set index in the resized array for existing elements only
+  for (int idx = 0; idx < min_len; idx++) {
+    int offset = operand_offset_at(idx);                         // offset in original array
+    operand_offset_at_put(new_ops(), idx, offset + 2*delta_len); // offset in resized array
+  }
+  // Copy the bootstrap specifiers only
+  Copy::conjoint_memory_atomic(operands()->short_at_addr(2*old_len),
+                               new_ops->short_at_addr(2*new_len),
+                               (min_size - 2*min_len) * sizeof(u2));
+  // Explicit deallocation of old operands array is not needed for 7u
+  set_operands(new_ops());
+} // end resize_operands()
+
+
+// Extend the operands array with the length and size of the ext_cp operands.
+// Used in RedefineClasses for CP merge.
+void constantPoolOopDesc::extend_operands(constantPoolHandle ext_cp, TRAPS) {
+  int delta_len = operand_array_length(ext_cp->operands());
+  if (delta_len == 0) {
+    return; // nothing to do
+  }
+  int delta_size = ext_cp->operands()->length();
+
+  assert(delta_len  > 0 && delta_size > 0, "extended operands array must be bigger");
+
+  if (operand_array_length(operands()) == 0) {
+    typeArrayHandle new_ops = oopFactory::new_permanent_intArray(delta_size, CHECK);
+    // The first element index defines the offset of second part
+    operand_offset_at_put(new_ops(), 0, 2*delta_len); // offset in new array
+    set_operands(new_ops());
+  } else {
+    resize_operands(delta_len, delta_size, CHECK);
+  }
+
+} // end extend_operands()
+
+
+// Shrink the operands array to a smaller array with new_len length.
+// Used in RedefineClasses for CP merge.
+void constantPoolOopDesc::shrink_operands(int new_len, TRAPS) {
+  int old_len = operand_array_length(operands());
+  if (new_len == old_len) {
+    return; // nothing to do
+  }
+  assert(new_len < old_len, "shrunken operands array must be smaller");
+
+  int free_base  = operand_next_offset_at(new_len - 1);
+  int delta_len  = new_len - old_len;
+  int delta_size = 2*delta_len + free_base - operands()->length();
+
+  resize_operands(delta_len, delta_size, CHECK);
+
+} // end shrink_operands()
+
+
+void constantPoolOopDesc::copy_operands(constantPoolHandle from_cp,
+                                        constantPoolHandle to_cp,
+                                        TRAPS) {
+
+  int from_oplen = operand_array_length(from_cp->operands());
+  int old_oplen  = operand_array_length(to_cp->operands());
+  if (from_oplen != 0) {
+    // append my operands to the target's operands array
+    if (old_oplen == 0) {
+      to_cp->set_operands(from_cp->operands());  // reuse; do not merge
+    } else {
+      int old_len  = to_cp->operands()->length();
+      int from_len = from_cp->operands()->length();
+      int old_off  = old_oplen * sizeof(u2);
+      int from_off = from_oplen * sizeof(u2);
+      typeArrayHandle new_operands = oopFactory::new_permanent_intArray(old_len + from_len, CHECK);
+      int fillp = 0, len = 0;
+      // first part of dest
+      Copy::conjoint_memory_atomic(to_cp->operands()->short_at_addr(0),
+                                   new_operands->short_at_addr(fillp),
+                                   (len = old_off) * sizeof(u2));
+      fillp += len;
+      // first part of src
+      Copy::conjoint_memory_atomic(from_cp->operands()->short_at_addr(0),
+                                   new_operands->short_at_addr(fillp),
+                                   (len = from_off) * sizeof(u2));
+      fillp += len;
+      // second part of dest
+      Copy::conjoint_memory_atomic(to_cp->operands()->short_at_addr(old_off),
+                                   new_operands->short_at_addr(fillp),
+                                   (len = old_len - old_off) * sizeof(u2));
+      fillp += len;
+      // second part of src
+      Copy::conjoint_memory_atomic(from_cp->operands()->short_at_addr(from_off),
+                                   new_operands->short_at_addr(fillp),
+                                   (len = from_len - from_off) * sizeof(u2));
+      fillp += len;
+      assert(fillp == new_operands->length(), "");
+
+      // Adjust indexes in the first part of the copied operands array.
+      for (int j = 0; j < from_oplen; j++) {
+        int offset = operand_offset_at(new_operands(), old_oplen + j);
+        assert(offset == operand_offset_at(from_cp->operands(), j), "correct copy");
+        offset += old_len;  // every new tuple is preceded by old_len extra u2's
+        operand_offset_at_put(new_operands(), old_oplen + j, offset);
+      }
+
+      // replace target operands array with combined array
+      to_cp->set_operands(new_operands());
+    }
+  }
+} // end copy_operands()
+
+
 // Copy this constant pool's entries at start_i to end_i (inclusive)
 // to the constant pool to_cp's entries starting at to_i. A total of
 // (end_i - start_i) + 1 entries are copied.
 void constantPoolOopDesc::copy_cp_to_impl(constantPoolHandle from_cp, int start_i, int end_i,
        constantPoolHandle to_cp, int to_i, TRAPS) {
 
+
   int dest_i = to_i;  // leave original alone for debug purposes
 
   for (int src_i = start_i; src_i <= end_i; /* see loop bottom */ ) {
@@ -1104,56 +1216,9 @@
       break;
     }
   }
+  copy_operands(from_cp, to_cp, CHECK);
 
-  int from_oplen = operand_array_length(from_cp->operands());
-  int old_oplen  = operand_array_length(to_cp->operands());
-  if (from_oplen != 0) {
-    // append my operands to the target's operands array
-    if (old_oplen == 0) {
-      to_cp->set_operands(from_cp->operands());  // reuse; do not merge
-    } else {
-      int old_len  = to_cp->operands()->length();
-      int from_len = from_cp->operands()->length();
-      int old_off  = old_oplen * sizeof(u2);
-      int from_off = from_oplen * sizeof(u2);
-      typeArrayHandle new_operands = oopFactory::new_permanent_shortArray(old_len + from_len, CHECK);
-      int fillp = 0, len = 0;
-      // first part of dest
-      Copy::conjoint_memory_atomic(to_cp->operands()->short_at_addr(0),
-                                   new_operands->short_at_addr(fillp),
-                                   (len = old_off) * sizeof(u2));
-      fillp += len;
-      // first part of src
-      Copy::conjoint_memory_atomic(to_cp->operands()->short_at_addr(0),
-                                   new_operands->short_at_addr(fillp),
-                                   (len = from_off) * sizeof(u2));
-      fillp += len;
-      // second part of dest
-      Copy::conjoint_memory_atomic(to_cp->operands()->short_at_addr(old_off),
-                                   new_operands->short_at_addr(fillp),
-                                   (len = old_len - old_off) * sizeof(u2));
-      fillp += len;
-      // second part of src
-      Copy::conjoint_memory_atomic(to_cp->operands()->short_at_addr(from_off),
-                                   new_operands->short_at_addr(fillp),
-                                   (len = from_len - from_off) * sizeof(u2));
-      fillp += len;
-      assert(fillp == new_operands->length(), "");
-
-      // Adjust indexes in the first part of the copied operands array.
-      for (int j = 0; j < from_oplen; j++) {
-        int offset = operand_offset_at(new_operands(), old_oplen + j);
-        assert(offset == operand_offset_at(from_cp->operands(), j), "correct copy");
-        offset += old_len;  // every new tuple is preceded by old_len extra u2's
-        operand_offset_at_put(new_operands(), old_oplen + j, offset);
-      }
-
-      // replace target operands array with combined array
-      to_cp->set_operands(new_operands());
-    }
-  }
-
-} // end copy_cp_to()
+} // end copy_cp_to_impl()
 
 
 // Copy this constant pool's entry at from_i to the constant pool
@@ -1337,6 +1402,46 @@
 } // end find_matching_entry()
 
 
+// Compare this constant pool's bootstrap specifier at idx1 to the constant pool
+// cp2's bootstrap specifier at idx2.
+bool constantPoolOopDesc::compare_operand_to(int idx1, constantPoolHandle cp2, int idx2, TRAPS) {
+  int k1 = operand_bootstrap_method_ref_index_at(idx1);
+  int k2 = cp2->operand_bootstrap_method_ref_index_at(idx2);
+  bool match = compare_entry_to(k1, cp2, k2, CHECK_false);
+
+  if (!match) {
+    return false;
+  }
+  int argc = operand_argument_count_at(idx1);
+  if (argc == cp2->operand_argument_count_at(idx2)) {
+    for (int j = 0; j < argc; j++) {
+      k1 = operand_argument_index_at(idx1, j);
+      k2 = cp2->operand_argument_index_at(idx2, j);
+      match = compare_entry_to(k1, cp2, k2, CHECK_false);
+      if (!match) {
+        return false;
+      }
+    }
+    return true;           // got through loop; all elements equal
+  }
+  return false;
+} // end compare_operand_to()
+
+// Search constant pool search_cp for a bootstrap specifier that matches
+// this constant pool's bootstrap specifier at pattern_i index.
+// Return the index of a matching bootstrap specifier or (-1) if there is no match.
+int constantPoolOopDesc::find_matching_operand(int pattern_i,
+                    constantPoolHandle search_cp, int search_len, TRAPS) {
+  for (int i = 0; i < search_len; i++) {
+    bool found = compare_operand_to(pattern_i, search_cp, i, CHECK_(-1));
+    if (found) {
+      return i;
+    }
+  }
+  return -1;  // bootstrap specifier not found; return unused index (-1)
+} // end find_matching_operand()
+
+
 #ifndef PRODUCT
 
 const char* constantPoolOopDesc::printable_name_at(int which) {
--- a/src/share/vm/oops/constantPoolOop.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/oops/constantPoolOop.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, 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
@@ -565,6 +565,47 @@
          _indy_argc_offset = 1,  // u2 argc
          _indy_argv_offset = 2   // u2 argv[argc]
   };
+
+  // These functions are used in RedefineClasses for CP merge
+
+  int operand_offset_at(int bootstrap_specifier_index) {
+    assert(0 <= bootstrap_specifier_index &&
+           bootstrap_specifier_index < operand_array_length(operands()),
+           "Corrupted CP operands");
+    return operand_offset_at(operands(), bootstrap_specifier_index);
+  }
+  int operand_bootstrap_method_ref_index_at(int bootstrap_specifier_index) {
+    int offset = operand_offset_at(bootstrap_specifier_index);
+    return operands()->short_at(offset + _indy_bsm_offset);
+  }
+  int operand_argument_count_at(int bootstrap_specifier_index) {
+    int offset = operand_offset_at(bootstrap_specifier_index);
+    int argc = operands()->short_at(offset + _indy_argc_offset);
+    return argc;
+  }
+  int operand_argument_index_at(int bootstrap_specifier_index, int j) {
+    int offset = operand_offset_at(bootstrap_specifier_index);
+    return operands()->short_at(offset + _indy_argv_offset + j);
+  }
+  int operand_next_offset_at(int bootstrap_specifier_index) {
+    int offset = operand_offset_at(bootstrap_specifier_index) + _indy_argv_offset
+                   + operand_argument_count_at(bootstrap_specifier_index);
+    return offset;
+  }
+  // Compare a bootsrap specifier in the operands arrays
+  bool compare_operand_to(int bootstrap_specifier_index1, constantPoolHandle cp2,
+                          int bootstrap_specifier_index2, TRAPS);
+  // Find a bootsrap specifier in the operands array
+  int find_matching_operand(int bootstrap_specifier_index, constantPoolHandle search_cp,
+                            int operands_cur_len, TRAPS);
+  // Resize the operands array with delta_len and delta_size
+  void resize_operands(int delta_len, int delta_size, TRAPS);
+  // Extend the operands array with the length and size of the ext_cp operands
+  void extend_operands(constantPoolHandle ext_cp, TRAPS);
+  // Shrink the operands array to a smaller array with new_len length
+  void shrink_operands(int new_len, TRAPS);
+
+
   int invoke_dynamic_bootstrap_method_ref_index_at(int which) {
     assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool");
     int op_base = invoke_dynamic_operand_base(which);
@@ -755,6 +796,7 @@
     copy_cp_to_impl(h_this, start_i, end_i, to_cp, to_i, THREAD);
   }
   static void copy_cp_to_impl(constantPoolHandle from_cp, int start_i, int end_i, constantPoolHandle to_cp, int to_i, TRAPS);
+  static void copy_operands(constantPoolHandle from_cp, constantPoolHandle to_cp, TRAPS);
   static void copy_entry_to(constantPoolHandle from_cp, int from_i, constantPoolHandle to_cp, int to_i, TRAPS);
   int  find_matching_entry(int pattern_i, constantPoolHandle search_cp, TRAPS);
   int  orig_length() const                { return _orig_length; }
--- a/src/share/vm/oops/instanceKlass.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/oops/instanceKlass.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -1910,6 +1910,17 @@
     FreeHeap(jmeths);
   }
 
+  // Deallocate MemberNameTable
+  {
+    Mutex* lock_or_null = SafepointSynchronize::is_at_safepoint() ? NULL : MemberNameTable_lock;
+    MutexLockerEx ml(lock_or_null, Mutex::_no_safepoint_check_flag);
+    MemberNameTable* mnt = member_names();
+    if (mnt != NULL) {
+      delete mnt;
+      set_member_names(NULL);
+    }
+  }
+
   int* indices = methods_cached_itable_indices_acquire();
   if (indices != (int*)NULL) {
     release_set_methods_cached_itable_indices(NULL);
@@ -2342,6 +2353,30 @@
   return NULL;
 }
 
+void instanceKlass::add_member_name(int index, Handle mem_name) {
+  jweak mem_name_wref = JNIHandles::make_weak_global(mem_name);
+  MutexLocker ml(MemberNameTable_lock);
+  assert(0 <= index && index < idnum_allocated_count(), "index is out of bounds");
+  DEBUG_ONLY(No_Safepoint_Verifier nsv);
+
+  if (_member_names == NULL) {
+    _member_names = new (ResourceObj::C_HEAP, mtClass) MemberNameTable(idnum_allocated_count());
+  }
+  _member_names->add_member_name(index, mem_name_wref);
+}
+
+oop instanceKlass::get_member_name(int index) {
+  MutexLocker ml(MemberNameTable_lock);
+  assert(0 <= index && index < idnum_allocated_count(), "index is out of bounds");
+  DEBUG_ONLY(No_Safepoint_Verifier nsv);
+
+  if (_member_names == NULL) {
+    return NULL;
+  }
+  oop mem_name =_member_names->get_member_name(index);
+  return mem_name;
+}
+
 // -----------------------------------------------------------------------------------------------------
 #ifndef PRODUCT
 
--- a/src/share/vm/oops/instanceKlass.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/oops/instanceKlass.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -94,6 +94,7 @@
 class nmethodBucket;
 class PreviousVersionNode;
 class JvmtiCachedClassFieldMap;
+class MemberNameTable;
 
 // This is used in iterators below.
 class FieldClosure: public StackObj {
@@ -265,6 +266,7 @@
   int             _vtable_len;           // length of Java vtable (in words)
   int             _itable_len;           // length of Java itable (in words)
   OopMapCache*    volatile _oop_map_cache;   // OopMapCache for all methods in the klass (allocated lazily)
+  MemberNameTable* _member_names;        // Member names
   JNIid*          _jni_ids;              // First JNI identifier for static fields in this class
   jmethodID*      _methods_jmethod_ids;  // jmethodIDs corresponding to method_idnum, or NULL if none
   int*            _methods_cached_itable_indices;  // itable_index cache for JNI invoke corresponding to methods idnum, or NULL
@@ -972,6 +974,12 @@
   // jvm support
   jint compute_modifier_flags(TRAPS) const;
 
+  // JSR-292 support
+  MemberNameTable* member_names() { return _member_names; }
+  void set_member_names(MemberNameTable* member_names) { _member_names = member_names; }
+  void add_member_name(int index, Handle member_name);
+  oop  get_member_name(int index);
+
 public:
   // JVMTI support
   jint jvmti_class_status() const;
--- a/src/share/vm/oops/objArrayKlass.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/oops/objArrayKlass.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -149,7 +149,7 @@
         if (element_is_null ||
             Klass::cast((new_val->klass()))->is_subtype_of(bound)) {
           bs->write_ref_field_pre(p, new_val);
-          *p = *from;
+          *p = element;
         } else {
           // We must do a barrier to cover the partial copy.
           const size_t pd = pointer_delta(p, dst, (size_t)heapOopSize);
--- a/src/share/vm/opto/compile.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/opto/compile.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -853,6 +853,7 @@
   }
 #endif
 
+  NOT_PRODUCT( verify_barriers(); )
   // Now that we know the size of all the monitors we can add a fixed slot
   // for the original deopt pc.
 
@@ -3276,6 +3277,72 @@
     }
   }
 }
+
+// Verify GC barriers consistency
+// Currently supported:
+// - G1 pre-barriers (see GraphKit::g1_write_barrier_pre())
+void Compile::verify_barriers() {
+  if (UseG1GC) {
+    // Verify G1 pre-barriers
+    const int marking_offset = in_bytes(JavaThread::satb_mark_queue_offset() + PtrQueue::byte_offset_of_active());
+
+    ResourceArea *area = Thread::current()->resource_area();
+    Unique_Node_List visited(area);
+    Node_List worklist(area);
+    // We're going to walk control flow backwards starting from the Root
+    worklist.push(_root);
+    while (worklist.size() > 0) {
+      Node* x = worklist.pop();
+      if (x == NULL || x == top()) continue;
+      if (visited.member(x)) {
+        continue;
+      } else {
+        visited.push(x);
+      }
+
+      if (x->is_Region()) {
+        for (uint i = 1; i < x->req(); i++) {
+          worklist.push(x->in(i));
+        }
+      } else {
+        worklist.push(x->in(0));
+        // We are looking for the pattern:
+        //                            /->ThreadLocal
+        // If->Bool->CmpI->LoadB->AddP->ConL(marking_offset)
+        //              \->ConI(0)
+        // We want to verify that the If and the LoadB have the same control
+        // See GraphKit::g1_write_barrier_pre()
+        if (x->is_If()) {
+          IfNode *iff = x->as_If();
+          if (iff->in(1)->is_Bool() && iff->in(1)->in(1)->is_Cmp()) {
+            CmpNode *cmp = iff->in(1)->in(1)->as_Cmp();
+            if (cmp->Opcode() == Op_CmpI && cmp->in(2)->is_Con() && cmp->in(2)->bottom_type()->is_int()->get_con() == 0
+                && cmp->in(1)->is_Load()) {
+              LoadNode* load = cmp->in(1)->as_Load();
+              if (load->Opcode() == Op_LoadB && load->in(2)->is_AddP() && load->in(2)->in(2)->Opcode() == Op_ThreadLocal
+                  && load->in(2)->in(3)->is_Con()
+                  && load->in(2)->in(3)->bottom_type()->is_intptr_t()->get_con() == marking_offset) {
+
+                Node* if_ctrl = iff->in(0);
+                Node* load_ctrl = load->in(0);
+
+                if (if_ctrl != load_ctrl) {
+                  // Skip possible CProj->NeverBranch in infinite loops
+                  if ((if_ctrl->is_Proj() && if_ctrl->Opcode() == Op_CProj)
+                      && (if_ctrl->in(0)->is_MultiBranch() && if_ctrl->in(0)->Opcode() == Op_NeverBranch)) {
+                    if_ctrl = if_ctrl->in(0)->in(0);
+                  }
+                }
+                assert(load_ctrl != NULL && if_ctrl == load_ctrl, "controls must match");
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
 #endif
 
 // The Compile object keeps track of failure reasons separately from the ciEnv.
--- a/src/share/vm/opto/compile.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/opto/compile.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -42,6 +42,7 @@
 #include "runtime/deoptimization.hpp"
 #include "runtime/vmThread.hpp"
 #include "trace/tracing.hpp"
+#include "utilities/ticks.hpp"
 
 class Block;
 class Bundle;
@@ -559,20 +560,19 @@
   bool              has_method_handle_invokes() const { return _has_method_handle_invokes;     }
   void          set_has_method_handle_invokes(bool z) {        _has_method_handle_invokes = z; }
 
-  jlong _latest_stage_start_counter;
+  Ticks _latest_stage_start_counter;
 
   void begin_method() {
 #ifndef PRODUCT
     if (_printer) _printer->begin_method(this);
 #endif
-    C->_latest_stage_start_counter = os::elapsed_counter();
+    C->_latest_stage_start_counter.stamp();
   }
 
   void print_method(CompilerPhaseType cpt, int level = 1) {
-    EventCompilerPhase event(UNTIMED);
+    EventCompilerPhase event;
     if (event.should_commit()) {
       event.set_starttime(C->_latest_stage_start_counter);
-      event.set_endtime(os::elapsed_counter());
       event.set_phase((u1) cpt);
       event.set_compileID(C->_compile_id);
       event.set_phaseLevel(level);
@@ -583,14 +583,13 @@
 #ifndef PRODUCT
     if (_printer) _printer->print_method(this, CompilerPhaseTypeHelper::to_string(cpt), level);
 #endif
-    C->_latest_stage_start_counter = os::elapsed_counter();
+    C->_latest_stage_start_counter.stamp();
   }
 
   void end_method(int level = 1) {
-    EventCompilerPhase event(UNTIMED);
+    EventCompilerPhase event;
     if (event.should_commit()) {
       event.set_starttime(C->_latest_stage_start_counter);
-      event.set_endtime(os::elapsed_counter());
       event.set_phase((u1) PHASE_END);
       event.set_compileID(C->_compile_id);
       event.set_phaseLevel(level);
@@ -1104,6 +1103,9 @@
   // Print bytecodes, including the scope inlining tree
   void print_codes();
 
+  // Verify GC barrier patterns
+  void verify_barriers() PRODUCT_RETURN;
+
   // End-of-run dumps.
   static void print_statistics() PRODUCT_RETURN;
 
--- a/src/share/vm/opto/graphKit.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/opto/graphKit.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -3600,7 +3600,7 @@
   Node* marking = __ load(__ ctrl(), marking_adr, TypeInt::INT, active_type, Compile::AliasIdxRaw);
 
   // if (!marking)
-  __ if_then(marking, BoolTest::ne, zero); {
+  __ if_then(marking, BoolTest::ne, zero, unlikely); {
     BasicType index_bt = TypeX_X->basic_type();
     assert(sizeof(size_t) == type2aelembytes(index_bt), "Loading G1 PtrQueue::_index with wrong size.");
     Node* index   = __ load(__ ctrl(), index_adr, TypeX_X, index_bt, Compile::AliasIdxRaw);
@@ -3705,7 +3705,8 @@
   Node* no_base = __ top();
   float likely  = PROB_LIKELY(0.999);
   float unlikely  = PROB_UNLIKELY(0.999);
-  Node* zero = __ ConI(0);
+  Node* young_card = __ ConI((jint)G1SATBCardTableModRefBS::g1_young_card_val());
+  Node* dirty_card = __ ConI((jint)CardTableModRefBS::dirty_card_val());
   Node* zeroX = __ ConX(0);
 
   // Get the alias_index for raw card-mark memory
@@ -3761,8 +3762,16 @@
         // load the original value of the card
         Node* card_val = __ load(__ ctrl(), card_adr, TypeInt::INT, T_BYTE, Compile::AliasIdxRaw);
 
-        __ if_then(card_val, BoolTest::ne, zero); {
-          g1_mark_card(ideal, card_adr, oop_store, alias_idx, index, index_adr, buffer, tf);
+        __ if_then(card_val, BoolTest::ne, young_card); {
+          sync_kit(ideal);
+          // Use Op_MemBarVolatile to achieve the effect of a StoreLoad barrier.
+          insert_mem_bar(Op_MemBarVolatile, oop_store);
+          __ sync_kit(this);
+
+          Node* card_val_reload = __ load(__ ctrl(), card_adr, TypeInt::INT, T_BYTE, Compile::AliasIdxRaw);
+          __ if_then(card_val_reload, BoolTest::ne, dirty_card); {
+            g1_mark_card(ideal, card_adr, oop_store, alias_idx, index, index_adr, buffer, tf);
+          } __ end_if();
         } __ end_if();
       } __ end_if();
     } __ end_if();
--- a/src/share/vm/opto/loopTransform.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/opto/loopTransform.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1954,7 +1954,7 @@
       // Find loads off the surviving projection; remove their control edge
       for (DUIterator_Fast imax, i = dp->fast_outs(imax); i < imax; i++) {
         Node* cd = dp->fast_out(i); // Control-dependent node
-        if( cd->is_Load() ) {   // Loads can now float around in the loop
+        if (cd->is_Load() && cd->depends_only_on_test()) {   // Loads can now float around in the loop
           // Allow the load to float around in the loop, or before it
           // but NOT before the pre-loop.
           _igvn.replace_input_of(cd, 0, ctrl); // ctrl, not NULL
--- a/src/share/vm/opto/matcher.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/opto/matcher.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -467,17 +467,17 @@
   C->FIRST_STACK_mask().Clear();
 
   // Add in the incoming argument area
-  OptoReg::Name init = OptoReg::add(_old_SP, C->out_preserve_stack_slots());
-  for (i = init; i < _in_arg_limit; i = OptoReg::add(i,1))
+  OptoReg::Name init_in = OptoReg::add(_old_SP, C->out_preserve_stack_slots());
+  for (i = init_in; i < _in_arg_limit; i = OptoReg::add(i,1)) {
     C->FIRST_STACK_mask().Insert(i);
-
+  }
   // Add in all bits past the outgoing argument area
   guarantee(RegMask::can_represent_arg(OptoReg::add(_out_arg_limit,-1)),
             "must be able to represent all call arguments in reg mask");
-  init = _out_arg_limit;
-  for (i = init; RegMask::can_represent(i); i = OptoReg::add(i,1))
+  OptoReg::Name init = _out_arg_limit;
+  for (i = init; RegMask::can_represent(i); i = OptoReg::add(i,1)) {
     C->FIRST_STACK_mask().Insert(i);
-
+  }
   // Finally, set the "infinite stack" bit.
   C->FIRST_STACK_mask().set_AllStack();
 
@@ -509,16 +509,36 @@
      idealreg2spillmask[Op_VecS]->OR(C->FIRST_STACK_mask());
   }
   if (Matcher::vector_size_supported(T_FLOAT,2)) {
+    // For VecD we need dual alignment and 8 bytes (2 slots) for spills.
+    // RA guarantees such alignment since it is needed for Double and Long values.
     *idealreg2spillmask[Op_VecD] = *idealreg2regmask[Op_VecD];
      idealreg2spillmask[Op_VecD]->OR(aligned_stack_mask);
   }
   if (Matcher::vector_size_supported(T_FLOAT,4)) {
+    // For VecX we need quadro alignment and 16 bytes (4 slots) for spills.
+    //
+    // RA can use input arguments stack slots for spills but until RA
+    // we don't know frame size and offset of input arg stack slots.
+    //
+    // Exclude last input arg stack slots to avoid spilling vectors there
+    // otherwise vector spills could stomp over stack slots in caller frame.
+    OptoReg::Name in = OptoReg::add(_in_arg_limit, -1);
+    for (int k = 1; (in >= init_in) && (k < RegMask::SlotsPerVecX); k++) {
+      aligned_stack_mask.Remove(in);
+      in = OptoReg::add(in, -1);
+    }
      aligned_stack_mask.clear_to_sets(RegMask::SlotsPerVecX);
      assert(aligned_stack_mask.is_AllStack(), "should be infinite stack");
     *idealreg2spillmask[Op_VecX] = *idealreg2regmask[Op_VecX];
      idealreg2spillmask[Op_VecX]->OR(aligned_stack_mask);
   }
   if (Matcher::vector_size_supported(T_FLOAT,8)) {
+    // For VecY we need octo alignment and 32 bytes (8 slots) for spills.
+    OptoReg::Name in = OptoReg::add(_in_arg_limit, -1);
+    for (int k = 1; (in >= init_in) && (k < RegMask::SlotsPerVecY); k++) {
+      aligned_stack_mask.Remove(in);
+      in = OptoReg::add(in, -1);
+    }
      aligned_stack_mask.clear_to_sets(RegMask::SlotsPerVecY);
      assert(aligned_stack_mask.is_AllStack(), "should be infinite stack");
     *idealreg2spillmask[Op_VecY] = *idealreg2regmask[Op_VecY];
--- a/src/share/vm/opto/memnode.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/opto/memnode.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1957,6 +1957,11 @@
       if (t != NULL) {
         // constant oop => constant klass
         if (offset == java_lang_Class::array_klass_offset_in_bytes()) {
+          if (t->is_void()) {
+            // We cannot create a void array.  Since void is a primitive type return null
+            // klass.  Users of this result need to do a null check on the returned klass.
+            return TypePtr::NULL_PTR;
+          }
           return TypeKlassPtr::make(ciArrayKlass::make(t));
         }
         if (!t->is_klass()) {
--- a/src/share/vm/opto/memnode.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/opto/memnode.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -219,6 +219,17 @@
 protected:
   const Type* load_array_final_field(const TypeKlassPtr *tkls,
                                      ciKlass* klass) const;
+  // depends_only_on_test is almost always true, and needs to be almost always
+  // true to enable key hoisting & commoning optimizations.  However, for the
+  // special case of RawPtr loads from TLS top & end, and other loads performed by
+  // GC barriers, the control edge carries the dependence preventing hoisting past
+  // a Safepoint instead of the memory edge.  (An unfortunate consequence of having
+  // Safepoints not set Raw Memory; itself an unfortunate consequence of having Nodes
+  // which produce results (new raw memory state) inside of loops preventing all
+  // manner of other optimizations).  Basically, it's ugly but so is the alternative.
+  // See comment in macro.cpp, around line 125 expand_allocate_common().
+  virtual bool depends_only_on_test() const { return adr_type() != TypeRawPtr::BOTTOM; }
+
 };
 
 //------------------------------LoadBNode--------------------------------------
@@ -383,16 +394,6 @@
   virtual uint ideal_reg() const { return Op_RegP; }
   virtual int store_Opcode() const { return Op_StoreP; }
   virtual BasicType memory_type() const { return T_ADDRESS; }
-  // depends_only_on_test is almost always true, and needs to be almost always
-  // true to enable key hoisting & commoning optimizations.  However, for the
-  // special case of RawPtr loads from TLS top & end, the control edge carries
-  // the dependence preventing hoisting past a Safepoint instead of the memory
-  // edge.  (An unfortunate consequence of having Safepoints not set Raw
-  // Memory; itself an unfortunate consequence of having Nodes which produce
-  // results (new raw memory state) inside of loops preventing all manner of
-  // other optimizations).  Basically, it's ugly but so is the alternative.
-  // See comment in macro.cpp, around line 125 expand_allocate_common().
-  virtual bool depends_only_on_test() const { return adr_type() != TypeRawPtr::BOTTOM; }
 };
 
 
@@ -406,16 +407,6 @@
   virtual uint ideal_reg() const { return Op_RegN; }
   virtual int store_Opcode() const { return Op_StoreN; }
   virtual BasicType memory_type() const { return T_NARROWOOP; }
-  // depends_only_on_test is almost always true, and needs to be almost always
-  // true to enable key hoisting & commoning optimizations.  However, for the
-  // special case of RawPtr loads from TLS top & end, the control edge carries
-  // the dependence preventing hoisting past a Safepoint instead of the memory
-  // edge.  (An unfortunate consequence of having Safepoints not set Raw
-  // Memory; itself an unfortunate consequence of having Nodes which produce
-  // results (new raw memory state) inside of loops preventing all manner of
-  // other optimizations).  Basically, it's ugly but so is the alternative.
-  // See comment in macro.cpp, around line 125 expand_allocate_common().
-  virtual bool depends_only_on_test() const { return adr_type() != TypeRawPtr::BOTTOM; }
 };
 
 //------------------------------LoadKlassNode----------------------------------
--- a/src/share/vm/opto/output.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/opto/output.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -345,6 +345,11 @@
   uint*      jmp_offset = NEW_RESOURCE_ARRAY(uint,nblocks);
   uint*      jmp_size   = NEW_RESOURCE_ARRAY(uint,nblocks);
   int*       jmp_nidx   = NEW_RESOURCE_ARRAY(int ,nblocks);
+
+  // Collect worst case block paddings
+  int* block_worst_case_pad = NEW_RESOURCE_ARRAY(int, nblocks);
+  memset(block_worst_case_pad, 0, nblocks * sizeof(int));
+
   DEBUG_ONLY( uint *jmp_target = NEW_RESOURCE_ARRAY(uint,nblocks); )
   DEBUG_ONLY( uint *jmp_rule = NEW_RESOURCE_ARRAY(uint,nblocks); )
 
@@ -461,6 +466,7 @@
           last_avoid_back_to_back_adr += max_loop_pad;
         }
         blk_size += max_loop_pad;
+        block_worst_case_pad[i + 1] = max_loop_pad;
       }
     }
 
@@ -500,9 +506,16 @@
         if (bnum > i) { // adjust following block's offset
           offset -= adjust_block_start;
         }
+
+        // This block can be a loop header, account for the padding
+        // in the previous block.
+        int block_padding = block_worst_case_pad[i];
+        assert(i == 0 || block_padding == 0 || br_offs >= block_padding, "Should have at least a padding on top");
         // In the following code a nop could be inserted before
         // the branch which will increase the backward distance.
-        bool needs_padding = ((uint)br_offs == last_may_be_short_branch_adr);
+        bool needs_padding = ((uint)(br_offs - block_padding) == last_may_be_short_branch_adr);
+        assert(!needs_padding || jmp_offset[i] == 0, "padding only branches at the beginning of block");
+
         if (needs_padding && offset <= 0)
           offset -= nop_size;
 
--- a/src/share/vm/prims/jni.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/prims/jni.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -5046,14 +5046,22 @@
   tty->print_cr("Running test: " #unit_test_function_call); \
   unit_test_function_call
 
+// Forward declaration
+void TestReservedSpace_test();
+void TestReserveMemorySpecial_test();
+void TestOldFreeSpaceCalculation_test();
+
 void execute_internal_vm_tests() {
   if (ExecuteInternalVMTests) {
     tty->print_cr("Running internal VM tests");
+    run_unit_test(TestReservedSpace_test());
+    run_unit_test(TestReserveMemorySpecial_test());
     run_unit_test(GCTimerAllTest::all());
     run_unit_test(arrayOopDesc::test_max_array_length());
     run_unit_test(CollectedHeap::test_is_in());
     run_unit_test(QuickSort::test_quick_sort());
     run_unit_test(AltHashing::test_alt_hash());
+    run_unit_test(TestOldFreeSpaceCalculation_test());
     tty->print_cr("All internal VM tests passed");
   }
 }
--- a/src/share/vm/prims/jvmtiClassFileReconstituter.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/prims/jvmtiClassFileReconstituter.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -204,7 +204,7 @@
 
   write_attribute_name_index("Code");
   write_u4(size);
-  write_u2(method->max_stack());
+  write_u2(method->verifier_max_stack());
   write_u2(method->max_locals());
   write_u4(code_size);
   copy_bytecodes(method, (unsigned char*)writeable_address(code_size));
--- a/src/share/vm/prims/jvmtiRedefineClasses.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, 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
@@ -35,6 +35,7 @@
 #include "prims/jvmtiImpl.hpp"
 #include "prims/jvmtiRedefineClasses.hpp"
 #include "prims/methodComparator.hpp"
+#include "prims/methodHandles.hpp"
 #include "runtime/deoptimization.hpp"
 #include "runtime/relocator.hpp"
 #include "utilities/bitMap.inline.hpp"
@@ -262,76 +263,23 @@
     case JVM_CONSTANT_NameAndType:
     {
       int name_ref_i = scratch_cp->name_ref_index_at(scratch_i);
-      int new_name_ref_i = 0;
-      bool match = (name_ref_i < *merge_cp_length_p) &&
-        scratch_cp->compare_entry_to(name_ref_i, *merge_cp_p, name_ref_i,
-          THREAD);
-      if (!match) {
-        // forward reference in *merge_cp_p or not a direct match
-
-        int found_i = scratch_cp->find_matching_entry(name_ref_i, *merge_cp_p,
-          THREAD);
-        if (found_i != 0) {
-          guarantee(found_i != name_ref_i,
-            "compare_entry_to() and find_matching_entry() do not agree");
-
-          // Found a matching entry somewhere else in *merge_cp_p so
-          // just need a mapping entry.
-          new_name_ref_i = found_i;
-          map_index(scratch_cp, name_ref_i, found_i);
-        } else {
-          // no match found so we have to append this entry to *merge_cp_p
-          append_entry(scratch_cp, name_ref_i, merge_cp_p, merge_cp_length_p,
-            THREAD);
-          // The above call to append_entry() can only append one entry
-          // so the post call query of *merge_cp_length_p is only for
-          // the sake of consistency.
-          new_name_ref_i = *merge_cp_length_p - 1;
-        }
-      }
+      int new_name_ref_i = find_or_append_indirect_entry(scratch_cp, name_ref_i, merge_cp_p,
+                                                         merge_cp_length_p, THREAD);
 
       int signature_ref_i = scratch_cp->signature_ref_index_at(scratch_i);
-      int new_signature_ref_i = 0;
-      match = (signature_ref_i < *merge_cp_length_p) &&
-        scratch_cp->compare_entry_to(signature_ref_i, *merge_cp_p,
-          signature_ref_i, THREAD);
-      if (!match) {
-        // forward reference in *merge_cp_p or not a direct match
-
-        int found_i = scratch_cp->find_matching_entry(signature_ref_i,
-          *merge_cp_p, THREAD);
-        if (found_i != 0) {
-          guarantee(found_i != signature_ref_i,
-            "compare_entry_to() and find_matching_entry() do not agree");
-
-          // Found a matching entry somewhere else in *merge_cp_p so
-          // just need a mapping entry.
-          new_signature_ref_i = found_i;
-          map_index(scratch_cp, signature_ref_i, found_i);
-        } else {
-          // no match found so we have to append this entry to *merge_cp_p
-          append_entry(scratch_cp, signature_ref_i, merge_cp_p,
-            merge_cp_length_p, THREAD);
-          // The above call to append_entry() can only append one entry
-          // so the post call query of *merge_cp_length_p is only for
-          // the sake of consistency.
-          new_signature_ref_i = *merge_cp_length_p - 1;
-        }
-      }
+      int new_signature_ref_i = find_or_append_indirect_entry(scratch_cp, signature_ref_i,
+                                                              merge_cp_p, merge_cp_length_p,
+                                                              THREAD);
 
       // If the referenced entries already exist in *merge_cp_p, then
       // both new_name_ref_i and new_signature_ref_i will both be 0.
       // In that case, all we are appending is the current entry.
-      if (new_name_ref_i == 0) {
-        new_name_ref_i = name_ref_i;
-      } else {
+      if (new_name_ref_i != name_ref_i) {
         RC_TRACE(0x00080000,
           ("NameAndType entry@%d name_ref_index change: %d to %d",
           *merge_cp_length_p, name_ref_i, new_name_ref_i));
       }
-      if (new_signature_ref_i == 0) {
-        new_signature_ref_i = signature_ref_i;
-      } else {
+      if (new_signature_ref_i != signature_ref_i) {
         RC_TRACE(0x00080000,
           ("NameAndType entry@%d signature_ref_index change: %d to %d",
           *merge_cp_length_p, signature_ref_i, new_signature_ref_i));
@@ -353,76 +301,11 @@
     case JVM_CONSTANT_Methodref:
     {
       int klass_ref_i = scratch_cp->uncached_klass_ref_index_at(scratch_i);
-      int new_klass_ref_i = 0;
-      bool match = (klass_ref_i < *merge_cp_length_p) &&
-        scratch_cp->compare_entry_to(klass_ref_i, *merge_cp_p, klass_ref_i,
-          THREAD);
-      if (!match) {
-        // forward reference in *merge_cp_p or not a direct match
-
-        int found_i = scratch_cp->find_matching_entry(klass_ref_i, *merge_cp_p,
-          THREAD);
-        if (found_i != 0) {
-          guarantee(found_i != klass_ref_i,
-            "compare_entry_to() and find_matching_entry() do not agree");
-
-          // Found a matching entry somewhere else in *merge_cp_p so
-          // just need a mapping entry.
-          new_klass_ref_i = found_i;
-          map_index(scratch_cp, klass_ref_i, found_i);
-        } else {
-          // no match found so we have to append this entry to *merge_cp_p
-          append_entry(scratch_cp, klass_ref_i, merge_cp_p, merge_cp_length_p,
-            THREAD);
-          // The above call to append_entry() can only append one entry
-          // so the post call query of *merge_cp_length_p is only for
-          // the sake of consistency. Without the optimization where we
-          // use JVM_CONSTANT_UnresolvedClass, then up to two entries
-          // could be appended.
-          new_klass_ref_i = *merge_cp_length_p - 1;
-        }
-      }
-
-      int name_and_type_ref_i =
-        scratch_cp->uncached_name_and_type_ref_index_at(scratch_i);
-      int new_name_and_type_ref_i = 0;
-      match = (name_and_type_ref_i < *merge_cp_length_p) &&
-        scratch_cp->compare_entry_to(name_and_type_ref_i, *merge_cp_p,
-          name_and_type_ref_i, THREAD);
-      if (!match) {
-        // forward reference in *merge_cp_p or not a direct match
-
-        int found_i = scratch_cp->find_matching_entry(name_and_type_ref_i,
-          *merge_cp_p, THREAD);
-        if (found_i != 0) {
-          guarantee(found_i != name_and_type_ref_i,
-            "compare_entry_to() and find_matching_entry() do not agree");
-
-          // Found a matching entry somewhere else in *merge_cp_p so
-          // just need a mapping entry.
-          new_name_and_type_ref_i = found_i;
-          map_index(scratch_cp, name_and_type_ref_i, found_i);
-        } else {
-          // no match found so we have to append this entry to *merge_cp_p
-          append_entry(scratch_cp, name_and_type_ref_i, merge_cp_p,
-            merge_cp_length_p, THREAD);
-          // The above call to append_entry() can append more than
-          // one entry so the post call query of *merge_cp_length_p
-          // is required in order to get the right index for the
-          // JVM_CONSTANT_NameAndType entry.
-          new_name_and_type_ref_i = *merge_cp_length_p - 1;
-        }
-      }
-
-      // If the referenced entries already exist in *merge_cp_p, then
-      // both new_klass_ref_i and new_name_and_type_ref_i will both be
-      // 0. In that case, all we are appending is the current entry.
-      if (new_klass_ref_i == 0) {
-        new_klass_ref_i = klass_ref_i;
-      }
-      if (new_name_and_type_ref_i == 0) {
-        new_name_and_type_ref_i = name_and_type_ref_i;
-      }
+      int new_klass_ref_i = find_or_append_indirect_entry(scratch_cp, klass_ref_i,
+                                                          merge_cp_p, merge_cp_length_p, THREAD);
+      int name_and_type_ref_i = scratch_cp->uncached_name_and_type_ref_index_at(scratch_i);
+      int new_name_and_type_ref_i = find_or_append_indirect_entry(scratch_cp, name_and_type_ref_i,
+                                                          merge_cp_p, merge_cp_length_p, THREAD);
 
       const char *entry_name;
       switch (scratch_cp->tag_at(scratch_i).value()) {
@@ -465,7 +348,79 @@
       (*merge_cp_length_p)++;
     } break;
 
-    // At this stage, Class or UnresolvedClass could be here, but not
+    // this is an indirect CP entry so it needs special handling
+    case JVM_CONSTANT_MethodType:
+    {
+      int ref_i = scratch_cp->method_type_index_at(scratch_i);
+      int new_ref_i = find_or_append_indirect_entry(scratch_cp, ref_i, merge_cp_p,
+                                                    merge_cp_length_p, THREAD);
+      if (new_ref_i != ref_i) {
+        RC_TRACE(0x00080000,
+                 ("MethodType entry@%d ref_index change: %d to %d",
+                  *merge_cp_length_p, ref_i, new_ref_i));
+      }
+      (*merge_cp_p)->method_type_index_at_put(*merge_cp_length_p, new_ref_i);
+      if (scratch_i != *merge_cp_length_p) {
+        // The new entry in *merge_cp_p is at a different index than
+        // the new entry in scratch_cp so we need to map the index values.
+        map_index(scratch_cp, scratch_i, *merge_cp_length_p);
+      }
+      (*merge_cp_length_p)++;
+    } break;
+
+    // this is an indirect CP entry so it needs special handling
+    case JVM_CONSTANT_MethodHandle:
+    {
+      int ref_kind = scratch_cp->method_handle_ref_kind_at(scratch_i);
+      int ref_i = scratch_cp->method_handle_index_at(scratch_i);
+      int new_ref_i = find_or_append_indirect_entry(scratch_cp, ref_i, merge_cp_p,
+                                                    merge_cp_length_p, THREAD);
+      if (new_ref_i != ref_i) {
+        RC_TRACE(0x00080000,
+                 ("MethodHandle entry@%d ref_index change: %d to %d",
+                  *merge_cp_length_p, ref_i, new_ref_i));
+      }
+      (*merge_cp_p)->method_handle_index_at_put(*merge_cp_length_p, ref_kind, new_ref_i);
+      if (scratch_i != *merge_cp_length_p) {
+        // The new entry in *merge_cp_p is at a different index than
+        // the new entry in scratch_cp so we need to map the index values.
+        map_index(scratch_cp, scratch_i, *merge_cp_length_p);
+      }
+      (*merge_cp_length_p)++;
+    } break;
+
+    // this is an indirect CP entry so it needs special handling
+    case JVM_CONSTANT_InvokeDynamic:
+    {
+      // Index of the bootstrap specifier in the operands array
+      int old_bs_i = scratch_cp->invoke_dynamic_bootstrap_specifier_index(scratch_i);
+      int new_bs_i = find_or_append_operand(scratch_cp, old_bs_i, merge_cp_p,
+                                                    merge_cp_length_p, THREAD);
+      // The bootstrap method NameAndType_info index
+      int old_ref_i = scratch_cp->invoke_dynamic_name_and_type_ref_index_at(scratch_i);
+      int new_ref_i = find_or_append_indirect_entry(scratch_cp, old_ref_i, merge_cp_p,
+                                                    merge_cp_length_p, THREAD);
+      if (new_bs_i != old_bs_i) {
+        RC_TRACE(0x00080000,
+                 ("InvokeDynamic entry@%d bootstrap_method_attr_index change: %d to %d",
+                  *merge_cp_length_p, old_bs_i, new_bs_i));
+      }
+      if (new_ref_i != old_ref_i) {
+        RC_TRACE(0x00080000,
+                 ("InvokeDynamic entry@%d name_and_type_index change: %d to %d",
+                  *merge_cp_length_p, old_ref_i, new_ref_i));
+      }
+
+      (*merge_cp_p)->invoke_dynamic_at_put(*merge_cp_length_p, new_bs_i, new_ref_i);
+      if (scratch_i != *merge_cp_length_p) {
+        // The new entry in *merge_cp_p is at a different index than
+        // the new entry in scratch_cp so we need to map the index values.
+        map_index(scratch_cp, scratch_i, *merge_cp_length_p);
+      }
+      (*merge_cp_length_p)++;
+    } break;
+
+   // At this stage, Class or UnresolvedClass could be here, but not
     // ClassIndex
     case JVM_CONSTANT_ClassIndex: // fall through
 
@@ -492,6 +447,134 @@
 } // end append_entry()
 
 
+int VM_RedefineClasses::find_or_append_indirect_entry(constantPoolHandle scratch_cp,
+      int ref_i, constantPoolHandle *merge_cp_p, int *merge_cp_length_p, TRAPS) {
+
+  int new_ref_i = ref_i;
+  bool match = (ref_i < *merge_cp_length_p) &&
+               scratch_cp->compare_entry_to(ref_i, *merge_cp_p, ref_i, THREAD);
+
+  if (!match) {
+    // forward reference in *merge_cp_p or not a direct match
+    int found_i = scratch_cp->find_matching_entry(ref_i, *merge_cp_p, THREAD);
+    if (found_i != 0) {
+      guarantee(found_i != ref_i, "compare_entry_to() and find_matching_entry() do not agree");
+      // Found a matching entry somewhere else in *merge_cp_p so just need a mapping entry.
+      new_ref_i = found_i;
+      map_index(scratch_cp, ref_i, found_i);
+    } else {
+      // no match found so we have to append this entry to *merge_cp_p
+      append_entry(scratch_cp, ref_i, merge_cp_p, merge_cp_length_p, THREAD);
+      // The above call to append_entry() can only append one entry
+      // so the post call query of *merge_cp_length_p is only for
+      // the sake of consistency.
+      new_ref_i = *merge_cp_length_p - 1;
+    }
+  }
+
+  return new_ref_i;
+} // end find_or_append_indirect_entry()
+
+
+// Append a bootstrap specifier into the merge_cp operands that is semantically equal
+// to the scratch_cp operands bootstrap specifier passed by the old_bs_i index.
+// Recursively append new merge_cp entries referenced by the new bootstrap specifier.
+void VM_RedefineClasses::append_operand(constantPoolHandle scratch_cp, int old_bs_i,
+       constantPoolHandle *merge_cp_p, int *merge_cp_length_p, TRAPS) {
+
+  int old_ref_i = scratch_cp->operand_bootstrap_method_ref_index_at(old_bs_i);
+  int new_ref_i = find_or_append_indirect_entry(scratch_cp, old_ref_i, merge_cp_p,
+                                                merge_cp_length_p, THREAD);
+  if (new_ref_i != old_ref_i) {
+    RC_TRACE(0x00080000,
+             ("operands entry@%d bootstrap method ref_index change: %d to %d",
+              _operands_cur_length, old_ref_i, new_ref_i));
+  }
+
+  typeArrayOop merge_ops = (*merge_cp_p)->operands();
+  int new_bs_i = _operands_cur_length;
+  // We have _operands_cur_length == 0 when the merge_cp operands is empty yet.
+  // However, the operand_offset_at(0) was set in the extend_operands() call.
+  int new_base = (new_bs_i == 0) ? (*merge_cp_p)->operand_offset_at(0)
+                                 : (*merge_cp_p)->operand_next_offset_at(new_bs_i - 1);
+  int argc     = scratch_cp->operand_argument_count_at(old_bs_i);
+
+  constantPoolOopDesc::operand_offset_at_put(merge_ops, _operands_cur_length, new_base);
+  merge_ops->short_at_put(new_base++, new_ref_i);
+  merge_ops->short_at_put(new_base++, argc);
+
+  for (int i = 0; i < argc; i++) {
+    int old_arg_ref_i = scratch_cp->operand_argument_index_at(old_bs_i, i);
+    int new_arg_ref_i = find_or_append_indirect_entry(scratch_cp, old_arg_ref_i, merge_cp_p,
+                                                      merge_cp_length_p, THREAD);
+    merge_ops->short_at_put(new_base++, new_arg_ref_i);
+    if (new_arg_ref_i != old_arg_ref_i) {
+      RC_TRACE(0x00080000,
+               ("operands entry@%d bootstrap method argument ref_index change: %d to %d",
+                _operands_cur_length, old_arg_ref_i, new_arg_ref_i));
+    }
+  }
+  if (old_bs_i != _operands_cur_length) {
+    // The bootstrap specifier in *merge_cp_p is at a different index than
+    // that in scratch_cp so we need to map the index values.
+    map_operand_index(old_bs_i, new_bs_i);
+  }
+  _operands_cur_length++;
+} // end append_operand()
+
+
+int VM_RedefineClasses::find_or_append_operand(constantPoolHandle scratch_cp,
+      int old_bs_i, constantPoolHandle *merge_cp_p, int *merge_cp_length_p, TRAPS) {
+
+  int new_bs_i = old_bs_i; // bootstrap specifier index
+  bool match = (old_bs_i < _operands_cur_length) &&
+               scratch_cp->compare_operand_to(old_bs_i, *merge_cp_p, old_bs_i, THREAD);
+
+  if (!match) {
+    // forward reference in *merge_cp_p or not a direct match
+    int found_i = scratch_cp->find_matching_operand(old_bs_i, *merge_cp_p,
+                                                    _operands_cur_length, THREAD);
+    if (found_i != -1) {
+      guarantee(found_i != old_bs_i, "compare_operand_to() and find_matching_operand() disagree");
+      // found a matching operand somewhere else in *merge_cp_p so just need a mapping
+      new_bs_i = found_i;
+      map_operand_index(old_bs_i, found_i);
+    } else {
+      // no match found so we have to append this bootstrap specifier to *merge_cp_p
+      append_operand(scratch_cp, old_bs_i, merge_cp_p, merge_cp_length_p, THREAD);
+      new_bs_i = _operands_cur_length - 1;
+    }
+  }
+  return new_bs_i;
+} // end find_or_append_operand()
+
+
+void VM_RedefineClasses::finalize_operands_merge(constantPoolHandle merge_cp, TRAPS) {
+  if (merge_cp->operands() == NULL) {
+    return;
+  }
+  // Shrink the merge_cp operands
+  merge_cp->shrink_operands(_operands_cur_length, CHECK);
+
+  if (RC_TRACE_ENABLED(0x00040000)) {
+    // don't want to loop unless we are tracing
+    int count = 0;
+    for (int i = 1; i < _operands_index_map_p->length(); i++) {
+      int value = _operands_index_map_p->at(i);
+      if (value != -1) {
+        RC_TRACE_WITH_THREAD(0x00040000, THREAD,
+          ("operands_index_map[%d]: old=%d new=%d", count, i, value));
+        count++;
+      }
+    }
+  }
+  // Clean-up
+  _operands_index_map_p = NULL;
+  _operands_cur_length = 0;
+  _operands_index_map_count = 0;
+} // end finalize_operands_merge()
+
+
 void VM_RedefineClasses::swap_all_method_annotations(int i, int j, instanceKlassHandle scratch_class) {
   typeArrayOop save;
 
@@ -777,6 +860,27 @@
 } // end find_new_index()
 
 
+// Find new bootstrap specifier index value for old bootstrap specifier index
+// value by seaching the index map. Returns zero (-1) if there is no mapped
+// value for the old bootstrap specifier index.
+int VM_RedefineClasses::find_new_operand_index(int old_index) {
+  if (_operands_index_map_count == 0) {
+    // map is empty so nothing can be found
+    return -1;
+  }
+
+  if (old_index == -1 || old_index >= _operands_index_map_p->length()) {
+    // The old_index is out of range so it is not mapped.
+    // This should not happen in regular constant pool merging use.
+    return -1;
+  }
+
+  int value = _operands_index_map_p->at(old_index);
+
+  return value;
+} // end find_new_operand_index()
+
+
 // Returns true if the current mismatch is due to a resolved/unresolved
 // class pair. Otherwise, returns false.
 bool VM_RedefineClasses::is_unresolved_class_mismatch(constantPoolHandle cp1,
@@ -1042,6 +1146,25 @@
 } // end map_index()
 
 
+// Map old_index to new_index as needed.
+void VM_RedefineClasses::map_operand_index(int old_index, int new_index) {
+  if (find_new_operand_index(old_index) != -1) {
+    // old_index is already mapped
+    return;
+  }
+
+  if (old_index == new_index) {
+    // no mapping is needed
+    return;
+  }
+
+  _operands_index_map_p->at_put(old_index, new_index);
+  _operands_index_map_count++;
+
+  RC_TRACE(0x00040000, ("mapped bootstrap specifier at index %d to %d", old_index, new_index));
+} // end map_index()
+
+
 // Merge old_cp and scratch_cp and return the results of the merge via
 // merge_cp_p. The number of entries in *merge_cp_p is returned via
 // merge_cp_length_p. The entries in old_cp occupy the same locations
@@ -1113,6 +1236,9 @@
       }
     } // end for each old_cp entry
 
+    constantPoolOopDesc::copy_operands(old_cp, *merge_cp_p, CHECK_0);
+    (*merge_cp_p)->extend_operands(scratch_cp, CHECK_0);
+
     // We don't need to sanity check that *merge_cp_length_p is within
     // *merge_cp_p bounds since we have the minimum on-entry check above.
     (*merge_cp_length_p) = old_i;
@@ -1235,6 +1361,7 @@
       ("after pass 1b: merge_cp_len=%d, scratch_i=%d, index_map_len=%d",
       *merge_cp_length_p, scratch_i, _index_map_count));
   }
+  finalize_operands_merge(*merge_cp_p, THREAD);
 
   return true;
 } // end merge_constant_pools()
@@ -1282,8 +1409,17 @@
   _index_map_count = 0;
   _index_map_p = new intArray(scratch_cp->length(), -1);
 
+  _operands_cur_length = constantPoolOopDesc::operand_array_length(old_cp->operands());
+  _operands_index_map_count = 0;
+  _operands_index_map_p = new intArray(
+    constantPoolOopDesc::operand_array_length(scratch_cp->operands()), -1);
+
+  // reference to the cp holder is needed for copy_operands()
+  merge_cp->set_pool_holder(scratch_class());
   bool result = merge_constant_pools(old_cp, scratch_cp, &merge_cp,
                   &merge_cp_length, THREAD);
+  merge_cp->set_pool_holder(NULL);
+
   if (!result) {
     // The merge can fail due to memory allocation failure or due
     // to robustness checks.
@@ -1326,7 +1462,7 @@
       // Replace the new constant pool with a shrunken copy of the
       // merged constant pool; the previous new constant pool will
       // get GCed.
-      set_new_constant_pool(scratch_class, merge_cp, merge_cp_length, true,
+      set_new_constant_pool(scratch_class, merge_cp, merge_cp_length,
         THREAD);
       // drop local ref to the merged constant pool
       merge_cp()->set_is_conc_safe(true);
@@ -1357,7 +1493,7 @@
     // merged constant pool so now the rewritten bytecodes have
     // valid references; the previous new constant pool will get
     // GCed.
-    set_new_constant_pool(scratch_class, merge_cp, merge_cp_length, true,
+    set_new_constant_pool(scratch_class, merge_cp, merge_cp_length,
       THREAD);
     merge_cp()->set_is_conc_safe(true);
   }
@@ -1540,6 +1676,7 @@
       case Bytecodes::_getfield       : // fall through
       case Bytecodes::_getstatic      : // fall through
       case Bytecodes::_instanceof     : // fall through
+      case Bytecodes::_invokedynamic  : // fall through
       case Bytecodes::_invokeinterface: // fall through
       case Bytecodes::_invokespecial  : // fall through
       case Bytecodes::_invokestatic   : // fall through
@@ -2343,30 +2480,30 @@
 // smaller constant pool is associated with scratch_class.
 void VM_RedefineClasses::set_new_constant_pool(
        instanceKlassHandle scratch_class, constantPoolHandle scratch_cp,
-       int scratch_cp_length, bool shrink, TRAPS) {
-  assert(!shrink || scratch_cp->length() >= scratch_cp_length, "sanity check");
-
-  if (shrink) {
-    // scratch_cp is a merged constant pool and has enough space for a
-    // worst case merge situation. We want to associate the minimum
-    // sized constant pool with the klass to save space.
-    constantPoolHandle smaller_cp(THREAD,
-      oopFactory::new_constantPool(scratch_cp_length,
-                                   oopDesc::IsUnsafeConc,
-                                   THREAD));
-    // preserve orig_length() value in the smaller copy
-    int orig_length = scratch_cp->orig_length();
-    assert(orig_length != 0, "sanity check");
-    smaller_cp->set_orig_length(orig_length);
-    scratch_cp->copy_cp_to(1, scratch_cp_length - 1, smaller_cp, 1, THREAD);
-    scratch_cp = smaller_cp;
-    smaller_cp()->set_is_conc_safe(true);
-  }
+       int scratch_cp_length, TRAPS) {
+  assert(scratch_cp->length() >= scratch_cp_length, "sanity check");
+
+  // scratch_cp is a merged constant pool and has enough space for a
+  // worst case merge situation. We want to associate the minimum
+  // sized constant pool with the klass to save space.
+  constantPoolHandle smaller_cp(THREAD,
+    oopFactory::new_constantPool(scratch_cp_length,
+                                 oopDesc::IsUnsafeConc,
+                                 THREAD));
+  // preserve orig_length() value in the smaller copy
+  int orig_length = scratch_cp->orig_length();
+  assert(orig_length != 0, "sanity check");
+  smaller_cp->set_orig_length(orig_length);
+
+  // attach klass to new constant pool
+  // reference to the cp holder is needed for copy_operands()
+  smaller_cp->set_pool_holder(scratch_class());
+
+  scratch_cp->copy_cp_to(1, scratch_cp_length - 1, smaller_cp, 1, THREAD);
+  scratch_cp = smaller_cp;
+  smaller_cp()->set_is_conc_safe(true);
 
   // attach new constant pool to klass
-  scratch_cp->set_pool_holder(scratch_class());
-
-  // attach klass to new constant pool
   scratch_class->set_constants(scratch_cp());
 
   int i;  // for portability
@@ -3310,6 +3447,16 @@
   // that reference methods of the evolved class.
   SystemDictionary::classes_do(adjust_cpool_cache_and_vtable, THREAD);
 
+  // JSR-292 support
+  MemberNameTable* mnt = the_class->member_names();
+  if (mnt != NULL) {
+    bool trace_name_printed = false;
+    mnt->adjust_method_entries(_matching_old_methods,
+                               _matching_new_methods,
+                               _matching_methods_length,
+                               &trace_name_printed);
+  }
+
   if (the_class->oop_map_cache() != NULL) {
     // Flush references to any obsolete methods from the oop map cache
     // so that obsolete methods are not pinned.
--- a/src/share/vm/prims/jvmtiRedefineClasses.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/prims/jvmtiRedefineClasses.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -370,6 +370,13 @@
   // _index_map_p contains any entries.
   int                         _index_map_count;
   intArray *                  _index_map_p;
+
+  // _operands_index_map_count is just an optimization for knowing if
+  // _operands_index_map_p contains any entries.
+  int                         _operands_cur_length;
+  int                         _operands_index_map_count;
+  intArray *                  _operands_index_map_p;
+
   // ptr to _class_count scratch_classes
   instanceKlassHandle *       _scratch_classes;
   jvmtiError                  _res;
@@ -431,16 +438,24 @@
   // and in all direct and indirect subclasses.
   void increment_class_counter(instanceKlass *ik, TRAPS);
 
-  // Support for constant pool merging (these routines are in alpha
-  // order):
+  // Support for constant pool merging (these routines are in alpha order):
   void append_entry(constantPoolHandle scratch_cp, int scratch_i,
     constantPoolHandle *merge_cp_p, int *merge_cp_length_p, TRAPS);
+  void append_operand(constantPoolHandle scratch_cp, int scratch_bootstrap_spec_index,
+    constantPoolHandle *merge_cp_p, int *merge_cp_length_p, TRAPS);
+  void finalize_operands_merge(constantPoolHandle merge_cp, TRAPS);
+  int find_or_append_indirect_entry(constantPoolHandle scratch_cp, int scratch_i,
+    constantPoolHandle *merge_cp_p, int *merge_cp_length_p, TRAPS);
+  int find_or_append_operand(constantPoolHandle scratch_cp, int scratch_bootstrap_spec_index,
+    constantPoolHandle *merge_cp_p, int *merge_cp_length_p, TRAPS);
   int find_new_index(int old_index);
+  int find_new_operand_index(int old_bootstrap_spec_index);
   bool is_unresolved_class_mismatch(constantPoolHandle cp1, int index1,
     constantPoolHandle cp2, int index2);
   bool is_unresolved_string_mismatch(constantPoolHandle cp1, int index1,
     constantPoolHandle cp2, int index2);
   void map_index(constantPoolHandle scratch_cp, int old_index, int new_index);
+  void map_operand_index(int old_bootstrap_spec_index, int new_bootstrap_spec_index);
   bool merge_constant_pools(constantPoolHandle old_cp,
     constantPoolHandle scratch_cp, constantPoolHandle *merge_cp_p,
     int *merge_cp_length_p, TRAPS);
@@ -474,7 +489,7 @@
          address& stackmap_addr_ref, address stackmap_end, u2 frame_i,
          u1 frame_size, TRAPS);
   void set_new_constant_pool(instanceKlassHandle scratch_class,
-    constantPoolHandle scratch_cp, int scratch_cp_length, bool shrink, TRAPS);
+    constantPoolHandle scratch_cp, int scratch_cp_length, TRAPS);
 
   void flush_dependent_code(instanceKlassHandle k_h, TRAPS);
 
--- a/src/share/vm/prims/methodHandles.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/prims/methodHandles.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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,6 +29,7 @@
 #include "interpreter/oopMapCache.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/oopFactory.hpp"
+#include "prims/jvmtiRedefineClassesTrace.hpp"
 #include "prims/methodHandles.hpp"
 #include "runtime/compilationPolicy.hpp"
 #include "runtime/javaCalls.hpp"
@@ -123,7 +124,9 @@
   return Handle(THREAD, k->allocate_instance(THREAD));
 }
 
-oop MethodHandles::init_MemberName(oop mname_oop, oop target_oop) {
+oop MethodHandles::init_MemberName(Handle mname, Handle target) {
+  Thread* thread = Thread::current();
+  oop target_oop = target();
   klassOop target_klass = target_oop->klass();
   if (target_klass == SystemDictionary::reflect_Field_klass()) {
     oop clazz = java_lang_reflect_Field::clazz(target_oop); // fd.field_holder()
@@ -131,24 +134,24 @@
     int mods  = java_lang_reflect_Field::modifiers(target_oop);
     oop type  = java_lang_reflect_Field::type(target_oop);
     oop name  = java_lang_reflect_Field::name(target_oop);
-    klassOop k = java_lang_Class::as_klassOop(clazz);
-    intptr_t offset = instanceKlass::cast(k)->field_offset(slot);
-    return init_field_MemberName(mname_oop, k, accessFlags_from(mods), type, name, offset);
+    KlassHandle k(thread, java_lang_Class::as_klassOop(clazz));
+    intptr_t offset = instanceKlass::cast(k())->field_offset(slot);
+    return init_field_MemberName(mname, k, accessFlags_from(mods), type, name, offset);
   } else if (target_klass == SystemDictionary::reflect_Method_klass()) {
     oop clazz  = java_lang_reflect_Method::clazz(target_oop);
     int slot   = java_lang_reflect_Method::slot(target_oop);
-    klassOop k = java_lang_Class::as_klassOop(clazz);
-    if (k != NULL && Klass::cast(k)->oop_is_instance()) {
-      methodOop m = instanceKlass::cast(k)->method_with_idnum(slot);
-      return init_method_MemberName(mname_oop, m, true, k);
+    KlassHandle k(thread, java_lang_Class::as_klassOop(clazz));
+    if (!k.is_null() && k->oop_is_instance()) {
+      methodOop m = instanceKlass::cast(k())->method_with_idnum(slot);
+      return init_method_MemberName(mname, m, true, k);
     }
   } else if (target_klass == SystemDictionary::reflect_Constructor_klass()) {
     oop clazz  = java_lang_reflect_Constructor::clazz(target_oop);
     int slot   = java_lang_reflect_Constructor::slot(target_oop);
-    klassOop k = java_lang_Class::as_klassOop(clazz);
-    if (k != NULL && Klass::cast(k)->oop_is_instance()) {
-      methodOop m = instanceKlass::cast(k)->method_with_idnum(slot);
-      return init_method_MemberName(mname_oop, m, false, k);
+    KlassHandle k(thread, java_lang_Class::as_klassOop(clazz));
+    if (!k.is_null() && k->oop_is_instance()) {
+      methodOop m = instanceKlass::cast(k())->method_with_idnum(slot);
+      return init_method_MemberName(mname, m, false, k);
     }
   } else if (target_klass == SystemDictionary::MemberName_klass()) {
     // Note: This only works if the MemberName has already been resolved.
@@ -156,17 +159,18 @@
     int flags        = java_lang_invoke_MemberName::flags(target_oop);
     oop vmtarget     = java_lang_invoke_MemberName::vmtarget(target_oop);
     intptr_t vmindex = java_lang_invoke_MemberName::vmindex(target_oop);
-    klassOop k       = java_lang_Class::as_klassOop(clazz);
+    KlassHandle k(thread, java_lang_Class::as_klassOop(clazz));
     int ref_kind     = (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK;
     if (vmtarget == NULL)  return NULL;  // not resolved
     if ((flags & IS_FIELD) != 0) {
       assert(vmtarget->is_klass(), "field vmtarget is klassOop");
       int basic_mods = (ref_kind_is_static(ref_kind) ? JVM_ACC_STATIC : 0);
       // FIXME:  how does k (receiver_limit) contribute?
-      return init_field_MemberName(mname_oop, klassOop(vmtarget), accessFlags_from(basic_mods), NULL, NULL, vmindex);
+      KlassHandle k_vmtarget(thread, klassOop(vmtarget));
+      return init_field_MemberName(mname, k_vmtarget, accessFlags_from(basic_mods), NULL, NULL, vmindex);
     } else if ((flags & (IS_METHOD | IS_CONSTRUCTOR)) != 0) {
       assert(vmtarget->is_method(), "method or constructor vmtarget is methodOop");
-      return init_method_MemberName(mname_oop, methodOop(vmtarget), ref_kind_does_dispatch(ref_kind), k);
+      return init_method_MemberName(mname, methodOop(vmtarget), ref_kind_does_dispatch(ref_kind), k);
     } else {
       return NULL;
     }
@@ -174,8 +178,9 @@
   return NULL;
 }
 
-oop MethodHandles::init_method_MemberName(oop mname_oop, methodOop m, bool do_dispatch,
-                                          klassOop resolved_klass) {
+oop MethodHandles::init_method_MemberName(Handle mname, methodOop m, bool do_dispatch,
+                                          KlassHandle resolved_klass_h) {
+  klassOop resolved_klass = resolved_klass_h();
   AccessFlags mods = m->access_flags();
   int flags = (jushort)( mods.as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS );
   int vmindex = methodOopDesc::nonvirtual_vtable_index; // implies never any dispatch
@@ -235,6 +240,7 @@
     }
   }
 
+  oop mname_oop = mname();
   java_lang_invoke_MemberName::set_flags(mname_oop,    flags);
   java_lang_invoke_MemberName::set_vmtarget(mname_oop, m);
   java_lang_invoke_MemberName::set_vmindex(mname_oop,  vmindex);   // vtable/itable index
@@ -246,11 +252,12 @@
   // If relevant, the vtable or itable value is stored as vmindex.
   // This is done eagerly, since it is readily available without
   // constructing any new objects.
-  // TO DO: maybe intern mname_oop
-  return mname_oop;
+  instanceKlass::cast(m->method_holder())->add_member_name(m->method_idnum(), mname);
+
+  return mname();
 }
 
-Handle MethodHandles::init_method_MemberName(oop mname_oop, CallInfo& info, TRAPS) {
+Handle MethodHandles::init_method_MemberName(Handle mname, CallInfo& info, TRAPS) {
   Handle empty;
   if (info.resolved_appendix().not_null()) {
     // The resolved MemberName must not be accompanied by an appendix argument,
@@ -270,23 +277,24 @@
   } else {
     vmindex = info.vtable_index();
   }
-  oop res = init_method_MemberName(mname_oop, m(), (vmindex >= 0), defc());
+  oop res = init_method_MemberName(mname, m(), (vmindex >= 0), defc());
   assert(res == NULL || (java_lang_invoke_MemberName::vmindex(res) == vmindex), "");
   return Handle(THREAD, res);
 }
 
-oop MethodHandles::init_field_MemberName(oop mname_oop, klassOop field_holder,
+oop MethodHandles::init_field_MemberName(Handle mname, KlassHandle field_holder,
                                          AccessFlags mods, oop type, oop name,
                                          intptr_t offset, bool is_setter) {
   int flags = (jushort)( mods.as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS );
   flags |= IS_FIELD | ((mods.is_static() ? JVM_REF_getStatic : JVM_REF_getField) << REFERENCE_KIND_SHIFT);
   if (is_setter)  flags += ((JVM_REF_putField - JVM_REF_getField) << REFERENCE_KIND_SHIFT);
-  oop vmtarget = field_holder;
+  oop vmtarget = field_holder();
   int vmindex  = offset;  // determines the field uniquely when combined with static bit
+  oop mname_oop = mname();
   java_lang_invoke_MemberName::set_flags(mname_oop,    flags);
   java_lang_invoke_MemberName::set_vmtarget(mname_oop, vmtarget);
   java_lang_invoke_MemberName::set_vmindex(mname_oop,  vmindex);
-  java_lang_invoke_MemberName::set_clazz(mname_oop,    Klass::cast(field_holder)->java_mirror());
+  java_lang_invoke_MemberName::set_clazz(mname_oop,    field_holder()->java_mirror());
   if (name != NULL)
     java_lang_invoke_MemberName::set_name(mname_oop,   name);
   if (type != NULL)
@@ -298,11 +306,10 @@
   // because they unambiguously identify the field.
   // Although the fieldDescriptor::_index would also identify the field,
   // we do not use it, because it is harder to decode.
-  // TO DO: maybe intern mname_oop
-  return mname_oop;
+  return mname();
 }
 
-Handle MethodHandles::init_field_MemberName(oop mname_oop, FieldAccessInfo& info, TRAPS) {
+Handle MethodHandles::init_field_MemberName(Handle mname, FieldAccessInfo& info, TRAPS) {
   return Handle();
 #if 0
   KlassHandle field_holder = info.klass();
@@ -728,7 +735,7 @@
           return empty;
         }
       }
-      return init_method_MemberName(mname(), result, THREAD);
+      return init_method_MemberName(mname, result, THREAD);
     }
   case IS_CONSTRUCTOR:
     {
@@ -746,7 +753,7 @@
         }
       }
       assert(result.is_statically_bound(), "");
-      return init_method_MemberName(mname(), result, THREAD);
+      return init_method_MemberName(mname, result, THREAD);
     }
   case IS_FIELD:
     {
@@ -759,7 +766,7 @@
       oop name = field_name_or_null(fd.name());
       bool is_setter = (ref_kind_is_valid(ref_kind) && ref_kind_is_setter(ref_kind));
       mname = Handle(THREAD,
-                     init_field_MemberName(mname(), sel_klass->as_klassOop(),
+                     init_field_MemberName(mname, sel_klass,
                                            fd.access_flags(), type, name, fd.offset(), is_setter));
       return mname;
     }
@@ -851,16 +858,16 @@
   THROW_MSG(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format");
 }
 
-int MethodHandles::find_MemberNames(klassOop k,
+int MethodHandles::find_MemberNames(KlassHandle k,
                                     Symbol* name, Symbol* sig,
-                                    int mflags, klassOop caller,
-                                    int skip, objArrayOop results) {
-  DEBUG_ONLY(No_Safepoint_Verifier nsv);
-  // this code contains no safepoints!
+                                    int mflags, KlassHandle caller,
+                                    int skip, objArrayHandle results) {
 
   // %%% take caller into account!
 
-  if (k == NULL || !Klass::cast(k)->oop_is_instance())  return -1;
+  Thread* thread = Thread::current();
+
+  if (k.is_null() || !k->oop_is_instance())  return -1;
 
   int rfill = 0, rlimit = results->length(), rskip = skip;
   // overflow measurement:
@@ -888,7 +895,7 @@
   }
 
   if ((match_flags & IS_FIELD) != 0) {
-    for (FieldStream st(k, local_only, !search_intfc); !st.eos(); st.next()) {
+    for (FieldStream st(k(), local_only, !search_intfc); !st.eos(); st.next()) {
       if (name != NULL && st.name() != name)
           continue;
       if (sig != NULL && st.signature() != sig)
@@ -897,15 +904,15 @@
       if (rskip > 0) {
         --rskip;
       } else if (rfill < rlimit) {
-        oop result = results->obj_at(rfill++);
-        if (!java_lang_invoke_MemberName::is_instance(result))
+        Handle result(thread, results->obj_at(rfill++));
+        if (!java_lang_invoke_MemberName::is_instance(result()))
           return -99;  // caller bug!
         oop type = field_signature_type_or_null(st.signature());
         oop name = field_name_or_null(st.name());
-        oop saved = MethodHandles::init_field_MemberName(result, st.klass()->as_klassOop(),
+        oop saved = MethodHandles::init_field_MemberName(result, st.klass(),
                                                          st.access_flags(), type, name,
                                                          st.offset());
-        if (saved != result)
+        if (saved != result())
           results->obj_at_put(rfill-1, saved);  // show saved instance to user
       } else if (++overflow >= overflow_limit) {
         match_flags = 0; break; // got tired of looking at overflow
@@ -938,7 +945,7 @@
     } else {
       // caller will accept either sort; no need to adjust name
     }
-    for (MethodStream st(k, local_only, !search_intfc); !st.eos(); st.next()) {
+    for (MethodStream st(k(), local_only, !search_intfc); !st.eos(); st.next()) {
       methodOop m = st.method();
       Symbol* m_name = m->name();
       if (m_name == clinit_name)
@@ -951,11 +958,11 @@
       if (rskip > 0) {
         --rskip;
       } else if (rfill < rlimit) {
-        oop result = results->obj_at(rfill++);
-        if (!java_lang_invoke_MemberName::is_instance(result))
+        Handle result(thread, results->obj_at(rfill++));
+        if (!java_lang_invoke_MemberName::is_instance(result()))
           return -99;  // caller bug!
-        oop saved = MethodHandles::init_method_MemberName(result, m, true, NULL);
-        if (saved != result)
+        oop saved = MethodHandles::init_method_MemberName(result, m, true, KlassHandle());
+        if (saved != result())
           results->obj_at_put(rfill-1, saved);  // show saved instance to user
       } else if (++overflow >= overflow_limit) {
         match_flags = 0; break; // got tired of looking at overflow
@@ -967,6 +974,85 @@
   return rfill + overflow;
 }
 
+//------------------------------------------------------------------------------
+// MemberNameTable
+//
+
+MemberNameTable::MemberNameTable(int methods_cnt)
+                  : GrowableArray<jweak>(methods_cnt, true) {
+  assert_locked_or_safepoint(MemberNameTable_lock);
+}
+
+MemberNameTable::~MemberNameTable() {
+  assert_locked_or_safepoint(MemberNameTable_lock);
+  int len = this->length();
+
+  for (int idx = 0; idx < len; idx++) {
+    jweak ref = this->at(idx);
+    JNIHandles::destroy_weak_global(ref);
+  }
+}
+
+void MemberNameTable::add_member_name(int index, jweak mem_name_wref) {
+  assert_locked_or_safepoint(MemberNameTable_lock);
+  this->at_put_grow(index, mem_name_wref);
+}
+
+// Return a member name oop or NULL.
+oop MemberNameTable::get_member_name(int index) {
+  assert_locked_or_safepoint(MemberNameTable_lock);
+  jweak ref = this->at(index);
+  oop mem_name = JNIHandles::resolve(ref);
+  return mem_name;
+}
+
+oop MemberNameTable::find_member_name_by_method(methodOop old_method) {
+  assert_locked_or_safepoint(MemberNameTable_lock);
+  oop found = NULL;
+  int len = this->length();
+
+  for (int idx = 0; idx < len; idx++) {
+    oop mem_name = JNIHandles::resolve(this->at(idx));
+    if (mem_name == NULL) {
+      continue;
+    }
+    methodOop method = (methodOop)java_lang_invoke_MemberName::vmtarget(mem_name);
+    if (method == old_method) {
+      found = mem_name;
+      break;
+    }
+  }
+  return found;
+}
+
+// It is called at safepoint only
+void MemberNameTable::adjust_method_entries(methodOop* old_methods, methodOop* new_methods,
+                                            int methods_length, bool *trace_name_printed) {
+  assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint");
+  // search the MemberNameTable for uses of either obsolete or EMCP methods
+  for (int j = 0; j < methods_length; j++) {
+    methodOop old_method = old_methods[j];
+    methodOop new_method = new_methods[j];
+    oop mem_name = find_member_name_by_method(old_method);
+    if (mem_name != NULL) {
+      java_lang_invoke_MemberName::adjust_vmtarget(mem_name, 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",
+                         Klass::cast(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()));
+      }
+    }
+  }
+}
+
 //
 // Here are the native methods in java.lang.invoke.MethodHandleNatives
 // They are the private interface between this JVM and the HotSpot-specific
@@ -1058,8 +1144,8 @@
   if (mname_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "mname is null"); }
   if (target_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "target is null"); }
   Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
-  oop target_oop = JNIHandles::resolve_non_null(target_jh);
-  MethodHandles::init_MemberName(mname(), target_oop);
+  Handle target(THREAD, JNIHandles::resolve_non_null(target_jh));
+  MethodHandles::init_MemberName(mname, target);
 }
 JVM_END
 
@@ -1174,11 +1260,12 @@
   } else if (vmtarget->is_klass()) {
     x = Klass::cast((klassOop) vmtarget())->java_mirror();
   } else {
-    Handle mname2 = MethodHandles::new_MemberName(CHECK_NULL);
-    if (vmtarget->is_method())
-      x = MethodHandles::init_method_MemberName(mname2(), methodOop(vmtarget()), false, NULL);
-    else
+    if (vmtarget->is_method()) {
+      x = mname();
+    } else {
+      Handle mname2 = MethodHandles::new_MemberName(CHECK_NULL);
       x = MethodHandles::init_MemberName(mname2(), vmtarget());
+    }
   }
   result->obj_at_put(1, x);
   return JNIHandles::make_local(env, result());
@@ -1221,8 +1308,8 @@
     // %%% TO DO
   }
 
-  int res = MethodHandles::find_MemberNames(k(), name, sig, mflags,
-                                            caller(), skip, results());
+  int res = MethodHandles::find_MemberNames(k, name, sig, mflags,
+                                            caller, skip, results);
   // TO DO: expand at least some of the MemberNames, to avoid massive callbacks
   return res;
 }
--- a/src/share/vm/prims/methodHandles.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/prims/methodHandles.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -39,7 +39,6 @@
   // in java.lang.invoke and sun.invoke.
   // See also  javaClasses for layouts java_lang_invoke_Method{Handle,Type,Type::Form}.
  public:
- public:
   static bool enabled()                         { return _enabled; }
   static void set_enabled(bool z);
 
@@ -54,18 +53,18 @@
   static Handle resolve_MemberName(Handle mname, KlassHandle caller, TRAPS); // compute vmtarget/vmindex from name/type
   static void expand_MemberName(Handle mname, int suppress, TRAPS);  // expand defc/name/type if missing
   static Handle new_MemberName(TRAPS);  // must be followed by init_MemberName
-  static oop init_MemberName(oop mname_oop, oop target_oop); // compute vmtarget/vmindex from target
-  static oop init_method_MemberName(oop mname_oop, methodOop m, bool do_dispatch,
-                                    klassOop resolved_klass);
-  static oop init_field_MemberName(oop mname_oop, klassOop field_holder,
+  static oop init_MemberName(Handle mname_h, Handle target_h); // compute vmtarget/vmindex from target
+  static oop init_method_MemberName(Handle mname_h, methodOop m, bool do_dispatch,
+                                    KlassHandle resolved_klass_h);
+  static oop init_field_MemberName(Handle mname_h, KlassHandle field_holder_h,
                                    AccessFlags mods, oop type, oop name,
                                    intptr_t offset, bool is_setter = false);
-  static Handle init_method_MemberName(oop mname_oop, CallInfo& info, TRAPS);
-  static Handle init_field_MemberName(oop mname_oop, FieldAccessInfo& info, TRAPS);
+  static Handle init_method_MemberName(Handle mname_h, CallInfo& info, TRAPS);
+  static Handle init_field_MemberName(Handle mname_h, FieldAccessInfo& info, TRAPS);
   static int method_ref_kind(methodOop m, bool do_dispatch_if_possible = true);
-  static int find_MemberNames(klassOop k, Symbol* name, Symbol* sig,
-                              int mflags, klassOop caller,
-                              int skip, objArrayOop results);
+  static int find_MemberNames(KlassHandle k, Symbol* name, Symbol* sig,
+                              int mflags, KlassHandle caller,
+                              int skip, objArrayHandle results);
   // bit values for suppress argument to expand_MemberName:
   enum { _suppress_defc = 1, _suppress_name = 2, _suppress_type = 4 };
 
@@ -230,4 +229,26 @@
   void generate();
 };
 
+//------------------------------------------------------------------------------
+// MemberNameTable
+//
+
+class MemberNameTable : public GrowableArray<jweak> {
+ public:
+  MemberNameTable(int methods_cnt);
+  ~MemberNameTable();
+
+  void add_member_name(int index, jweak mem_name_ref);
+  oop  get_member_name(int index);
+
+ public:
+  // RedefineClasses() API support:
+  // If a MemberName refers to old_method then update it
+  // to refer to new_method.
+  void adjust_method_entries(methodOop* old_methods, methodOop* new_methods,
+                             int methods_length, bool *trace_name_printed);
+ private:
+  oop find_member_name_by_method(methodOop old_method);
+};
+
 #endif // SHARE_VM_PRIMS_METHODHANDLES_HPP
--- a/src/share/vm/prims/whitebox.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/prims/whitebox.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -27,6 +27,8 @@
 #include "memory/universe.hpp"
 #include "oops/oop.inline.hpp"
 
+#include "code/codeCache.hpp"
+
 #include "classfile/symbolTable.hpp"
 
 #include "prims/whitebox.hpp"
@@ -131,6 +133,13 @@
   return MemTracker::wbtest_wait_for_data_merge();
 WB_END
 
+WB_ENTRY(void, WB_DeoptimizeAll(JNIEnv* env, jobject o))
+  MutexLockerEx mu(Compile_lock);
+  CodeCache::mark_all_nmethods_for_deoptimization();
+  VM_Deoptimize op;
+  VMThread::execute(&op);
+WB_END
+
 //Some convenience methods to deal with objects from java
 int WhiteBox::offset_for_field(const char* field_name, oop object,
     Symbol* signature_symbol) {
@@ -204,6 +213,7 @@
   {CC"NMTUncommitMemory",   CC"(JJ)V",                (void*)&WB_NMTUncommitMemory  },
   {CC"NMTReleaseMemory",    CC"(JJ)V",                (void*)&WB_NMTReleaseMemory   },
   {CC"NMTWaitForDataMerge", CC"()Z",                  (void*)&WB_NMTWaitForDataMerge},
+  {CC"deoptimizeAll",       CC"()V",                  (void*)&WB_DeoptimizeAll     },
 };
 
 #undef CC
--- a/src/share/vm/runtime/arguments.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/runtime/arguments.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1450,6 +1450,17 @@
   }
   FLAG_SET_DEFAULT(UseParallelGC, true);
 
+  if (UseAdaptiveSizePolicy) {
+    // We don't want to limit adaptive heap sizing's freedom to adjust the heap
+    // unless the user actually sets these flags.
+    if (FLAG_IS_DEFAULT(MinHeapFreeRatio)) {
+      FLAG_SET_DEFAULT(MinHeapFreeRatio, 0);
+    }
+    if (FLAG_IS_DEFAULT(MaxHeapFreeRatio)) {
+      FLAG_SET_DEFAULT(MaxHeapFreeRatio, 100);
+    }
+  }
+
   // If no heap maximum was requested explicitly, use some reasonable fraction
   // of the physical memory, up to a maximum of 1GB.
   if (UseParallelGC) {
@@ -1722,7 +1733,7 @@
 }
 
 bool Arguments::verify_percentage(uintx value, const char* name) {
-  if (value <= 100) {
+  if (is_percentage(value)) {
     return true;
   }
   jio_fprintf(defaultStream::error_stream(),
@@ -1771,6 +1782,34 @@
   }
 }
 
+bool Arguments::verify_MinHeapFreeRatio(FormatBuffer<80>& err_msg, uintx min_heap_free_ratio) {
+  if (!is_percentage(min_heap_free_ratio)) {
+    err_msg.print("MinHeapFreeRatio must have a value between 0 and 100");
+    return false;
+  }
+  if (min_heap_free_ratio > MaxHeapFreeRatio) {
+    err_msg.print("MinHeapFreeRatio (" UINTX_FORMAT ") must be less than or "
+                  "equal to MaxHeapFreeRatio (" UINTX_FORMAT ")", min_heap_free_ratio,
+                  MaxHeapFreeRatio);
+    return false;
+  }
+  return true;
+}
+
+bool Arguments::verify_MaxHeapFreeRatio(FormatBuffer<80>& err_msg, uintx max_heap_free_ratio) {
+  if (!is_percentage(max_heap_free_ratio)) {
+    err_msg.print("MaxHeapFreeRatio must have a value between 0 and 100");
+    return false;
+  }
+  if (max_heap_free_ratio < MinHeapFreeRatio) {
+    err_msg.print("MaxHeapFreeRatio (" UINTX_FORMAT ") must be greater than or "
+                  "equal to MinHeapFreeRatio (" UINTX_FORMAT ")", max_heap_free_ratio,
+                  MinHeapFreeRatio);
+    return false;
+  }
+  return true;
+}
+
 // Check consistency of GC selection
 bool Arguments::check_gc_consistency() {
   check_gclog_consistency();
@@ -1855,15 +1894,19 @@
                               "AdaptiveSizePolicyWeight");
   status = status && verify_percentage(AdaptivePermSizeWeight, "AdaptivePermSizeWeight");
   status = status && verify_percentage(ThresholdTolerance, "ThresholdTolerance");
-  status = status && verify_percentage(MinHeapFreeRatio, "MinHeapFreeRatio");
-  status = status && verify_percentage(MaxHeapFreeRatio, "MaxHeapFreeRatio");
-
-  if (MinHeapFreeRatio > MaxHeapFreeRatio) {
-    jio_fprintf(defaultStream::error_stream(),
-                "MinHeapFreeRatio (" UINTX_FORMAT ") must be less than or "
-                "equal to MaxHeapFreeRatio (" UINTX_FORMAT ")\n",
-                MinHeapFreeRatio, MaxHeapFreeRatio);
-    status = false;
+
+  {
+    // Using "else if" below to avoid printing two error messages if min > max.
+    // This will also prevent us from reporting both min>100 and max>100 at the
+    // same time, but that is less annoying than printing two identical errors IMHO.
+    FormatBuffer<80> err_msg("");
+    if (!verify_MinHeapFreeRatio(err_msg, MinHeapFreeRatio)) {
+      jio_fprintf(defaultStream::error_stream(), "%s\n", err_msg.buffer());
+      status = false;
+    } else if (!verify_MaxHeapFreeRatio(err_msg, MaxHeapFreeRatio)) {
+      jio_fprintf(defaultStream::error_stream(), "%s\n", err_msg.buffer());
+      status = false;
+    }
   }
   // Keeping the heap 100% free is hard ;-) so limit it to 99%.
   MinHeapFreeRatio = MIN2(MinHeapFreeRatio, (uintx) 99);
@@ -1946,11 +1989,12 @@
   // than just disable the lock verification. This will be fixed under
   // bug 4788986.
   if (UseConcMarkSweepGC && FLSVerifyAllHeapReferences) {
-    if (VerifyGCStartAt == 0) {
+    if (VerifyDuringStartup) {
       warning("Heap verification at start-up disabled "
               "(due to current incompatibility with FLSVerifyAllHeapReferences)");
-      VerifyGCStartAt = 1;      // Disable verification at start-up
+      VerifyDuringStartup = false; // Disable verification at start-up
     }
+
     if (VerifyBeforeExit) {
       warning("Heap verification at shutdown disabled "
               "(due to current incompatibility with FLSVerifyAllHeapReferences)");
@@ -2552,7 +2596,9 @@
          FLAG_SET_CMDLINE(uintx, MaxNewSize, NewSize);
       }
 
+#ifndef _ALLBSD_SOURCE  // UseLargePages is not yet supported on BSD.
       FLAG_SET_DEFAULT(UseLargePages, true);
+#endif
 
       // Increase some data structure sizes for efficiency
       FLAG_SET_CMDLINE(uintx, BaseFootPrintEstimate, MaxHeapSize);
@@ -3114,6 +3160,10 @@
   UNSUPPORTED_OPTION(UseG1GC, "G1 GC");
 #endif
 
+#ifdef _ALLBSD_SOURCE  // UseLargePages is not yet supported on BSD.
+  UNSUPPORTED_OPTION(UseLargePages, "-XX:+UseLargePages");
+#endif
+
 #ifndef PRODUCT
   if (TraceBytecodesAt != 0) {
     TraceBytecodes = true;
--- a/src/share/vm/runtime/arguments.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/runtime/arguments.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -27,6 +27,7 @@
 
 #include "runtime/java.hpp"
 #include "runtime/perfData.hpp"
+#include "utilities/debug.hpp"
 #include "utilities/top.hpp"
 
 // Arguments parses the command line and recognizes options
@@ -350,6 +351,9 @@
   static bool is_bad_option(const JavaVMOption* option, jboolean ignore) {
     return is_bad_option(option, ignore, NULL);
   }
+  static bool is_percentage(uintx val) {
+    return val <= 100;
+  }
   static bool verify_interval(uintx val, uintx min,
                               uintx max, const char* name);
   static bool verify_min_value(intx val, intx min, const char* name);
@@ -411,6 +415,12 @@
  public:
   // Parses the arguments
   static jint parse(const JavaVMInitArgs* args);
+  // Verifies that the given value will fit as a MinHeapFreeRatio. If not, an error
+  // message is returned in the provided buffer.
+  static bool verify_MinHeapFreeRatio(FormatBuffer<80>& err_msg, uintx min_heap_free_ratio);
+  // Verifies that the given value will fit as a MaxHeapFreeRatio. If not, an error
+  // message is returned in the provided buffer.
+  static bool verify_MaxHeapFreeRatio(FormatBuffer<80>& err_msg, uintx max_heap_free_ratio);
   // Check for consistency in the selection of the garbage collector.
   static bool check_gc_consistency();
   // Check consistecy or otherwise of VM argument settings
--- a/src/share/vm/runtime/globals.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/runtime/globals.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1711,6 +1711,9 @@
   product(bool, CMSAbortSemantics, false,                                   \
           "Whether abort-on-overflow semantics is implemented")             \
                                                                             \
+  product(bool, CMSParallelInitialMarkEnabled, false,                       \
+          "Use the parallel initial mark.")                                 \
+                                                                            \
   product(bool, CMSParallelRemarkEnabled, true,                             \
           "Whether parallel remark enabled (only if ParNewGC)")             \
                                                                             \
@@ -1722,6 +1725,14 @@
           "Whether to always record survivor space PLAB bdries"             \
           " (effective only if CMSParallelSurvivorRemarkEnabled)")          \
                                                                             \
+  product(bool, CMSEdenChunksRecordAlways, false,                           \
+          "Whether to always record eden chunks used for "                  \
+          "the parallel initial mark or remark of eden" )                   \
+                                                                            \
+  product(bool, CMSPrintEdenSurvivorChunks, false,                          \
+          "Print the eden and the survivor chunks used for the parallel "   \
+          "initial mark or remark of the eden/survivor spaces")             \
+                                                                            \
   product(bool, CMSConcurrentMTEnabled, true,                               \
           "Whether multi-threaded concurrent work enabled (if ParNewGC)")   \
                                                                             \
@@ -1931,6 +1942,9 @@
   notproduct(bool, ExecuteInternalVMTests, false,                           \
           "Enable execution of internal VM tests.")                         \
                                                                             \
+  notproduct(bool, VerboseInternalVMTests, false,                           \
+          "Turn on logging for internal VM tests.")                         \
+                                                                            \
   product_pd(bool, UseTLAB, "Use thread-local object allocation")           \
                                                                             \
   product_pd(bool, ResizeTLAB,                                              \
@@ -2140,6 +2154,13 @@
   product(intx, PrefetchFieldsAhead, -1,                                    \
           "How many fields ahead to prefetch in oop scan (<= 0 means off)") \
                                                                             \
+  diagnostic(bool, VerifySilently, false,                                   \
+          "Don't print print the verification progress")                    \
+                                                                            \
+  diagnostic(bool, VerifyDuringStartup, false,                              \
+          "Verify memory system before executing any Java code "            \
+          "during VM initialization")                                       \
+                                                                            \
   diagnostic(bool, VerifyBeforeExit, trueInDebug,                           \
           "Verify system before exiting")                                   \
                                                                             \
@@ -3029,10 +3050,10 @@
   product_pd(uintx, MaxPermSize,                                            \
           "Maximum size of permanent generation (in bytes)")                \
                                                                             \
-  product(uintx, MinHeapFreeRatio,    40,                                   \
+  manageable(uintx, MinHeapFreeRatio,    40,                                \
           "Min percentage of heap free after GC to avoid expansion")        \
                                                                             \
-  product(uintx, MaxHeapFreeRatio,    70,                                   \
+  manageable(uintx, MaxHeapFreeRatio,    70,                                \
           "Max percentage of heap free after GC to avoid shrinking")        \
                                                                             \
   product(intx, SoftRefLRUPolicyMSPerMB, 1000,                              \
--- a/src/share/vm/runtime/mutexLocker.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/runtime/mutexLocker.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -60,6 +60,7 @@
 Mutex*   JNIGlobalHandle_lock         = NULL;
 Mutex*   JNIHandleBlockFreeList_lock  = NULL;
 Mutex*   JNICachedItableIndex_lock    = NULL;
+Mutex*   MemberNameTable_lock         = NULL;
 Mutex*   JmethodIdCreation_lock       = NULL;
 Mutex*   JfieldIdCreation_lock        = NULL;
 Monitor* JNICritical_lock             = NULL;
@@ -266,6 +267,7 @@
   def(Heap_lock                    , Monitor, nonleaf+1,   false);
   def(JfieldIdCreation_lock        , Mutex  , nonleaf+1,   true ); // jfieldID, Used in VM_Operation
   def(JNICachedItableIndex_lock    , Mutex  , nonleaf+1,   false); // Used to cache an itable index during JNI invoke
+  def(MemberNameTable_lock         , Mutex  , nonleaf+1,   false); // Used to protect MemberNameTable
 
   def(CompiledIC_lock              , Mutex  , nonleaf+2,   false); // locks VtableStubs_lock, InlineCacheBuffer_lock
   def(CompileTaskAlloc_lock        , Mutex  , nonleaf+2,   true );
--- a/src/share/vm/runtime/mutexLocker.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/runtime/mutexLocker.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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,6 +54,7 @@
 extern Mutex*   JNIGlobalHandle_lock;            // a lock on creating JNI global handles
 extern Mutex*   JNIHandleBlockFreeList_lock;     // a lock on the JNI handle block free list
 extern Mutex*   JNICachedItableIndex_lock;       // a lock on caching an itable index during JNI invoke
+extern Mutex*   MemberNameTable_lock;            // a lock on the MemberNameTable updates
 extern Mutex*   JmethodIdCreation_lock;          // a lock on creating JNI method identifiers
 extern Mutex*   JfieldIdCreation_lock;           // a lock on creating JNI static field identifiers
 extern Monitor* JNICritical_lock;                // a lock used while entering and exiting JNI critical regions, allows GC to sometimes get in
--- a/src/share/vm/runtime/os.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/runtime/os.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -334,8 +334,8 @@
 
   static char*  non_memory_address_word();
   // reserve, commit and pin the entire memory region
-  static char*  reserve_memory_special(size_t size, char* addr = NULL,
-                bool executable = false);
+  static char*  reserve_memory_special(size_t size, size_t alignment,
+                                       char* addr, bool executable);
   static bool   release_memory_special(char* addr, size_t bytes);
   static void   large_page_init();
   static size_t large_page_size();
--- a/src/share/vm/runtime/sweeper.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/runtime/sweeper.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,6 +36,7 @@
 #include "runtime/vm_operations.hpp"
 #include "trace/tracing.hpp"
 #include "utilities/events.hpp"
+#include "utilities/ticks.inline.hpp"
 #include "utilities/xmlstream.hpp"
 
 #ifdef ASSERT
@@ -148,12 +149,12 @@
 
 int       NMethodSweeper::_number_of_flushes = 0; // Total of full traversals caused by full cache
 int       NMethodSweeper::_total_nof_methods_reclaimed = 0;
-jlong     NMethodSweeper::_total_time_sweeping = 0;
-jlong     NMethodSweeper::_total_time_this_sweep = 0;
-jlong     NMethodSweeper::_peak_sweep_time = 0;
-jlong     NMethodSweeper::_peak_sweep_fraction_time = 0;
-jlong     NMethodSweeper::_total_disconnect_time = 0;
-jlong     NMethodSweeper::_peak_disconnect_time = 0;
+Tickspan  NMethodSweeper::_total_time_sweeping;
+Tickspan  NMethodSweeper::_total_time_this_sweep;
+Tickspan  NMethodSweeper::_peak_sweep_time;
+Tickspan  NMethodSweeper::_peak_sweep_fraction_time;
+Tickspan  NMethodSweeper::_total_disconnect_time;
+Tickspan  NMethodSweeper::_peak_disconnect_time;
 
 class MarkActivationClosure: public CodeBlobClosure {
 public:
@@ -192,7 +193,7 @@
     _invocations = NmethodSweepFraction;
     _current     = CodeCache::first_nmethod();
     _traversals  += 1;
-    _total_time_this_sweep = 0;
+    _total_time_this_sweep = Tickspan();
 
     if (PrintMethodFlushing) {
       tty->print_cr("### Sweep: stack traversal %d", _traversals);
@@ -257,8 +258,7 @@
 }
 
 void NMethodSweeper::sweep_code_cache() {
-
-  jlong sweep_start_counter = os::elapsed_counter();
+  Ticks sweep_start_counter = Ticks::now();
 
   _flushed_count   = 0;
   _zombified_count = 0;
@@ -323,8 +323,8 @@
     }
   }
 
-  jlong sweep_end_counter = os::elapsed_counter();
-  jlong sweep_time = sweep_end_counter - sweep_start_counter;
+  const Ticks sweep_end_counter = Ticks::now();
+  const Tickspan sweep_time = sweep_end_counter - sweep_start_counter;
   _total_time_sweeping  += sweep_time;
   _total_time_this_sweep += sweep_time;
   _peak_sweep_fraction_time = MAX2(sweep_time, _peak_sweep_fraction_time);
@@ -345,7 +345,7 @@
 
 #ifdef ASSERT
   if(PrintMethodFlushing) {
-    tty->print_cr("### sweeper:      sweep time(%d): " INT64_FORMAT, _invocations, (jlong)sweep_time);
+    tty->print_cr("### sweeper:      sweep time(%d): " INT64_FORMAT, _invocations, (jlong)sweep_time.value());
   }
 #endif
 
@@ -530,7 +530,7 @@
     }
   }
 
-  jlong disconnect_start_counter = os::elapsed_counter();
+  Ticks disconnect_start_counter = Ticks::now();
 
   // Traverse the code cache trying to dump the oldest nmethods
   uint curr_max_comp_id = CompileBroker::get_compilation_id();
@@ -578,8 +578,8 @@
     CompileBroker::set_should_compile_new_jobs(CompileBroker::stop_compilation);
   }
 
-  jlong disconnect_end_counter = os::elapsed_counter();
-  jlong disconnect_time = disconnect_end_counter - disconnect_start_counter;
+  const Ticks disconnect_end_counter = Ticks::now();
+  const Tickspan disconnect_time = disconnect_end_counter - disconnect_start_counter;
   _total_disconnect_time += disconnect_time;
   _peak_disconnect_time = MAX2(disconnect_time, _peak_disconnect_time);
 
@@ -598,7 +598,7 @@
 #ifdef ASSERT
 
   if(PrintMethodFlushing && Verbose) {
-    tty->print_cr("### sweeper: unload time: " INT64_FORMAT, (jlong)disconnect_time);
+    tty->print_cr("### sweeper: unload time: " INT64_FORMAT, (jlong)disconnect_time.value());
   }
 #endif
 }
--- a/src/share/vm/runtime/sweeper.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/runtime/sweeper.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
 #ifndef SHARE_VM_RUNTIME_SWEEPER_HPP
 #define SHARE_VM_RUNTIME_SWEEPER_HPP
 
+#include "utilities/ticks.hpp"
 // An NmethodSweeper is an incremental cleaner for:
 //    - cleanup inline caches
 //    - reclamation of unreferences zombie nmethods
@@ -56,12 +57,12 @@
   // Stat counters
   static int       _number_of_flushes;            // Total of full traversals caused by full cache
   static int       _total_nof_methods_reclaimed;  // Accumulated nof methods flushed
-  static jlong     _total_time_sweeping;          // Accumulated time sweeping
-  static jlong     _total_time_this_sweep;        // Total time this sweep
-  static jlong     _peak_sweep_time;              // Peak time for a full sweep
-  static jlong     _peak_sweep_fraction_time;     // Peak time sweeping one fraction
-  static jlong     _total_disconnect_time;        // Total time cleaning code mem
-  static jlong     _peak_disconnect_time;         // Peak time cleaning code mem
+  static Tickspan     _total_time_sweeping;          // Accumulated time sweeping
+  static Tickspan     _total_time_this_sweep;        // Total time this sweep
+  static Tickspan     _peak_sweep_time;              // Peak time for a full sweep
+  static Tickspan     _peak_sweep_fraction_time;     // Peak time sweeping one fraction
+  static Tickspan     _total_disconnect_time;        // Total time cleaning code mem
+  static Tickspan     _peak_disconnect_time;         // Peak time cleaning code mem
 
   static void process_nmethod(nmethod *nm);
 
@@ -71,13 +72,14 @@
   static long traversal_count()              { return _traversals; }
   static int  number_of_flushes()            { return _number_of_flushes; }
   static int  total_nof_methods_reclaimed()  { return _total_nof_methods_reclaimed; }
-  static jlong total_time_sweeping()         { return _total_time_sweeping; }
-  static jlong peak_sweep_time()             { return _peak_sweep_time; }
-  static jlong peak_sweep_fraction_time()    { return _peak_sweep_fraction_time; }
-  static jlong total_disconnect_time()       { return _total_disconnect_time; }
-  static jlong peak_disconnect_time()        { return _peak_disconnect_time; }
+  static const Tickspan total_time_sweeping()         { return _total_time_sweeping; }
+  static const Tickspan peak_sweep_time()             { return _peak_sweep_time; }
+  static const Tickspan peak_sweep_fraction_time()    { return _peak_sweep_fraction_time; }
+  static const Tickspan total_disconnect_time()       { return _total_disconnect_time; }
+  static const Tickspan peak_disconnect_time()        { return _peak_disconnect_time; }
 
 #ifdef ASSERT
+  static bool is_sweeping(nmethod* which) { return _current == which; }
   // Keep track of sweeper activity in the ring buffer
   static void record_sweep(nmethod* nm, int line);
   static void report_events(int id, address entry);
--- a/src/share/vm/runtime/thread.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/runtime/thread.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -3423,9 +3423,10 @@
   }
 
   assert (Universe::is_fully_initialized(), "not initialized");
-  if (VerifyBeforeGC && VerifyGCStartAt == 0) {
-    Universe::heap()->prepare_for_verify();
-    Universe::verify();   // make sure we're starting with a clean slate
+  if (VerifyDuringStartup) {
+    // Make sure we're starting with a clean slate.
+    VM_Verify verify_op;
+    VMThread::execute(&verify_op);
   }
 
   EXCEPTION_MARK;
@@ -3511,11 +3512,12 @@
       java_lang_Thread::set_thread_status(thread_object,
                                           java_lang_Thread::RUNNABLE);
 
-      // The VM preresolve methods to these classes. Make sure that get initialized
+      // The VM creates & returns objects of this class. Make sure it's initialized.
+      initialize_class(vmSymbols::java_lang_Class(), CHECK_0);
+
+      // The VM preresolves methods to these classes. Make sure that they get initialized
       initialize_class(vmSymbols::java_lang_reflect_Method(), CHECK_0);
       initialize_class(vmSymbols::java_lang_ref_Finalizer(),  CHECK_0);
-      // The VM creates & returns objects of this class. Make sure it's initialized.
-      initialize_class(vmSymbols::java_lang_Class(), CHECK_0);
       call_initializeSystemClass(CHECK_0);
 
       // get the Java runtime name after java.lang.System is initialized
--- a/src/share/vm/runtime/virtualspace.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/runtime/virtualspace.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -45,8 +45,19 @@
 
 
 // ReservedSpace
+
+// Dummy constructor
+ReservedSpace::ReservedSpace() : _base(NULL), _size(0), _noaccess_prefix(0),
+    _alignment(0), _special(false), _executable(false) {
+}
+
 ReservedSpace::ReservedSpace(size_t size) {
-  initialize(size, 0, false, NULL, 0, false);
+  size_t page_size = os::page_size_for_region(size, size, 1);
+  bool large_pages = page_size != (size_t)os::vm_page_size();
+  // Don't force the alignment to be large page aligned,
+  // since that will waste memory.
+  size_t alignment = os::vm_allocation_granularity();
+  initialize(size, alignment, large_pages, NULL, 0, false);
 }
 
 ReservedSpace::ReservedSpace(size_t size, size_t alignment,
@@ -326,16 +337,18 @@
 
   if (special) {
 
-    base = os::reserve_memory_special(size, requested_address, executable);
+    base = os::reserve_memory_special(size, alignment, requested_address, executable);
 
     if (base != NULL) {
       if (failed_to_reserve_as_requested(base, requested_address, size, true)) {
         // OS ignored requested address. Try different address.
         return;
       }
-      // Check alignment constraints
+      // Check alignment constraints.
       assert((uintptr_t) base % alignment == 0,
-             "Large pages returned a non-aligned address");
+             err_msg("Large pages returned a non-aligned address, base: "
+                 PTR_FORMAT " alignment: " PTR_FORMAT,
+                 base, (void*)(uintptr_t)alignment));
       _special = true;
     } else {
       // failed; try to reserve regular memory below
@@ -931,4 +944,188 @@
   tty->print_cr(" - [low_b, high_b]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]",  low_boundary(), high_boundary());
 }
 
+
+/////////////// Unit tests ///////////////
+
+#ifndef PRODUCT
+
+#define test_log(...) \
+  do {\
+    if (VerboseInternalVMTests) { \
+      tty->print_cr(__VA_ARGS__); \
+      tty->flush(); \
+    }\
+  } while (false)
+
+class TestReservedSpace : AllStatic {
+ public:
+  static void small_page_write(void* addr, size_t size) {
+    size_t page_size = os::vm_page_size();
+
+    char* end = (char*)addr + size;
+    for (char* p = (char*)addr; p < end; p += page_size) {
+      *p = 1;
+    }
+  }
+
+  static void release_memory_for_test(ReservedSpace rs) {
+    if (rs.special()) {
+      guarantee(os::release_memory_special(rs.base(), rs.size()), "Shouldn't fail");
+    } else {
+      guarantee(os::release_memory(rs.base(), rs.size()), "Shouldn't fail");
+    }
+  }
+
+  static void test_reserved_space1(size_t size, size_t alignment) {
+    test_log("test_reserved_space1(%p)", (void*) (uintptr_t) size);
+
+    assert(is_size_aligned(size, alignment), "Incorrect input parameters");
+
+    ReservedSpace rs(size,          // size
+                     alignment,     // alignment
+                     UseLargePages, // large
+                     NULL,          // requested_address
+                     0);            // noacces_prefix
+
+    test_log(" rs.special() == %d", rs.special());
+
+    assert(rs.base() != NULL, "Must be");
+    assert(rs.size() == size, "Must be");
+
+    assert(is_ptr_aligned(rs.base(), alignment), "aligned sizes should always give aligned addresses");
+    assert(is_size_aligned(rs.size(), alignment), "aligned sizes should always give aligned addresses");
+
+    if (rs.special()) {
+      small_page_write(rs.base(), size);
+    }
+
+    release_memory_for_test(rs);
+  }
+
+  static void test_reserved_space2(size_t size) {
+    test_log("test_reserved_space2(%p)", (void*)(uintptr_t)size);
+
+    assert(is_size_aligned(size, os::vm_allocation_granularity()), "Must be at least AG aligned");
+
+    ReservedSpace rs(size);
+
+    test_log(" rs.special() == %d", rs.special());
+
+    assert(rs.base() != NULL, "Must be");
+    assert(rs.size() == size, "Must be");
+
+    if (rs.special()) {
+      small_page_write(rs.base(), size);
+    }
+
+    release_memory_for_test(rs);
+  }
+
+  static void test_reserved_space3(size_t size, size_t alignment, bool maybe_large) {
+    test_log("test_reserved_space3(%p, %p, %d)",
+        (void*)(uintptr_t)size, (void*)(uintptr_t)alignment, maybe_large);
+
+    assert(is_size_aligned(size, os::vm_allocation_granularity()), "Must be at least AG aligned");
+    assert(is_size_aligned(size, alignment), "Must be at least aligned against alignment");
+
+    bool large = maybe_large && UseLargePages && size >= os::large_page_size();
+
+    ReservedSpace rs(size, alignment, large, false);
+
+    test_log(" rs.special() == %d", rs.special());
+
+    assert(rs.base() != NULL, "Must be");
+    assert(rs.size() == size, "Must be");
+
+    if (rs.special()) {
+      small_page_write(rs.base(), size);
+    }
+
+    release_memory_for_test(rs);
+  }
+
+
+  static void test_reserved_space1() {
+    size_t size = 2 * 1024 * 1024;
+    size_t ag   = os::vm_allocation_granularity();
+
+    test_reserved_space1(size,      ag);
+    test_reserved_space1(size * 2,  ag);
+    test_reserved_space1(size * 10, ag);
+  }
+
+  static void test_reserved_space2() {
+    size_t size = 2 * 1024 * 1024;
+    size_t ag = os::vm_allocation_granularity();
+
+    test_reserved_space2(size * 1);
+    test_reserved_space2(size * 2);
+    test_reserved_space2(size * 10);
+    test_reserved_space2(ag);
+    test_reserved_space2(size - ag);
+    test_reserved_space2(size);
+    test_reserved_space2(size + ag);
+    test_reserved_space2(size * 2);
+    test_reserved_space2(size * 2 - ag);
+    test_reserved_space2(size * 2 + ag);
+    test_reserved_space2(size * 3);
+    test_reserved_space2(size * 3 - ag);
+    test_reserved_space2(size * 3 + ag);
+    test_reserved_space2(size * 10);
+    test_reserved_space2(size * 10 + size / 2);
+  }
+
+  static void test_reserved_space3() {
+    size_t ag = os::vm_allocation_granularity();
+
+    test_reserved_space3(ag,      ag    , false);
+    test_reserved_space3(ag * 2,  ag    , false);
+    test_reserved_space3(ag * 3,  ag    , false);
+    test_reserved_space3(ag * 2,  ag * 2, false);
+    test_reserved_space3(ag * 4,  ag * 2, false);
+    test_reserved_space3(ag * 8,  ag * 2, false);
+    test_reserved_space3(ag * 4,  ag * 4, false);
+    test_reserved_space3(ag * 8,  ag * 4, false);
+    test_reserved_space3(ag * 16, ag * 4, false);
+
+    if (UseLargePages) {
+      size_t lp = os::large_page_size();
+
+      // Without large pages
+      test_reserved_space3(lp,     ag * 4, false);
+      test_reserved_space3(lp * 2, ag * 4, false);
+      test_reserved_space3(lp * 4, ag * 4, false);
+      test_reserved_space3(lp,     lp    , false);
+      test_reserved_space3(lp * 2, lp    , false);
+      test_reserved_space3(lp * 3, lp    , false);
+      test_reserved_space3(lp * 2, lp * 2, false);
+      test_reserved_space3(lp * 4, lp * 2, false);
+      test_reserved_space3(lp * 8, lp * 2, false);
+
+      // With large pages
+      test_reserved_space3(lp, ag * 4    , true);
+      test_reserved_space3(lp * 2, ag * 4, true);
+      test_reserved_space3(lp * 4, ag * 4, true);
+      test_reserved_space3(lp, lp        , true);
+      test_reserved_space3(lp * 2, lp    , true);
+      test_reserved_space3(lp * 3, lp    , true);
+      test_reserved_space3(lp * 2, lp * 2, true);
+      test_reserved_space3(lp * 4, lp * 2, true);
+      test_reserved_space3(lp * 8, lp * 2, true);
+    }
+  }
+
+  static void test_reserved_space() {
+    test_reserved_space1();
+    test_reserved_space2();
+    test_reserved_space3();
+  }
+};
+
+void TestReservedSpace_test() {
+  TestReservedSpace::test_reserved_space();
+}
+
+#endif // PRODUCT
+
 #endif
--- a/src/share/vm/runtime/virtualspace.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/runtime/virtualspace.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -90,6 +90,7 @@
 
  public:
   // Constructor
+  ReservedSpace();
   ReservedSpace(size_t size);
   ReservedSpace(size_t size, size_t alignment, bool large,
                 char* requested_address = NULL,
--- a/src/share/vm/runtime/vmThread.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/runtime/vmThread.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -308,7 +308,7 @@
     os::check_heap();
     // Silent verification so as not to pollute normal output,
     // unless we really asked for it.
-    Universe::verify(!(PrintGCDetails || Verbose));
+    Universe::verify(!(PrintGCDetails || Verbose) || VerifySilently);
   }
 
   CompileBroker::set_should_block();
--- a/src/share/vm/runtime/vm_operations.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/runtime/vm_operations.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -192,7 +192,8 @@
 }
 
 void VM_Verify::doit() {
-  Universe::verify();
+  Universe::heap()->prepare_for_verify();
+  Universe::verify(_silent);
 }
 
 bool VM_PrintThreads::doit_prologue() {
--- a/src/share/vm/runtime/vm_operations.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/runtime/vm_operations.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -303,9 +303,9 @@
 
 class VM_Verify: public VM_Operation {
  private:
-  KlassHandle _dependee;
+  bool _silent;
  public:
-  VM_Verify() {}
+  VM_Verify(bool silent = VerifySilently) : _silent(silent) {}
   VMOp_Type type() const { return VMOp_Verify; }
   void doit();
 };
--- a/src/share/vm/services/attachListener.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/services/attachListener.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -282,6 +282,20 @@
       return JNI_ERR;
     }
   }
+
+  if (strncmp(name, "MaxHeapFreeRatio", 17) == 0) {
+    FormatBuffer<80> err_msg("");
+    if (!Arguments::verify_MaxHeapFreeRatio(err_msg, value)) {
+      out->print_cr(err_msg.buffer());
+      return JNI_ERR;
+    }
+  } else if (strncmp(name, "MinHeapFreeRatio", 17) == 0) {
+    FormatBuffer<80> err_msg("");
+    if (!Arguments::verify_MinHeapFreeRatio(err_msg, value)) {
+      out->print_cr(err_msg.buffer());
+      return JNI_ERR;
+    }
+  }
   bool res = CommandLineFlags::uintxAtPut((char*)name, &value, ATTACH_ON_DEMAND);
   if (! res) {
     out->print_cr("setting flag %s failed", name);
--- a/src/share/vm/services/management.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/services/management.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -851,8 +851,6 @@
       total_used += u.used();
       total_committed += u.committed();
 
-      // if any one of the memory pool has undefined init_size or max_size,
-      // set it to -1
       if (u.init_size() == (size_t)-1) {
         has_undefined_init_size = true;
       }
@@ -869,6 +867,15 @@
     }
   }
 
+  // if any one of the memory pool has undefined init_size or max_size,
+  // set it to -1
+  if (has_undefined_init_size) {
+    total_init = (size_t)-1;
+  }
+  if (has_undefined_max_size) {
+    total_max = (size_t)-1;
+  }
+
   // In our current implementation, we make sure that all non-heap
   // pools have defined init and max sizes. Heap pools do not matter,
   // as we never use total_init and total_max for them.
@@ -1793,6 +1800,18 @@
     succeed = CommandLineFlags::intxAtPut(name, &ivalue, MANAGEMENT);
   } else if (flag->is_uintx()) {
     uintx uvalue = (uintx)new_value.j;
+
+    if (strncmp(name, "MaxHeapFreeRatio", 17) == 0) {
+      FormatBuffer<80> err_msg("");
+      if (!Arguments::verify_MaxHeapFreeRatio(err_msg, uvalue)) {
+        THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), err_msg.buffer());
+      }
+    } else if (strncmp(name, "MinHeapFreeRatio", 17) == 0) {
+      FormatBuffer<80> err_msg("");
+      if (!Arguments::verify_MinHeapFreeRatio(err_msg, uvalue)) {
+        THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), err_msg.buffer());
+      }
+    }
     succeed = CommandLineFlags::uintxAtPut(name, &uvalue, MANAGEMENT);
   } else if (flag->is_uint64_t()) {
     uint64_t uvalue = (uint64_t)new_value.j;
--- a/src/share/vm/services/memTracker.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/services/memTracker.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -302,6 +302,13 @@
     }
   }
 
+  static inline void record_virtual_memory_release(address addr, size_t size,
+      Thread* thread = NULL) {
+    if (is_on()) {
+      Tracker tkr(Tracker::Release, thread);
+      tkr.record(addr, size);
+    }
+  }
 
   // record memory type on virtual memory base address
   static inline void record_virtual_memory_type(address base, MEMFLAGS flags,
--- a/src/share/vm/trace/noTraceBackend.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/trace/noTraceBackend.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -25,9 +25,7 @@
 #define SHARE_VM_TRACE_NOTRACEBACKEND_HPP
 
 #include "prims/jni.h"
-
-typedef jlong TracingTime;
-typedef jlong RelativeTracingTime;
+#include "trace/traceTime.hpp"
 
 class NoTraceBackend {
 public:
@@ -44,5 +42,3 @@
 typedef NoTraceBackend Tracing;
 
 #endif
-
-
--- a/src/share/vm/trace/trace.xml	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/trace/trace.xml	Mon Jul 07 08:54:46 2014 +0200
@@ -169,8 +169,8 @@
       <value type="UINT" field="gcId"  label="GC ID" relation="GC_ID" />
       <value type="GCNAME" field="name" label="Name" description="The name of the Garbage Collector" />
       <value type="GCCAUSE" field="cause" label="Cause" description="The reason for triggering this Garbage Collection" />
-      <value type="RELATIVE_TICKS" field="sumOfPauses" label="Sum of Pauses" description="Sum of all the times in which Java execution was paused during the garbage collection" />
-      <value type="RELATIVE_TICKS" field="longestPause" label="Longest Pause" description="Longest individual pause during the garbage collection" />
+      <value type="TICKSPAN" field="sumOfPauses" label="Sum of Pauses" description="Sum of all the times in which Java execution was paused during the garbage collection" />
+      <value type="TICKSPAN" field="longestPause" label="Longest Pause" description="Longest individual pause during the garbage collection" />
     </event>
 
     <event id="GCParallelOld" path="vm/gc/collector/parold_garbage_collection" label="Parallel Old Garbage Collection"
--- a/src/share/vm/trace/traceBackend.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/trace/traceBackend.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -26,10 +26,11 @@
 
 #if INCLUDE_TRACE
 
+#include "runtime/globals.hpp"
+#include "runtime/os.hpp"
 #include "trace/traceTime.hpp"
 #include "tracefiles/traceEventIds.hpp"
-#include "runtime/globals.hpp"
-#include "runtime/os.hpp"
+
 
 class TraceBackend {
 public:
@@ -44,10 +45,6 @@
     return os::elapsed_counter();
   }
 
-  static TracingTime time_adjustment(jlong time) {
-    return time;
-  }
-
   static void on_unloading_classes(BoolObjectClosure* is_alive, int no_of_classes_unloading) {
   }
 };
--- a/src/share/vm/trace/traceEvent.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/trace/traceEvent.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,13 +36,10 @@
 #include "trace/tracing.hpp"
 #include "tracefiles/traceEventIds.hpp"
 #include "tracefiles/traceTypes.hpp"
+#include "utilities/ticks.hpp"
 
 template<typename T>
 class TraceEvent : public StackObj {
- protected:
-  jlong _startTime;
-  jlong _endTime;
-
  private:
   bool _started;
 #ifdef ASSERT
@@ -52,6 +49,18 @@
   bool _ignore_check;
 #endif
 
+ protected:
+  jlong _startTime;
+  jlong _endTime;
+
+  void set_starttime(const TracingTime& time) {
+    _startTime = time;
+  }
+
+  void set_endtime(const TracingTime& time) {
+    _endTime = time;
+  }
+
  public:
   TraceEvent(EventStartTime timing=TIMED) :
     _startTime(0),
@@ -90,7 +99,7 @@
         return;
     }
     if (_endTime == 0) {
-      static_cast<T *>(this)->set_endtime(Tracing::time());
+      static_cast<T*>(this)->set_endtime(Tracing::time());
     }
     if (static_cast<T*>(this)->should_write()) {
       static_cast<T*>(this)->writeEvent();
@@ -98,12 +107,12 @@
     set_commited();
   }
 
-  void set_starttime(jlong time) {
-    _startTime = time;
+  void set_starttime(const Ticks& time) {
+    _startTime = time.value();
   }
 
-  void set_endtime(jlong time) {
-    _endTime = time;
+  void set_endtime(const Ticks& time) {
+    _endTime = time.value();
   }
 
   TraceEventId id() const {
--- a/src/share/vm/trace/traceEventClasses.xsl	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/trace/traceEventClasses.xsl	Mon Jul 07 08:54:46 2014 +0200
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
- Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2012, 2013, 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
@@ -23,8 +23,8 @@
 -->
 
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+<xsl:import href="xsl_util.xsl"/>
 <xsl:output method="text" indent="no" omit-xml-declaration="yes"/>
-<xsl:import href="xsl_util.xsl"/>
 
 <xsl:template match="/">
   <xsl:call-template name="file-header"/>
@@ -40,6 +40,7 @@
 #include "runtime/handles.inline.hpp"
 #include "tracefiles/traceTypes.hpp"
 #include "trace/traceEvent.hpp"
+#include "utilities/ticks.hpp"
 
 #if INCLUDE_TRACE
 
@@ -54,8 +55,8 @@
 class TraceEvent {
 public:
   TraceEvent() {}
-  void set_starttime(jlong time) const {}
-  void set_endtime(jlong time) const {}
+  void set_starttime(const Ticks&amp; time) {}
+  void set_endtime(const Ticks&amp; time) {}
   bool should_commit() const { return false; }
   void commit() const {}
 };
@@ -174,20 +175,21 @@
 
 <xsl:template match="value[@type='TICKS']" mode="write-setters">
 #if INCLUDE_TRACE
-  <xsl:value-of select="concat('void set_', @field, '(jlong time) { _', @field, ' = time; }')"/>
+<xsl:value-of select="concat('  void set_', @field, '(const Ticks&amp; time) { _', @field, ' = time; }')"/>
 #else
-  <xsl:value-of select="concat('void set_', @field, '(jlong ignore) {}')"/>
+<xsl:value-of select="concat('  void set_', @field, '(const Ticks&amp; ignore) {}')"/>
 #endif
 </xsl:template>
 
-<xsl:template match="value[@type='RELATIVE_TICKS']" mode="write-setters">
+<xsl:template match="value[@type='TICKSPAN']" mode="write-setters">
 #if INCLUDE_TRACE
-  <xsl:value-of select="concat('void set_', @field, '(jlong time) { _', @field, ' = time; }')"/>
+  <xsl:value-of select="concat('  void set_', @field, '(const Tickspan&amp; time) { _', @field, ' = time; }')"/>
 #else
-  <xsl:value-of select="concat('void set_', @field, '(jlong ignore) {}')"/>
+  <xsl:value-of select="concat('  void set_', @field, '(const Tickspan&amp; ignore) {}')"/>
 #endif
 </xsl:template>
 
+
 <xsl:template match="value" mode="write-fields">
   <xsl:variable name="type" select="@type"/>
   <xsl:variable name="wt" select="//primary_type[@symbol=$type]/@type"/>
@@ -227,7 +229,17 @@
 <xsl:template match="value" mode="write-data">
   <xsl:variable name="type" select="@type"/>
   <xsl:variable name="wt" select="//primary_type[@symbol=$type]/@writetype"/>
-  <xsl:value-of select="concat('    ts.print_val(&quot;', @label, '&quot;, _', @field, ');')"/>
+  <xsl:choose>
+    <xsl:when test="@type='TICKSPAN'">
+      <xsl:value-of select="concat('    ts.print_val(&quot;', @label, '&quot;, _', @field, '.value());')"/>
+    </xsl:when>
+    <xsl:when test="@type='TICKS'">
+      <xsl:value-of select="concat('    ts.print_val(&quot;', @label, '&quot;, _', @field, '.value());')"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:value-of select="concat('    ts.print_val(&quot;', @label, '&quot;, _', @field, ');')"/>
+    </xsl:otherwise>
+  </xsl:choose>
   <xsl:if test="position() != last()">
     <xsl:text>
     ts.print(", ");
--- a/src/share/vm/trace/traceEventIds.xsl	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/trace/traceEventIds.xsl	Mon Jul 07 08:54:46 2014 +0200
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
- Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2012, 2013, 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
@@ -23,8 +23,8 @@
 -->
 
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+<xsl:import href="xsl_util.xsl"/>
 <xsl:output method="text" indent="no" omit-xml-declaration="yes"/>
-<xsl:import href="xsl_util.xsl"/>
 
 <xsl:template match="/">
   <xsl:call-template name="file-header"/>
--- a/src/share/vm/trace/traceMacros.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/trace/traceMacros.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/src/share/vm/trace/traceTime.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/trace/traceTime.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,5 @@
 #include "prims/jni.h"
 
 typedef jlong TracingTime;
-typedef jlong RelativeTracingTime;
 
-#endif
+#endif // SHARE_VM_TRACE_TRACETIME_HPP
--- a/src/share/vm/trace/traceTypes.xsl	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/trace/traceTypes.xsl	Mon Jul 07 08:54:46 2014 +0200
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
- Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2012, 2013, 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
@@ -23,8 +23,8 @@
 -->
 
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+<xsl:import href="xsl_util.xsl"/>
 <xsl:output method="text" indent="no" omit-xml-declaration="yes"/>
-<xsl:import href="xsl_util.xsl"/>
 
 <xsl:template match="/">
   <xsl:call-template name="file-header"/>
@@ -32,11 +32,13 @@
 #ifndef TRACEFILES_JFRTYPES_HPP
 #define TRACEFILES_JFRTYPES_HPP
 
+
+#include "oops/klassOop.hpp"
+#include "oops/methodOop.hpp"
+#include "oops/symbol.hpp"
 #include "trace/traceDataTypes.hpp"
 #include "utilities/globalDefinitions.hpp"
-#include "oops/symbol.hpp"
-#include "oops/klassOop.hpp"
-#include "oops/methodOop.hpp"
+#include "utilities/ticks.hpp"
 
 enum JVMContentType {
   _not_a_content_type = (JVM_CONTENT_TYPES_START - 1),
--- a/src/share/vm/trace/tracetypes.xml	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/trace/tracetypes.xml	Mon Jul 07 08:54:46 2014 +0200
@@ -249,13 +249,13 @@
     <primary_type symbol="NANOS" datatype="LONG" contenttype="NANOS"
                   type="s8" sizeop="sizeof(s8)"/>
 
-    <!-- 64-bit signed integer, SEMANTIC value ABSOLUTE TICKS -->
+    <!-- 64-bit signed integer, SEMANTIC value TICKS -->
     <primary_type symbol="TICKS" datatype="LONG" contenttype="TICKS"
-                  type="s8" sizeop="sizeof(s8)"/>
+                  type="Ticks" sizeop="sizeof(s8)"/>
 
-    <!-- 64-bit signed integer, SEMANTIC value RELATIVE TICKS -->
-    <primary_type symbol="RELATIVE_TICKS" datatype="LONG" contenttype="TICKS"
-                  type="s8" sizeop="sizeof(s8)"/>
+    <!-- 64-bit signed integer, SEMANTIC value TICKS duration -->
+    <primary_type symbol="TICKSPAN" datatype="LONG" contenttype="TICKS"
+                  type="Tickspan" sizeop="sizeof(s8)"/>
 
     <!-- 64-bit unsigned integer, SEMANTIC value ADDRESS (mem loc) -->
     <primary_type symbol="ADDRESS" datatype="U8" contenttype="ADDRESS"
--- a/src/share/vm/trace/tracing.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/trace/tracing.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/src/share/vm/utilities/globalDefinitions.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/utilities/globalDefinitions.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -379,6 +379,14 @@
 
 #define align_size_up_(size, alignment) (((size) + ((alignment) - 1)) & ~((alignment) - 1))
 
+inline bool is_size_aligned(size_t size, size_t alignment) {
+  return align_size_up_(size, alignment) == size;
+}
+
+inline bool is_ptr_aligned(void* ptr, size_t alignment) {
+  return align_size_up_((intptr_t)ptr, (intptr_t)alignment) == (intptr_t)ptr;
+}
+
 inline intptr_t align_size_up(intptr_t size, intptr_t alignment) {
   return align_size_up_(size, alignment);
 }
@@ -389,6 +397,14 @@
   return align_size_down_(size, alignment);
 }
 
+inline void* align_ptr_up(void* ptr, size_t alignment) {
+  return (void*)align_size_up((intptr_t)ptr, (intptr_t)alignment);
+}
+
+inline void* align_ptr_down(void* ptr, size_t alignment) {
+  return (void*)align_size_down((intptr_t)ptr, (intptr_t)alignment);
+}
+
 // Align objects by rounding up their size, in HeapWord units.
 
 #define align_object_size_(size) align_size_up_(size, MinObjAlignment)
--- a/src/share/vm/utilities/growableArray.hpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/utilities/growableArray.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -194,6 +194,7 @@
 
   void  clear()                 { _len = 0; }
   int   length() const          { return _len; }
+  int   max_length() const      { return _max; }
   void  trunc_to(int l)         { assert(l <= _len,"cannot increase length"); _len = l; }
   bool  is_empty() const        { return _len == 0; }
   bool  is_nonempty() const     { return _len != 0; }
@@ -281,6 +282,13 @@
     return -1;
   }
 
+  int  find_from_end(const E& elem) const {
+    for (int i = _len-1; i >= 0; i--) {
+      if (_data[i] == elem) return i;
+    }
+    return -1;
+  }
+
   int  find(void* token, bool f(void*, E)) const {
     for (int i = 0; i < _len; i++) {
       if (f(token, _data[i])) return i;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/utilities/ticks.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2013, 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 "runtime/os.hpp"
+#include "utilities/ticks.inline.hpp"
+
+#ifdef ASSERT
+ const jlong Ticks::invalid_time_stamp = -2; // 0xFFFF FFFF`FFFF FFFE
+#endif
+
+void Ticks::stamp() {
+  _stamp_ticks = os::elapsed_counter();
+}
+
+const Ticks Ticks::now() {
+  Ticks t;
+  t.stamp();
+  return t;
+}
+
+Tickspan::Tickspan(const Ticks& end, const Ticks& start) {
+  assert(end.value() != Ticks::invalid_time_stamp, "end is unstamped!");
+  assert(start.value() != Ticks::invalid_time_stamp, "start is unstamped!");
+
+  assert(end >= start, "negative time!");
+
+  _span_ticks = end.value() - start.value();
+}
+
+template <typename ReturnType>
+static ReturnType time_conversion(const Tickspan& span, TicksToTimeHelper::Unit unit) {
+  assert(TicksToTimeHelper::SECONDS == unit ||
+         TicksToTimeHelper::MILLISECONDS == unit, "invalid unit!");
+
+  ReturnType frequency_per_unit = (ReturnType)os::elapsed_frequency() / (ReturnType)unit;
+
+  return (ReturnType) ((ReturnType)span.value() / frequency_per_unit);
+}
+
+double TicksToTimeHelper::seconds(const Tickspan& span) {
+  return time_conversion<double>(span, SECONDS);
+}
+
+jlong TicksToTimeHelper::milliseconds(const Tickspan& span) {
+  return time_conversion<jlong>(span, MILLISECONDS);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/utilities/ticks.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2013, 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_UTILITIES_TICKS_HPP
+#define SHARE_VM_UTILITIES_TICKS_HPP
+
+#include "memory/allocation.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+class Ticks;
+
+class Tickspan VALUE_OBJ_CLASS_SPEC {
+  friend class Ticks;
+  friend Tickspan operator-(const Ticks& end, const Ticks& start);
+
+ private:
+  jlong _span_ticks;
+
+  Tickspan(const Ticks& end, const Ticks& start);
+
+ public:
+  Tickspan() : _span_ticks(0) {}
+
+  Tickspan& operator+=(const Tickspan& rhs) {
+    _span_ticks += rhs._span_ticks;
+    return *this;
+  }
+
+  jlong value() const {
+    return _span_ticks;
+  }
+
+};
+
+class Ticks VALUE_OBJ_CLASS_SPEC {
+ private:
+  jlong _stamp_ticks;
+
+ public:
+  Ticks() : _stamp_ticks(0) {
+    assert((_stamp_ticks = invalid_time_stamp) == invalid_time_stamp,
+      "initial unstamped time value assignment");
+  }
+
+  Ticks& operator+=(const Tickspan& span) {
+    _stamp_ticks += span.value();
+    return *this;
+  }
+
+  Ticks& operator-=(const Tickspan& span) {
+    _stamp_ticks -= span.value();
+    return *this;
+  }
+
+  void stamp();
+
+  jlong value() const {
+    return _stamp_ticks;
+  }
+
+  static const Ticks now();
+
+#ifdef ASSERT
+  static const jlong invalid_time_stamp;
+#endif
+
+#ifndef PRODUCT
+  // only for internal use by GC VM tests
+  friend class TimePartitionPhasesIteratorTest;
+  friend class GCTimerTest;
+
+ private:
+  // implicit type conversion
+  Ticks(int ticks) : _stamp_ticks(ticks) {}
+
+#endif // !PRODUCT
+
+};
+
+class TicksToTimeHelper : public AllStatic {
+ public:
+  enum Unit {
+    SECONDS = 1,
+    MILLISECONDS = 1000
+  };
+  static double seconds(const Tickspan& span);
+  static jlong milliseconds(const Tickspan& span);
+};
+
+#endif // SHARE_VM_UTILITIES_TICKS_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/utilities/ticks.inline.hpp	Mon Jul 07 08:54:46 2014 +0200
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2013, 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_UTILITIES_TICKS_INLINE_HPP
+#define SHARE_VM_UTILITIES_TICKS_INLINE_HPP
+
+#include "utilities/ticks.hpp"
+
+inline Tickspan operator+(Tickspan lhs, const Tickspan& rhs) {
+  lhs += rhs;
+  return lhs;
+}
+
+inline bool operator==(const Tickspan& lhs, const Tickspan& rhs) {
+  return lhs.value() == rhs.value();
+}
+
+inline bool operator!=(const Tickspan& lhs, const Tickspan& rhs) {
+  return !operator==(lhs,rhs);
+}
+
+inline bool operator<(const Tickspan& lhs, const Tickspan& rhs) {
+  return lhs.value() < rhs.value();
+}
+
+inline bool operator>(const Tickspan& lhs, const Tickspan& rhs) {
+  return operator<(rhs,lhs);
+}
+
+inline bool operator<=(const Tickspan& lhs, const Tickspan& rhs) {
+  return !operator>(lhs,rhs);
+}
+
+inline bool operator>=(const Tickspan& lhs, const Tickspan& rhs) {
+  return !operator<(lhs,rhs);
+}
+
+inline Ticks operator+(Ticks lhs, const Tickspan& span) {
+  lhs += span;
+  return lhs;
+}
+
+inline Ticks operator-(Ticks lhs, const Tickspan& span) {
+  lhs -= span;
+  return lhs;
+}
+
+inline Tickspan operator-(const Ticks& end, const Ticks& start) {
+  return Tickspan(end, start);
+}
+
+inline bool operator==(const Ticks& lhs, const Ticks& rhs) {
+  return lhs.value() == rhs.value();
+}
+
+inline bool operator!=(const Ticks& lhs, const Ticks& rhs) {
+  return !operator==(lhs,rhs);
+}
+
+inline bool operator<(const Ticks& lhs, const Ticks& rhs) {
+  return lhs.value() < rhs.value();
+}
+
+inline bool operator>(const Ticks& lhs, const Ticks& rhs) {
+  return operator<(rhs,lhs);
+}
+
+inline bool operator<=(const Ticks& lhs, const Ticks& rhs) {
+  return !operator>(lhs,rhs);
+}
+
+inline bool operator>=(const Ticks& lhs, const Ticks& rhs) {
+  return !operator<(lhs,rhs);
+}
+
+#endif // SHARE_VM_UTILITIES_TICKS_INLINE_HPP
--- a/src/share/vm/utilities/vmError.cpp	Thu May 08 16:16:21 2014 +0200
+++ b/src/share/vm/utilities/vmError.cpp	Mon Jul 07 08:54:46 2014 +0200
@@ -705,18 +705,6 @@
        st->cr();
      }
 
-#ifdef LINUX
-  STEP(193, "(printing large pages allocation errors)")
-
-     if (_verbose) {
-       jint largepage_failures = os::Linux::num_largepage_commit_fails;
-       if (largepage_failures > 0) {
-         st->print_cr("Large page allocation failures have occurred " INT32_FORMAT " times", largepage_failures);
-         st->cr();
-       }
-     }
-#endif
-
   STEP(195, "(printing code cache information)" )
 
      if (_verbose && Universe::is_fully_initialized()) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/codegen/LoadWithMask.java	Mon Jul 07 08:54:46 2014 +0200
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8032207
+ * @summary Invalid node sizing for loadUS2L_immI16 and loadI2L_immI
+ * @run main/othervm -server -Xbatch -XX:-TieredCompilation -XX:CompileCommand=compileonly,LoadWithMask.foo LoadWithMask
+ *
+ */
+public class LoadWithMask {
+  static int x[] = new int[1];
+  static long foo() {
+    return x[0] & 0xfff0ffff;
+  }
+
+  public static void main(String[] args) {
+    x[0] = -1;
+    long l = 0;
+    for (int i = 0; i < 100000; ++i) {
+      l = foo();
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/codegen/LoadWithMask2.java	Mon Jul 07 08:54:46 2014 +0200
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8031743
+ * @summary loadI2L_immI broken for negative memory values
+ * @run main/othervm -server -Xbatch -XX:-TieredCompilation -XX:CompileCommand=compileonly,*.foo* LoadWithMask2
+ *
+ */
+public class LoadWithMask2 {
+  static int x;
+  static long foo1() {
+    return x & 0xfffffffe;
+  }
+  static long foo2() {
+    return x & 0xff000000;
+  }
+  static long foo3() {
+    return x & 0x8abcdef1;
+  }
+
+  public static void main(String[] args) {
+    x = -1;
+    long l = 0;
+    for (int i = 0; i < 100000; ++i) {
+      l = foo1() & foo2() & foo3();
+    }
+    if (l > 0) {
+      System.out.println("FAILED");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/reflection/ArrayNewInstanceOfVoid.java	Mon Jul 07 08:54:46 2014 +0200
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8029366
+ * @summary ShouldNotReachHere error when creating an array with component type of void
+ */
+
+public class ArrayNewInstanceOfVoid {
+    public static void main(String[] args) {
+        for (int i = 0; i < 100_000; i++) {
+            test();
+        }
+    }
+
+    private static void test() {
+        try {
+            java.lang.reflect.Array.newInstance(void.class, 2);
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/regalloc/C1ObjectSpillInLogicOp.java	Mon Jul 07 08:54:46 2014 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8027751
+ * @summary C1 crashes generating G1 post-barrier in Unsafe.getAndSetObject() intrinsic because of the new value spill
+ * @run main/othervm -XX:+UseG1GC C1ObjectSpillInLogicOp
+ *
+ * G1 barriers use logical operators (xor) on T_OBJECT mixed with T_LONG or T_INT.
+ * The current implementation of logical operations on x86 in C1 doesn't allow for long operands to be on stack.
+ * There is a special code in the register allocator that forces long arguments in registers on x86. However T_OBJECT
+ * can be spilled just fine, and in that case the xor emission will fail.
+ */
+
+import java.util.concurrent.atomic.*;
+public class C1ObjectSpillInLogicOp {
+  static public void main(String[] args) {
+    AtomicReferenceArray<Integer> x = new AtomicReferenceArray(128);
+    Integer y = new Integer(0);
+    for (int i = 0; i < 50000; i++) {
+      x.getAndSet(i % x.length(), y);
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/gc/8000311/Test8000311.java	Mon Jul 07 08:54:46 2014 +0200
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test Test8000311
+ * @key gc
+ * @bug 8000311
+ * @summary G1: ParallelGCThreads==0 broken
+ * @run main/othervm -XX:+UseG1GC -XX:ParallelGCThreads=0 -XX:+ResizePLAB -XX:+ExplicitGCInvokesConcurrent Test8000311
+ * @author filipp.zhinkin@oracle.com
+ */
+
+import java.util.*;
+
+public class Test8000311 {
+  public static void main(String args[]) {
+    for(int i = 0; i<100; i++) {
+      byte[] garbage = new byte[1000];
+      System.gc();
+    }
+  }
+}
--- a/test/gc/TestVerifyBeforeGCDuringStartup.java	Thu May 08 16:16:21 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test TestVerifyBeforeGCDuringStartup.java
- * @key gc
- * @bug 8010463
- * @summary Simple test run with -XX:+VerifyBeforeGC -XX:-UseTLAB to verify 8010463
- * @library /testlibrary
- */
-
-import com.oracle.java.testlibrary.OutputAnalyzer;
-import com.oracle.java.testlibrary.ProcessTools;
-
-public class TestVerifyBeforeGCDuringStartup {
-  public static void main(String args[]) throws Exception {
-    ProcessBuilder pb =
-      ProcessTools.createJavaProcessBuilder(System.getProperty("test.vm.opts"),
-                                            "-XX:-UseTLAB",
-                                            "-XX:+UnlockDiagnosticVMOptions",
-                                            "-XX:+VerifyBeforeGC", "-version");
-    OutputAnalyzer output = new OutputAnalyzer(pb.start());
-    output.shouldContain("[Verifying");
-    output.shouldHaveExitValue(0);
-  }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/gc/TestVerifyDuringStartup.java	Mon Jul 07 08:54:46 2014 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test TestVerifyDuringStartup.java
+ * @key gc
+ * @bug 8010463
+ * @summary Simple test run with -XX:+VerifyDuringStartup -XX:-UseTLAB to verify 8010463
+ * @library /testlibrary
+ */
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.ProcessTools;
+
+public class TestVerifyDuringStartup {
+  public static void main(String args[]) throws Exception {
+    ProcessBuilder pb =
+      ProcessTools.createJavaProcessBuilder(System.getProperty("test.vm.opts"),
+                                            "-XX:-UseTLAB",
+                                            "-XX:+UnlockDiagnosticVMOptions",
+                                            "-XX:+VerifyDuringStartup", "-version");
+    OutputAnalyzer output = new OutputAnalyzer(pb.start());
+    output.shouldContain("[Verifying");
+    output.shouldHaveExitValue(0);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/gc/TestVerifySilently.java	Mon Jul 07 08:54:46 2014 +0200
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+
+/* @test TestVerifySilently.java
+ * @key gc
+ * @bug 8032771
+ * @summary Test silent verification.
+ * @library /testlibrary
+ */
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.ProcessTools;
+import java.util.ArrayList;
+import java.util.Collections;
+
+class RunSystemGC {
+  public static void main(String args[]) throws Exception {
+    System.gc();
+  }
+}
+
+
+public class TestVerifySilently {
+  private static String[] getTestJavaOpts() {
+    String testVmOptsStr = System.getProperty("test.java.opts");
+    if (!testVmOptsStr.isEmpty()) {
+      return testVmOptsStr.split(" ");
+    } else {
+      return new String[] {};
+    }
+  }
+
+  private static OutputAnalyzer runTest(boolean verifySilently) throws Exception {
+    ArrayList<String> vmOpts = new ArrayList();
+
+    Collections.addAll(vmOpts, getTestJavaOpts());
+    Collections.addAll(vmOpts, new String[] {"-XX:+UnlockDiagnosticVMOptions",
+                                             "-XX:+VerifyDuringStartup",
+                                             "-XX:+VerifyBeforeGC",
+                                             "-XX:+VerifyAfterGC",
+                                             "-XX:" + (verifySilently ? "+":"-") + "VerifySilently",
+                                             RunSystemGC.class.getName()});
+    ProcessBuilder pb =
+      ProcessTools.createJavaProcessBuilder(vmOpts.toArray(new String[vmOpts.size()]));
+    OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+    System.out.println("Output:\n" + output.getOutput());
+    return output;
+  }
+
+
+  public static void main(String args[]) throws Exception {
+
+    OutputAnalyzer output;
+
+    output = runTest(false);
+    output.shouldContain("[Verifying");
+    output.shouldHaveExitValue(0);
+
+    output = runTest(true);
+    output.shouldNotContain("[Verifying");
+    output.shouldHaveExitValue(0);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/gc/arguments/TestDynMaxHeapFreeRatio.java	Mon Jul 07 08:54:46 2014 +0200
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+/**
+ * @test TestDynMaxHeapFreeRatio
+ * @bug 8028391
+ * @summary Verify that MaxHeapFreeRatio flag is manageable
+ * @library /testlibrary
+ * @run main TestDynMaxHeapFreeRatio
+ * @run main/othervm -XX:MinHeapFreeRatio=0 -XX:MaxHeapFreeRatio=100 TestDynMaxHeapFreeRatio
+ * @run main/othervm -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=50 -XX:-UseAdaptiveSizePolicy TestDynMaxHeapFreeRatio
+ * @run main/othervm -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=50 TestDynMaxHeapFreeRatio
+ * @run main/othervm -XX:MinHeapFreeRatio=51 -XX:MaxHeapFreeRatio=52 TestDynMaxHeapFreeRatio
+ * @run main/othervm -XX:MinHeapFreeRatio=75 -XX:MaxHeapFreeRatio=100 TestDynMaxHeapFreeRatio
+ */
+import com.oracle.java.testlibrary.TestDynamicVMOption;
+import com.oracle.java.testlibrary.DynamicVMOptionChecker;
+
+public class TestDynMaxHeapFreeRatio extends TestDynamicVMOption {
+
+    public static final String MinFreeRatioFlagName = "MinHeapFreeRatio";
+    public static final String MaxFreeRatioFlagName = "MaxHeapFreeRatio";
+
+    public TestDynMaxHeapFreeRatio() {
+        super(MaxFreeRatioFlagName);
+    }
+
+    public void test() {
+
+        int minHeapFreeValue = DynamicVMOptionChecker.getIntValue(MinFreeRatioFlagName);
+        System.out.println(MinFreeRatioFlagName + " = " + minHeapFreeValue);
+
+        testPercentageValues();
+
+        checkInvalidValue(Integer.toString(minHeapFreeValue - 1));
+        checkValidValue(Integer.toString(minHeapFreeValue));
+        checkValidValue("100");
+    }
+
+    public static void main(String args[]) throws Exception {
+        new TestDynMaxHeapFreeRatio().test();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/gc/arguments/TestDynMinHeapFreeRatio.java	Mon Jul 07 08:54:46 2014 +0200
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+/**
+ * @test TestDynMinHeapFreeRatio
+ * @bug 8028391
+ * @summary Verify that MinHeapFreeRatio flag is manageable
+ * @library /testlibrary
+ * @run main TestDynMinHeapFreeRatio
+ * @run main/othervm -XX:MinHeapFreeRatio=0 -XX:MaxHeapFreeRatio=100 TestDynMinHeapFreeRatio
+ * @run main/othervm -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=50 -XX:-UseAdaptiveSizePolicy TestDynMinHeapFreeRatio
+ * @run main/othervm -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=50 TestDynMinHeapFreeRatio
+ * @run main/othervm -XX:MinHeapFreeRatio=51 -XX:MaxHeapFreeRatio=52 TestDynMinHeapFreeRatio
+ * @run main/othervm -XX:MinHeapFreeRatio=75 -XX:MaxHeapFreeRatio=100 TestDynMinHeapFreeRatio
+ */
+import com.oracle.java.testlibrary.TestDynamicVMOption;
+import com.oracle.java.testlibrary.DynamicVMOptionChecker;
+
+public class TestDynMinHeapFreeRatio extends TestDynamicVMOption {
+
+    public static final String MinFreeRatioFlagName = "MinHeapFreeRatio";
+    public static final String MaxFreeRatioFlagName = "MaxHeapFreeRatio";
+
+    public TestDynMinHeapFreeRatio() {
+        super(MinFreeRatioFlagName);
+    }
+
+    public void test() {
+        int maxHeapFreeValue = DynamicVMOptionChecker.getIntValue(MaxFreeRatioFlagName);
+        System.out.println(MaxFreeRatioFlagName + " = " + maxHeapFreeValue);
+
+        testPercentageValues();
+
+        checkInvalidValue(Integer.toString(maxHeapFreeValue + 1));
+        checkValidValue(Integer.toString(maxHeapFreeValue));
+        checkValidValue("0");
+    }
+
+    public static void main(String args[]) throws Exception {
+        new TestDynMinHeapFreeRatio().test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/gc/g1/TestHumongousCodeCacheRoots.java	Mon Jul 07 08:54:46 2014 +0200
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key regression
+ * @key gc
+ * @bug 8027756
+ * @library /testlibrary /testlibrary/whitebox
+ * @build TestHumongousCodeCacheRoots
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @summary Humongous objects may have references from the code cache
+ * @run main TestHumongousCodeCacheRoots
+*/
+
+import com.oracle.java.testlibrary.*;
+import sun.hotspot.WhiteBox;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+class TestHumongousCodeCacheRootsHelper {
+
+    static final int n = 1000000;
+    static final int[] AA = new int[n];
+    static final int[] BB = new int[n];
+
+    public static void main(String args[]) throws Exception {
+        // do some work so that the compiler compiles this method, inlining the
+        // reference to the integer array (which is a humonguous object) into
+        // the code cache.
+        for(int i = 0; i < n; i++) {
+            AA[i] = 0;
+            BB[i] = 0;
+        }
+        // trigger a GC that checks that the verification code allows humongous
+        // objects with code cache roots; objects should be all live here.
+        System.gc();
+
+        // deoptimize everyhing: this should make all compiled code zombies.
+        WhiteBox wb = WhiteBox.getWhiteBox();
+        wb.deoptimizeAll();
+
+        // trigger a GC that checks that the verification code allows humongous
+        // objects with code cache roots; objects should be all live here.
+        System.gc();
+
+        // wait a little for the code cache sweeper to try to clean up zombie nmethods
+        // and unregister the code roots.
+        try { Thread.sleep(5000); } catch (InterruptedException ex) { }
+
+        // do some work on the arrays to make sure that they need to be live after the GCs
+        for(int i = 0; i < n; i++) {
+            AA[i] = 1;
+            BB[i] = 10;
+        }
+
+        System.out.println();
+    }
+}
+
+public class TestHumongousCodeCacheRoots {
+
+  /**
+   * Executes a class in a new VM process with the given parameters.
+   * @param vmargs Arguments to the VM to run
+   * @param classname Name of the class to run
+   * @param arguments Arguments to the class
+   * @param useTestDotJavaDotOpts Use test.java.opts as part of the VM argument string
+   * @return The OutputAnalyzer with the results for the invocation.
+   */
+  public static OutputAnalyzer runWhiteBoxTest(String[] vmargs, String classname, String[] arguments, boolean useTestDotJavaDotOpts) throws Exception {
+    ArrayList<String> finalargs = new ArrayList<String>();
+
+    String[] whiteboxOpts = new String[] {
+      "-Xbootclasspath/a:.",
+      "-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI",
+      "-cp", System.getProperty("java.class.path"),
+    };
+
+    if (useTestDotJavaDotOpts) {
+      // System.getProperty("test.java.opts") is '' if no options is set,
+      // we need to skip such a result
+      String[] externalVMOpts = new String[0];
+      if (System.getProperty("test.java.opts") != null && System.getProperty("test.java.opts").length() != 0) {
+        externalVMOpts = System.getProperty("test.java.opts").split(" ");
+      }
+      finalargs.addAll(Arrays.asList(externalVMOpts));
+    }
+
+    finalargs.addAll(Arrays.asList(vmargs));
+    finalargs.addAll(Arrays.asList(whiteboxOpts));
+    finalargs.add(classname);
+    finalargs.addAll(Arrays.asList(arguments));
+
+    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(finalargs.toArray(new String[0]));
+    OutputAnalyzer output = new OutputAnalyzer(pb.start());
+    output.shouldHaveExitValue(0);
+
+    return output;
+  }
+
+  public static void runTest(String compiler, String[] other) throws Exception {
+    ArrayList<String> joined = new ArrayList<String>();
+    joined.add(compiler);
+    joined.addAll(Arrays.asList(other));
+    runWhiteBoxTest(joined.toArray(new String[0]), TestHumongousCodeCacheRootsHelper.class.getName(),
+      new String[] {}, false);
+  }
+
+  public static void main(String[] args) throws Exception {
+    final String[] baseArguments = new String[] {
+      "-XX:+UseG1GC", "-XX:G1HeapRegionSize=1M", "-Xmx100M", // make sure we get a humongous region
+      "-XX:+UnlockDiagnosticVMOptions",
+      "-XX:InitiatingHeapOccupancyPercent=1", // strong code root marking
+      "-XX:+G1VerifyHeapRegionCodeRoots", "-XX:+VerifyAfterGC", // make sure that verification is run
+      "-XX:NmethodSweepFraction=1", "-XX:NmethodSweepCheckInterval=1",  // make the code cache sweep more predictable
+    };
+    runTest("-client", baseArguments);
+    runTest("-server", baseArguments);
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/gc/g1/TestPrintRegionRememberedSetInfo.java	Mon Jul 07 08:54:46 2014 +0200
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test TestPrintRegionRememberedSetInfo
+ * @key gc
+ * @bug 8014240
+ * @summary Test output of G1PrintRegionRememberedSetInfo
+ * @library /testlibrary
+ * @run main TestPrintRegionRememberedSetInfo
+ * @author thomas.schatzl@oracle.com
+ */
+
+import com.oracle.java.testlibrary.*;
+import java.lang.Thread;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+class RunAndWaitForMarking {
+    public static void main(String[] args) {
+        System.gc();
+        try {
+            Thread.sleep(200);
+        } catch (InterruptedException e) {
+        }
+    }
+}
+
+public class TestPrintRegionRememberedSetInfo {
+
+    public static String runTest(String arg) throws Exception {
+        ArrayList<String> finalargs = new ArrayList<String>();
+        String[] defaultArgs = new String[] {
+            "-XX:+UseG1GC",
+            "-Xmx10m",
+            "-XX:+ExplicitGCInvokesConcurrent",
+            "-XX:+UnlockDiagnosticVMOptions",
+            "-XX:+G1PrintRegionLivenessInfo",
+            "-XX:G1HeapRegionSize=1M",
+            "-XX:InitiatingHeapOccupancyPercent=0",
+        };
+
+        finalargs.addAll(Arrays.asList(defaultArgs));
+        finalargs.add(arg);
+
+        finalargs.add(RunAndWaitForMarking.class.getName());
+
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+            finalargs.toArray(new String[0]));
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        output.shouldHaveExitValue(0);
+
+        String result = output.getStdout();
+        return result;
+    }
+
+    public static void main(String[] args) throws Exception {
+        String result;
+
+        result = runTest("-XX:+G1PrintRegionLivenessInfo");
+        // check that we got region statistics output
+        if (result.indexOf("PHASE") == -1) {
+            throw new RuntimeException("Unexpected output from -XX:+PrintRegionLivenessInfo found.");
+        }
+
+        result = runTest("-XX:-G1PrintRegionLivenessInfo");
+        if (result.indexOf("remset") != -1) {
+            throw new RuntimeException("Should find remembered set information in output.");
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/gc/g1/TestSummarizeRSetStats.java	Mon Jul 07 08:54:46 2014 +0200
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test TestSummarizeRSetStats.java
+ * @bug 8013895
+ * @library /testlibrary
+ * @build TestSummarizeRSetStatsTools TestSummarizeRSetStats
+ * @summary Verify output of -XX:+G1SummarizeRSetStats
+ * @run main TestSummarizeRSetStats
+ *
+ * Test the output of G1SummarizeRSetStats in conjunction with G1SummarizeRSetStatsPeriod.
+ */
+
+public class TestSummarizeRSetStats {
+
+    public static void main(String[] args) throws Exception {
+        String result;
+
+        if (!TestSummarizeRSetStatsTools.testingG1GC()) {
+            return;
+        }
+
+        // no remembered set summary output
+        result = TestSummarizeRSetStatsTools.runTest(null, 0);
+        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 0, 0);
+
+        // no remembered set summary output
+        result = TestSummarizeRSetStatsTools.runTest(null, 2);
+        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 0, 0);
+
+        // no remembered set summary output
+        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:G1SummarizeRSetStatsPeriod=1" }, 3);
+        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 0, 0);
+
+        // single remembered set summary output at the end
+        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats" }, 0);
+        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 0);
+
+        // single remembered set summary output at the end
+        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats" }, 2);
+        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 0);
+
+        // single remembered set summary output
+        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 0);
+        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 0);
+
+        // two times remembered set summary output
+        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 1);
+        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 2);
+
+        // four times remembered set summary output
+        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 3);
+        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 6);
+
+        // three times remembered set summary output
+        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=2" }, 3);
+        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 4);
+
+        // single remembered set summary output
+        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=100" }, 3);
+        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 2);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/gc/g1/TestSummarizeRSetStatsPerRegion.java	Mon Jul 07 08:54:46 2014 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test TestSummarizeRSetStatsPerRegion.java
+ * @bug 8014078
+ * @library /testlibrary
+ * @build TestSummarizeRSetStatsTools TestSummarizeRSetStatsPerRegion
+ * @summary Verify output of -XX:+G1SummarizeRSetStats in regards to per-region type output
+ * @run main TestSummarizeRSetStatsPerRegion
+ */
+
+import com.oracle.java.testlibrary.*;
+import java.lang.Thread;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+public class TestSummarizeRSetStatsPerRegion {
+
+    public static void main(String[] args) throws Exception {
+        String result;
+
+        if (!TestSummarizeRSetStatsTools.testingG1GC()) {
+            return;
+        }
+
+        // single remembered set summary output at the end
+        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats" }, 0);
+        TestSummarizeRSetStatsTools.expectPerRegionRSetSummaries(result, 1, 0);
+
+        // two times remembered set summary output
+        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 1);
+        TestSummarizeRSetStatsTools.expectPerRegionRSetSummaries(result, 1, 2);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/gc/g1/TestSummarizeRSetStatsThreads.java	Mon Jul 07 08:54:46 2014 +0200
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test TestSummarizeRSetStatsThreads
+ * @bug 8025441
+ * @summary Ensure that various values of worker threads/concurrent
+ * refinement threads do not crash the VM.
+ * @key gc
+ * @library /testlibrary
+ */
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.oracle.java.testlibrary.ProcessTools;
+import com.oracle.java.testlibrary.OutputAnalyzer;
+
+public class TestSummarizeRSetStatsThreads {
+
+  private static void runTest(int refinementThreads, int workerThreads) throws Exception {
+    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
+                                                              "-XX:+UnlockDiagnosticVMOptions",
+                                                              "-XX:+G1SummarizeRSetStats",
+                                                              "-XX:G1ConcRefinementThreads=" + refinementThreads,
+                                                              "-XX:ParallelGCThreads=" + workerThreads,
+                                                              "-version");
+
+    OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+    // check output to contain the string "Concurrent RS threads times (s)" followed by
+    // the correct number of values in the next line.
+
+    // a zero in refinement thread numbers indicates that the value in ParallelGCThreads should be used.
+    // Additionally use at least one thread.
+    int expectedNumRefinementThreads = refinementThreads == 0 ? workerThreads : refinementThreads;
+    expectedNumRefinementThreads = Math.max(1, expectedNumRefinementThreads);
+    // create the pattern made up of n copies of a floating point number pattern
+    String numberPattern = String.format("%0" + expectedNumRefinementThreads + "d", 0)
+      .replace("0", "\\s+\\d+\\.\\d+");
+    String pattern = "Concurrent RS threads times \\(s\\)$" + numberPattern + "$";
+    Matcher m = Pattern.compile(pattern, Pattern.MULTILINE).matcher(output.getStdout());
+
+    if (!m.find()) {
+      throw new Exception("Could not find correct output for concurrent RS threads times in stdout," +
+        " should match the pattern \"" + pattern + "\", but stdout is \n" + output.getStdout());
+    }
+    output.shouldHaveExitValue(0);
+  }
+
+  public static void main(String[] args) throws Exception {
+    if (!TestSummarizeRSetStatsTools.testingG1GC()) {
+      return;
+    }
+    // different valid combinations of number of refinement and gc worker threads
+    runTest(0, 0);
+    runTest(0, 5);
+    runTest(5, 0);
+    runTest(10, 10);
+    runTest(1, 2);
+    runTest(4, 3);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/gc/g1/TestSummarizeRSetStatsTools.java	Mon Jul 07 08:54:46 2014 +0200
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+/*
+ * Common helpers for TestSummarizeRSetStats* tests
+ */
+
+import sun.management.ManagementFactoryHelper;
+import com.sun.management.HotSpotDiagnosticMXBean;
+import com.sun.management.VMOption;
+
+import com.oracle.java.testlibrary.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.lang.Thread;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+class VerifySummaryOutput {
+    // 4M size, both are directly allocated into the old gen
+    static Object[] largeObject1 = new Object[1024 * 1024];
+    static Object[] largeObject2 = new Object[1024 * 1024];
+
+    static int[] temp;
+
+    public static void main(String[] args) {
+        // create some cross-references between these objects
+        for (int i = 0; i < largeObject1.length; i++) {
+            largeObject1[i] = largeObject2;
+        }
+
+        for (int i = 0; i < largeObject2.length; i++) {
+            largeObject2[i] = largeObject1;
+        }
+
+        int numGCs = Integer.parseInt(args[0]);
+
+        if (numGCs > 0) {
+            // try to force a minor collection: the young gen is 4M, the
+            // amount of data allocated below is roughly that (4*1024*1024 +
+            // some header data)
+            for (int i = 0; i < 1024 ; i++) {
+                temp = new int[1024];
+            }
+        }
+
+        for (int i = 0; i < numGCs - 1; i++) {
+            System.gc();
+        }
+    }
+}
+
+public class TestSummarizeRSetStatsTools {
+
+    // the VM is currently run using G1GC, i.e. trying to test G1 functionality.
+    public static boolean testingG1GC() {
+        HotSpotDiagnosticMXBean diagnostic = ManagementFactoryHelper.getDiagnosticMXBean();
+
+        VMOption option = diagnostic.getVMOption("UseG1GC");
+        if (option.getValue().equals("false")) {
+          System.out.println("Skipping this test. It is only a G1 test.");
+          return false;
+        }
+        return true;
+    }
+
+    public static String runTest(String[] additionalArgs, int numGCs) throws Exception {
+        ArrayList<String> finalargs = new ArrayList<String>();
+        String[] defaultArgs = new String[] {
+            "-XX:+UseG1GC",
+            "-XX:+UseCompressedOops",
+            "-Xmn4m",
+            "-Xmx20m",
+            "-XX:InitiatingHeapOccupancyPercent=100", // we don't want the additional GCs due to initial marking
+            "-XX:+PrintGC",
+            "-XX:+UnlockDiagnosticVMOptions",
+            "-XX:G1HeapRegionSize=1M",
+        };
+
+        finalargs.addAll(Arrays.asList(defaultArgs));
+
+        if (additionalArgs != null) {
+            finalargs.addAll(Arrays.asList(additionalArgs));
+        }
+
+        finalargs.add(VerifySummaryOutput.class.getName());
+        finalargs.add(String.valueOf(numGCs));
+
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+            finalargs.toArray(new String[0]));
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+        output.shouldHaveExitValue(0);
+
+        String result = output.getStdout();
+        return result;
+    }
+
+    private static void checkCounts(int expected, int actual, String which) throws Exception {
+        if (expected != actual) {
+            throw new Exception("RSet summaries mention " + which + " regions an incorrect number of times. Expected " + expected + ", got " + actual);
+        }
+    }
+
+    public static void expectPerRegionRSetSummaries(String result, int expectedCumulative, int expectedPeriodic) throws Exception {
+        expectRSetSummaries(result, expectedCumulative, expectedPeriodic);
+        int actualYoung = result.split("Young regions").length - 1;
+        int actualHumonguous = result.split("Humonguous regions").length - 1;
+        int actualFree = result.split("Free regions").length - 1;
+        int actualOther = result.split("Old regions").length - 1;
+
+        // the strings we check for above are printed four times per summary
+        int expectedPerRegionTypeInfo = (expectedCumulative + expectedPeriodic) * 4;
+
+        checkCounts(expectedPerRegionTypeInfo, actualYoung, "Young");
+        checkCounts(expectedPerRegionTypeInfo, actualHumonguous, "Humonguous");
+        checkCounts(expectedPerRegionTypeInfo, actualFree, "Free");
+        checkCounts(expectedPerRegionTypeInfo, actualOther, "Old");
+    }
+
+    public static void expectRSetSummaries(String result, int expectedCumulative, int expectedPeriodic) throws Exception {
+        int actualTotal = result.split("concurrent refinement").length - 1;
+        int actualCumulative = result.split("Cumulative RS summary").length - 1;
+
+        if (expectedCumulative != actualCumulative) {
+            throw new Exception("Incorrect amount of RSet summaries at the end. Expected " + expectedCumulative + ", got " + actualCumulative);
+        }
+
+        if (expectedPeriodic != (actualTotal - actualCumulative)) {
+            throw new Exception("Incorrect amount of per-period RSet summaries at the end. Expected " + expectedPeriodic + ", got " + (actualTotal - actualCumulative));
+        }
+    }
+}
+
--- a/test/runtime/6929067/Test6929067.sh	Thu May 08 16:16:21 2014 +0200
+++ b/test/runtime/6929067/Test6929067.sh	Mon Jul 07 08:54:46 2014 +0200
@@ -3,6 +3,7 @@
 ##
 ## @test Test6929067.sh
 ## @bug 6929067
+## @bug 8021296
 ## @summary Stack guard pages should be removed when thread is detached
 ## @compile T.java
 ## @run shell Test6929067.sh
@@ -21,6 +22,11 @@
 OS=`uname -s`
 case "$OS" in
   Linux)
+    gcc_cmd=`which gcc`
+    if [ "x$gcc_cmd" == "x" ]; then
+        echo "WARNING: gcc not found. Cannot execute test." 2>&1
+        exit 0;
+    fi
     NULL=/dev/null
     PS=":"
     FS="/"
@@ -119,10 +125,10 @@
 # Check to ensure you have a /usr/lib/libpthread.so if you don't please look
 # for /usr/lib/`uname -m`-linux-gnu version ensure to add that path to below compilation.
 
-gcc -DLINUX ${COMP_FLAG} -o invoke \
-  -I${COMPILEJAVA}/include -I${COMPILEJAVA}/include/linux \
-  -L${COMPILEJAVA}/jre/lib/${ARCH}/${VMTYPE} \
-  -ljvm -lpthread invoke.c
+$gcc_cmd -DLINUX ${COMP_FLAG} -o invoke \
+    -I${COMPILEJAVA}/include -I${COMPILEJAVA}/include/linux \
+    -L${COMPILEJAVA}/jre/lib/${ARCH}/${VMTYPE} \
+    -ljvm -lpthread invoke.c
 
 ./invoke
 exit $?
--- a/test/runtime/7107135/Test7107135.sh	Thu May 08 16:16:21 2014 +0200
+++ b/test/runtime/7107135/Test7107135.sh	Mon Jul 07 08:54:46 2014 +0200
@@ -27,6 +27,7 @@
 ##
 ## @test Test7107135.sh
 ## @bug 7107135
+## @bug 8021296
 ## @summary Stack guard pages lost after loading library with executable stack.
 ## @run shell Test7107135.sh
 ##
@@ -45,6 +46,11 @@
 case "$OS" in
   Linux)
     echo "Testing on Linux"
+    gcc_cmd=`which gcc`
+    if [ "x$gcc_cmd" == "x" ]; then
+        echo "WARNING: gcc not found. Cannot execute test." 2>&1
+        exit 0;
+    fi
     ;;
   *)
     NULL=NUL
@@ -62,7 +68,10 @@
 cp ${TESTSRC}${FS}*.java ${THIS_DIR}
 ${TESTJAVA}${FS}bin${FS}javac *.java
 
-gcc -fPIC -shared -c -o test.o -I${TESTJAVA}${FS}include -I${TESTJAVA}${FS}include${FS}linux ${TESTSRC}${FS}test.c
+$gcc_cmd -fPIC -shared -c -o test.o \
+    -I${TESTJAVA}${FS}include -I${TESTJAVA}${FS}include${FS}linux \
+    ${TESTSRC}${FS}test.c
+
 ld -shared -z   execstack -o libtest-rwx.so test.o
 ld -shared -z noexecstack -o libtest-rw.so  test.o
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/jsig/Test8017498.sh	Mon Jul 07 08:54:46 2014 +0200
@@ -0,0 +1,94 @@
+#!/bin/sh
+
+#
+#  Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+#  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+#  This code is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License version 2 only, as
+#  published by the Free Software Foundation.
+#
+#  This code is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+#  version 2 for more details (a copy is included in the LICENSE file that
+#  accompanied this code).
+#
+#  You should have received a copy of the GNU General Public License version
+#  2 along with this work; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+#  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+#  or visit www.oracle.com if you need additional information or have any
+#  questions.
+#
+
+##
+## @test Test8017498.sh
+## @bug 8017498
+## @bug 8020791
+## @bug 8021296
+## @summary sigaction(sig) results in process hang/timed-out if sig is much greater than SIGRTMAX
+## @run shell/timeout=30 Test8017498.sh
+##
+
+if [ "${TESTSRC}" = "" ]
+then
+  TESTSRC=${PWD}
+  echo "TESTSRC not set.  Using "${TESTSRC}" as default"
+fi
+echo "TESTSRC=${TESTSRC}"
+## Adding common setup Variables for running shell tests.
+. ${TESTSRC}/../../test_env.sh
+
+# set platform-dependent variables
+OS=`uname -s`
+case "$OS" in
+  Linux)
+    echo "Testing on Linux"
+    gcc_cmd=`which gcc`
+    if [ "x$gcc_cmd" == "x" ]; then
+        echo "WARNING: gcc not found. Cannot execute test." 2>&1
+        exit 0;
+    fi
+    if [ "$VM_BITS" = "64" ]
+    then
+        MY_LD_PRELOAD=${TESTJAVA}${FS}jre${FS}lib${FS}amd64${FS}libjsig.so
+    else
+        MY_LD_PRELOAD=${TESTJAVA}${FS}jre${FS}lib${FS}i386${FS}libjsig.so
+    fi
+    echo MY_LD_PRELOAD = ${MY_LD_PRELOAD}
+    ;;
+  *)
+    echo "Test passed; only valid for Linux"
+    exit 0;
+    ;;
+esac
+
+THIS_DIR=.
+
+cp ${TESTSRC}${FS}*.java ${THIS_DIR}
+${TESTJAVA}${FS}bin${FS}javac *.java
+
+$gcc_cmd -DLINUX -fPIC -shared \
+    -o ${TESTSRC}${FS}libTestJNI.so \
+    -I${TESTJAVA}${FS}include \
+    -I${TESTJAVA}${FS}include${FS}linux \
+    ${TESTSRC}${FS}TestJNI.c
+
+# run the java test in the background
+cmd="LD_PRELOAD=$MY_LD_PRELOAD \
+    ${TESTJAVA}${FS}bin${FS}java \
+    -Djava.library.path=${TESTSRC}${FS} -server TestJNI 100"
+echo "$cmd > test.out 2>&1"
+eval $cmd > test.out 2>&1
+
+grep "old handler" test.out > ${NULL}
+if [ $? = 0 ]
+then
+    echo "Test Passed"
+    exit 0
+fi
+
+echo "Test Failed"
+exit 1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/jsig/TestJNI.c	Mon Jul 07 08:54:46 2014 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2013, 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 <stdio.h>
+#include <jni.h>
+#include <signal.h>
+#include <sys/ucontext.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void sig_handler(int sig, siginfo_t *info, ucontext_t *context) {
+
+    printf( " HANDLER (1) " );
+}
+
+JNIEXPORT void JNICALL Java_TestJNI_doSomething(JNIEnv *env, jclass klass, jint val) {
+    struct sigaction act;
+    struct sigaction oact;
+
+    act.sa_flags = SA_ONSTACK|SA_RESTART|SA_SIGINFO;
+    sigfillset(&act.sa_mask);
+    act.sa_handler = SIG_DFL;
+    act.sa_sigaction = (void (*)())sig_handler;
+    sigaction(0x20+val, &act, &oact);
+
+    printf( " doSomething(%d) " , val);
+    printf( " old handler = %p " , oact.sa_handler);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/jsig/TestJNI.java	Mon Jul 07 08:54:46 2014 +0200
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+public class TestJNI {
+    static {
+        System.loadLibrary("TestJNI");
+    }
+    public static native void doSomething(int val);
+    public static void main(String[] args) {
+        int intArg = 43;
+        if (args.length > 0) {
+            try {
+                intArg = Integer.parseInt(args[0]);
+            } catch (NumberFormatException e) {
+                System.err.println("arg " + args[0] + " must be an integer");
+                System.exit(1);
+            }
+        }
+        TestJNI.doSomething(intArg);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/memory/LargePages/TestLargePagesFlags.java	Mon Jul 07 08:54:46 2014 +0200
@@ -0,0 +1,389 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test TestLargePagesFlags
+ * @summary Tests how large pages are choosen depending on the given large pages flag combinations.
+ * @library /testlibrary
+ * @run main TestLargePagesFlags
+ */
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.Platform;
+import com.oracle.java.testlibrary.ProcessTools;
+import java.util.ArrayList;
+
+public class TestLargePagesFlags {
+
+  public static void main(String [] args) throws Exception {
+    if (!Platform.isLinux()) {
+      System.out.println("Skipping. TestLargePagesFlags has only been implemented for Linux.");
+      return;
+    }
+
+    testUseTransparentHugePages();
+    testUseHugeTLBFS();
+    testUseSHM();
+    testCombinations();
+  }
+
+  public static void testUseTransparentHugePages() throws Exception {
+    if (!canUse(UseTransparentHugePages(true))) {
+      System.out.println("Skipping testUseTransparentHugePages");
+      return;
+    }
+
+    // -XX:-UseLargePages overrides all other flags.
+    new FlagTester()
+      .use(UseLargePages(false),
+           UseTransparentHugePages(true))
+      .expect(
+           UseLargePages(false),
+           UseTransparentHugePages(false),
+           UseHugeTLBFS(false),
+           UseSHM(false));
+
+    // Explicitly turn on UseTransparentHugePages.
+    new FlagTester()
+      .use(UseTransparentHugePages(true))
+      .expect(
+           UseLargePages(true),
+           UseTransparentHugePages(true),
+           UseHugeTLBFS(false),
+           UseSHM(false));
+
+    new FlagTester()
+      .use(UseLargePages(true),
+           UseTransparentHugePages(true))
+      .expect(
+           UseLargePages(true),
+           UseTransparentHugePages(true),
+           UseHugeTLBFS(false),
+           UseSHM(false));
+
+    // Setting a specific large pages flag will turn
+    // off heuristics to choose large pages type.
+    new FlagTester()
+      .use(UseLargePages(true),
+           UseTransparentHugePages(false))
+      .expect(
+           UseLargePages(false),
+           UseTransparentHugePages(false),
+           UseHugeTLBFS(false),
+           UseSHM(false));
+
+    // Don't turn on UseTransparentHugePages
+    // unless the user explicitly asks for them.
+    new FlagTester()
+      .use(UseLargePages(true))
+      .expect(
+           UseTransparentHugePages(false));
+  }
+
+  public static void testUseHugeTLBFS() throws Exception {
+    if (!canUse(UseHugeTLBFS(true))) {
+      System.out.println("Skipping testUseHugeTLBFS");
+      return;
+    }
+
+    // -XX:-UseLargePages overrides all other flags.
+    new FlagTester()
+      .use(UseLargePages(false),
+           UseHugeTLBFS(true))
+      .expect(
+           UseLargePages(false),
+           UseTransparentHugePages(false),
+           UseHugeTLBFS(false),
+           UseSHM(false));
+
+    // Explicitly turn on UseHugeTLBFS.
+    new FlagTester()
+      .use(UseHugeTLBFS(true))
+      .expect(
+           UseLargePages(true),
+           UseTransparentHugePages(false),
+           UseHugeTLBFS(true),
+           UseSHM(false));
+
+    new FlagTester()
+      .use(UseLargePages(true),
+           UseHugeTLBFS(true))
+      .expect(
+           UseLargePages(true),
+           UseTransparentHugePages(false),
+           UseHugeTLBFS(true),
+           UseSHM(false));
+
+    // Setting a specific large pages flag will turn
+    // off heuristics to choose large pages type.
+    new FlagTester()
+      .use(UseLargePages(true),
+           UseHugeTLBFS(false))
+      .expect(
+           UseLargePages(false),
+           UseTransparentHugePages(false),
+           UseHugeTLBFS(false),
+           UseSHM(false));
+
+    // Using UseLargePages will default to UseHugeTLBFS large pages.
+    new FlagTester()
+      .use(UseLargePages(true))
+      .expect(
+           UseLargePages(true),
+           UseTransparentHugePages(false),
+           UseHugeTLBFS(true),
+           UseSHM(false));
+  }
+
+  public static void testUseSHM() throws Exception {
+    if (!canUse(UseSHM(true))) {
+      System.out.println("Skipping testUseSHM");
+      return;
+    }
+
+    // -XX:-UseLargePages overrides all other flags.
+    new FlagTester()
+      .use(UseLargePages(false),
+           UseSHM(true))
+      .expect(
+           UseLargePages(false),
+           UseTransparentHugePages(false),
+           UseHugeTLBFS(false),
+           UseSHM(false));
+
+    // Explicitly turn on UseSHM.
+    new FlagTester()
+      .use(UseSHM(true))
+      .expect(
+           UseLargePages(true),
+           UseTransparentHugePages(false),
+           UseHugeTLBFS(false),
+           UseSHM(true)) ;
+
+    new FlagTester()
+      .use(UseLargePages(true),
+           UseSHM(true))
+      .expect(
+           UseLargePages(true),
+           UseTransparentHugePages(false),
+           UseHugeTLBFS(false),
+           UseSHM(true)) ;
+
+    // Setting a specific large pages flag will turn
+    // off heuristics to choose large pages type.
+    new FlagTester()
+      .use(UseLargePages(true),
+           UseSHM(false))
+      .expect(
+           UseLargePages(false),
+           UseTransparentHugePages(false),
+           UseHugeTLBFS(false),
+           UseSHM(false));
+
+    // Setting UseLargePages can allow the system to choose
+    // UseHugeTLBFS instead of UseSHM, but never UseTransparentHugePages.
+    new FlagTester()
+      .use(UseLargePages(true))
+      .expect(
+           UseLargePages(true),
+           UseTransparentHugePages(false));
+  }
+
+  public static void testCombinations() throws Exception {
+    if (!canUse(UseSHM(true)) || !canUse(UseHugeTLBFS(true))) {
+      System.out.println("Skipping testUseHugeTLBFSAndUseSHMCombination");
+      return;
+    }
+
+    // UseHugeTLBFS takes precedence over SHM.
+
+    new FlagTester()
+      .use(UseLargePages(true),
+           UseHugeTLBFS(true),
+           UseSHM(true))
+      .expect(
+           UseLargePages(true),
+           UseTransparentHugePages(false),
+           UseHugeTLBFS(true),
+           UseSHM(false));
+
+    new FlagTester()
+      .use(UseLargePages(true),
+           UseHugeTLBFS(false),
+           UseSHM(true))
+      .expect(
+           UseLargePages(true),
+           UseTransparentHugePages(false),
+           UseHugeTLBFS(false),
+           UseSHM(true));
+
+    new FlagTester()
+      .use(UseLargePages(true),
+           UseHugeTLBFS(true),
+           UseSHM(false))
+      .expect(
+           UseLargePages(true),
+           UseTransparentHugePages(false),
+           UseHugeTLBFS(true),
+           UseSHM(false));
+
+    new FlagTester()
+      .use(UseLargePages(true),
+           UseHugeTLBFS(false),
+           UseSHM(false))
+      .expect(
+           UseLargePages(false),
+           UseTransparentHugePages(false),
+           UseHugeTLBFS(false),
+           UseSHM(false));
+
+
+    if (!canUse(UseTransparentHugePages(true))) {
+      return;
+    }
+
+    // UseTransparentHugePages takes precedence.
+
+    new FlagTester()
+      .use(UseLargePages(true),
+           UseTransparentHugePages(true),
+           UseHugeTLBFS(true),
+           UseSHM(true))
+      .expect(
+           UseLargePages(true),
+           UseTransparentHugePages(true),
+           UseHugeTLBFS(false),
+           UseSHM(false));
+
+    new FlagTester()
+      .use(UseTransparentHugePages(true),
+           UseHugeTLBFS(true),
+           UseSHM(true))
+      .expect(
+           UseLargePages(true),
+           UseTransparentHugePages(true),
+           UseHugeTLBFS(false),
+           UseSHM(false));
+  }
+
+  private static class FlagTester {
+    private Flag [] useFlags;
+
+    public FlagTester use(Flag... useFlags) {
+      this.useFlags = useFlags;
+      return this;
+    }
+
+    public void expect(Flag... expectedFlags) throws Exception {
+      if (useFlags == null) {
+        throw new IllegalStateException("Must run use() before expect()");
+      }
+
+      OutputAnalyzer output = executeNewJVM(useFlags);
+
+      for (Flag flag : expectedFlags) {
+        System.out.println("Looking for: " + flag.flagString());
+        String strValue = output.firstMatch(".* " + flag.name() +  " .* :?= (\\S+).*", 1);
+
+        if (strValue == null) {
+          throw new RuntimeException("Flag " + flag.name() + " couldn't be found");
+        }
+
+        if (!flag.value().equals(strValue)) {
+          throw new RuntimeException("Wrong value for: " + flag.name()
+                                     + " expected: " + flag.value()
+                                     + " got: " + strValue);
+        }
+      }
+
+      output.shouldHaveExitValue(0);
+    }
+  }
+
+  private static OutputAnalyzer executeNewJVM(Flag... flags) throws Exception {
+    ArrayList<String> args = new ArrayList<>();
+    for (Flag flag : flags) {
+      args.add(flag.flagString());
+    }
+    args.add("-XX:+PrintFlagsFinal");
+    args.add("-version");
+
+    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args.toArray(new String[args.size()]));
+    OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+    return output;
+  }
+
+  private static boolean canUse(Flag flag) {
+    try {
+      new FlagTester().use(flag).expect(flag);
+    } catch (Exception e) {
+      return false;
+    }
+
+    return true;
+  }
+
+  private static Flag UseLargePages(boolean value) {
+    return new BooleanFlag("UseLargePages", value);
+  }
+
+  private static Flag UseTransparentHugePages(boolean value) {
+    return new BooleanFlag("UseTransparentHugePages", value);
+  }
+
+  private static Flag UseHugeTLBFS(boolean value) {
+    return new BooleanFlag("UseHugeTLBFS", value);
+  }
+
+  private static Flag UseSHM(boolean value) {
+    return new BooleanFlag("UseSHM", value);
+  }
+
+  private static class BooleanFlag implements Flag {
+    private String name;
+    private boolean value;
+
+    BooleanFlag(String name, boolean value) {
+      this.name = name;
+      this.value = value;
+    }
+
+    public String flagString() {
+      return "-XX:" + (value ? "+" : "-") + name;
+    }
+
+    public String name() {
+      return name;
+    }
+
+    public String value() {
+      return Boolean.toString(value);
+    }
+  }
+
+  private static interface Flag {
+    public String flagString();
+    public String name();
+    public String value();
+  }
+}
--- a/test/testlibrary/OutputAnalyzerTest.java	Thu May 08 16:16:21 2014 +0200
+++ b/test/testlibrary/OutputAnalyzerTest.java	Mon Jul 07 08:54:46 2014 +0200
@@ -172,5 +172,22 @@
     } catch (RuntimeException e) {
         // expected
     }
+
+    {
+      String aaaa = "aaaa";
+      String result = output.firstMatch(aaaa);
+      if (!aaaa.equals(result)) {
+        throw new Exception("firstMatch(String) faild to match. Expected: " + aaaa + " got: " + result);
+      }
+    }
+
+    {
+      String aa = "aa";
+      String aa_grouped_aa = aa + "(" + aa + ")";
+      String result = output.firstMatch(aa_grouped_aa, 1);
+      if (!aa.equals(result)) {
+        throw new Exception("firstMatch(String, int) failed to match. Expected: " + aa + " got: " + result);
+      }
+    }
   }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/testlibrary/com/oracle/java/testlibrary/DynamicVMOptionChecker.java	Mon Jul 07 08:54:46 2014 +0200
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+package com.oracle.java.testlibrary;
+
+import com.sun.management.HotSpotDiagnosticMXBean;
+import com.sun.management.VMOption;
+import java.lang.management.ManagementFactory;
+
+/**
+ * Simple class to check writeability, invalid and valid values for VMOption
+ */
+public class DynamicVMOptionChecker {
+
+    /**
+     * Reads VM option from PlatformMXBean and parse it to integer value
+     *
+     * @param name of option
+     * @return parsed value
+     */
+    public static int getIntValue(String name) {
+
+        VMOption option = ManagementFactory.
+                getPlatformMXBean(HotSpotDiagnosticMXBean.class).
+                getVMOption(name);
+
+        return Integer.parseInt(option.getValue());
+    }
+
+    /**
+     * Checks that VM option is dynamically writable
+     *
+     * @param name
+     * @throws RuntimeException if option if not writable
+     * @return always true
+     */
+    public static boolean checkIsWritable(String name) {
+        VMOption option = ManagementFactory.
+                getPlatformMXBean(HotSpotDiagnosticMXBean.class).
+                getVMOption(name);
+
+        if (!option.isWriteable()) {
+            throw new RuntimeException(name + " is not writable");
+        }
+
+        return true;
+    }
+
+    /**
+     * Checks that value cannot be set
+     *
+     * @param name of flag
+     * @param value string representation of value to set
+     * @throws RuntimeException on error - when expected exception hasn't been thrown
+     */
+    public static void checkInvalidValue(String name, String value) {
+        // should throw
+        try {
+            ManagementFactory.
+                    getPlatformMXBean(HotSpotDiagnosticMXBean.class).
+                    setVMOption(name, value);
+
+        } catch (IllegalArgumentException e) {
+            return;
+        }
+
+        throw new RuntimeException("Expected IllegalArgumentException was not thrown, " + name + "= " + value);
+    }
+
+    /**
+     * Checks that value can be set
+     *
+     * @param name of flag to set
+     * @param value string representation of value to set
+     * @throws RuntimeException on error - when value in VM is not equal to origin
+     */
+    public static void checkValidValue(String name, String value) {
+        ManagementFactory.
+                getPlatformMXBean(HotSpotDiagnosticMXBean.class).
+                setVMOption(name, value);
+
+        VMOption option = ManagementFactory.
+                getPlatformMXBean(HotSpotDiagnosticMXBean.class).
+                getVMOption(name);
+
+        if (!option.getValue().equals(value)) {
+            throw new RuntimeException("Actual value of " + name + " \"" + option.getValue()
+                    + "\" not equal origin \"" + value + "\"");
+        }
+    }
+
+}
--- a/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java	Thu May 08 16:16:21 2014 +0200
+++ b/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java	Mon Jul 07 08:54:46 2014 +0200
@@ -241,7 +241,38 @@
   }
 
   /**
-   * Verifiy the exit value of the process
+   * Get the captured group of the first string matching the pattern.
+   * stderr is searched before stdout.
+   *
+   * @param pattern The multi-line pattern to match
+   * @param group The group to capture
+   * @return The matched string or null if no match was found
+   */
+  public String firstMatch(String pattern, int group) {
+    Matcher stderrMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
+    Matcher stdoutMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
+    if (stderrMatcher.find()) {
+      return stderrMatcher.group(group);
+    }
+    if (stdoutMatcher.find()) {
+      return stdoutMatcher.group(group);
+    }
+    return null;
+  }
+
+  /**
+   * Get the first string matching the pattern.
+   * stderr is searched before stdout.
+   *
+   * @param pattern The multi-line pattern to match
+   * @return The matched string or null if no match was found
+   */
+  public String firstMatch(String pattern) {
+    return firstMatch(pattern, 0);
+  }
+
+  /**
+   * Verify the exit value of the process
    *
    * @param expectedExitValue Expected exit value from process
    * @throws RuntimeException If the exit value from the process did not match the expected value
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/testlibrary/com/oracle/java/testlibrary/TestDynamicVMOption.java	Mon Jul 07 08:54:46 2014 +0200
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ */
+package com.oracle.java.testlibrary;
+
+/**
+ * Simple class to check writeability, invalid and valid values for concrete VMOption
+ */
+public class TestDynamicVMOption {
+
+    private final String name;
+    private final int value;
+
+    /**
+     * Constructor
+     *
+     * @param name of VM option to test
+     */
+    public TestDynamicVMOption(String name) {
+        this.name = name;
+        this.value = DynamicVMOptionChecker.getIntValue(name);
+        System.out.println(this.name + " = " + this.value);
+    }
+
+    /**
+     * Checks that this value can accept valid percentage values and cannot accept invalid percentage values
+     *
+     * @throws RuntimeException
+     */
+    public void testPercentageValues() {
+        checkInvalidValue(Integer.toString(Integer.MIN_VALUE));
+        checkInvalidValue(Integer.toString(Integer.MAX_VALUE));
+        checkInvalidValue("-10");
+        checkInvalidValue("190");
+    }
+
+    /**
+     * Reads VM option from PlatformMXBean and parse it to integer value
+     *
+     * @return value
+     */
+    public int getIntValue() {
+        return DynamicVMOptionChecker.getIntValue(this.name);
+    }
+
+    /**
+     * Checks that this VM option is dynamically writable
+     *
+     * @throws RuntimeException if option if not writable
+     * @return true
+     */
+    public boolean checkIsWritable() throws RuntimeException {
+        return DynamicVMOptionChecker.checkIsWritable(this.name);
+    }
+
+    /**
+     * Checks that value for this VM option cannot be set
+     *
+     * @param value to check
+     * @throws RuntimeException on error - when expected exception hasn't been thrown
+     */
+    public void checkInvalidValue(String value) {
+        DynamicVMOptionChecker.checkInvalidValue(this.name, value);
+    }
+
+    /**
+     * Checks that value for this VM option can be set
+     *
+     * @param value to check
+     * @throws RuntimeException on error - when value in VM is not equal to origin
+     */
+    public void checkValidValue(String value) {
+        DynamicVMOptionChecker.checkValidValue(this.name, value);
+    }
+
+}
--- a/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java	Thu May 08 16:16:21 2014 +0200
+++ b/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java	Mon Jul 07 08:54:46 2014 +0200
@@ -78,4 +78,7 @@
   public native void NMTUncommitMemory(long addr, long size);
   public native void NMTReleaseMemory(long addr, long size);
   public native boolean NMTWaitForDataMerge();
+
+  // Compiler
+  public native void    deoptimizeAll();
 }