changeset 9736:924ad9151e00

Merge
author amurillo
date Fri, 13 Nov 2015 10:35:26 -0800
parents 1bf156be1f07 19ed05bd68dc
children a22b7c80529f 756e5b1c59fa
files src/share/vm/gc/g1/satbQueue.cpp src/share/vm/gc/g1/satbQueue.hpp test/runtime/classFileParserBug/ignoredClinit.jasm
diffstat 437 files changed, 3442 insertions(+), 3538 deletions(-) [+]
line wrap: on
line diff
--- a/agent/src/os/linux/libproc_impl.c	Thu Nov 12 14:13:49 2015 -0800
+++ b/agent/src/os/linux/libproc_impl.c	Fri Nov 13 10:35:26 2015 -0800
@@ -38,6 +38,7 @@
   int fd;
   char alt_path[PATH_MAX + 1], *alt_path_end;
   const char *s;
+  int free_space;
 
   if (!alt_root_initialized) {
     alt_root_initialized = -1;
@@ -48,14 +49,22 @@
     return open(name, O_RDONLY);
   }
 
-  strcpy(alt_path, alt_root);
+
+  if (strlen(alt_root) + strlen(name) < PATH_MAX) {
+    // Buffer too small.
+    return -1;
+  }
+
+  strncpy(alt_path, alt_root, PATH_MAX);
+  alt_path[PATH_MAX] = '\0';
   alt_path_end = alt_path + strlen(alt_path);
+  free_space = PATH_MAX + 1 - (alt_path_end-alt_path);
 
-  // Strip path items one by one and try to open file with alt_root prepended
+  // Strip path items one by one and try to open file with alt_root prepended.
   s = name;
   while (1) {
-    strcat(alt_path, s);
-    s += 1;
+    strncat(alt_path, s, free_space);
+    s += 1;  // Skip /.
 
     fd = open(alt_path, O_RDONLY);
     if (fd >= 0) {
@@ -70,7 +79,8 @@
       break;
     }
 
-    *alt_path_end = 0;
+    // Cut off what we appended above.
+    *alt_path_end = '\0';
   }
 
   return -1;
--- a/agent/src/os/linux/ps_core.c	Thu Nov 12 14:13:49 2015 -0800
+++ b/agent/src/os/linux/ps_core.c	Fri Nov 13 10:35:26 2015 -0800
@@ -774,72 +774,78 @@
 
 // process segments from interpreter (ld.so or ld-linux.so)
 static bool read_interp_segments(struct ps_prochandle* ph) {
-   ELF_EHDR interp_ehdr;
+  ELF_EHDR interp_ehdr;
 
-   if (read_elf_header(ph->core->interp_fd, &interp_ehdr) != true) {
-       print_debug("interpreter is not a valid ELF file\n");
-       return false;
-   }
+  if (read_elf_header(ph->core->interp_fd, &interp_ehdr) != true) {
+    print_debug("interpreter is not a valid ELF file\n");
+    return false;
+  }
 
-   if (read_lib_segments(ph, ph->core->interp_fd, &interp_ehdr, ph->core->ld_base_addr) != true) {
-       print_debug("can't read segments of interpreter\n");
-       return false;
-   }
+  if (read_lib_segments(ph, ph->core->interp_fd, &interp_ehdr, ph->core->ld_base_addr) != true) {
+    print_debug("can't read segments of interpreter\n");
+    return false;
+  }
 
-   return true;
+  return true;
 }
 
 // process segments of a a.out
 static bool read_exec_segments(struct ps_prochandle* ph, ELF_EHDR* exec_ehdr) {
-   int i = 0;
-   ELF_PHDR* phbuf = NULL;
-   ELF_PHDR* exec_php = NULL;
+  int i = 0;
+  ELF_PHDR* phbuf = NULL;
+  ELF_PHDR* exec_php = NULL;
 
-   if ((phbuf = read_program_header_table(ph->core->exec_fd, exec_ehdr)) == NULL)
-      return false;
+  if ((phbuf = read_program_header_table(ph->core->exec_fd, exec_ehdr)) == NULL) {
+    return false;
+  }
 
-   for (exec_php = phbuf, i = 0; i < exec_ehdr->e_phnum; i++) {
-      switch (exec_php->p_type) {
+  for (exec_php = phbuf, i = 0; i < exec_ehdr->e_phnum; i++) {
+    switch (exec_php->p_type) {
 
-         // add mappings for PT_LOAD segments
-         case PT_LOAD: {
-            // add only non-writable segments of non-zero filesz
-            if (!(exec_php->p_flags & PF_W) && exec_php->p_filesz != 0) {
-               if (add_map_info(ph, ph->core->exec_fd, exec_php->p_offset, exec_php->p_vaddr, exec_php->p_filesz) == NULL) goto err;
-            }
-            break;
-         }
+      // add mappings for PT_LOAD segments
+    case PT_LOAD: {
+      // add only non-writable segments of non-zero filesz
+      if (!(exec_php->p_flags & PF_W) && exec_php->p_filesz != 0) {
+        if (add_map_info(ph, ph->core->exec_fd, exec_php->p_offset, exec_php->p_vaddr, exec_php->p_filesz) == NULL) goto err;
+      }
+      break;
+    }
 
-         // read the interpreter and it's segments
-         case PT_INTERP: {
-            char interp_name[BUF_SIZE];
+    // read the interpreter and it's segments
+    case PT_INTERP: {
+      char interp_name[BUF_SIZE + 1];
 
-            pread(ph->core->exec_fd, interp_name, MIN(exec_php->p_filesz, BUF_SIZE), exec_php->p_offset);
-            print_debug("ELF interpreter %s\n", interp_name);
-            // read interpreter segments as well
-            if ((ph->core->interp_fd = pathmap_open(interp_name)) < 0) {
-               print_debug("can't open runtime loader\n");
-               goto err;
-            }
-            break;
-         }
+      // BUF_SIZE is PATH_MAX + NAME_MAX + 1.
+      if (exec_php->p_filesz > BUF_SIZE) {
+        goto err;
+      }
+      pread(ph->core->exec_fd, interp_name, exec_php->p_filesz, exec_php->p_offset);
+      interp_name[exec_php->p_filesz] = '\0';
+      print_debug("ELF interpreter %s\n", interp_name);
+      // read interpreter segments as well
+      if ((ph->core->interp_fd = pathmap_open(interp_name)) < 0) {
+        print_debug("can't open runtime loader\n");
+        goto err;
+      }
+      break;
+    }
 
-         // from PT_DYNAMIC we want to read address of first link_map addr
-         case PT_DYNAMIC: {
-            ph->core->dynamic_addr = exec_php->p_vaddr;
-            print_debug("address of _DYNAMIC is 0x%lx\n", ph->core->dynamic_addr);
-            break;
-         }
+    // from PT_DYNAMIC we want to read address of first link_map addr
+    case PT_DYNAMIC: {
+      ph->core->dynamic_addr = exec_php->p_vaddr;
+      print_debug("address of _DYNAMIC is 0x%lx\n", ph->core->dynamic_addr);
+      break;
+    }
 
-      } // switch
-      exec_php++;
-   } // for
+    } // switch
+    exec_php++;
+  } // for
 
-   free(phbuf);
-   return true;
-err:
-   free(phbuf);
-   return false;
+  free(phbuf);
+  return true;
+ err:
+  free(phbuf);
+  return false;
 }
 
 
--- a/make/aix/makefiles/mapfile-vers-debug	Thu Nov 12 14:13:49 2015 -0800
+++ b/make/aix/makefiles/mapfile-vers-debug	Fri Nov 13 10:35:26 2015 -0800
@@ -39,7 +39,6 @@
                 jio_snprintf;
                 jio_vfprintf;
                 jio_vsnprintf;
-                fork1;
                 numa_warn;
                 numa_error;
 
--- a/make/aix/makefiles/mapfile-vers-product	Thu Nov 12 14:13:49 2015 -0800
+++ b/make/aix/makefiles/mapfile-vers-product	Fri Nov 13 10:35:26 2015 -0800
@@ -34,7 +34,6 @@
                 jio_snprintf;
                 jio_vfprintf;
                 jio_vsnprintf;
-                fork1;
                 numa_warn;
                 numa_error;
 
--- a/make/aix/makefiles/trace.make	Thu Nov 12 14:13:49 2015 -0800
+++ b/make/aix/makefiles/trace.make	Fri Nov 13 10:35:26 2015 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -82,8 +82,7 @@
 
 GENERATE_CODE= \
   $(QUIETLY) echo $(LOG_INFO) Generating $@; \
-  $(XSLT) -IN $(word 1,$^) -XSL $(word 2,$^) -OUT $@; \
-  test -f $@
+  $(XSLT) -IN $(word 1,$^) -XSL $(word 2,$^) -OUT $@
 
 $(TraceOutDir)/traceEventIds.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventIds.xsl $(XML_DEPS)
 	$(GENERATE_CODE)
--- a/make/bsd/makefiles/mapfile-vers-debug	Thu Nov 12 14:13:49 2015 -0800
+++ b/make/bsd/makefiles/mapfile-vers-debug	Fri Nov 13 10:35:26 2015 -0800
@@ -34,7 +34,6 @@
                 jio_snprintf;
                 jio_vfprintf;
                 jio_vsnprintf;
-                fork1;
                 numa_warn;
                 numa_error;
 
--- a/make/bsd/makefiles/mapfile-vers-product	Thu Nov 12 14:13:49 2015 -0800
+++ b/make/bsd/makefiles/mapfile-vers-product	Fri Nov 13 10:35:26 2015 -0800
@@ -34,7 +34,6 @@
                 jio_snprintf;
                 jio_vfprintf;
                 jio_vsnprintf;
-                fork1;
                 numa_warn;
                 numa_error;
 
--- a/make/bsd/makefiles/trace.make	Thu Nov 12 14:13:49 2015 -0800
+++ b/make/bsd/makefiles/trace.make	Fri Nov 13 10:35:26 2015 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -83,8 +83,7 @@
 
 GENERATE_CODE= \
   $(QUIETLY) echo $(LOG_INFO) Generating $@; \
-  $(XSLT) -IN $(word 1,$^) -XSL $(word 2,$^) -OUT $@; \
-  test -f $@
+  $(XSLT) -IN $(word 1,$^) -XSL $(word 2,$^) -OUT $@
 
 $(TraceOutDir)/traceEventIds.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventIds.xsl $(XML_DEPS)
 	$(GENERATE_CODE)
--- a/make/hotspot.script	Thu Nov 12 14:13:49 2015 -0800
+++ b/make/hotspot.script	Fri Nov 13 10:35:26 2015 -0800
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-# Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -156,7 +156,7 @@
     export LD_LIBRARY_PATH
 fi
 
-JPARMS="-XXaltjvm=$MYDIR -Dsun.java.launcher.is_altjvm=true $@ $JAVA_ARGS";
+JPARMS="-XXaltjvm=$MYDIR -Dsun.java.launcher.is_altjvm=true";
 
 # Locate the java launcher
 LAUNCHER=$JDK/bin/java
@@ -181,8 +181,6 @@
 cd `pwd`
 handle SIGUSR1 nostop noprint
 handle SIGUSR2 nostop noprint
-set args $JPARMS
-file $LAUNCHER
 directory $GDBSRCDIR
 # Get us to a point where we can set breakpoints in libjvm.so
 set breakpoint pending on
@@ -194,11 +192,10 @@
 EOF
 }
 
-
 case "$MODE" in
     gdb)
 	init_gdb
-        $GDB -x $GDBSCR
+        $GDB -x $GDBSCR --args $LAUNCHER $JPARMS "$@" $JAVA_ARGS
 	rm -f $GDBSCR
         ;;
     gud)
@@ -219,15 +216,15 @@
 	rm -f $GDBSCR
         ;;
     dbx)
-        $DBX -s $HOME/.dbxrc -c "loadobject -load libjvm.so; stop in JNI_CreateJavaVM; run $JPARMS; delete all" $LAUNCHER
+        $DBX -s $HOME/.dbxrc -c "loadobject -load libjvm.so; stop in JNI_CreateJavaVM; run $JPARMS $@ $JAVA_ARGS; delete all" $LAUNCHER
         ;;
     valgrind)
         echo Warning: Defaulting to 16Mb heap to make Valgrind run faster, use -Xmx for larger heap
         echo
-        $VALGRIND --tool=memcheck --leak-check=yes --num-callers=50 $LAUNCHER -Xmx16m $JPARMS
+        $VALGRIND --tool=memcheck --leak-check=yes --num-callers=50 $LAUNCHER -Xmx16m $JPARMS "$@" $JAVA_ARGS
         ;;
     run)
-        LD_PRELOAD=$PRELOADING exec $LAUNCHER $JPARMS
+        LD_PRELOAD=$PRELOADING exec $LAUNCHER $JPARMS "$@" $JAVA_ARGS
         ;;
     *)
         echo Error: Internal error, unknown launch mode \"$MODE\"
--- a/make/linux/makefiles/mapfile-vers-debug	Thu Nov 12 14:13:49 2015 -0800
+++ b/make/linux/makefiles/mapfile-vers-debug	Fri Nov 13 10:35:26 2015 -0800
@@ -34,7 +34,6 @@
                 jio_snprintf;
                 jio_vfprintf;
                 jio_vsnprintf;
-                fork1;
                 numa_warn;
                 numa_error;
 
--- a/make/linux/makefiles/mapfile-vers-product	Thu Nov 12 14:13:49 2015 -0800
+++ b/make/linux/makefiles/mapfile-vers-product	Fri Nov 13 10:35:26 2015 -0800
@@ -34,7 +34,6 @@
                 jio_snprintf;
                 jio_vfprintf;
                 jio_vsnprintf;
-                fork1;
                 numa_warn;
                 numa_error;
 
--- a/make/linux/makefiles/trace.make	Thu Nov 12 14:13:49 2015 -0800
+++ b/make/linux/makefiles/trace.make	Fri Nov 13 10:35:26 2015 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -82,8 +82,7 @@
 
 GENERATE_CODE= \
   $(QUIETLY) echo $(LOG_INFO) Generating $@; \
-  $(XSLT) -IN $(word 1,$^) -XSL $(word 2,$^) -OUT $@; \
-  test -f $@
+  $(XSLT) -IN $(word 1,$^) -XSL $(word 2,$^) -OUT $@
 
 $(TraceOutDir)/traceEventIds.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventIds.xsl $(XML_DEPS)
 	$(GENERATE_CODE)
--- a/make/solaris/makefiles/sparcWorks.make	Thu Nov 12 14:13:49 2015 -0800
+++ b/make/solaris/makefiles/sparcWorks.make	Fri Nov 13 10:35:26 2015 -0800
@@ -550,19 +550,6 @@
 #LINK_INTO = LIBJVM
 endif
 
-# Solaris platforms collect lots of redundant file-ident lines,
-# to the point of wasting a significant percentage of file space.
-# (The text is stored in ELF .comment sections, contributed by
-# all "#pragma ident" directives in header and source files.)
-# This command "compresses" the .comment sections simply by
-# removing repeated lines.  The data can be extracted from
-# binaries in the field by using "mcs -p libjvm.so" or the older
-# command "what libjvm.so".
-LINK_LIB.CXX/POST_HOOK += $(MCS) -c $@ || exit 1;
-# (The exit 1 is necessary to cause a build failure if the command fails and
-# multiple commands are strung together, and the final semicolon is necessary
-# since the hook must terminate itself as a valid command.)
-
 # Also, strip debug and line number information (worth about 1.7Mb).
 # If we can create .debuginfo files, then the VM is stripped in vm.make
 # and this macro is not used.
--- a/make/solaris/makefiles/trace.make	Thu Nov 12 14:13:49 2015 -0800
+++ b/make/solaris/makefiles/trace.make	Fri Nov 13 10:35:26 2015 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -78,8 +78,7 @@
 
 GENERATE_CODE= \
   $(QUIETLY) echo $(LOG_INFO) Generating $@; \
-  $(XSLT) -IN $(word 1,$^) -XSL $(word 2,$^) -OUT $@; \
-  test -f $@
+  $(XSLT) -IN $(word 1,$^) -XSL $(word 2,$^) -OUT $@
 
 $(TraceOutDir)/traceEventIds.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventIds.xsl $(XML_DEPS)
 	$(GENERATE_CODE)
--- a/make/test/JtregNative.gmk	Thu Nov 12 14:13:49 2015 -0800
+++ b/make/test/JtregNative.gmk	Fri Nov 13 10:35:26 2015 -0800
@@ -45,6 +45,7 @@
     $(HOTSPOT_TOPDIR)/test/runtime/jni/8025979 \
     $(HOTSPOT_TOPDIR)/test/runtime/jni/8033445 \
     $(HOTSPOT_TOPDIR)/test/runtime/jni/ToStringInInterfaceTest \
+    $(HOTSPOT_TOPDIR)/test/runtime/SameObject \
     #
 
 BUILD_HOTSPOT_JTREG_OUTPUT_DIR := $(BUILD_OUTPUT)/support/test/hotspot/jtreg/native
--- a/make/windows/makefiles/compile.make	Thu Nov 12 14:13:49 2015 -0800
+++ b/make/windows/makefiles/compile.make	Fri Nov 13 10:35:26 2015 -0800
@@ -19,7 +19,7 @@
 # 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.
-#  
+#
 #
 
 # Generic compiler settings
@@ -54,7 +54,11 @@
 # improving the quality of crash log stack traces involving jvm.dll.
 
 # These are always used in all compiles
-CXX_FLAGS=$(EXTRA_CFLAGS) /nologo /W3 /WX
+CXX_FLAGS=$(EXTRA_CFLAGS) /nologo /W3
+
+!if "$(WARNINGS_AS_ERRORS)" != "false"
+CXX_FLAGS=$(CXX_FLAGS) /WX
+!endif
 
 # Let's add debug information when Full Debug Symbols is enabled
 !if "$(ENABLE_FULL_DEBUG_SYMBOLS)" == "1"
@@ -167,7 +171,7 @@
 !endif
 
 
-!if $(MSC_VER) >= 1600 
+!if $(MSC_VER) >= 1600
 LD_FLAGS= $(LD_FLAGS) psapi.lib
 !endif
 
@@ -191,4 +195,3 @@
 !if "$(MFC_DEBUG)" == "true"
 RC_FLAGS = $(RC_FLAGS) /D "_DEBUG"
 !endif
-
--- a/make/windows/makefiles/defs.make	Thu Nov 12 14:13:49 2015 -0800
+++ b/make/windows/makefiles/defs.make	Fri Nov 13 10:35:26 2015 -0800
@@ -31,6 +31,8 @@
 SLASH_JAVA ?= J:
 PATH_SEP = ;
 
+MAKE_ARGS += WARNINGS_AS_ERRORS=$(WARNINGS_AS_ERRORS)
+
 # Need PLATFORM (os-arch combo names) for jdk and hotspot, plus libarch name
 ifeq ($(ARCH_DATA_MODEL),32)
   ARCH_DATA_MODEL=32
--- a/src/cpu/ppc/vm/ppc.ad	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/cpu/ppc/vm/ppc.ad	Fri Nov 13 10:35:26 2015 -0800
@@ -5572,7 +5572,6 @@
 
 instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{
   match(Set dst (DecodeNKlass (LoadNKlass mem)));
-  // SAPJVM GL 2014-05-21 Differs.
   predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0 &&
             _kids[0]->_leaf->as_Load()->is_unordered());
   ins_cost(MEMORY_REF_COST);
@@ -10949,7 +10948,7 @@
     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register,
                                  $tmp3$$Register, $tmp1$$Register, $tmp2$$Register,
-                                 UseBiasedLocking && !UseOptoBiasInlining); // SAPJVM MD 2014-11-06 UseOptoBiasInlining
+                                 UseBiasedLocking && !UseOptoBiasInlining);
     // If locking was successfull, crx should indicate 'EQ'.
     // The compiler generates a branch to the runtime call to
     // _complete_monitor_locking_Java for the case where crx is 'NE'.
--- a/src/cpu/ppc/vm/relocInfo_ppc.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/cpu/ppc/vm/relocInfo_ppc.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -61,7 +61,7 @@
       nativeMovConstReg_at(addr())->set_narrow_oop(no, code());
     }
   } else {
-    assert((address) (nativeMovConstReg_at(addr())->data()) == x, "data must match");
+    guarantee((address) (nativeMovConstReg_at(addr())->data()) == x, "data must match");
   }
 }
 
--- a/src/cpu/sparc/vm/nativeInst_sparc.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/cpu/sparc/vm/nativeInst_sparc.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -60,7 +60,7 @@
   masm.patchable_sethi(x, destreg);
   int len = buffer - masm.pc();
   for (int i = 0; i < len; i++) {
-    assert(instaddr[i] == buffer[i], "instructions must match");
+    guarantee(instaddr[i] == buffer[i], "instructions must match");
   }
 }
 
--- a/src/cpu/sparc/vm/relocInfo_sparc.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/cpu/sparc/vm/relocInfo_sparc.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -84,7 +84,7 @@
     inst &= ~Assembler::simm(    -1, 13);
     inst |=  Assembler::simm(simm13, 13);
     if (verify_only) {
-      assert(ip->long_at(0) == inst, "instructions must match");
+      guarantee(ip->long_at(0) == inst, "instructions must match");
     } else {
       ip->set_long_at(0, inst);
     }
@@ -102,15 +102,15 @@
       inst &= ~Assembler::hi22(-1);
       inst |=  Assembler::hi22((intptr_t)np);
       if (verify_only) {
-        assert(ip->long_at(0) == inst, "instructions must match");
+        guarantee(ip->long_at(0) == inst, "instructions must match");
       } else {
         ip->set_long_at(0, inst);
       }
       inst2 = ip->long_at( NativeInstruction::nop_instruction_size );
       guarantee(Assembler::inv_op(inst2)==Assembler::arith_op, "arith op");
       if (verify_only) {
-        assert(ip->long_at(NativeInstruction::nop_instruction_size) == NativeInstruction::set_data32_simm13( inst2, (intptr_t)np),
-               "instructions must match");
+        guarantee(ip->long_at(NativeInstruction::nop_instruction_size) == NativeInstruction::set_data32_simm13( inst2, (intptr_t)np),
+                  "instructions must match");
       } else {
         ip->set_long_at(NativeInstruction::nop_instruction_size, NativeInstruction::set_data32_simm13( inst2, (intptr_t)np));
       }
@@ -127,7 +127,7 @@
     inst |=  Assembler::hi22((intptr_t)x);
     // (ignore offset; it doesn't play into the sethi)
     if (verify_only) {
-      assert(ip->long_at(0) == inst, "instructions must match");
+      guarantee(ip->long_at(0) == inst, "instructions must match");
     } else {
       ip->set_long_at(0, inst);
     }
--- a/src/cpu/x86/vm/relocInfo_x86.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/cpu/x86/vm/relocInfo_x86.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -41,7 +41,7 @@
          which == Assembler::imm_operand, "format unpacks ok");
   if (which == Assembler::imm_operand) {
     if (verify_only) {
-      assert(*pd_address_in_code() == x, "instructions must match");
+      guarantee(*pd_address_in_code() == x, "instructions must match");
     } else {
       *pd_address_in_code() = x;
     }
@@ -50,13 +50,13 @@
     // both compressed oops and compressed classes look the same
     if (Universe::heap()->is_in_reserved((oop)x)) {
     if (verify_only) {
-      assert(*(uint32_t*) disp == oopDesc::encode_heap_oop((oop)x), "instructions must match");
+      guarantee(*(uint32_t*) disp == oopDesc::encode_heap_oop((oop)x), "instructions must match");
     } else {
       *(int32_t*) disp = oopDesc::encode_heap_oop((oop)x);
     }
   } else {
       if (verify_only) {
-        assert(*(uint32_t*) disp == Klass::encode_klass((Klass*)x), "instructions must match");
+        guarantee(*(uint32_t*) disp == Klass::encode_klass((Klass*)x), "instructions must match");
       } else {
         *(int32_t*) disp = Klass::encode_klass((Klass*)x);
       }
@@ -67,14 +67,14 @@
     address disp = Assembler::locate_operand(ip, which);
     address next_ip = Assembler::locate_next_instruction(ip);
     if (verify_only) {
-      assert(*(int32_t*) disp == (x - next_ip), "instructions must match");
+      guarantee(*(int32_t*) disp == (x - next_ip), "instructions must match");
     } else {
       *(int32_t*) disp = x - next_ip;
     }
   }
 #else
   if (verify_only) {
-    assert(*pd_address_in_code() == (x + o), "instructions must match");
+    guarantee(*pd_address_in_code() == (x + o), "instructions must match");
   } else {
     *pd_address_in_code() = x + o;
   }
--- a/src/cpu/x86/vm/stubRoutines_x86.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/cpu/x86/vm/stubRoutines_x86.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -147,7 +147,7 @@
   b_pow_x_table[0] = b;
   for (int k = 0; k < D; ++k) {
     // If "a" has non-zero coefficient at x**k,/ add ((b * x**k) mod P) to the result.
-    if ((a & (uint64_t)(1 << (D - 1 - k))) != 0) product ^= b_pow_x_table[k];
+    if ((a & (((uint32_t)1) << (D - 1 - k))) != 0) product ^= b_pow_x_table[k];
 
     // Compute b_pow_x_table[k+1] = (b ** x**(k+1)) mod P.
     if (b_pow_x_table[k] & 1) {
--- a/src/cpu/x86/vm/templateTable_x86.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/cpu/x86/vm/templateTable_x86.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -1611,7 +1611,7 @@
 void TemplateTable::fneg() {
   transition(ftos, ftos);
   if (UseSSE >= 1) {
-    static jlong *float_signflip  = double_quadword(&float_signflip_pool[1], 0x8000000080000000, 0x8000000080000000);
+    static jlong *float_signflip  = double_quadword(&float_signflip_pool[1],  CONST64(0x8000000080000000),  CONST64(0x8000000080000000));
     __ xorps(xmm0, ExternalAddress((address) float_signflip));
   } else {
     LP64_ONLY(ShouldNotReachHere());
@@ -1622,7 +1622,8 @@
 void TemplateTable::dneg() {
   transition(dtos, dtos);
   if (UseSSE >= 2) {
-    static jlong *double_signflip  = double_quadword(&double_signflip_pool[1], 0x8000000000000000, 0x8000000000000000);
+    static jlong *double_signflip =
+      double_quadword(&double_signflip_pool[1], CONST64(0x8000000000000000), CONST64(0x8000000000000000));
     __ xorpd(xmm0, ExternalAddress((address) double_signflip));
   } else {
 #ifdef _LP64
--- a/src/cpu/x86/vm/vm_version_x86.hpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/cpu/x86/vm/vm_version_x86.hpp	Fri Nov 13 10:35:26 2015 -0800
@@ -652,7 +652,7 @@
       result = _cpuid_info.std_cpuid1_ebx.bits.threads_per_cpu /
                cores_per_cpu();
     }
-    return result;
+    return (result == 0 ? 1 : result);
   }
 
   static intx L1_line_size()  {
--- a/src/cpu/zero/vm/vm_version_zero.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/cpu/zero/vm/vm_version_zero.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -37,5 +37,9 @@
     warning("Unaligned memory access is not available on this CPU");
     FLAG_SET_DEFAULT(UseUnalignedAccesses, false);
   }
+  // Disable prefetching for Zero
+  if (! FLAG_IS_DEFAULT(AllocatePrefetchDistance)) {
+    warning("Prefetching is not available for a Zero VM");
+  }
   FLAG_SET_DEFAULT(AllocatePrefetchDistance, 0);
 }
--- a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java	Fri Nov 13 10:35:26 2015 -0800
@@ -1112,7 +1112,7 @@
     @HotSpotVMField(name = "JavaThread::_osthread", type = "OSThread*", get = HotSpotVMField.Type.OFFSET) @Stable public int osThreadOffset;
     @HotSpotVMField(name = "JavaThread::_dirty_card_queue", type = "DirtyCardQueue", get = HotSpotVMField.Type.OFFSET) @Stable public int javaThreadDirtyCardQueueOffset;
     @HotSpotVMField(name = "JavaThread::_is_method_handle_return", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int threadIsMethodHandleReturnOffset;
-    @HotSpotVMField(name = "JavaThread::_satb_mark_queue", type = "ObjPtrQueue", get = HotSpotVMField.Type.OFFSET) @Stable public int javaThreadSatbMarkQueueOffset;
+    @HotSpotVMField(name = "JavaThread::_satb_mark_queue", type = "SATBMarkQueue", get = HotSpotVMField.Type.OFFSET) @Stable public int javaThreadSatbMarkQueueOffset;
     @HotSpotVMField(name = "JavaThread::_vm_result", type = "oop", get = HotSpotVMField.Type.OFFSET) @Stable public int threadObjectResultOffset;
     @HotSpotVMField(name = "JavaThread::_jvmci_counters", type = "jlong*", get = HotSpotVMField.Type.OFFSET) @Stable public int jvmciCountersThreadOffset;
 
--- a/src/os/aix/vm/jvm_aix.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/os/aix/vm/jvm_aix.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2012, 2013 SAP AG. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -48,7 +48,6 @@
                    : handler;
   switch (sig) {
     /* The following are already used by the VM. */
-    case INTERRUPT_SIGNAL:
     case SIGFPE:
     case SIGILL:
     case SIGSEGV:
--- a/src/os/aix/vm/jvm_aix.h	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/os/aix/vm/jvm_aix.h	Fri Nov 13 10:35:26 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2012, 2013 SAP AG. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -113,7 +113,6 @@
 /* Signal definitions */
 
 #define BREAK_SIGNAL     SIGQUIT           /* Thread dumping support.    */
-#define INTERRUPT_SIGNAL SIGUSR1           /* Interruptible I/O support. */
 #define SHUTDOWN1_SIGNAL SIGHUP            /* Shutdown Hooks support.    */
 #define SHUTDOWN2_SIGNAL SIGINT
 #define SHUTDOWN3_SIGNAL SIGTERM
--- a/src/os/aix/vm/loadlib_aix.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/os/aix/vm/loadlib_aix.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -33,153 +33,337 @@
 #ifndef __STDC_FORMAT_MACROS
 #define __STDC_FORMAT_MACROS
 #endif
-// 'allocation.inline.hpp' triggers the inclusion of 'inttypes.h' which defines macros
-// required by the definitions in 'globalDefinitions.hpp'. But these macros in 'inttypes.h'
-// are only defined if '__STDC_FORMAT_MACROS' is defined!
-#include "memory/allocation.inline.hpp"
-#include "oops/oop.inline.hpp"
-#include "runtime/threadCritical.hpp"
+
+#include "loadlib_aix.hpp"
+// for CritSect
+#include "misc_aix.hpp"
+#include "porting_aix.hpp"
 #include "utilities/debug.hpp"
 #include "utilities/ostream.hpp"
-#include "loadlib_aix.hpp"
-#include "porting_aix.hpp"
 
 // For loadquery()
 #include <sys/ldr.h>
 
-///////////////////////////////////////////////////////////////////////////////
-// Implementation for LoadedLibraryModule
+// Use raw malloc instead of os::malloc - this code gets used for error reporting.
 
-// output debug info
-void LoadedLibraryModule::print(outputStream* os) const {
-  os->print("%15.15s: text: " INTPTR_FORMAT " - " INTPTR_FORMAT
-               ", data: " INTPTR_FORMAT " - " INTPTR_FORMAT " ",
-      shortname, text_from, text_to, data_from, data_to);
-  os->print(" %s", fullpath);
-  if (strlen(membername) > 0) {
-    os->print("(%s)", membername);
+// A class to "intern" eternal strings.
+// TODO: similar coding exists in AIX version of dladdr and potentially elsewhere: consolidate!
+class StringList {
+
+  char** _list;
+  int _cap;
+  int _num;
+
+  // Enlarge list. If oom, leave old list intact and return false.
+  bool enlarge() {
+    int cap2 = _cap + 64;
+    char** l2 = (char**) ::realloc(_list, sizeof(char*) * cap2);
+    if (!l2) {
+      return false;
+    }
+    _list = l2;
+    _cap = cap2;
+    return true;
   }
-  os->cr();
+
+  // Append string to end of list.
+  // Returns NULL if oom.
+  char* append(const char* s) {
+    if (_cap == _num) {
+      if (!enlarge()) {
+        return NULL;
+      }
+    }
+    assert0(_cap > _num);
+    char* s2 = ::strdup(s);
+    if (!s2) {
+      return NULL;
+    }
+    _list[_num] = s2;
+    trcVerbose("StringDir: added %s at pos %d", s2, _num);
+    _num ++;
+    return s2;
+  }
+
+public:
+
+  StringList()
+    : _list(NULL)
+    , _cap(0)
+    , _num(0)
+  {}
+
+  // String is copied into the list; pointer to copy is returned.
+  // Returns NULL if oom.
+  char* add (const char* s) {
+    for (int i = 0; i < _num; i++) {
+      if (strcmp(_list[i], s) == 0) {
+        return _list[i];
+      }
+    }
+    return append(s);
+  }
+
+};
+
+static StringList g_stringlist;
+
+//////////////////////
+
+// Entries are kept in a linked list ordered by text address. Entries are not
+// eternal - this list is rebuilt on every reload.
+// Note that we do not hand out those entries, but copies of them.
+
+struct entry_t {
+  entry_t* next;
+  loaded_module_t info;
+};
+
+static void print_entry(const entry_t* e, outputStream* os) {
+  const loaded_module_t* const lm = &(e->info);
+  os->print(" %c text: " INTPTR_FORMAT " - " INTPTR_FORMAT
+            ", data: " INTPTR_FORMAT " - " INTPTR_FORMAT " "
+            "%s",
+      (lm->is_in_vm ? '*' : ' '),
+      lm->text, (uintptr_t)lm->text + lm->text_len,
+      lm->data, (uintptr_t)lm->data + lm->data_len,
+      lm->path);
+  if (lm->member) {
+    os->print("(%s)", lm->member);
+  }
 }
 
+static entry_t* g_first = NULL;
 
-///////////////////////////////////////////////////////////////////////////////
-// Implementation for LoadedLibraries
-
-// class variables
-LoadedLibraryModule LoadedLibraries::tab[MAX_MODULES];
-int LoadedLibraries::num_loaded = 0;
-
-// Checks whether the address p points to any of the loaded code segments.
-// If it does, returns the LoadedLibraryModule entry. If not, returns NULL.
-// static
-const LoadedLibraryModule* LoadedLibraries::find_for_text_address(const unsigned char* p) {
-
-  if (num_loaded == 0) {
-    reload();
-  }
-  for (int i = 0; i < num_loaded; i++) {
-    if (tab[i].is_in_text(p)) {
-      return &tab[i];
+static entry_t* find_entry_for_text_address(const void* p) {
+  for (entry_t* e = g_first; e; e = e->next) {
+    if ((uintptr_t)p >= (uintptr_t)e->info.text &&
+        (uintptr_t)p < ((uintptr_t)e->info.text + e->info.text_len)) {
+      return e;
     }
   }
   return NULL;
 }
 
-// Checks whether the address p points to any of the loaded data segments.
-// If it does, returns the LoadedLibraryModule entry. If not, returns NULL.
-// static
-const LoadedLibraryModule* LoadedLibraries::find_for_data_address(const unsigned char* p) {
-  if (num_loaded == 0) {
-    reload();
-  }
-  for (int i = 0; i < num_loaded; i++) {
-    if (tab[i].is_in_data(p)) {
-      return &tab[i];
+static entry_t* find_entry_for_data_address(const void* p) {
+  for (entry_t* e = g_first; e; e = e->next) {
+    if ((uintptr_t)p >= (uintptr_t)e->info.data &&
+        (uintptr_t)p < ((uintptr_t)e->info.data + e->info.data_len)) {
+      return e;
     }
   }
   return NULL;
 }
 
-// Rebuild the internal table of LoadedLibraryModule objects
-// static
-void LoadedLibraries::reload() {
+// Adds a new entry to the list (ordered by text address ascending).
+static void add_entry_to_list(entry_t* e, entry_t** start) {
+  entry_t* last = NULL;
+  entry_t* e2 = *start;
+  while (e2 && e2->info.text < e->info.text) {
+    last = e2;
+    e2 = e2->next;
+  }
+  if (last) {
+    last->next = e;
+  } else {
+    *start = e;
+  }
+  e->next = e2;
+}
 
-  ThreadCritical cs;
+static void free_entry_list(entry_t** start) {
+  entry_t* e = *start;
+  while (e) {
+    entry_t* const e2 = e->next;
+    ::free(e);
+    e = e2;
+  }
+  *start = NULL;
+}
 
-  // discard old content
-  num_loaded = 0;
 
-  // Call loadquery(L_GETINFO..) to get a list of all loaded Dlls from AIX.
-  size_t buf_size = 4096;
-  char* loadquery_buf = AllocateHeap(buf_size, mtInternal);
+// Rebuild the internal module table. If an error occurs, old table remains
+// unchanged.
+static bool reload_table() {
 
-  while(loadquery(L_GETINFO, loadquery_buf, buf_size) == -1) {
-    if (errno == ENOMEM) {
-      buf_size *= 2;
-      loadquery_buf = ReallocateHeap(loadquery_buf, buf_size, mtInternal);
+  bool rc = false;
+
+  trcVerbose("reload module table...");
+
+  entry_t* new_list = NULL;
+  const struct ld_info* ldi = NULL;
+
+  // Call loadquery(L_GETINFO..) to get a list of all loaded Dlls from AIX. loadquery
+  // requires a large enough buffer.
+  uint8_t* buffer = NULL;
+  size_t buflen = 1024;
+  for (;;) {
+    buffer = (uint8_t*) ::realloc(buffer, buflen);
+    if (loadquery(L_GETINFO, buffer, buflen) == -1) {
+      if (errno == ENOMEM) {
+        buflen *= 2;
+      } else {
+        trcVerbose("loadquery failed (%d)", errno);
+        goto cleanup;
+      }
     } else {
-      FreeHeap(loadquery_buf);
-      // Ensure that the uintptr_t pointer is valid
-      assert(errno != EFAULT, "loadquery: Invalid uintptr_t in info buffer.");
-      fprintf(stderr, "loadquery failed (%d %s)", errno, strerror(errno));
-      return;
-    }
-  }
-
-  // Iterate over the loadquery result. For details see sys/ldr.h on AIX.
-  const struct ld_info* p = (struct ld_info*) loadquery_buf;
-
-  // Ensure we have all loaded libs.
-  bool all_loaded = false;
-  while(num_loaded < MAX_MODULES) {
-    LoadedLibraryModule& mod = tab[num_loaded];
-    mod.text_from = (const unsigned char*) p->ldinfo_textorg;
-    mod.text_to   = (const unsigned char*) (((char*)p->ldinfo_textorg) + p->ldinfo_textsize);
-    mod.data_from = (const unsigned char*) p->ldinfo_dataorg;
-    mod.data_to   = (const unsigned char*) (((char*)p->ldinfo_dataorg) + p->ldinfo_datasize);
-    sprintf(mod.fullpath, "%.*s", sizeof(mod.fullpath), p->ldinfo_filename);
-    // do we have a member name as well (see ldr.h)?
-    const char* p_mbr_name = p->ldinfo_filename + strlen(p->ldinfo_filename) + 1;
-    if (*p_mbr_name) {
-      sprintf(mod.membername, "%.*s", sizeof(mod.membername), p_mbr_name);
-    } else {
-      mod.membername[0] = '\0';
-    }
-
-    // fill in the short name
-    const char* p_slash = strrchr(mod.fullpath, '/');
-    if (p_slash) {
-      sprintf(mod.shortname, "%.*s", sizeof(mod.shortname), p_slash + 1);
-    } else {
-      sprintf(mod.shortname, "%.*s", sizeof(mod.shortname), mod.fullpath);
-    }
-    num_loaded ++;
-
-    // next entry...
-    if (p->ldinfo_next) {
-      p = (struct ld_info*)(((char*)p) + p->ldinfo_next);
-    } else {
-      all_loaded = true;
       break;
     }
   }
 
-  FreeHeap(loadquery_buf);
+  trcVerbose("loadquery buffer size is %llu.", buflen);
 
-  // Ensure we have all loaded libs
-  assert(all_loaded, "loadquery returned more entries then expected. Please increase MAX_MODULES");
+  // Iterate over the loadquery result. For details see sys/ldr.h on AIX.
+  ldi = (struct ld_info*) buffer;
+
+  for (;;) {
+
+    entry_t* e = (entry_t*) ::malloc(sizeof(entry_t));
+    if (!e) {
+      trcVerbose("OOM.");
+      goto cleanup;
+    }
+
+    memset(e, 0, sizeof(entry_t));
+
+    e->info.text = ldi->ldinfo_textorg;
+    e->info.text_len = ldi->ldinfo_textsize;
+    e->info.data = ldi->ldinfo_dataorg;
+    e->info.data_len = ldi->ldinfo_datasize;
+
+    e->info.path = g_stringlist.add(ldi->ldinfo_filename);
+    if (!e->info.path) {
+      trcVerbose("OOM.");
+      goto cleanup;
+    }
+
+    // Extract short name
+    {
+      const char* p = strrchr(e->info.path, '/');
+      if (p) {
+        p ++;
+        e->info.shortname = p;
+      } else {
+        e->info.shortname = e->info.path;
+      }
+    }
+
+    // Do we have a member name as well (see ldr.h)?
+    const char* p_mbr_name =
+      ldi->ldinfo_filename + strlen(ldi->ldinfo_filename) + 1;
+    if (*p_mbr_name) {
+      e->info.member = g_stringlist.add(p_mbr_name);
+      if (!e->info.member) {
+        trcVerbose("OOM.");
+        goto cleanup;
+      }
+    } else {
+      e->info.member = NULL;
+    }
+
+    if (strcmp(e->info.shortname, "libjvm.so") == 0) {
+      // Note that this, theoretically, is fuzzy. We may accidentally contain
+      // more than one libjvm.so. But that is improbable, so lets go with this
+      // solution.
+      e->info.is_in_vm = true;
+    }
+
+    trcVerbose("entry: %p %llu, %p %llu, %s %s %s, %d",
+      e->info.text, e->info.text_len,
+      e->info.data, e->info.data_len,
+      e->info.path, e->info.shortname,
+      (e->info.member ? e->info.member : "NULL"),
+      e->info.is_in_vm
+    );
+
+    // Add to list.
+    add_entry_to_list(e, &new_list);
+
+    // Next entry...
+    if (ldi->ldinfo_next) {
+      ldi = (struct ld_info*)(((char*)ldi) + ldi->ldinfo_next);
+    } else {
+      break;
+    }
+  }
+
+  // We are done. All is well. Free old list and swap to new one.
+  if (g_first) {
+    free_entry_list(&g_first);
+  }
+  g_first = new_list;
+  new_list = NULL;
+
+  rc = true;
+
+cleanup:
+
+  if (new_list) {
+    free_entry_list(&new_list);
+  }
+
+  ::free(buffer);
+
+  return rc;
 
 } // end LoadedLibraries::reload()
 
 
-// output loaded libraries table
-//static
-void LoadedLibraries::print(outputStream* os) {
+///////////////////////////////////////////////////////////////////////////////
+// Externals
 
-  for (int i = 0; i < num_loaded; i++) {
-    tab[i].print(os);
-  }
+static MiscUtils::CritSect g_cs;
 
+// Rebuild the internal module table. If an error occurs, old table remains
+// unchanged.
+bool LoadedLibraries::reload() {
+  MiscUtils::AutoCritSect lck(&g_cs);
+  return reload_table();
 }
 
+void LoadedLibraries::print(outputStream* os) {
+  MiscUtils::AutoCritSect lck(&g_cs);
+  if (!g_first) {
+    reload_table();
+  }
+  for (entry_t* e = g_first; e; e = e->next) {
+    print_entry(e, os);
+    os->cr();
+  }
+}
+
+bool LoadedLibraries::find_for_text_address(const void* p,
+                                            loaded_module_t* info) {
+  MiscUtils::AutoCritSect lck(&g_cs);
+  if (!g_first) {
+    reload_table();
+  }
+  const entry_t* const e = find_entry_for_text_address(p);
+  if (e) {
+    if (info) {
+      *info = e->info;
+    }
+    return true;
+  }
+  return false;
+}
+
+
+bool LoadedLibraries::find_for_data_address (
+  const void* p,
+  loaded_module_t* info // optional. can be NULL:
+) {
+  MiscUtils::AutoCritSect lck(&g_cs);
+  if (!g_first) {
+    reload_table();
+  }
+  const entry_t* const e = find_entry_for_data_address(p);
+  if (e) {
+    if (info) {
+      *info = e->info;
+    }
+    return true;
+  }
+  return false;
+}
+
--- a/src/os/aix/vm/loadlib_aix.hpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/os/aix/vm/loadlib_aix.hpp	Fri Nov 13 10:35:26 2015 -0800
@@ -26,73 +26,47 @@
 // Loadlib_aix.cpp contains support code for analysing the memory
 // layout of loaded binaries in ones own process space.
 //
-// It is needed, among other things, to provide a  dladdr() emulation, because
-// that one is not provided by AIX
+// It is needed, among other things, to provide dladdr(3), which is
+// missing on AIX.
 
 #ifndef OS_AIX_VM_LOADLIB_AIX_HPP
 #define OS_AIX_VM_LOADLIB_AIX_HPP
 
+#include <stddef.h>
+
 class outputStream;
 
-// This class holds information about a single loaded library module.
+// Struct holds information about a single loaded library module.
 // Note that on AIX, a single library can be spread over multiple
-// uintptr_t range on a module base, eg.
+// uintptr_t ranges on a module base, eg.
 // libC.a(shr3_64.o) or libC.a(shrcore_64.o).
-class LoadedLibraryModule {
 
-    friend class LoadedLibraries;
+// Note: all pointers to strings (path, member) point to strings which are immortal.
+struct loaded_module_t {
 
-    char fullpath[512];  // eg /usr/lib/libC.a
-    char shortname[30];  // eg libC.a
-    char membername[30]; // eg shrcore_64.o
-    const unsigned char* text_from;
-    const unsigned char* text_to;
-    const unsigned char* data_from;
-    const unsigned char* data_to;
+  // Points to the full path of the lodaed module, e.g.
+  // "/usr/lib/libC.a".
+  const char* path;
 
-  public:
+  // Host library name without path
+  const char* shortname;
 
-    const char* get_fullpath() const {
-      return fullpath;
-    }
-    const char* get_shortname() const {
-      return shortname;
-    }
-    const char* get_membername() const {
-      return membername;
-    }
+  // Points to the object file (AIX specific stuff)
+  // e.g "shrcore_64.o".
+  const char* member;
 
-    // text_from, text_to: returns the range of the text (code)
-    // segment for that module
-    const unsigned char* get_text_from() const {
-      return text_from;
-    }
-    const unsigned char* get_text_to() const {
-      return text_to;
-    }
+  // Text area from, to
+  const void* text;
+  size_t text_len;
 
-    // data_from/data_to: returns the range of the data
-    // segment for that module
-    const unsigned char* get_data_from() const {
-      return data_from;
-    }
-    const unsigned char* get_data_to() const {
-      return data_to;
-    }
+  // Data area from, to
+  const void* data;
+  size_t data_len;
 
-    // returns true if the
-    bool is_in_text(const unsigned char* p) const {
-      return p >= text_from && p < text_to ? true : false;
-    }
+  // True if this module is part of the vm.
+  bool is_in_vm;
 
-    bool is_in_data(const unsigned char* p) const {
-      return p >= data_from && p < data_to ? true : false;
-    }
-
-    // output debug info
-    void print(outputStream* os) const;
-
-}; // end LoadedLibraryModule
+};
 
 // This class is a singleton holding a map of all loaded binaries
 // in the AIX process space.
@@ -100,29 +74,31 @@
 // : AllStatic (including allocation.hpp just for AllStatic is overkill.)
 {
 
-  private:
-
-    enum {MAX_MODULES = 100};
-    static LoadedLibraryModule tab[MAX_MODULES];
-    static int num_loaded;
-
   public:
 
-    // rebuild the internal table of LoadedLibraryModule objects
-    static void reload();
+    // Rebuild the internal module table. If an error occurs, internal module
+    // table remains untouched.
+    static bool reload();
 
-    // checks whether the address p points to any of the loaded code segments.
-    // If it does, returns the LoadedLibraryModule entry. If not, returns NULL.
-    static const LoadedLibraryModule* find_for_text_address(const  unsigned char* p);
+    // Check whether the given address points into the text segment of a
+    // loaded module. Return true if this is the case.
+    // Optionally, information about the module is returned (info)
+    static bool find_for_text_address (
+      const void* p,
+      loaded_module_t* info // Optional, leave NULL if not needed.
+    );
 
-    // checks whether the address p points to any of the loaded data segments.
-    // If it does, returns the LoadedLibraryModule entry. If not, returns NULL.
-    static const LoadedLibraryModule* find_for_data_address(const  unsigned char* p);
+    // Check whether the given address points into the data segment of a
+    // loaded module. Return true if this is the case.
+    // Optionally, information about the module is returned (info)
+    static bool find_for_data_address (
+      const void* p,
+      loaded_module_t* info // Optional, leave NULL if not needed.
+    );
 
-    // output debug info
+    // Output debug info
     static void print(outputStream* os);
 
-}; // end LoadedLibraries
-
+};
 
 #endif // OS_AIX_VM_LOADLIB_AIX_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/aix/vm/misc_aix.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2015 SAP AG. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 "misc_aix.hpp"
+#include "runtime/stubRoutines.hpp"
+
+#include <pthread.h>
+
+void MiscUtils::init_critsect(MiscUtils::critsect_t* cs) {
+  const int rc = pthread_mutex_init(cs, NULL);
+  assert0(rc == 0);
+}
+
+void MiscUtils::free_critsect(MiscUtils::critsect_t* cs) {
+  const int rc = pthread_mutex_destroy(cs);
+  assert0(rc == 0);
+}
+
+void MiscUtils::enter_critsect(MiscUtils::critsect_t* cs) {
+  const int rc = pthread_mutex_lock(cs);
+  assert0(rc == 0);
+}
+
+void MiscUtils::leave_critsect(MiscUtils::critsect_t* cs) {
+  const int rc = pthread_mutex_unlock(cs);
+  assert0(rc == 0);
+}
+
+bool MiscUtils::is_readable_pointer(const void* p) {
+  if (!CanUseSafeFetch32()) {
+    return true;
+  }
+  int* const aligned = (int*) align_size_down((intptr_t)p, 4);
+  int cafebabe = 0xcafebabe;
+  int deadbeef = 0xdeadbeef;
+  return (SafeFetch32(aligned, cafebabe) != cafebabe) ||
+         (SafeFetch32(aligned, deadbeef) != deadbeef);
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/aix/vm/misc_aix.hpp	Fri Nov 13 10:35:26 2015 -0800
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2012, 2015 SAP AG. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 OS_AIX_VM_MISC_AIX_HPP
+#define OS_AIX_VM_MISC_AIX_HPP
+
+// misc_aix.hpp, misc_aix.cpp: convenience functions needed for the OpenJDK AIX
+// port.
+#include "utilities/globalDefinitions.hpp"
+
+#include <pthread.h>
+
+// Trace if verbose to tty.
+#define trcVerbose(fmt, ...) { \
+  if (Verbose) { \
+    fprintf(stderr, fmt, ##__VA_ARGS__); \
+    fputc('\n', stderr); fflush(stderr); \
+  } \
+}
+#define ERRBYE(s) { trcVerbose(s); return -1; }
+#define trc(fmt, ...)
+
+#define assert0(b) assert((b), "")
+#define guarantee0(b) guarantee((b), "")
+template <class T1, class T2> bool is_aligned_to(T1 what, T2 alignment) {
+  return (((uintx)(what)) & (((uintx)(alignment)) - 1)) == 0 ? true : false;
+}
+
+// CritSect: simple critical section implementation using pthread mutexes.
+namespace MiscUtils {
+  typedef pthread_mutex_t critsect_t;
+
+  void init_critsect(MiscUtils::critsect_t* cs);
+  void free_critsect(MiscUtils::critsect_t* cs);
+  void enter_critsect(MiscUtils::critsect_t* cs);
+  void leave_critsect(MiscUtils::critsect_t* cs);
+
+  // Need to wrap this in an object because we need to dynamically initialize
+  // critical section (because of windows, where there is no way to initialize
+  // a CRITICAL_SECTION statically. On Unix, we could use
+  // PTHREAD_MUTEX_INITIALIZER).
+
+  // Note: The critical section does NOT get cleaned up in the destructor. That is
+  // by design: the CritSect class is only ever used as global objects whose
+  // lifetime spans the whole VM life; in that context we don't want the lock to
+  // be cleaned up when global C++ objects are destroyed, but to continue to work
+  // correctly right to the very end of the process life.
+  class CritSect {
+    critsect_t _cs;
+   public:
+    CritSect()        { init_critsect(&_cs); }
+    //~CritSect()       { free_critsect(&_cs); }
+    void enter()      { enter_critsect(&_cs); }
+    void leave()      { leave_critsect(&_cs); }
+  };
+
+  class AutoCritSect {
+    CritSect* const _pcsobj;
+   public:
+    AutoCritSect(CritSect* pcsobj)
+      : _pcsobj(pcsobj)
+    {
+      _pcsobj->enter();
+    }
+    ~AutoCritSect() {
+      _pcsobj->leave();
+    }
+  };
+
+  // Returns true if pointer can be dereferenced without triggering a segment
+  // violation. Returns false if pointer is invalid.
+  // Note: Depends on stub routines; prior to stub routine generation, will
+  // always return true. Use CanUseSafeFetch32 to handle this case.
+  bool is_readable_pointer(const void* p);
+
+}
+
+#endif // OS_AIX_VM_MISC_AIX_HPP
+
--- a/src/os/aix/vm/os_aix.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/os/aix/vm/os_aix.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -40,6 +40,7 @@
 #include "loadlib_aix.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/filemap.hpp"
+#include "misc_aix.hpp"
 #include "mutex_aix.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "os_aix.inline.hpp"
@@ -159,23 +160,10 @@
 #define PV_8_Compat 0x308000   /* Power PC 8 */
 #endif
 
-#define trcVerbose(fmt, ...) { /* PPC port */  \
-  if (Verbose) { \
-    fprintf(stderr, fmt, ##__VA_ARGS__); \
-    fputc('\n', stderr); fflush(stderr); \
-  } \
-}
-#define trc(fmt, ...)        /* PPC port */
-
-#define ERRBYE(s) { \
-    trcVerbose(s); \
-    return -1; \
-}
-
 // Query dimensions of the stack of the calling thread.
 static bool query_stack_dimensions(address* p_stack_base, size_t* p_stack_size);
 
-// function to check a given stack pointer against given stack limits
+// Function to check a given stack pointer against given stack limits.
 inline bool is_valid_stackpointer(stackptr_t sp, stackptr_t stack_base, size_t stack_size) {
   if (((uintptr_t)sp) & 0x7) {
     return false;
@@ -189,7 +177,7 @@
   return true;
 }
 
-// returns true if function is a valid codepointer
+// Returns true if function is a valid codepointer.
 inline bool is_valid_codepointer(codeptr_t p) {
   if (!p) {
     return false;
@@ -197,7 +185,7 @@
   if (((uintptr_t)p) & 0x3) {
     return false;
   }
-  if (LoadedLibraries::find_for_text_address((address)p) == NULL) {
+  if (!LoadedLibraries::find_for_text_address(p, NULL)) {
     return false;
   }
   return true;
@@ -1387,26 +1375,15 @@
 
   // Input could be a real pc or a function pointer literal. The latter
   // would be a function descriptor residing in the data segment of a module.
-
-  const LoadedLibraryModule* lib = LoadedLibraries::find_for_text_address(addr);
-  if (lib) {
-    if (strcmp(lib->get_shortname(), "libjvm.so") == 0) {
-      return true;
-    } else {
-      return false;
-    }
+  loaded_module_t lm;
+  if (LoadedLibraries::find_for_text_address(addr, &lm) != NULL) {
+    return lm.is_in_vm;
+  } else if (LoadedLibraries::find_for_data_address(addr, &lm) != NULL) {
+    return lm.is_in_vm;
   } else {
-    lib = LoadedLibraries::find_for_data_address(addr);
-    if (lib) {
-      if (strcmp(lib->get_shortname(), "libjvm.so") == 0) {
-        return true;
-      } else {
-        return false;
-      }
-    } else {
-      return false;
-    }
-  }
+    return false;
+  }
+
 }
 
 // Resolve an AIX function descriptor literal to a code pointer.
@@ -1418,21 +1395,18 @@
 //   NULL is returned.
 static address resolve_function_descriptor_to_code_pointer(address p) {
 
-  const LoadedLibraryModule* lib = LoadedLibraries::find_for_text_address(p);
-  if (lib) {
-    // its a real code pointer
+  if (LoadedLibraries::find_for_text_address(p, NULL) != NULL) {
+    // It is a real code pointer.
     return p;
-  } else {
-    lib = LoadedLibraries::find_for_data_address(p);
-    if (lib) {
-      // pointer to data segment, potential function descriptor
-      address code_entry = (address)(((FunctionDescriptor*)p)->entry());
-      if (LoadedLibraries::find_for_text_address(code_entry)) {
-        // Its a function descriptor
-        return code_entry;
-      }
+  } else if (LoadedLibraries::find_for_data_address(p, NULL) != NULL) {
+    // Pointer to data segment, potential function descriptor.
+    address code_entry = (address)(((FunctionDescriptor*)p)->entry());
+    if (LoadedLibraries::find_for_text_address(code_entry, NULL) != NULL) {
+      // It is a function descriptor.
+      return code_entry;
     }
   }
+
   return NULL;
 }
 
@@ -1461,7 +1435,6 @@
                          char* p_errmsg, size_t errmsglen // [out] optional: user provided buffer for error messages
                          ) {
 
-  // initialize output parameters
   if (p_name && namelen > 0) {
     *p_name = '\0';
   }
@@ -1469,16 +1442,15 @@
     *p_errmsg = '\0';
   }
 
-  const LoadedLibraryModule* const lib = LoadedLibraries::find_for_text_address((address)pc);
-  if (lib) {
-    if (p_name && namelen > 0) {
-      sprintf(p_name, "%.*s", namelen, lib->get_shortname());
+  if (p_name && namelen > 0) {
+    loaded_module_t lm;
+    if (LoadedLibraries::find_for_text_address(pc, &lm) != NULL) {
+      strncpy(p_name, lm.shortname, namelen);
+      p_name[namelen - 1] = '\0';
     }
     return 0;
   }
 
-  trcVerbose("pc outside any module");
-
   return -1;
 }
 
@@ -1690,7 +1662,6 @@
   print_signal_handler(st, SIGPIPE, buf, buflen);
   print_signal_handler(st, SIGXFSZ, buf, buflen);
   print_signal_handler(st, SIGILL , buf, buflen);
-  print_signal_handler(st, INTERRUPT_SIGNAL, buf, buflen);
   print_signal_handler(st, SR_signum, buf, buflen);
   print_signal_handler(st, SHUTDOWN1_SIGNAL, buf, buflen);
   print_signal_handler(st, SHUTDOWN2_SIGNAL , buf, buflen);
@@ -3309,7 +3280,6 @@
   }
 
   DO_SIGNAL_CHECK(SR_signum);
-  DO_SIGNAL_CHECK(INTERRUPT_SIGNAL);
 }
 
 typedef int (*os_sigaction_t)(int, const struct sigaction *, struct sigaction *);
@@ -3351,10 +3321,6 @@
     jvmHandler = (address)user_handler();
     break;
 
-  case INTERRUPT_SIGNAL:
-    jvmHandler = CAST_FROM_FN_PTR(address, SIG_DFL);
-    break;
-
   default:
     if (sig == SR_signum) {
       jvmHandler = CAST_FROM_FN_PTR(address, (sa_sigaction_t)SR_handler);
@@ -3787,18 +3753,11 @@
 
   st->print(PTR_FORMAT ": ", addr);
 
-  const LoadedLibraryModule* lib = LoadedLibraries::find_for_text_address(addr);
-  if (lib) {
-    lib->print(st);
+  loaded_module_t lm;
+  if (LoadedLibraries::find_for_text_address(addr, &lm) != NULL ||
+      LoadedLibraries::find_for_data_address(addr, &lm) != NULL) {
+    st->print("%s", lm.path);
     return true;
-  } else {
-    lib = LoadedLibraries::find_for_data_address(addr);
-    if (lib) {
-      lib->print(st);
-      return true;
-    } else {
-      st->print_cr("(outside any module)");
-    }
   }
 
   return false;
@@ -3965,9 +3924,6 @@
   if (::fstat64(fd, &buf64) >= 0) {
     mode = buf64.st_mode;
     if (S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) {
-      // XXX: is the following call interruptible? If so, this might
-      // need to go through the INTERRUPT_IO() wrapper as for other
-      // blocking, interruptible calls in this file.
       int n;
       if (::ioctl(fd, FIONREAD, &n) >= 0) {
         *bytes = n;
--- a/src/os/aix/vm/perfMemory_aix.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/os/aix/vm/perfMemory_aix.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -201,6 +201,7 @@
 // the backing store files. Returns true if the directory is considered
 // a secure location. Returns false if the statbuf is a symbolic link or
 // if an error occurred.
+//
 static bool is_statbuf_secure(struct stat *statp) {
   if (S_ISLNK(statp->st_mode) || !S_ISDIR(statp->st_mode)) {
     // The path represents a link or some non-directory file type,
@@ -209,15 +210,18 @@
     return false;
   }
   // We have an existing directory, check if the permissions are safe.
+  //
   if ((statp->st_mode & (S_IWGRP|S_IWOTH)) != 0) {
     // The directory is open for writing and could be subjected
     // to a symlink or a hard link attack. Declare it insecure.
+    //
     return false;
   }
-  // See if the uid of the directory matches the effective uid of the process.
-  //
-  if (statp->st_uid != geteuid()) {
+  // If user is not root then see if the uid of the directory matches the effective uid of the process.
+  uid_t euid = geteuid();
+  if ((euid != 0) && (statp->st_uid != euid)) {
     // The directory was not created by this user, declare it insecure.
+    //
     return false;
   }
   return true;
@@ -228,6 +232,7 @@
 // the backing store files. Returns true if the directory exists
 // and is considered a secure location. Returns false if the path
 // is a symbolic link or if an error occurred.
+//
 static bool is_directory_secure(const char* path) {
   struct stat statbuf;
   int result = 0;
--- a/src/os/aix/vm/porting_aix.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/os/aix/vm/porting_aix.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -23,11 +23,13 @@
  */
 
 #include "asm/assembler.hpp"
+#include "loadlib_aix.hpp"
 #include "memory/allocation.hpp"
 #include "memory/allocation.inline.hpp"
+// For CritSect
+#include "misc_aix.hpp"
+#include "porting_aix.hpp"
 #include "runtime/os.hpp"
-#include "loadlib_aix.hpp"
-#include "porting_aix.hpp"
 #include "utilities/debug.hpp"
 
 #include <demangle.h>
@@ -45,23 +47,6 @@
 
 #define PTRDIFF_BYTES(p1,p2) (((ptrdiff_t)p1) - ((ptrdiff_t)p2))
 
-// Align a pointer without having to cast.
-inline char* align_ptr_up(char* ptr, intptr_t alignment) {
-  return (char*) align_size_up((intptr_t)ptr, alignment);
-}
-
-// Trace if verbose to tty.
-// I use these now instead of the Xtrace system because the latter is
-// not available at init time, hence worthless. Until we fix this, all
-// tracing here is done with -XX:+Verbose.
-#define trcVerbose(fmt, ...) { \
-  if (Verbose) { \
-    fprintf(stderr, fmt, ##__VA_ARGS__); \
-    fputc('\n', stderr); fflush(stderr); \
-  } \
-}
-#define ERRBYE(s) { trcVerbose(s); return -1; }
-
 // Unfortunately, the interface of dladdr makes the implementator
 // responsible for maintaining memory for function name/library
 // name. I guess this is because most OS's keep those values as part
@@ -139,18 +124,37 @@
     ERRBYE("invalid program counter");
   }
 
+  // We see random but frequent crashes in this function since some months mainly on shutdown
+  // (-XX:+DumpInfoAtExit). It appears the page we are reading is randomly disappearing while
+  // we read it (?).
+  // As the pc cannot be trusted to be anything sensible lets make all reads via SafeFetch. Also
+  // bail if this is not a text address right now.
+  if (!LoadedLibraries::find_for_text_address(pc, NULL)) {
+    ERRBYE("not a text address");
+  }
+
+  // .. (Note that is_readable_pointer returns true if safefetch stubs are not there yet;
+  // in that case I try reading the traceback table unsafe - I rather risk secondary crashes in
+  // error files than not having a callstack.)
+#define CHECK_POINTER_READABLE(p) \
+  if (!MiscUtils::is_readable_pointer(p)) { \
+    ERRBYE("pc not readable"); \
+  }
+
   codeptr_t pc2 = pc;
 
-  // make sure the pointer is word aligned.
+  // Make sure the pointer is word aligned.
   pc2 = (codeptr_t) align_ptr_up((char*)pc2, 4);
+  CHECK_POINTER_READABLE(pc2)
 
   // Find start of traceback table.
   // (starts after code, is marked by word-aligned (32bit) zeros)
   while ((*pc2 != NULL) && (searchcount++ < MAX_FUNC_SEARCH_LEN)) {
+    CHECK_POINTER_READABLE(pc2)
     pc2++;
   }
   if (*pc2 != 0) {
-    ERRBYE("could not find traceback table within 5000 bytes of program counter");
+    ERRBYE("no traceback table found");
   }
   //
   // Set up addressability to the traceback table
@@ -162,7 +166,7 @@
   if (tb->tb.lang >= 0xf && tb->tb.lang <= 0xfb) {
     // Language specifiers, go from 0 (C) to 14 (Objective C).
     // According to spec, 0xf-0xfa reserved, 0xfb-0xff reserved for ibm.
-    ERRBYE("not a traceback table");
+    ERRBYE("no traceback table found");
   }
 
   // Existence of fields in the tbtable extension are contingent upon
@@ -173,6 +177,8 @@
   if (tb->tb.fixedparms != 0 || tb->tb.floatparms != 0)
     pc2++;
 
+  CHECK_POINTER_READABLE(pc2)
+
   if (tb->tb.has_tboff == TRUE) {
 
     // I want to know the displacement
@@ -182,7 +188,7 @@
 
     // Weed out the cases where we did find the wrong traceback table.
     if (pc < start_of_procedure) {
-      ERRBYE("could not find (the real) traceback table within 5000 bytes of program counter");
+      ERRBYE("no traceback table found");
     }
 
     // return the displacement
@@ -204,15 +210,24 @@
   if (tb->tb.has_ctl == TRUE)
     pc2 += (*pc2) + 1; // don't care
 
+  CHECK_POINTER_READABLE(pc2)
+
   //
   // return function name if it exists.
   //
   if (p_name && namelen > 0) {
     if (tb->tb.name_present) {
+      // Copy name from text because it may not be zero terminated.
+      // 256 is good enough for most cases; do not use large buffers here.
       char buf[256];
       const short l = MIN2<short>(*((short*)pc2), sizeof(buf) - 1);
-      memcpy(buf, (char*)pc2 + sizeof(short), l);
-      buf[l] = '\0';
+      // Be very careful.
+      int i = 0; char* const p = (char*)pc2 + sizeof(short);
+      while (i < l && MiscUtils::is_readable_pointer(p + i)) {
+        buf[i] = p[i];
+        i++;
+      }
+      buf[i] = '\0';
 
       p_name[0] = '\0';
 
@@ -275,7 +290,8 @@
   info->dli_saddr = NULL;
 
   address p = (address) addr;
-  const LoadedLibraryModule* lib = NULL;
+  loaded_module_t lm;
+  bool found = false;
 
   enum { noclue, code, data } type = noclue;
 
@@ -284,28 +300,28 @@
   // Note: input address may be a function. I accept both a pointer to
   // the entry of a function and a pointer to the function decriptor.
   // (see ppc64 ABI)
-  lib = LoadedLibraries::find_for_text_address(p);
-  if (lib) {
+  found = LoadedLibraries::find_for_text_address(p, &lm);
+  if (found) {
     type = code;
   }
 
-  if (!lib) {
+  if (!found) {
     // Not a pointer into any text segment. Is it a function descriptor?
     const FunctionDescriptor* const pfd = (const FunctionDescriptor*) p;
     p = pfd->entry();
     if (p) {
-      lib = LoadedLibraries::find_for_text_address(p);
-      if (lib) {
+      found = LoadedLibraries::find_for_text_address(p, &lm);
+      if (found) {
         type = code;
       }
     }
   }
 
-  if (!lib) {
+  if (!found) {
     // Neither direct code pointer nor function descriptor. A data ptr?
     p = (address)addr;
-    lib = LoadedLibraries::find_for_data_address(p);
-    if (lib) {
+    found = LoadedLibraries::find_for_data_address(p, &lm);
+    if (found) {
       type = data;
     }
   }
@@ -313,12 +329,10 @@
   // If we did find the shared library this address belongs to (either
   // code or data segment) resolve library path and, if possible, the
   // symbol name.
-  if (lib) {
-    const char* const interned_libpath =
-      dladdr_fixed_strings.intern(lib->get_fullpath());
-    if (interned_libpath) {
-      info->dli_fname = interned_libpath;
-    }
+  if (found) {
+
+    // No need to intern the libpath, that one is already interned one layer below.
+    info->dli_fname = lm.path;
 
     if (type == code) {
 
@@ -328,7 +342,7 @@
       int displacement = 0;
 
       if (getFuncName((codeptr_t) p, funcname, sizeof(funcname), &displacement,
-                      NULL, NULL, 0, true /* demangle */) == 0) {
+                      NULL, NULL, 0, false) == 0) {
         if (funcname[0] != '\0') {
           const char* const interned = dladdr_fixed_strings.intern(funcname);
           info->dli_sname = interned;
--- a/src/os/aix/vm/porting_aix.hpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/os/aix/vm/porting_aix.hpp	Fri Nov 13 10:35:26 2015 -0800
@@ -27,13 +27,6 @@
 
 #include <stddef.h>
 
-// PPC port only:
-#define assert0(b) assert( (b), "" )
-#define guarantee0(b) assert( (b), "" )
-template <class T1, class T2> bool is_aligned_to(T1 what, T2 alignment) {
-  return  ( ((uintx)(what)) & (((uintx)(alignment)) - 1) ) == 0 ? true : false;
-}
-
 // Header file to contain porting-relevant code which does not have a
 // home anywhere else and which can not go into os_<platform>.h because
 // that header is included inside the os class definition, hence all
@@ -68,13 +61,9 @@
 #endif
 int dladdr(void *addr, Dl_info *info);
 
+typedef unsigned int* codeptr_t;
 
-// The semantics in this file are thus that codeptr_t is a *real code ptr*.
-// This means that any function taking codeptr_t as arguments will assume
-// a real codeptr and won't handle function descriptors (eg getFuncName),
-// whereas functions taking address as args will deal with function
-// descriptors (eg os::dll_address_to_library_name).
-typedef unsigned int* codeptr_t;
+struct tbtable;
 
 // helper function - given a program counter, tries to locate the traceback table and
 // returns info from it (like, most importantly, function name, displacement of the
@@ -87,65 +76,9 @@
       char* p_name, size_t namelen,    // [out] optional: user provided buffer for the function name
       int* p_displacement,             // [out] optional: displacement
       const struct tbtable** p_tb,     // [out] optional: ptr to traceback table to get further information
-      char* p_errmsg, size_t errmsglen,// [out] optional: user provided buffer for error messages
-      bool demangle = true             // [in] whether to demangle the name
+      char* p_errmsg, size_t errmsglen, // [out] optional: user provided buffer for error messages
+      bool demangle                    // [in] whether to demangle the name
     );
 
-// -------------------------------------------------------------------------
+#endif // OS_AIX_VM_PORTING_AIX_HPP
 
-// A simple critical section which shall be based upon OS critical
-// sections (CRITICAL_SECTION resp. Posix Mutex) and nothing else.
-
-#include <pthread.h>
-
-namespace MiscUtils {
-  typedef pthread_mutex_t critsect_t;
-
-  inline void init_critsect(MiscUtils::critsect_t* cs) {
-    pthread_mutex_init(cs, NULL);
-  }
-  inline void free_critsect(MiscUtils::critsect_t* cs) {
-    pthread_mutex_destroy(cs);
-  }
-  inline void enter_critsect(MiscUtils::critsect_t* cs) {
-    pthread_mutex_lock(cs);
-  }
-  inline void leave_critsect(MiscUtils::critsect_t* cs) {
-    pthread_mutex_unlock(cs);
-  }
-
-  // Need to wrap this in an object because we need to dynamically initialize
-  // critical section (because of windows, where there is no way to initialize
-  // a CRITICAL_SECTION statically. On Unix, we could use
-  // PTHREAD_MUTEX_INITIALIZER)
-
-  // Note: The critical section does NOT get cleaned up in the destructor. That is
-  // by design: the CritSect class is only ever used as global objects whose
-  // lifetime spans the whole VM life; in that context we don't want the lock to
-  // be cleaned up when global C++ objects are destroyed, but to continue to work
-  // correctly right to the very end of the process life.
-  class CritSect {
-    critsect_t _cs;
-  public:
-    CritSect()        { init_critsect(&_cs); }
-    //~CritSect()       { free_critsect(&_cs); }
-    void enter()      { enter_critsect(&_cs); }
-    void leave()      { leave_critsect(&_cs); }
-  };
-
-  class AutoCritSect {
-    CritSect* const _pcsobj;
-  public:
-    AutoCritSect(CritSect* pcsobj)
-      : _pcsobj(pcsobj)
-    {
-      _pcsobj->enter();
-    }
-    ~AutoCritSect() {
-      _pcsobj->leave();
-    }
-  };
-
-}
-
-#endif // OS_AIX_VM_PORTING_AIX_HPP
--- a/src/os/bsd/vm/jvm_bsd.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/os/bsd/vm/jvm_bsd.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -47,7 +47,6 @@
                    : handler;
   switch (sig) {
     /* The following are already used by the VM. */
-    case INTERRUPT_SIGNAL:
     case SIGFPE:
     case SIGILL:
     case SIGSEGV:
--- a/src/os/bsd/vm/jvm_bsd.h	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/os/bsd/vm/jvm_bsd.h	Fri Nov 13 10:35:26 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -107,7 +107,6 @@
 /* Signal definitions */
 
 #define BREAK_SIGNAL     SIGQUIT           /* Thread dumping support.    */
-#define INTERRUPT_SIGNAL SIGUSR1           /* Interruptible I/O support. */
 #define SHUTDOWN1_SIGNAL SIGHUP            /* Shutdown Hooks support.    */
 #define SHUTDOWN2_SIGNAL SIGINT
 #define SHUTDOWN3_SIGNAL SIGTERM
--- a/src/os/bsd/vm/os_bsd.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/os/bsd/vm/os_bsd.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -1777,7 +1777,6 @@
   print_signal_handler(st, SIGPIPE, buf, buflen);
   print_signal_handler(st, SIGXFSZ, buf, buflen);
   print_signal_handler(st, SIGILL , buf, buflen);
-  print_signal_handler(st, INTERRUPT_SIGNAL, buf, buflen);
   print_signal_handler(st, SR_signum, buf, buflen);
   print_signal_handler(st, SHUTDOWN1_SIGNAL, buf, buflen);
   print_signal_handler(st, SHUTDOWN2_SIGNAL , buf, buflen);
@@ -3345,7 +3344,6 @@
   }
 
   DO_SIGNAL_CHECK(SR_signum);
-  DO_SIGNAL_CHECK(INTERRUPT_SIGNAL);
 }
 
 typedef int (*os_sigaction_t)(int, const struct sigaction *, struct sigaction *);
@@ -3391,10 +3389,6 @@
     jvmHandler = (address)user_handler();
     break;
 
-  case INTERRUPT_SIGNAL:
-    jvmHandler = CAST_FROM_FN_PTR(address, SIG_DFL);
-    break;
-
   default:
     if (sig == SR_signum) {
       jvmHandler = CAST_FROM_FN_PTR(address, (sa_sigaction_t)SR_handler);
@@ -3913,9 +3907,6 @@
   if (::fstat(fd, &buf) >= 0) {
     mode = buf.st_mode;
     if (S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) {
-      // XXX: is the following call interruptible? If so, this might
-      // need to go through the INTERRUPT_IO() wrapper as for other
-      // blocking, interruptible calls in this file.
       int n;
       if (::ioctl(fd, FIONREAD, &n) >= 0) {
         *bytes = n;
--- a/src/os/bsd/vm/perfMemory_bsd.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/os/bsd/vm/perfMemory_bsd.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -217,9 +217,9 @@
     //
     return false;
   }
-  // See if the uid of the directory matches the effective uid of the process.
-  //
-  if (statp->st_uid != geteuid()) {
+  // If user is not root then see if the uid of the directory matches the effective uid of the process.
+  uid_t euid = geteuid();
+  if ((euid != 0) && (statp->st_uid != euid)) {
     // The directory was not created by this user, declare it insecure.
     //
     return false;
--- a/src/os/linux/vm/attachListener_linux.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/os/linux/vm/attachListener_linux.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -254,6 +254,8 @@
   do {
     int n;
     RESTARTABLE(read(s, buf+off, left), n);
+    assert(n <= left, "buffer was too small, impossible!");
+    buf[max_len - 1] = '\0';
     if (n == -1) {
       return NULL;      // reset by peer or other error
     }
--- a/src/os/linux/vm/jvm_linux.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/os/linux/vm/jvm_linux.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -47,7 +47,6 @@
                    : handler;
   switch (sig) {
     /* The following are already used by the VM. */
-    case INTERRUPT_SIGNAL:
     case SIGFPE:
     case SIGILL:
     case SIGSEGV:
--- a/src/os/linux/vm/jvm_linux.h	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/os/linux/vm/jvm_linux.h	Fri Nov 13 10:35:26 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -88,7 +88,6 @@
 /* Signal definitions */
 
 #define BREAK_SIGNAL     SIGQUIT           /* Thread dumping support.    */
-#define INTERRUPT_SIGNAL SIGUSR1           /* Interruptible I/O support. */
 #define SHUTDOWN1_SIGNAL SIGHUP            /* Shutdown Hooks support.    */
 #define SHUTDOWN2_SIGNAL SIGINT
 #define SHUTDOWN3_SIGNAL SIGTERM
--- a/src/os/linux/vm/os_linux.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/os/linux/vm/os_linux.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -2302,7 +2302,6 @@
   print_signal_handler(st, SIGPIPE, buf, buflen);
   print_signal_handler(st, SIGXFSZ, buf, buflen);
   print_signal_handler(st, SIGILL , buf, buflen);
-  print_signal_handler(st, INTERRUPT_SIGNAL, buf, buflen);
   print_signal_handler(st, SR_signum, buf, buflen);
   print_signal_handler(st, SHUTDOWN1_SIGNAL, buf, buflen);
   print_signal_handler(st, SHUTDOWN2_SIGNAL , buf, buflen);
@@ -2820,7 +2819,6 @@
 // Something to do with the numa-aware allocator needs these symbols
 extern "C" JNIEXPORT void numa_warn(int number, char *where, ...) { }
 extern "C" JNIEXPORT void numa_error(char *where) { }
-extern "C" JNIEXPORT int fork1() { return fork(); }
 
 
 // If we are running with libnuma version > 2, then we should
@@ -4254,7 +4252,9 @@
 
 void os::Linux::set_our_sigflags(int sig, int flags) {
   assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
-  sigflags[sig] = flags;
+  if (sig > 0 && sig < MAXSIGNUM) {
+    sigflags[sig] = flags;
+  }
 }
 
 void os::Linux::set_signal_handler(int sig, bool set_installed) {
@@ -4496,7 +4496,6 @@
   }
 
   DO_SIGNAL_CHECK(SR_signum);
-  DO_SIGNAL_CHECK(INTERRUPT_SIGNAL);
 }
 
 typedef int (*os_sigaction_t)(int, const struct sigaction *, struct sigaction *);
@@ -4542,10 +4541,6 @@
     jvmHandler = (address)user_handler();
     break;
 
-  case INTERRUPT_SIGNAL:
-    jvmHandler = CAST_FROM_FN_PTR(address, SIG_DFL);
-    break;
-
   default:
     if (sig == SR_signum) {
       jvmHandler = CAST_FROM_FN_PTR(address, (sa_sigaction_t)SR_handler);
@@ -5130,9 +5125,6 @@
   if (::fstat64(fd, &buf64) >= 0) {
     mode = buf64.st_mode;
     if (S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) {
-      // XXX: is the following call interruptible? If so, this might
-      // need to go through the INTERRUPT_IO() wrapper as for other
-      // blocking, interruptible calls in this file.
       int n;
       if (::ioctl(fd, FIONREAD, &n) >= 0) {
         *bytes = n;
@@ -5937,23 +5929,21 @@
   char core_pattern[core_pattern_len] = {0};
 
   int core_pattern_file = ::open("/proc/sys/kernel/core_pattern", O_RDONLY);
-  if (core_pattern_file != -1) {
-    ssize_t ret = ::read(core_pattern_file, core_pattern, core_pattern_len);
-    ::close(core_pattern_file);
-
-    if (ret > 0) {
-      char *last_char = core_pattern + strlen(core_pattern) - 1;
-
-      if (*last_char == '\n') {
-        *last_char = '\0';
-      }
-    }
-  }
-
-  if (strlen(core_pattern) == 0) {
+  if (core_pattern_file == -1) {
     return -1;
   }
 
+  ssize_t ret = ::read(core_pattern_file, core_pattern, core_pattern_len);
+  ::close(core_pattern_file);
+  if (ret <= 0 || ret >= core_pattern_len || core_pattern[0] == '\n') {
+    return -1;
+  }
+  if (core_pattern[ret-1] == '\n') {
+    core_pattern[ret-1] = '\0';
+  } else {
+    core_pattern[ret] = '\0';
+  }
+
   char *pid_pos = strstr(core_pattern, "%p");
   int written;
 
--- a/src/os/posix/vm/os_posix.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/os/posix/vm/os_posix.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -177,6 +177,10 @@
   return aligned_base;
 }
 
+int os::log_vsnprintf(char* buf, size_t len, const char* fmt, va_list args) {
+    return vsnprintf(buf, len, fmt, args);
+}
+
 void os::Posix::print_load_average(outputStream* st) {
   st->print("load average:");
   double loadavg[3];
--- a/src/os/solaris/vm/jvm_solaris.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/os/solaris/vm/jvm_solaris.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -73,11 +73,6 @@
       if (os::Solaris::is_sig_ignored(sig)) return (void*)1;
   }
 
-  /* Check parameterized signals. Don't allow sharing of our interrupt signal */
-  if (sig == os::Solaris::SIGinterrupt()) {
-      return (void *)-1;
-  }
-
   void* oldHandler = os::signal(sig, newHandler);
   if (oldHandler == os::user_handler()) {
       return (void *)2;
--- a/src/os/solaris/vm/jvm_solaris.h	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/os/solaris/vm/jvm_solaris.h	Fri Nov 13 10:35:26 2015 -0800
@@ -87,7 +87,6 @@
 /* Signal definitions */
 
 #define BREAK_SIGNAL     SIGQUIT           /* Thread dumping support.    */
-#define INTERRUPT_SIGNAL SIGUSR1           /* Interruptible I/O support. */
 #define ASYNC_SIGNAL     SIGUSR2           /* Watcher & async err support. */
 #define SHUTDOWN1_SIGNAL SIGHUP            /* Shutdown Hooks support.    */
 #define SHUTDOWN2_SIGNAL SIGINT
@@ -95,8 +94,7 @@
 /* alternative signals used with -XX:+UseAltSigs (or for backward
    compatibility with 1.2, -Xusealtsigs) flag. Chosen to be
    unlikely to conflict with applications embedding the vm */
-#define ALT_INTERRUPT_SIGNAL (SIGRTMIN + SIGRTMAX)/2 /* alternate intio signal */
-#define ALT_ASYNC_SIGNAL     ALT_INTERRUPT_SIGNAL+1  /* alternate async signal */
+#define ALT_ASYNC_SIGNAL     (SIGRTMIN + SIGRTMAX)/2  /* alternate async signal */
 
 /* With 1.4.1 libjsig added versioning: used in os_solaris.cpp and jsig.c */
 #define JSIG_VERSION_1_4_1   0x30140100
--- a/src/os/solaris/vm/os_solaris.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/os/solaris/vm/os_solaris.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -138,11 +138,6 @@
   #define LGRP_RSRC_MEM      1       /* memory resources */
 #endif
 
-// see thr_setprio(3T) for the basis of these numbers
-#define MinimumPriority 0
-#define NormalPriority  64
-#define MaximumPriority 127
-
 // Values for ThreadPriorityPolicy == 1
 int prio_policy1[CriticalPriority+1] = {
   -99999,  0, 16,  32,  48,  64,
@@ -1003,8 +998,9 @@
 
 // defined for >= Solaris 10. This allows builds on earlier versions
 // of Solaris to take advantage of the newly reserved Solaris JVM signals
-// With SIGJVM1, SIGJVM2, INTERRUPT_SIGNAL is SIGJVM1, ASYNC_SIGNAL is SIGJVM2
-// and -XX:+UseAltSigs does nothing since these should have no conflict
+// With SIGJVM1, SIGJVM2, ASYNC_SIGNAL is SIGJVM2 and -XX:+UseAltSigs does
+// nothing since these should have no conflict. Previously INTERRUPT_SIGNAL
+// was SIGJVM1.
 //
 #if !defined(SIGJVM1)
   #define SIGJVM1 39
@@ -1013,7 +1009,7 @@
 
 debug_only(static bool signal_sets_initialized = false);
 static sigset_t unblocked_sigs, vm_sigs, allowdebug_blocked_sigs;
-int os::Solaris::_SIGinterrupt = INTERRUPT_SIGNAL;
+
 int os::Solaris::_SIGasync = ASYNC_SIGNAL;
 
 bool os::Solaris::is_sig_ignored(int sig) {
@@ -1058,17 +1054,13 @@
   sigaddset(&unblocked_sigs, SIGFPE);
 
   if (isJVM1available) {
-    os::Solaris::set_SIGinterrupt(SIGJVM1);
     os::Solaris::set_SIGasync(SIGJVM2);
   } else if (UseAltSigs) {
-    os::Solaris::set_SIGinterrupt(ALT_INTERRUPT_SIGNAL);
     os::Solaris::set_SIGasync(ALT_ASYNC_SIGNAL);
   } else {
-    os::Solaris::set_SIGinterrupt(INTERRUPT_SIGNAL);
     os::Solaris::set_SIGasync(ASYNC_SIGNAL);
   }
 
-  sigaddset(&unblocked_sigs, os::Solaris::SIGinterrupt());
   sigaddset(&unblocked_sigs, os::Solaris::SIGasync());
 
   if (!ReduceSignalUsage) {
@@ -1939,8 +1931,6 @@
 static int Maxsignum = 0;
 static int *ourSigFlags = NULL;
 
-extern "C" void sigINTRHandler(int, siginfo_t*, void*);
-
 int os::Solaris::get_our_sigflags(int sig) {
   assert(ourSigFlags!=NULL, "signal data structure not initialized");
   assert(sig > 0 && sig < Maxsignum, "vm signal out of expected range");
@@ -2005,8 +1995,7 @@
   os::Posix::print_sa_flags(st, sa.sa_flags);
 
   // Check: is it our handler?
-  if (handler == CAST_FROM_FN_PTR(address, signalHandler) ||
-      handler == CAST_FROM_FN_PTR(address, sigINTRHandler)) {
+  if (handler == CAST_FROM_FN_PTR(address, signalHandler)) {
     // It is our signal handler
     // check for flags
     if (sa.sa_flags != os::Solaris::get_our_sigflags(sig)) {
@@ -2026,13 +2015,11 @@
   print_signal_handler(st, SIGPIPE, buf, buflen);
   print_signal_handler(st, SIGXFSZ, buf, buflen);
   print_signal_handler(st, SIGILL , buf, buflen);
-  print_signal_handler(st, INTERRUPT_SIGNAL, buf, buflen);
   print_signal_handler(st, ASYNC_SIGNAL, buf, buflen);
   print_signal_handler(st, BREAK_SIGNAL, buf, buflen);
   print_signal_handler(st, SHUTDOWN1_SIGNAL , buf, buflen);
   print_signal_handler(st, SHUTDOWN2_SIGNAL , buf, buflen);
   print_signal_handler(st, SHUTDOWN3_SIGNAL, buf, buflen);
-  print_signal_handler(st, os::Solaris::SIGinterrupt(), buf, buflen);
   print_signal_handler(st, os::Solaris::SIGasync(), buf, buflen);
 }
 
@@ -3146,7 +3133,7 @@
 static int  myCur       = 0;
 static bool priocntl_enable = false;
 
-static const int criticalPrio = 60; // FX/60 is critical thread class/priority on T4
+static const int criticalPrio = FXCriticalPriority;
 static int java_MaxPriority_to_os_priority = 0; // Saved mapping
 
 
@@ -3796,7 +3783,6 @@
 // SIGBUS, SIGSEGV, SIGILL, SIGFPE, BREAK_SIGNAL, SIGPIPE, SIGXFSZ,
 // os::Solaris::SIGasync
 // It should be consulted by handlers for any of those signals.
-// It explicitly does not recognize os::Solaris::SIGinterrupt
 //
 // The caller of this routine must pass in the three arguments supplied
 // to the function referred to in the "sa_sigaction" (not the "sa_handler")
@@ -3818,20 +3804,6 @@
   errno = orig_errno;
 }
 
-// Do not delete - if guarantee is ever removed,  a signal handler (even empty)
-// is needed to provoke threads blocked on IO to return an EINTR
-// Note: this explicitly does NOT call JVM_handle_solaris_signal and
-// does NOT participate in signal chaining due to requirement for
-// NOT setting SA_RESTART to make EINTR work.
-extern "C" void sigINTRHandler(int sig, siginfo_t* info, void* ucVoid) {
-  if (UseSignalChaining) {
-    struct sigaction *actp = os::Solaris::get_chained_signal_action(sig);
-    if (actp && actp->sa_handler) {
-      vm_exit_during_initialization("Signal chaining detected for VM interrupt signal, try -XX:+UseAltSigs");
-    }
-  }
-}
-
 // This boolean allows users to forward their own non-matching signals
 // to JVM_handle_solaris_signal, harmlessly.
 bool os::Solaris::signal_handlers_are_installed = false;
@@ -3969,13 +3941,6 @@
   // not using stack banging
   if (!UseStackBanging && sig == SIGSEGV) {
     sigAct.sa_flags = SA_SIGINFO | SA_RESTART | SA_ONSTACK;
-  } else if (sig == os::Solaris::SIGinterrupt()) {
-    // Interruptible i/o requires SA_RESTART cleared so EINTR
-    // is returned instead of restarting system calls
-    sigemptyset(&sigAct.sa_mask);
-    sigAct.sa_handler = NULL;
-    sigAct.sa_flags = SA_SIGINFO;
-    sigAct.sa_sigaction = sigINTRHandler;
   } else {
     sigAct.sa_flags = SA_SIGINFO | SA_RESTART;
   }
@@ -4027,7 +3992,6 @@
   }
 
   // See comments above for using JVM1/JVM2 and UseAltSigs
-  DO_SIGNAL_CHECK(os::Solaris::SIGinterrupt());
   DO_SIGNAL_CHECK(os::Solaris::SIGasync());
 
 }
@@ -4072,12 +4036,9 @@
     break;
 
   default:
-    int intrsig = os::Solaris::SIGinterrupt();
     int asynsig = os::Solaris::SIGasync();
 
-    if (sig == intrsig) {
-      jvmHandler = CAST_FROM_FN_PTR(address, sigINTRHandler);
-    } else if (sig == asynsig) {
+    if (sig == asynsig) {
       jvmHandler = CAST_FROM_FN_PTR(address, signalHandler);
     } else {
       return;
@@ -4148,8 +4109,7 @@
   set_signal_handler(SIGFPE, true, true);
 
 
-  if (os::Solaris::SIGinterrupt() > OLDMAXSIGNUM || os::Solaris::SIGasync() > OLDMAXSIGNUM) {
-
+  if (os::Solaris::SIGasync() > OLDMAXSIGNUM) {
     // Pre-1.4.1 Libjsig limited to signal chaining signals <= 32 so
     // can not register overridable signals which might be > 32
     if (libjsig_is_loaded && libjsigversion <= JSIG_VERSION_1_4_1) {
@@ -4159,8 +4119,6 @@
     }
   }
 
-  // Never ok to chain our SIGinterrupt
-  set_signal_handler(os::Solaris::SIGinterrupt(), true, false);
   set_signal_handler(os::Solaris::SIGasync(), true, true);
 
   if (libjsig_is_loaded && !libjsigdone) {
--- a/src/os/solaris/vm/os_solaris.hpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/os/solaris/vm/os_solaris.hpp	Fri Nov 13 10:35:26 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,14 @@
 
 // Solaris_OS defines the interface to Solaris operating systems
 
+// see thr_setprio(3T) for the basis of these numbers
+#define MinimumPriority 0
+#define NormalPriority  64
+#define MaximumPriority 127
+
+// FX/60 is critical thread class/priority on T4
+#define FXCriticalPriority 60
+
 // Information about the protection of the page at address '0' on this os.
 static bool zero_page_read_protected() { return true; }
 
@@ -114,16 +122,13 @@
   static void save_preinstalled_handler(int, struct sigaction&);
   static void check_signal_handler(int sig);
   // For overridable signals
-  static int _SIGinterrupt;                  // user-overridable INTERRUPT_SIGNAL
   static int _SIGasync;                      // user-overridable ASYNC_SIGNAL
-  static void set_SIGinterrupt(int newsig) { _SIGinterrupt = newsig; }
   static void set_SIGasync(int newsig) { _SIGasync = newsig; }
 
  public:
   // Large Page Support--ISM.
   static bool largepage_range(char* addr, size_t size);
 
-  static int SIGinterrupt() { return _SIGinterrupt; }
   static int SIGasync() { return _SIGasync; }
   static address handler_start, handler_end; // start and end pc of thr_sighndlrinfo
 
--- a/src/os/windows/vm/attachListener_windows.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/os/windows/vm/attachListener_windows.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -191,7 +191,8 @@
   // check that all paramteres to the operation
   if (strlen(cmd) > AttachOperation::name_length_max) return ATTACH_ERROR_ILLEGALARG;
   if (strlen(arg0) > AttachOperation::arg_length_max) return ATTACH_ERROR_ILLEGALARG;
-  if (strlen(arg0) > AttachOperation::arg_length_max) return ATTACH_ERROR_ILLEGALARG;
+  if (strlen(arg1) > AttachOperation::arg_length_max) return ATTACH_ERROR_ILLEGALARG;
+  if (strlen(arg2) > AttachOperation::arg_length_max) return ATTACH_ERROR_ILLEGALARG;
   if (strlen(pipename) > Win32AttachOperation::pipe_name_max) return ATTACH_ERROR_ILLEGALARG;
 
   // check for a well-formed pipename
--- a/src/os/windows/vm/os_windows.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/os/windows/vm/os_windows.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -1608,6 +1608,15 @@
   if (nl != NULL) *nl = '\0';
 }
 
+int os::log_vsnprintf(char* buf, size_t len, const char* fmt, va_list args) {
+  int ret = vsnprintf(buf, len, fmt, args);
+  // Get the correct buffer size if buf is too small
+  if (ret < 0) {
+    return _vscprintf(fmt, args);
+  }
+  return ret;
+}
+
 void os::print_os_info_brief(outputStream* st) {
   os::print_os_info(st);
 }
--- a/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -325,8 +325,6 @@
     }
   }
 
-  guarantee(sig != os::Solaris::SIGinterrupt(), "Can not chain VM interrupt signal, try -XX:+UseAltSigs");
-
   if (sig == os::Solaris::SIGasync()) {
     if (thread || vmthread) {
       OSThread::SR_handler(t, uc);
--- a/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -382,8 +382,6 @@
     }
   }
 
-  guarantee(sig != os::Solaris::SIGinterrupt(), "Can not chain VM interrupt signal, try -XX:+UseAltSigs");
-
   if (sig == os::Solaris::SIGasync()) {
     if(thread || vmthread){
       OSThread::SR_handler(t, uc);
--- a/src/share/vm/asm/codeBuffer.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/asm/codeBuffer.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -873,6 +873,7 @@
 
   // Figure new capacity for each section.
   csize_t new_capacity[SECT_LIMIT];
+  memset(new_capacity, 0, sizeof(csize_t) * SECT_LIMIT);
   csize_t new_total_cap
     = figure_expanded_capacities(which_cs, amount, new_capacity);
 
--- a/src/share/vm/classfile/classFileParser.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/classfile/classFileParser.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -92,6 +92,7 @@
 
 // Used for backward compatibility reasons:
 // - to check NameAndType_info signatures more aggressively
+// - to disallow argument and require ACC_STATIC for <clinit> methods
 #define JAVA_7_VERSION                    51
 
 // Extension method support.
@@ -1997,9 +1998,7 @@
     } else if ((flags & JVM_ACC_STATIC) == JVM_ACC_STATIC) {
       flags &= JVM_ACC_STATIC | JVM_ACC_STRICT;
     } else {
-      // As of major_version 51, a method named <clinit> without ACC_STATIC is
-      // just another method. So, do a normal method modifer check.
-      verify_legal_method_modifiers(flags, is_interface, name, CHECK_(nullHandle));
+      classfile_parse_error("Method <clinit> is not static in class file %s", CHECK_(nullHandle));
     }
   } else {
     verify_legal_method_modifiers(flags, is_interface, name, CHECK_(nullHandle));
@@ -5159,6 +5158,14 @@
     return -2;
   }
 
+  // Class initializers cannot have args for class format version >= 51.
+  if (name == vmSymbols::class_initializer_name() &&
+      signature != vmSymbols::void_method_signature() &&
+      _major_version >= JAVA_7_VERSION) {
+    throwIllegalSignature("Method", name, signature, CHECK_0);
+    return 0;
+  }
+
   unsigned int args_size = 0;
   char buf[fixed_buffer_size];
   char* p = signature->as_utf8_flexible_buffer(THREAD, buf, fixed_buffer_size);
@@ -5182,8 +5189,8 @@
     // The first non-signature thing better be a ')'
     if ((length > 0) && (*p++ == JVM_SIGNATURE_ENDFUNC)) {
       length--;
-      if (name == vmSymbols::object_initializer_name()) {
-        // All "<init>" methods must return void
+      if (name->utf8_length() > 0 && name->byte_at(0) == '<') {
+        // All internal methods must return void
         if ((length == 1) && (p[0] == JVM_SIGNATURE_VOID)) {
           return args_size;
         }
--- a/src/share/vm/classfile/defaultMethods.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/classfile/defaultMethods.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -26,6 +26,7 @@
 #include "classfile/bytecodeAssembler.hpp"
 #include "classfile/defaultMethods.hpp"
 #include "classfile/symbolTable.hpp"
+#include "logging/log.hpp"
 #include "memory/allocation.hpp"
 #include "memory/metadataFactory.hpp"
 #include "memory/resourceArea.hpp"
@@ -74,7 +75,6 @@
   }
 };
 
-#ifndef PRODUCT
 static void print_slot(outputStream* str, Symbol* name, Symbol* signature) {
   ResourceMark rm;
   str->print("%s%s", name->as_C_string(), signature->as_C_string());
@@ -87,7 +87,6 @@
   }
   print_slot(str, mo->name(), mo->signature());
 }
-#endif // ndef PRODUCT
 
 /**
  * Perform a depth-first iteration over the class hierarchy, applying
@@ -246,21 +245,22 @@
   }
 };
 
-#ifndef PRODUCT
 class PrintHierarchy : public HierarchyVisitor<PrintHierarchy> {
+ private:
+   outputStream* _st;
  public:
-
   bool visit() {
     InstanceKlass* cls = current_class();
-    streamIndentor si(tty, current_depth() * 2);
-    tty->indent().print_cr("%s", cls->name()->as_C_string());
+    streamIndentor si(_st, current_depth() * 2);
+    _st->indent().print_cr("%s", cls->name()->as_C_string());
     return true;
   }
 
   void* new_node_data(InstanceKlass* cls) { return NULL; }
   void free_node_data(void* data) { return; }
+
+  PrintHierarchy(outputStream* st = tty) : _st(st) {}
 };
-#endif // ndef PRODUCT
 
 // Used to register InstanceKlass objects and all related metadata structures
 // (Methods, ConstantPools) as "in-use" by the current thread so that they can't
@@ -434,9 +434,11 @@
     } else if (num_defaults > 1) {
       _exception_message = generate_conflicts_message(&qualified_methods,CHECK);
       _exception_name = vmSymbols::java_lang_IncompatibleClassChangeError();
-      if (TraceDefaultMethods) {
-        _exception_message->print_value_on(tty);
-        tty->cr();
+      if (log_is_enabled(Debug, defaultmethods)) {
+        ResourceMark rm;
+        outputStream* logstream = LogHandle(defaultmethods)::debug_stream();
+        _exception_message->print_value_on(logstream);
+        logstream->cr();
       }
     }
   }
@@ -450,27 +452,6 @@
     return false;
   }
 
-#ifndef PRODUCT
-  void print_sig_on(outputStream* str, Symbol* signature, int indent) const {
-    streamIndentor si(str, indent * 2);
-
-    str->indent().print_cr("Logical Method %s:", signature->as_C_string());
-
-    streamIndentor si2(str);
-    for (int i = 0; i < _members.length(); ++i) {
-      str->indent();
-      print_method(str, _members.at(i).first);
-      if (_members.at(i).second == DISQUALIFIED) {
-        str->print(" (disqualified)");
-      }
-      str->cr();
-    }
-
-    if (_selected_target != NULL) {
-      print_selected(str, 1);
-    }
-  }
-
   void print_selected(outputStream* str, int indent) const {
     assert(has_target(), "Should be called otherwise");
     streamIndentor si(str, indent * 2);
@@ -478,7 +459,7 @@
     print_method(str, _selected_target);
     Klass* method_holder = _selected_target->method_holder();
     if (!method_holder->is_interface()) {
-      tty->print(" : in superclass");
+      str->print(" : in superclass");
     }
     str->cr();
   }
@@ -489,7 +470,6 @@
     streamIndentor si(str, indent * 2);
     str->indent().print_cr("%s: %s", _exception_name->as_C_string(), _exception_message->as_C_string());
   }
-#endif // ndef PRODUCT
 };
 
 Symbol* MethodFamily::generate_no_defaults_message(TRAPS) const {
@@ -608,11 +588,9 @@
   bool is_bound() { return _binding != NULL; }
   MethodFamily* get_binding() { return _binding; }
 
-#ifndef PRODUCT
   void print_on(outputStream* str) const {
     print_slot(str, name(), signature());
   }
-#endif // ndef PRODUCT
 };
 
 static bool already_in_vtable_slots(GrowableArray<EmptyVtableSlot*>* slots, Method* m) {
@@ -681,17 +659,18 @@
     super = super->java_super();
   }
 
-#ifndef PRODUCT
-  if (TraceDefaultMethods) {
-    tty->print_cr("Slots that need filling:");
-    streamIndentor si(tty);
+  if (log_is_enabled(Debug, defaultmethods)) {
+    log_debug(defaultmethods)("Slots that need filling:");
+    ResourceMark rm;
+    outputStream* logstream = LogHandle(defaultmethods)::debug_stream();
+    streamIndentor si(logstream);
     for (int i = 0; i < slots->length(); ++i) {
-      tty->indent();
-      slots->at(i)->print_on(tty);
-      tty->cr();
+      logstream->indent();
+      slots->at(i)->print_on(logstream);
+      logstream->cr();
     }
   }
-#endif // ndef PRODUCT
+
   return slots;
 }
 
@@ -812,46 +791,32 @@
   KeepAliveVisitor loadKeepAlive(&keepAlive);
   loadKeepAlive.run(klass);
 
-#ifndef PRODUCT
-  if (TraceDefaultMethods) {
-    ResourceMark rm;  // be careful with these!
-    tty->print_cr("%s %s requires default method processing",
-        klass->is_interface() ? "Interface" : "Class",
-        klass->name()->as_klass_external_name());
-    PrintHierarchy printer;
+  if (log_is_enabled(Debug, defaultmethods)) {
+    ResourceMark rm;
+    log_debug(defaultmethods)("%s %s requires default method processing",
+                              klass->is_interface() ? "Interface" : "Class",
+                              klass->name()->as_klass_external_name());
+    PrintHierarchy printer(LogHandle(defaultmethods)::debug_stream());
     printer.run(klass);
   }
-#endif // ndef PRODUCT
 
   GrowableArray<EmptyVtableSlot*>* empty_slots =
       find_empty_vtable_slots(klass, mirandas, CHECK);
 
   for (int i = 0; i < empty_slots->length(); ++i) {
     EmptyVtableSlot* slot = empty_slots->at(i);
-#ifndef PRODUCT
-    if (TraceDefaultMethods) {
-      streamIndentor si(tty, 2);
-      tty->indent().print("Looking for default methods for slot ");
-      slot->print_on(tty);
-      tty->cr();
+    if (log_is_enabled(Debug, defaultmethods)) {
+      outputStream* logstream = LogHandle(defaultmethods)::debug_stream();
+      streamIndentor si(logstream, 2);
+      logstream->indent().print("Looking for default methods for slot ");
+      slot->print_on(logstream);
+      logstream->cr();
     }
-#endif // ndef PRODUCT
-
     generate_erased_defaults(klass, empty_slots, slot, CHECK);
- }
-#ifndef PRODUCT
-  if (TraceDefaultMethods) {
-    tty->print_cr("Creating defaults and overpasses...");
   }
-#endif // ndef PRODUCT
-
+  log_debug(defaultmethods)("Creating defaults and overpasses...");
   create_defaults_and_exceptions(empty_slots, klass, CHECK);
-
-#ifndef PRODUCT
-  if (TraceDefaultMethods) {
-    tty->print_cr("Default method processing complete");
-  }
-#endif // ndef PRODUCT
+  log_debug(defaultmethods)("Default method processing complete");
 }
 
 static int assemble_method_error(
@@ -947,18 +912,18 @@
       MethodFamily* method = slot->get_binding();
       BytecodeBuffer buffer;
 
-#ifndef PRODUCT
-      if (TraceDefaultMethods) {
-        tty->print("for slot: ");
-        slot->print_on(tty);
-        tty->cr();
+      if (log_is_enabled(Debug, defaultmethods)) {
+        ResourceMark rm;
+        outputStream* logstream = LogHandle(defaultmethods)::debug_stream();
+        logstream->print("for slot: ");
+        slot->print_on(logstream);
+        logstream->cr();
         if (method->has_target()) {
-          method->print_selected(tty, 1);
+          method->print_selected(logstream, 1);
         } else if (method->throws_exception()) {
-          method->print_exception(tty, 1);
+          method->print_exception(logstream, 1);
         }
       }
-#endif // ndef PRODUCT
 
       if (method->has_target()) {
         Method* selected = method->get_selected_target();
@@ -982,12 +947,9 @@
     }
   }
 
-#ifndef PRODUCT
-  if (TraceDefaultMethods) {
-    tty->print_cr("Created %d overpass methods", overpasses.length());
-    tty->print_cr("Created %d default  methods", defaults.length());
-  }
-#endif // ndef PRODUCT
+
+  log_debug(defaultmethods)("Created %d overpass methods", overpasses.length());
+  log_debug(defaultmethods)("Created %d default  methods", defaults.length());
 
   if (overpasses.length() > 0) {
     switchover_constant_pool(&bpool, klass, &overpasses, CHECK);
--- a/src/share/vm/classfile/verifier.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/classfile/verifier.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -2846,7 +2846,7 @@
   if (sig_stream.type() != T_VOID) {
     if (method_name == vmSymbols::object_initializer_name()) {
       // <init> method must have a void return type
-      /* Unreachable?  Class file parser verifies that <init> methods have
+      /* Unreachable?  Class file parser verifies that methods with '<' have
        * void return */
       verify_error(ErrorContext::bad_code(bci),
           "Return type must be void in <init> method");
--- a/src/share/vm/code/nmethod.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/code/nmethod.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -674,10 +674,6 @@
   return nm;
 }
 
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable:4355) //  warning C4355: 'this' : used in base member initializer list
-#endif
 // For native wrappers
 nmethod::nmethod(
   Method* method,
@@ -767,10 +763,6 @@
   }
 }
 
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
 void* nmethod::operator new(size_t size, int nmethod_size, int comp_level) throw () {
   return CodeCache::allocate(nmethod_size, CodeCache::get_code_blob_type(comp_level));
 }
@@ -2303,7 +2295,7 @@
     assert(cur != NULL, "not NULL-terminated");
     nmethod* next = cur->_oops_do_mark_link;
     cur->_oops_do_mark_link = NULL;
-    cur->verify_oop_relocations();
+    DEBUG_ONLY(cur->verify_oop_relocations());
     NOT_PRODUCT(if (TraceScavenge)  cur->print_on(tty, "oops_do, unmark"));
     cur = next;
   }
--- a/src/share/vm/code/relocInfo.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/code/relocInfo.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -438,10 +438,10 @@
 void Relocation::const_verify_data_value(address x) {
 #ifdef _LP64
   if (format() == relocInfo::narrow_oop_in_const) {
-    assert(*(narrowOop*)addr() == oopDesc::encode_heap_oop((oop) x), "must agree");
+    guarantee(*(narrowOop*)addr() == oopDesc::encode_heap_oop((oop) x), "must agree");
   } else {
 #endif
-    assert(*(address*)addr() == x, "must agree");
+    guarantee(*(address*)addr() == x, "must agree");
 #ifdef _LP64
   }
 #endif
--- a/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -1542,9 +1542,7 @@
   do_compaction_work(clear_all_soft_refs);
 
   // Has the GC time limit been exceeded?
-  size_t max_eden_size = _young_gen->max_capacity() -
-                         _young_gen->to()->capacity() -
-                         _young_gen->from()->capacity();
+  size_t max_eden_size = _young_gen->max_eden_size();
   GCCause::Cause gc_cause = gch->gc_cause();
   size_policy()->check_gc_overhead_limit(_young_gen->used(),
                                          _young_gen->eden()->used(),
@@ -7350,6 +7348,14 @@
 
   set_freeFinger(freeFinger);
   set_freeRangeInFreeLists(freeRangeInFreeLists);
+  if (CMSTestInFreeList) {
+    if (freeRangeInFreeLists) {
+      FreeChunk* fc = (FreeChunk*) freeFinger;
+      assert(fc->is_free(), "A chunk on the free list should be free.");
+      assert(fc->size() > 0, "Free range should have a size");
+      assert(_sp->verify_chunk_in_free_list(fc), "Chunk is not in free lists");
+    }
+  }
 }
 
 // Note that the sweeper runs concurrently with mutators. Thus,
@@ -7502,7 +7508,12 @@
 
 void SweepClosure::do_already_free_chunk(FreeChunk* fc) {
   const size_t size = fc->size();
-
+  // Chunks that cannot be coalesced are not in the
+  // free lists.
+  if (CMSTestInFreeList && !fc->cantCoalesce()) {
+    assert(_sp->verify_chunk_in_free_list(fc),
+           "free chunk should be in free lists");
+  }
   // a chunk that is already free, should not have been
   // marked in the bit map
   HeapWord* const addr = (HeapWord*) fc;
@@ -7609,6 +7620,9 @@
   // of the adaptive free list allocator.
   const bool fcInFreeLists = fc->is_free();
   assert((HeapWord*)fc <= _limit, "sweep invariant");
+  if (CMSTestInFreeList && fcInFreeLists) {
+    assert(_sp->verify_chunk_in_free_list(fc), "free chunk is not in free lists");
+  }
 
   if (CMSTraceSweeper) {
     gclog_or_tty->print_cr("  -- pick up another chunk at " PTR_FORMAT " (" SIZE_FORMAT ")", p2i(fc), chunkSize);
@@ -7660,7 +7674,11 @@
     if (freeRangeInFreeLists()) {
       FreeChunk* const ffc = (FreeChunk*)freeFinger();
       assert(ffc->size() == pointer_delta(fc_addr, freeFinger()),
-        "Size of free range is inconsistent with chunk size.");
+             "Size of free range is inconsistent with chunk size.");
+      if (CMSTestInFreeList) {
+        assert(_sp->verify_chunk_in_free_list(ffc),
+               "Chunk is not in free lists");
+      }
       _sp->coalDeath(ffc->size());
       _sp->removeFreeChunkFromFreeLists(ffc);
       set_freeRangeInFreeLists(false);
@@ -7729,6 +7747,12 @@
   assert(size > 0,
     "A zero sized chunk cannot be added to the free lists.");
   if (!freeRangeInFreeLists()) {
+    if (CMSTestInFreeList) {
+      FreeChunk* fc = (FreeChunk*) chunk;
+      fc->set_size(size);
+      assert(!_sp->verify_chunk_in_free_list(fc),
+             "chunk should not be in free lists yet");
+    }
     if (CMSTraceSweeper) {
       gclog_or_tty->print_cr(" -- add free block " PTR_FORMAT " (" SIZE_FORMAT ") to free lists",
                     p2i(chunk), size);
--- a/src/share/vm/gc/cms/parNewGeneration.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/cms/parNewGeneration.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -57,10 +57,6 @@
 #include "utilities/globalDefinitions.hpp"
 #include "utilities/stack.inline.hpp"
 
-#ifdef _MSC_VER
-#pragma warning( push )
-#pragma warning( disable:4355 ) // 'this' : used in base member initializer list
-#endif
 ParScanThreadState::ParScanThreadState(Space* to_space_,
                                        ParNewGeneration* young_gen_,
                                        Generation* old_gen_,
@@ -104,9 +100,6 @@
   _old_gen_closure.set_generation(old_gen_);
   _old_gen_root_closure.set_generation(old_gen_);
 }
-#ifdef _MSC_VER
-#pragma warning( pop )
-#endif
 
 void ParScanThreadState::record_survivor_plab(HeapWord* plab_start,
                                               size_t plab_word_size) {
@@ -597,10 +590,6 @@
   par_scan_state.evacuate_followers_closure().do_void();
 }
 
-#ifdef _MSC_VER
-#pragma warning( push )
-#pragma warning( disable:4355 ) // 'this' : used in base member initializer list
-#endif
 ParNewGeneration::ParNewGeneration(ReservedSpace rs, size_t initial_byte_size)
   : DefNewGeneration(rs, initial_byte_size, "PCopy"),
   _overflow_list(NULL),
@@ -643,9 +632,6 @@
                                      ParallelGCThreads, CHECK);
   }
 }
-#ifdef _MSC_VER
-#pragma warning( pop )
-#endif
 
 // ParNewGeneration::
 ParKeepAliveClosure::ParKeepAliveClosure(ParScanWeakRefClosure* cl) :
--- a/src/share/vm/gc/g1/concurrentMark.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/concurrentMark.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -454,10 +454,6 @@
   return true;
 }
 
-#ifdef _MSC_VER // the use of 'this' below gets a warning, make it go away
-#pragma warning( disable:4355 ) // 'this' : used in base member initializer list
-#endif // _MSC_VER
-
 uint ConcurrentMark::scale_parallel_threads(uint n_par_threads) {
   return MAX2((n_par_threads + 2) / 4, 1U);
 }
@@ -509,19 +505,6 @@
   _count_card_bitmaps(NULL),
   _count_marked_bytes(NULL),
   _completed_initialization(false) {
-  CMVerboseLevel verbose_level = (CMVerboseLevel) G1MarkingVerboseLevel;
-  if (verbose_level < no_verbose) {
-    verbose_level = no_verbose;
-  }
-  if (verbose_level > high_verbose) {
-    verbose_level = high_verbose;
-  }
-  _verbose_level = verbose_level;
-
-  if (verbose_low()) {
-    gclog_or_tty->print_cr("[global] init, heap start = " PTR_FORMAT ", "
-                           "heap end = " PTR_FORMAT, p2i(_heap_start), p2i(_heap_end));
-  }
 
   _markBitMap1.initialize(g1h->reserved_region(), prev_bitmap_storage);
   _markBitMap2.initialize(g1h->reserved_region(), next_bitmap_storage);
@@ -706,10 +689,6 @@
   // Reset all the marking data structures and any necessary flags
   reset_marking_state();
 
-  if (verbose_low()) {
-    gclog_or_tty->print_cr("[global] resetting");
-  }
-
   // We do reset all of them, since different phases will use
   // different number of active threads. So, it's easiest to have all
   // of them ready.
@@ -823,12 +802,8 @@
     // This closure can be called concurrently to the mutator, so we must make sure
     // that the result of the getNextMarkedWordAddress() call is compared to the
     // value passed to it as limit to detect any found bits.
-    // We can use the region's orig_end() for the limit and the comparison value
-    // as it always contains the "real" end of the region that never changes and
-    // has no side effects.
-    // Due to the latter, there can also be no problem with the compiler generating
-    // reloads of the orig_end() call.
-    HeapWord* end = r->orig_end();
+    // end never changes in G1.
+    HeapWord* end = r->end();
     return _bitmap->getNextMarkedWordAddress(r->bottom(), end) != end;
   }
 };
@@ -842,9 +817,7 @@
 class NoteStartOfMarkHRClosure: public HeapRegionClosure {
 public:
   bool doHeapRegion(HeapRegion* r) {
-    if (!r->is_continues_humongous()) {
-      r->note_start_of_marking();
-    }
+    r->note_start_of_marking();
     return false;
   }
 };
@@ -918,11 +891,6 @@
 
 void ConcurrentMark::enter_first_sync_barrier(uint worker_id) {
   bool barrier_aborted;
-
-  if (verbose_low()) {
-    gclog_or_tty->print_cr("[%u] entering first barrier", worker_id);
-  }
-
   {
     SuspendibleThreadSetLeaver sts_leave(concurrent());
     barrier_aborted = !_first_overflow_barrier_sync.enter();
@@ -931,14 +899,6 @@
   // at this point everyone should have synced up and not be doing any
   // more work
 
-  if (verbose_low()) {
-    if (barrier_aborted) {
-      gclog_or_tty->print_cr("[%u] aborted first barrier", worker_id);
-    } else {
-      gclog_or_tty->print_cr("[%u] leaving first barrier", worker_id);
-    }
-  }
-
   if (barrier_aborted) {
     // If the barrier aborted we ignore the overflow condition and
     // just abort the whole marking phase as quickly as possible.
@@ -974,26 +934,10 @@
 }
 
 void ConcurrentMark::enter_second_sync_barrier(uint worker_id) {
-  bool barrier_aborted;
-
-  if (verbose_low()) {
-    gclog_or_tty->print_cr("[%u] entering second barrier", worker_id);
-  }
-
-  {
-    SuspendibleThreadSetLeaver sts_leave(concurrent());
-    barrier_aborted = !_second_overflow_barrier_sync.enter();
-  }
+  SuspendibleThreadSetLeaver sts_leave(concurrent());
+  _second_overflow_barrier_sync.enter();
 
   // at this point everything should be re-initialized and ready to go
-
-  if (verbose_low()) {
-    if (barrier_aborted) {
-      gclog_or_tty->print_cr("[%u] aborted second barrier", worker_id);
-    } else {
-      gclog_or_tty->print_cr("[%u] leaving second barrier", worker_id);
-    }
-  }
 }
 
 #ifndef PRODUCT
@@ -1332,22 +1276,10 @@
 
   // Takes a region that's not empty (i.e., it has at least one
   // live object in it and sets its corresponding bit on the region
-  // bitmap to 1. If the region is "starts humongous" it will also set
-  // to 1 the bits on the region bitmap that correspond to its
-  // associated "continues humongous" regions.
+  // bitmap to 1.
   void set_bit_for_region(HeapRegion* hr) {
-    assert(!hr->is_continues_humongous(), "should have filtered those out");
-
     BitMap::idx_t index = (BitMap::idx_t) hr->hrm_index();
-    if (!hr->is_starts_humongous()) {
-      // Normal (non-humongous) case: just set the bit.
-      _region_bm->par_at_put(index, true);
-    } else {
-      // Starts humongous case: calculate how many regions are part of
-      // this humongous region and then set the bit range.
-      BitMap::idx_t end_index = (BitMap::idx_t) hr->last_hc_index();
-      _region_bm->par_at_put_range(index, end_index, true);
-    }
+    _region_bm->par_at_put(index, true);
   }
 
 public:
@@ -1371,18 +1303,6 @@
     _bm(bm), _region_marked_bytes(0) { }
 
   bool doHeapRegion(HeapRegion* hr) {
-
-    if (hr->is_continues_humongous()) {
-      // We will ignore these here and process them when their
-      // associated "starts humongous" region is processed (see
-      // set_bit_for_heap_region()). Note that we cannot rely on their
-      // associated "starts humongous" region to have their bit set to
-      // 1 since, due to the region chunking in the parallel region
-      // iteration, a "continues humongous" region might be visited
-      // before its associated "starts humongous".
-      return false;
-    }
-
     HeapWord* ntams = hr->next_top_at_mark_start();
     HeapWord* start = hr->bottom();
 
@@ -1420,6 +1340,11 @@
       // Add the size of this object to the number of marked bytes.
       marked_bytes += (size_t)obj_sz * HeapWordSize;
 
+      // This will happen if we are handling a humongous object that spans
+      // several heap regions.
+      if (obj_end > hr->end()) {
+        break;
+      }
       // Find the next marked object after this one.
       start = _bm->getNextMarkedWordAddress(obj_end, ntams);
     }
@@ -1471,7 +1396,6 @@
   CalcLiveObjectsClosure _calc_cl;
   BitMap* _region_bm;   // Region BM to be verified
   BitMap* _card_bm;     // Card BM to be verified
-  bool _verbose;        // verbose output?
 
   BitMap* _exp_region_bm; // Expected Region BM values
   BitMap* _exp_card_bm;   // Expected card BM values
@@ -1483,28 +1407,16 @@
                                 BitMap* region_bm,
                                 BitMap* card_bm,
                                 BitMap* exp_region_bm,
-                                BitMap* exp_card_bm,
-                                bool verbose) :
+                                BitMap* exp_card_bm) :
     _g1h(g1h), _cm(g1h->concurrent_mark()),
     _calc_cl(_cm->nextMarkBitMap(), g1h, exp_region_bm, exp_card_bm),
-    _region_bm(region_bm), _card_bm(card_bm), _verbose(verbose),
+    _region_bm(region_bm), _card_bm(card_bm),
     _exp_region_bm(exp_region_bm), _exp_card_bm(exp_card_bm),
     _failures(0) { }
 
   int failures() const { return _failures; }
 
   bool doHeapRegion(HeapRegion* hr) {
-    if (hr->is_continues_humongous()) {
-      // We will ignore these here and process them when their
-      // associated "starts humongous" region is processed (see
-      // set_bit_for_heap_region()). Note that we cannot rely on their
-      // associated "starts humongous" region to have their bit set to
-      // 1 since, due to the region chunking in the parallel region
-      // iteration, a "continues humongous" region might be visited
-      // before its associated "starts humongous".
-      return false;
-    }
-
     int failures = 0;
 
     // Call the CalcLiveObjectsClosure to walk the marking bitmap for
@@ -1513,22 +1425,29 @@
     bool res = _calc_cl.doHeapRegion(hr);
     assert(res == false, "should be continuing");
 
-    MutexLockerEx x((_verbose ? ParGCRareEvent_lock : NULL),
-                    Mutex::_no_safepoint_check_flag);
-
     // Verify the marked bytes for this region.
     size_t exp_marked_bytes = _calc_cl.region_marked_bytes();
     size_t act_marked_bytes = hr->next_marked_bytes();
 
-    // We're not OK if expected marked bytes > actual marked bytes. It means
-    // we have missed accounting some objects during the actual marking.
     if (exp_marked_bytes > act_marked_bytes) {
-      if (_verbose) {
-        gclog_or_tty->print_cr("Region %u: marked bytes mismatch: "
-                               "expected: " SIZE_FORMAT ", actual: " SIZE_FORMAT,
-                               hr->hrm_index(), exp_marked_bytes, act_marked_bytes);
+      if (hr->is_starts_humongous()) {
+        // For start_humongous regions, the size of the whole object will be
+        // in exp_marked_bytes.
+        HeapRegion* region = hr;
+        int num_regions;
+        for (num_regions = 0; region != NULL; num_regions++) {
+          region = _g1h->next_region_in_humongous(region);
+        }
+        if ((num_regions-1) * HeapRegion::GrainBytes >= exp_marked_bytes) {
+          failures += 1;
+        } else if (num_regions * HeapRegion::GrainBytes < exp_marked_bytes) {
+          failures += 1;
+        }
+      } else {
+        // We're not OK if expected marked bytes > actual marked bytes. It means
+        // we have missed accounting some objects during the actual marking.
+        failures += 1;
       }
-      failures += 1;
     }
 
     // Verify the bit, for this region, in the actual and expected
@@ -1540,12 +1459,6 @@
     bool expected = _exp_region_bm->at(index);
     bool actual = _region_bm->at(index);
     if (expected && !actual) {
-      if (_verbose) {
-        gclog_or_tty->print_cr("Region %u: region bitmap mismatch: "
-                               "expected: %s, actual: %s",
-                               hr->hrm_index(),
-                               BOOL_TO_STR(expected), BOOL_TO_STR(actual));
-      }
       failures += 1;
     }
 
@@ -1561,23 +1474,10 @@
       actual = _card_bm->at(i);
 
       if (expected && !actual) {
-        if (_verbose) {
-          gclog_or_tty->print_cr("Region %u: card bitmap mismatch at " SIZE_FORMAT ": "
-                                 "expected: %s, actual: %s",
-                                 hr->hrm_index(), i,
-                                 BOOL_TO_STR(expected), BOOL_TO_STR(actual));
-        }
         failures += 1;
       }
     }
 
-    if (failures > 0 && _verbose)  {
-      gclog_or_tty->print_cr("Region " HR_FORMAT ", ntams: " PTR_FORMAT ", "
-                             "marked_bytes: calc/actual " SIZE_FORMAT "/" SIZE_FORMAT,
-                             HR_FORMAT_PARAMS(hr), p2i(hr->next_top_at_mark_start()),
-                             _calc_cl.region_marked_bytes(), hr->next_marked_bytes());
-    }
-
     _failures += failures;
 
     // We could stop iteration over the heap when we
@@ -1599,7 +1499,6 @@
   BitMap* _expected_card_bm;
 
   int  _failures;
-  bool _verbose;
 
   HeapRegionClaimer _hrclaimer;
 
@@ -1611,13 +1510,11 @@
       _g1h(g1h), _cm(_g1h->concurrent_mark()),
       _actual_region_bm(region_bm), _actual_card_bm(card_bm),
       _expected_region_bm(expected_region_bm), _expected_card_bm(expected_card_bm),
-      _failures(0), _verbose(false),
+      _failures(0),
       _n_workers(_g1h->workers()->active_workers()), _hrclaimer(_n_workers) {
     assert(VerifyDuringGC, "don't call this otherwise");
     assert(_expected_card_bm->size() == _actual_card_bm->size(), "sanity");
     assert(_expected_region_bm->size() == _actual_region_bm->size(), "sanity");
-
-    _verbose = _cm->verbose_medium();
   }
 
   void work(uint worker_id) {
@@ -1626,8 +1523,7 @@
     VerifyLiveObjectDataHRClosure verify_cl(_g1h,
                                             _actual_region_bm, _actual_card_bm,
                                             _expected_region_bm,
-                                            _expected_card_bm,
-                                            _verbose);
+                                            _expected_card_bm);
 
     _g1h->heap_region_par_iterate(&verify_cl, worker_id, &_hrclaimer);
 
@@ -1652,18 +1548,6 @@
     CMCountDataClosureBase(g1h, region_bm, card_bm) { }
 
   bool doHeapRegion(HeapRegion* hr) {
-
-    if (hr->is_continues_humongous()) {
-      // We will ignore these here and process them when their
-      // associated "starts humongous" region is processed (see
-      // set_bit_for_heap_region()). Note that we cannot rely on their
-      // associated "starts humongous" region to have their bit set to
-      // 1 since, due to the region chunking in the parallel region
-      // iteration, a "continues humongous" region might be visited
-      // before its associated "starts humongous".
-      return false;
-    }
-
     HeapWord* ntams = hr->next_top_at_mark_start();
     HeapWord* top   = hr->top();
 
@@ -1760,7 +1644,7 @@
   const HeapRegionSetCount& humongous_regions_removed() { return _humongous_regions_removed; }
 
   bool doHeapRegion(HeapRegion *hr) {
-    if (hr->is_continues_humongous() || hr->is_archive()) {
+    if (hr->is_archive()) {
       return false;
     }
     // We use a claim value of zero here because all regions
@@ -1772,7 +1656,6 @@
       _freed_bytes += hr->used();
       hr->set_containing_set(NULL);
       if (hr->is_humongous()) {
-        assert(hr->is_starts_humongous(), "we should only see starts humongous");
         _humongous_regions_removed.increment(1u, hr->capacity());
         _g1->free_humongous_region(hr, _local_cleanup_list, true);
       } else {
@@ -2095,12 +1978,6 @@
   template <class T> void do_oop_work(T* p) {
     if (!_cm->has_overflown()) {
       oop obj = oopDesc::load_decode_heap_oop(p);
-      if (_cm->verbose_high()) {
-        gclog_or_tty->print_cr("\t[%u] we're looking at location "
-                               "*" PTR_FORMAT " = " PTR_FORMAT,
-                               _task->worker_id(), p2i(p), p2i((void*) obj));
-      }
-
       _task->deal_with_reference(obj);
       _ref_counter--;
 
@@ -2129,10 +2006,6 @@
         } while (_task->has_aborted() && !_cm->has_overflown());
         _ref_counter = _ref_counter_limit;
       }
-    } else {
-      if (_cm->verbose_high()) {
-         gclog_or_tty->print_cr("\t[%u] CM Overflow", _task->worker_id());
-      }
     }
   }
 };
@@ -2156,11 +2029,6 @@
 
   void do_void() {
     do {
-      if (_cm->verbose_high()) {
-        gclog_or_tty->print_cr("\t[%u] Drain: Calling do_marking_step - serial: %s",
-                               _task->worker_id(), BOOL_TO_STR(_is_serial));
-      }
-
       // We call CMTask::do_marking_step() to completely drain the local
       // and global marking stacks of entries pushed by the 'keep alive'
       // oop closure (an instance of G1CMKeepAliveAndDrainClosure above).
@@ -2436,7 +2304,7 @@
   // circumspect about treating the argument as an object.
   void do_entry(void* entry) const {
     _task->increment_refs_reached();
-    HeapRegion* hr = _g1h->heap_region_containing_raw(entry);
+    HeapRegion* hr = _g1h->heap_region_containing(entry);
     if (entry < hr->next_top_at_mark_start()) {
       // Until we get here, we don't know whether entry refers to a valid
       // object; it could instead have been a stale reference.
@@ -2586,32 +2454,9 @@
   while (finger < _heap_end) {
     assert(_g1h->is_in_g1_reserved(finger), "invariant");
 
-    // Note on how this code handles humongous regions. In the
-    // normal case the finger will reach the start of a "starts
-    // humongous" (SH) region. Its end will either be the end of the
-    // last "continues humongous" (CH) region in the sequence, or the
-    // standard end of the SH region (if the SH is the only region in
-    // the sequence). That way claim_region() will skip over the CH
-    // regions. However, there is a subtle race between a CM thread
-    // executing this method and a mutator thread doing a humongous
-    // object allocation. The two are not mutually exclusive as the CM
-    // thread does not need to hold the Heap_lock when it gets
-    // here. So there is a chance that claim_region() will come across
-    // a free region that's in the progress of becoming a SH or a CH
-    // region. In the former case, it will either
-    //   a) Miss the update to the region's end, in which case it will
-    //      visit every subsequent CH region, will find their bitmaps
-    //      empty, and do nothing, or
-    //   b) Will observe the update of the region's end (in which case
-    //      it will skip the subsequent CH regions).
-    // If it comes across a region that suddenly becomes CH, the
-    // scenario will be similar to b). So, the race between
-    // claim_region() and a humongous object allocation might force us
-    // to do a bit of unnecessary work (due to some unnecessary bitmap
-    // iterations) but it should not introduce and correctness issues.
-    HeapRegion* curr_region = _g1h->heap_region_containing_raw(finger);
-
-    // Above heap_region_containing_raw may return NULL as we always scan claim
+    HeapRegion* curr_region = _g1h->heap_region_containing(finger);
+
+    // Above heap_region_containing may return NULL as we always scan claim
     // until the end of the heap. In this case, just jump to the next region.
     HeapWord* end = curr_region != NULL ? curr_region->end() : finger + HeapRegion::GrainWords;
 
@@ -2622,55 +2467,21 @@
       HeapWord*   bottom        = curr_region->bottom();
       HeapWord*   limit         = curr_region->next_top_at_mark_start();
 
-      if (verbose_low()) {
-        gclog_or_tty->print_cr("[%u] curr_region = " PTR_FORMAT " "
-                               "[" PTR_FORMAT ", " PTR_FORMAT "), "
-                               "limit = " PTR_FORMAT,
-                               worker_id, p2i(curr_region), p2i(bottom), p2i(end), p2i(limit));
-      }
-
       // notice that _finger == end cannot be guaranteed here since,
       // someone else might have moved the finger even further
       assert(_finger >= end, "the finger should have moved forward");
 
-      if (verbose_low()) {
-        gclog_or_tty->print_cr("[%u] we were successful with region = "
-                               PTR_FORMAT, worker_id, p2i(curr_region));
-      }
-
       if (limit > bottom) {
-        if (verbose_low()) {
-          gclog_or_tty->print_cr("[%u] region " PTR_FORMAT " is not empty, "
-                                 "returning it ", worker_id, p2i(curr_region));
-        }
         return curr_region;
       } else {
         assert(limit == bottom,
                "the region limit should be at bottom");
-        if (verbose_low()) {
-          gclog_or_tty->print_cr("[%u] region " PTR_FORMAT " is empty, "
-                                 "returning NULL", worker_id, p2i(curr_region));
-        }
         // we return NULL and the caller should try calling
         // claim_region() again.
         return NULL;
       }
     } else {
       assert(_finger > finger, "the finger should have moved forward");
-      if (verbose_low()) {
-        if (curr_region == NULL) {
-          gclog_or_tty->print_cr("[%u] found uncommitted region, moving finger, "
-                                 "global finger = " PTR_FORMAT ", "
-                                 "our finger = " PTR_FORMAT,
-                                 worker_id, p2i(_finger), p2i(finger));
-        } else {
-          gclog_or_tty->print_cr("[%u] somebody else moved the finger, "
-                                 "global finger = " PTR_FORMAT ", "
-                                 "our finger = " PTR_FORMAT,
-                                 worker_id, p2i(_finger), p2i(finger));
-        }
-      }
-
       // read it again
       finger = _finger;
     }
@@ -2721,16 +2532,9 @@
   // Verify the global finger
   HeapWord* global_finger = finger();
   if (global_finger != NULL && global_finger < _heap_end) {
-    // The global finger always points to a heap region boundary. We
-    // use heap_region_containing_raw() to get the containing region
-    // given that the global finger could be pointing to a free region
-    // which subsequently becomes continues humongous. If that
-    // happens, heap_region_containing() will return the bottom of the
-    // corresponding starts humongous region and the check below will
-    // not hold any more.
     // Since we always iterate over all regions, we might get a NULL HeapRegion
     // here.
-    HeapRegion* global_hr = _g1h->heap_region_containing_raw(global_finger);
+    HeapRegion* global_hr = _g1h->heap_region_containing(global_finger);
     guarantee(global_hr == NULL || global_finger == global_hr->bottom(),
               "global finger: " PTR_FORMAT " region: " HR_FORMAT,
               p2i(global_finger), HR_FORMAT_PARAMS(global_hr));
@@ -2743,7 +2547,7 @@
     HeapWord* task_finger = task->finger();
     if (task_finger != NULL && task_finger < _heap_end) {
       // See above note on the global finger verification.
-      HeapRegion* task_hr = _g1h->heap_region_containing_raw(task_finger);
+      HeapRegion* task_hr = _g1h->heap_region_containing(task_finger);
       guarantee(task_hr == NULL || task_finger == task_hr->bottom() ||
                 !task_hr->in_collection_set(),
                 "task finger: " PTR_FORMAT " region: " HR_FORMAT,
@@ -2771,17 +2575,6 @@
     _cm_card_bm(cm_card_bm), _max_worker_id(max_worker_id) { }
 
   bool doHeapRegion(HeapRegion* hr) {
-    if (hr->is_continues_humongous()) {
-      // We will ignore these here and process them when their
-      // associated "starts humongous" region is processed.
-      // Note that we cannot rely on their associated
-      // "starts humongous" region to have their bit set to 1
-      // since, due to the region chunking in the parallel region
-      // iteration, a "continues humongous" region might be visited
-      // before its associated "starts humongous".
-      return false;
-    }
-
     HeapWord* start = hr->bottom();
     HeapWord* limit = hr->next_top_at_mark_start();
     HeapWord* end = hr->end();
@@ -2926,7 +2719,7 @@
 }
 
 void ConcurrentMark::print_stats() {
-  if (verbose_stats()) {
+  if (G1MarkingVerboseLevel > 0) {
     gclog_or_tty->print_cr("---------------------------------------------------------------------");
     for (size_t i = 0; i < _active_tasks; ++i) {
       _tasks[i]->print_stats();
@@ -3038,18 +2831,6 @@
   }
 }
 
-#ifndef PRODUCT
-// for debugging purposes
-void ConcurrentMark::print_finger() {
-  gclog_or_tty->print_cr("heap [" PTR_FORMAT ", " PTR_FORMAT "), global finger = " PTR_FORMAT,
-                         p2i(_heap_start), p2i(_heap_end), p2i(_finger));
-  for (uint i = 0; i < _max_worker_id; ++i) {
-    gclog_or_tty->print("   %u: " PTR_FORMAT, i, p2i(_tasks[i]->finger()));
-  }
-  gclog_or_tty->cr();
-}
-#endif
-
 // Closure for iteration over bitmaps
 class CMBitMapClosure : public BitMapClosure {
 private:
@@ -3066,8 +2847,6 @@
     HeapWord* addr = _nextMarkBitMap->offsetToHeapWord(offset);
     assert(_nextMarkBitMap->isMarked(addr), "invariant");
     assert( addr < _cm->finger(), "invariant");
-
-    statsOnly( _task->increase_objs_found_on_bitmap() );
     assert(addr >= _task->finger(), "invariant");
 
     // We move that task's local finger along.
@@ -3103,14 +2882,6 @@
 void CMTask::setup_for_region(HeapRegion* hr) {
   assert(hr != NULL,
         "claim_region() should have filtered out NULL regions");
-  assert(!hr->is_continues_humongous(),
-        "claim_region() should have filtered out continues humongous regions");
-
-  if (_cm->verbose_low()) {
-    gclog_or_tty->print_cr("[%u] setting up for region " PTR_FORMAT,
-                           _worker_id, p2i(hr));
-  }
-
   _curr_region  = hr;
   _finger       = hr->bottom();
   update_region_limit();
@@ -3122,11 +2893,6 @@
   HeapWord* limit           = hr->next_top_at_mark_start();
 
   if (limit == bottom) {
-    if (_cm->verbose_low()) {
-      gclog_or_tty->print_cr("[%u] found an empty region "
-                             "[" PTR_FORMAT ", " PTR_FORMAT ")",
-                             _worker_id, p2i(bottom), p2i(limit));
-    }
     // The region was collected underneath our feet.
     // We set the finger to bottom to ensure that the bitmap
     // iteration that will follow this will not do anything.
@@ -3155,10 +2921,6 @@
 
 void CMTask::giveup_current_region() {
   assert(_curr_region != NULL, "invariant");
-  if (_cm->verbose_low()) {
-    gclog_or_tty->print_cr("[%u] giving up region " PTR_FORMAT,
-                           _worker_id, p2i(_curr_region));
-  }
   clear_region_fields();
 }
 
@@ -3181,11 +2943,6 @@
 
 void CMTask::reset(CMBitMap* nextMarkBitMap) {
   guarantee(nextMarkBitMap != NULL, "invariant");
-
-  if (_cm->verbose_low()) {
-    gclog_or_tty->print_cr("[%u] resetting", _worker_id);
-  }
-
   _nextMarkBitMap                = nextMarkBitMap;
   clear_region_fields();
 
@@ -3193,30 +2950,6 @@
   _elapsed_time_ms               = 0.0;
   _termination_time_ms           = 0.0;
   _termination_start_time_ms     = 0.0;
-
-#if _MARKING_STATS_
-  _aborted                       = 0;
-  _aborted_overflow              = 0;
-  _aborted_cm_aborted            = 0;
-  _aborted_yield                 = 0;
-  _aborted_timed_out             = 0;
-  _aborted_satb                  = 0;
-  _aborted_termination           = 0;
-  _steal_attempts                = 0;
-  _steals                        = 0;
-  _local_pushes                  = 0;
-  _local_pops                    = 0;
-  _local_max_size                = 0;
-  _objs_scanned                  = 0;
-  _global_pushes                 = 0;
-  _global_pops                   = 0;
-  _global_max_size               = 0;
-  _global_transfers_to           = 0;
-  _global_transfers_from         = 0;
-  _regions_claimed               = 0;
-  _objs_found_on_bitmap          = 0;
-  _satb_buffers_processed        = 0;
-#endif // _MARKING_STATS_
 }
 
 bool CMTask::should_exit_termination() {
@@ -3257,42 +2990,16 @@
   // (2) If marking has been aborted for Full GC, then we also abort.
   if (_cm->has_aborted()) {
     set_has_aborted();
-    statsOnly( ++_aborted_cm_aborted );
     return;
   }
 
   double curr_time_ms = os::elapsedVTime() * 1000.0;
 
-  // (3) If marking stats are enabled, then we update the step history.
-#if _MARKING_STATS_
-  if (_words_scanned >= _words_scanned_limit) {
-    ++_clock_due_to_scanning;
-  }
-  if (_refs_reached >= _refs_reached_limit) {
-    ++_clock_due_to_marking;
-  }
-
-  double last_interval_ms = curr_time_ms - _interval_start_time_ms;
-  _interval_start_time_ms = curr_time_ms;
-  _all_clock_intervals_ms.add(last_interval_ms);
-
-  if (_cm->verbose_medium()) {
-      gclog_or_tty->print_cr("[%u] regular clock, interval = %1.2lfms, "
-                        "scanned = " SIZE_FORMAT "%s, refs reached = " SIZE_FORMAT "%s",
-                        _worker_id, last_interval_ms,
-                        _words_scanned,
-                        (_words_scanned >= _words_scanned_limit) ? " (*)" : "",
-                        _refs_reached,
-                        (_refs_reached >= _refs_reached_limit) ? " (*)" : "");
-  }
-#endif // _MARKING_STATS_
-
   // (4) We check whether we should yield. If we have to, then we abort.
   if (SuspendibleThreadSet::should_yield()) {
     // We should yield. To do this we abort the task. The caller is
     // responsible for yielding.
     set_has_aborted();
-    statsOnly( ++_aborted_yield );
     return;
   }
 
@@ -3302,7 +3009,6 @@
   if (elapsed_time_ms > _time_target_ms) {
     set_has_aborted();
     _has_timed_out = true;
-    statsOnly( ++_aborted_timed_out );
     return;
   }
 
@@ -3310,14 +3016,9 @@
   // buffers available for processing. If there are, we abort.
   SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
   if (!_draining_satb_buffers && satb_mq_set.process_completed_buffers()) {
-    if (_cm->verbose_low()) {
-      gclog_or_tty->print_cr("[%u] aborting to deal with pending SATB buffers",
-                             _worker_id);
-    }
     // we do need to process SATB buffers, we'll abort and restart
     // the marking task to do so
     set_has_aborted();
-    statsOnly( ++_aborted_satb );
     return;
   }
 }
@@ -3336,10 +3037,6 @@
   // entries to/from the global stack). It basically tries to decrease the
   // scanning limit so that the clock is called earlier.
 
-  if (_cm->verbose_medium()) {
-    gclog_or_tty->print_cr("[%u] decreasing limits", _worker_id);
-  }
-
   _words_scanned_limit = _real_words_scanned_limit -
     3 * words_scanned_period / 4;
   _refs_reached_limit  = _real_refs_reached_limit -
@@ -3361,26 +3058,8 @@
   if (n > 0) {
     // we popped at least one entry from the local queue
 
-    statsOnly( ++_global_transfers_to; _local_pops += n );
-
     if (!_cm->mark_stack_push(buffer, n)) {
-      if (_cm->verbose_low()) {
-        gclog_or_tty->print_cr("[%u] aborting due to global stack overflow",
-                               _worker_id);
-      }
       set_has_aborted();
-    } else {
-      // the transfer was successful
-
-      if (_cm->verbose_medium()) {
-        gclog_or_tty->print_cr("[%u] pushed %d entries to the global stack",
-                               _worker_id, n);
-      }
-      statsOnly( size_t tmp_size = _cm->mark_stack_size();
-                 if (tmp_size > _global_max_size) {
-                   _global_max_size = tmp_size;
-                 }
-                 _global_pushes += n );
     }
   }
 
@@ -3398,24 +3077,12 @@
          "we should not pop more than the given limit");
   if (n > 0) {
     // yes, we did actually pop at least one entry
-
-    statsOnly( ++_global_transfers_from; _global_pops += n );
-    if (_cm->verbose_medium()) {
-      gclog_or_tty->print_cr("[%u] popped %d entries from the global stack",
-                             _worker_id, n);
-    }
     for (int i = 0; i < n; ++i) {
       bool success = _task_queue->push(buffer[i]);
       // We only call this when the local queue is empty or under a
       // given target limit. So, we do not expect this push to fail.
       assert(success, "invariant");
     }
-
-    statsOnly( size_t tmp_size = (size_t)_task_queue->size();
-               if (tmp_size > _local_max_size) {
-                 _local_max_size = tmp_size;
-               }
-               _local_pushes += n );
   }
 
   // this operation was quite expensive, so decrease the limits
@@ -3436,21 +3103,9 @@
   }
 
   if (_task_queue->size() > target_size) {
-    if (_cm->verbose_high()) {
-      gclog_or_tty->print_cr("[%u] draining local queue, target size = " SIZE_FORMAT,
-                             _worker_id, target_size);
-    }
-
     oop obj;
     bool ret = _task_queue->pop_local(obj);
     while (ret) {
-      statsOnly( ++_local_pops );
-
-      if (_cm->verbose_high()) {
-        gclog_or_tty->print_cr("[%u] popped " PTR_FORMAT, _worker_id,
-                               p2i((void*) obj));
-      }
-
       assert(_g1h->is_in_g1_reserved((HeapWord*) obj), "invariant" );
       assert(!_g1h->is_on_master_free_list(
                   _g1h->heap_region_containing((HeapWord*) obj)), "invariant");
@@ -3463,11 +3118,6 @@
         ret = _task_queue->pop_local(obj);
       }
     }
-
-    if (_cm->verbose_high()) {
-      gclog_or_tty->print_cr("[%u] drained local queue, size = %u",
-                             _worker_id, _task_queue->size());
-    }
   }
 }
 
@@ -3492,20 +3142,10 @@
   }
 
   if (_cm->mark_stack_size() > target_size) {
-    if (_cm->verbose_low()) {
-      gclog_or_tty->print_cr("[%u] draining global_stack, target size " SIZE_FORMAT,
-                             _worker_id, target_size);
-    }
-
     while (!has_aborted() && _cm->mark_stack_size() > target_size) {
       get_entries_from_global_stack();
       drain_local_queue(partially);
     }
-
-    if (_cm->verbose_low()) {
-      gclog_or_tty->print_cr("[%u] drained global stack, size = " SIZE_FORMAT,
-                             _worker_id, _cm->mark_stack_size());
-    }
   }
 }
 
@@ -3529,10 +3169,6 @@
   // until we run out of buffers or we need to abort.
   while (!has_aborted() &&
          satb_mq_set.apply_closure_to_completed_buffer(&satb_cl)) {
-    if (_cm->verbose_medium()) {
-      gclog_or_tty->print_cr("[%u] processed an SATB buffer", _worker_id);
-    }
-    statsOnly( ++_satb_buffers_processed );
     regular_clock_call();
   }
 
@@ -3557,34 +3193,6 @@
                          _step_times_ms.sd());
   gclog_or_tty->print_cr("                    max = %1.2lfms, total = %1.2lfms",
                          _step_times_ms.maximum(), _step_times_ms.sum());
-
-#if _MARKING_STATS_
-  gclog_or_tty->print_cr("  Clock Intervals (cum): num = %d, avg = %1.2lfms, sd = %1.2lfms",
-                         _all_clock_intervals_ms.num(), _all_clock_intervals_ms.avg(),
-                         _all_clock_intervals_ms.sd());
-  gclog_or_tty->print_cr("                         max = %1.2lfms, total = %1.2lfms",
-                         _all_clock_intervals_ms.maximum(),
-                         _all_clock_intervals_ms.sum());
-  gclog_or_tty->print_cr("  Clock Causes (cum): scanning = " SIZE_FORMAT ", marking = " SIZE_FORMAT,
-                         _clock_due_to_scanning, _clock_due_to_marking);
-  gclog_or_tty->print_cr("  Objects: scanned = " SIZE_FORMAT ", found on the bitmap = " SIZE_FORMAT,
-                         _objs_scanned, _objs_found_on_bitmap);
-  gclog_or_tty->print_cr("  Local Queue:  pushes = " SIZE_FORMAT ", pops = " SIZE_FORMAT ", max size = " SIZE_FORMAT,
-                         _local_pushes, _local_pops, _local_max_size);
-  gclog_or_tty->print_cr("  Global Stack: pushes = " SIZE_FORMAT ", pops = " SIZE_FORMAT ", max size = " SIZE_FORMAT,
-                         _global_pushes, _global_pops, _global_max_size);
-  gclog_or_tty->print_cr("                transfers to = " SIZE_FORMAT ", transfers from = " SIZE_FORMAT,
-                         _global_transfers_to,_global_transfers_from);
-  gclog_or_tty->print_cr("  Regions: claimed = " SIZE_FORMAT, _regions_claimed);
-  gclog_or_tty->print_cr("  SATB buffers: processed = " SIZE_FORMAT, _satb_buffers_processed);
-  gclog_or_tty->print_cr("  Steals: attempts = " SIZE_FORMAT ", successes = " SIZE_FORMAT,
-                         _steal_attempts, _steals);
-  gclog_or_tty->print_cr("  Aborted: " SIZE_FORMAT ", due to", _aborted);
-  gclog_or_tty->print_cr("    overflow: " SIZE_FORMAT ", global abort: " SIZE_FORMAT ", yield: " SIZE_FORMAT,
-                         _aborted_overflow, _aborted_cm_aborted, _aborted_yield);
-  gclog_or_tty->print_cr("    time out: " SIZE_FORMAT ", SATB: " SIZE_FORMAT ", termination: " SIZE_FORMAT,
-                         _aborted_timed_out, _aborted_satb, _aborted_termination);
-#endif // _MARKING_STATS_
 }
 
 bool ConcurrentMark::try_stealing(uint worker_id, int* hash_seed, oop& obj) {
@@ -3727,7 +3335,6 @@
   _claimed = true;
 
   _start_time_ms = os::elapsedVTime() * 1000.0;
-  statsOnly( _interval_start_time_ms = _start_time_ms );
 
   // If do_stealing is true then do_marking_step will attempt to
   // steal work from the other CMTasks. It only makes sense to
@@ -3751,12 +3358,6 @@
 
   ++_calls;
 
-  if (_cm->verbose_low()) {
-    gclog_or_tty->print_cr("[%u] >>>>>>>>>> START, call = %d, "
-                           "target = %1.2lfms >>>>>>>>>>",
-                           _worker_id, _calls, _time_target_ms);
-  }
-
   // Set up the bitmap and oop closures. Anything that uses them is
   // eventually called from this method, so it is OK to allocate these
   // statically.
@@ -3801,14 +3402,6 @@
       // fresh region, _finger points to start().
       MemRegion mr = MemRegion(_finger, _region_limit);
 
-      if (_cm->verbose_low()) {
-        gclog_or_tty->print_cr("[%u] we're scanning part "
-                               "[" PTR_FORMAT ", " PTR_FORMAT ") "
-                               "of region " HR_FORMAT,
-                               _worker_id, p2i(_finger), p2i(_region_limit),
-                               HR_FORMAT_PARAMS(_curr_region));
-      }
-
       assert(!_curr_region->is_humongous() || mr.start() == _curr_region->bottom(),
              "humongous regions should go around loop once only");
 
@@ -3881,20 +3474,9 @@
       assert(_curr_region  == NULL, "invariant");
       assert(_finger       == NULL, "invariant");
       assert(_region_limit == NULL, "invariant");
-      if (_cm->verbose_low()) {
-        gclog_or_tty->print_cr("[%u] trying to claim a new region", _worker_id);
-      }
       HeapRegion* claimed_region = _cm->claim_region(_worker_id);
       if (claimed_region != NULL) {
         // Yes, we managed to claim one
-        statsOnly( ++_regions_claimed );
-
-        if (_cm->verbose_low()) {
-          gclog_or_tty->print_cr("[%u] we successfully claimed "
-                                 "region " PTR_FORMAT,
-                                 _worker_id, p2i(claimed_region));
-        }
-
         setup_for_region(claimed_region);
         assert(_curr_region == claimed_region, "invariant");
       }
@@ -3917,11 +3499,6 @@
     // tasks might be pushing objects to it concurrently.
     assert(_cm->out_of_regions(),
            "at this point we should be out of regions");
-
-    if (_cm->verbose_low()) {
-      gclog_or_tty->print_cr("[%u] all regions claimed", _worker_id);
-    }
-
     // Try to reduce the number of available SATB buffers so that
     // remark has less work to do.
     drain_satb_buffers();
@@ -3941,23 +3518,9 @@
     // tasks might be pushing objects to it concurrently.
     assert(_cm->out_of_regions() && _task_queue->size() == 0,
            "only way to reach here");
-
-    if (_cm->verbose_low()) {
-      gclog_or_tty->print_cr("[%u] starting to steal", _worker_id);
-    }
-
     while (!has_aborted()) {
       oop obj;
-      statsOnly( ++_steal_attempts );
-
       if (_cm->try_stealing(_worker_id, &_hash_seed, obj)) {
-        if (_cm->verbose_medium()) {
-          gclog_or_tty->print_cr("[%u] stolen " PTR_FORMAT " successfully",
-                                 _worker_id, p2i((void*) obj));
-        }
-
-        statsOnly( ++_steals );
-
         assert(_nextMarkBitMap->isMarked((HeapWord*) obj),
                "any stolen object should be marked");
         scan_object(obj);
@@ -3989,11 +3552,6 @@
     // Separated the asserts so that we know which one fires.
     assert(_cm->out_of_regions(), "only way to reach here");
     assert(_task_queue->size() == 0, "only way to reach here");
-
-    if (_cm->verbose_low()) {
-      gclog_or_tty->print_cr("[%u] starting termination protocol", _worker_id);
-    }
-
     _termination_start_time_ms = os::elapsedVTime() * 1000.0;
 
     // The CMTask class also extends the TerminatorTerminator class,
@@ -4028,21 +3586,10 @@
       guarantee(_task_queue->size() == 0, "only way to reach here");
       guarantee(!_cm->has_overflown(), "only way to reach here");
       guarantee(!_cm->mark_stack_overflow(), "only way to reach here");
-
-      if (_cm->verbose_low()) {
-        gclog_or_tty->print_cr("[%u] all tasks terminated", _worker_id);
-      }
     } else {
       // Apparently there's more work to do. Let's abort this task. It
       // will restart it and we can hopefully find more things to do.
-
-      if (_cm->verbose_low()) {
-        gclog_or_tty->print_cr("[%u] apparently there is more work to do",
-                               _worker_id);
-      }
-
       set_has_aborted();
-      statsOnly( ++_aborted_termination );
     }
   }
 
@@ -4057,9 +3604,6 @@
 
   if (has_aborted()) {
     // The task was aborted for some reason.
-
-    statsOnly( ++_aborted );
-
     if (_has_timed_out) {
       double diff_ms = elapsed_time_ms - _time_target_ms;
       // Keep statistics of how well we did with respect to hitting
@@ -4076,10 +3620,6 @@
       // what they are doing and re-initialize in a safe manner. We
       // will achieve this with the use of two barrier sync points.
 
-      if (_cm->verbose_low()) {
-        gclog_or_tty->print_cr("[%u] detected overflow", _worker_id);
-      }
-
       if (!is_serial) {
         // We only need to enter the sync barrier if being called
         // from a parallel context
@@ -4091,8 +3631,6 @@
         // task 0 will clear the global data structures.
       }
 
-      statsOnly( ++_aborted_overflow );
-
       // We clear the local state of this task...
       clear_region_fields();
 
@@ -4104,22 +3642,6 @@
       // marking, everything has been re-initialized and we're
       // ready to restart.
     }
-
-    if (_cm->verbose_low()) {
-      gclog_or_tty->print_cr("[%u] <<<<<<<<<< ABORTING, target = %1.2lfms, "
-                             "elapsed = %1.2lfms <<<<<<<<<<",
-                             _worker_id, _time_target_ms, elapsed_time_ms);
-      if (_cm->has_aborted()) {
-        gclog_or_tty->print_cr("[%u] ========== MARKING ABORTED ==========",
-                               _worker_id);
-      }
-    }
-  } else {
-    if (_cm->verbose_low()) {
-      gclog_or_tty->print_cr("[%u] <<<<<<<<<< FINISHED, target = %1.2lfms, "
-                             "elapsed = %1.2lfms <<<<<<<<<<",
-                             _worker_id, _time_target_ms, elapsed_time_ms);
-    }
   }
 
   _claimed = false;
@@ -4143,9 +3665,6 @@
   guarantee(task_queue != NULL, "invariant");
   guarantee(task_queues != NULL, "invariant");
 
-  statsOnly( _clock_due_to_scanning = 0;
-             _clock_due_to_marking  = 0 );
-
   _marking_step_diffs_ms.add(0.5);
 }
 
--- a/src/share/vm/gc/g1/concurrentMark.hpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/concurrentMark.hpp	Fri Nov 13 10:35:26 2015 -0800
@@ -244,30 +244,6 @@
   bool should_force() PRODUCT_RETURN_( return false; );
 };
 
-// this will enable a variety of different statistics per GC task
-#define _MARKING_STATS_       0
-// this will enable the higher verbose levels
-#define _MARKING_VERBOSE_     0
-
-#if _MARKING_STATS_
-#define statsOnly(statement)  \
-do {                          \
-  statement ;                 \
-} while (0)
-#else // _MARKING_STATS_
-#define statsOnly(statement)  \
-do {                          \
-} while (0)
-#endif // _MARKING_STATS_
-
-typedef enum {
-  no_verbose  = 0,   // verbose turned off
-  stats_verbose,     // only prints stats at the end of marking
-  low_verbose,       // low verbose, mostly per region and per major event
-  medium_verbose,    // a bit more detailed than low
-  high_verbose       // per object verbose
-} CMVerboseLevel;
-
 class YoungList;
 
 // Root Regions are regions that are not empty at the beginning of a
@@ -415,9 +391,6 @@
   // time of remark.
   volatile bool           _concurrent_marking_in_progress;
 
-  // Verbose level
-  CMVerboseLevel          _verbose_level;
-
   // All of these times are in ms
   NumberSeq _init_times;
   NumberSeq _remark_times;
@@ -746,31 +719,12 @@
 
   bool has_aborted()      { return _has_aborted; }
 
-  // This prints the global/local fingers. It is used for debugging.
-  NOT_PRODUCT(void print_finger();)
-
   void print_summary_info();
 
   void print_worker_threads_on(outputStream* st) const;
 
   void print_on_error(outputStream* st) const;
 
-  // The following indicate whether a given verbose level has been
-  // set. Notice that anything above stats is conditional to
-  // _MARKING_VERBOSE_ having been set to 1
-  bool verbose_stats() {
-    return _verbose_level >= stats_verbose;
-  }
-  bool verbose_low() {
-    return _MARKING_VERBOSE_ && _verbose_level >= low_verbose;
-  }
-  bool verbose_medium() {
-    return _MARKING_VERBOSE_ && _verbose_level >= medium_verbose;
-  }
-  bool verbose_high() {
-    return _MARKING_VERBOSE_ && _verbose_level >= high_verbose;
-  }
-
   // Liveness counting
 
   // Utility routine to set an exclusive range of cards on the given
@@ -818,16 +772,13 @@
                            size_t* marked_bytes_array,
                            BitMap* task_card_bm);
 
-  // Counts the given memory region in the task/worker counting
-  // data structures for the given worker id.
-  inline void count_region(MemRegion mr, HeapRegion* hr, uint worker_id);
-
   // Counts the given object in the given task/worker counting
   // data structures.
   inline void count_object(oop obj,
                            HeapRegion* hr,
                            size_t* marked_bytes_array,
-                           BitMap* task_card_bm);
+                           BitMap* task_card_bm,
+                           size_t word_size);
 
   // Attempts to mark the given object and, if successful, counts
   // the object in the given task/worker counting structures.
@@ -969,43 +920,6 @@
   size_t*                     _marked_bytes_array;
   BitMap*                     _card_bm;
 
-  // LOTS of statistics related with this task
-#if _MARKING_STATS_
-  NumberSeq                   _all_clock_intervals_ms;
-  double                      _interval_start_time_ms;
-
-  size_t                      _aborted;
-  size_t                      _aborted_overflow;
-  size_t                      _aborted_cm_aborted;
-  size_t                      _aborted_yield;
-  size_t                      _aborted_timed_out;
-  size_t                      _aborted_satb;
-  size_t                      _aborted_termination;
-
-  size_t                      _steal_attempts;
-  size_t                      _steals;
-
-  size_t                      _clock_due_to_marking;
-  size_t                      _clock_due_to_scanning;
-
-  size_t                      _local_pushes;
-  size_t                      _local_pops;
-  size_t                      _local_max_size;
-  size_t                      _objs_scanned;
-
-  size_t                      _global_pushes;
-  size_t                      _global_pops;
-  size_t                      _global_max_size;
-
-  size_t                      _global_transfers_to;
-  size_t                      _global_transfers_from;
-
-  size_t                      _regions_claimed;
-  size_t                      _objs_found_on_bitmap;
-
-  size_t                      _satb_buffers_processed;
-#endif // _MARKING_STATS_
-
   // it updates the local fields after this task has claimed
   // a new region to scan
   void setup_for_region(HeapRegion* hr);
@@ -1139,10 +1053,6 @@
 
   // it prints statistics associated with this task
   void print_stats();
-
-#if _MARKING_STATS_
-  void increase_objs_found_on_bitmap() { ++_objs_found_on_bitmap; }
-#endif // _MARKING_STATS_
 };
 
 // Class that's used to to print out per-region liveness
--- a/src/share/vm/gc/g1/concurrentMark.inline.hpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/concurrentMark.inline.hpp	Fri Nov 13 10:35:26 2015 -0800
@@ -89,9 +89,7 @@
   size_t region_size_bytes = mr.byte_size();
   uint index = hr->hrm_index();
 
-  assert(!hr->is_continues_humongous(), "should not be HC region");
   assert(hr == g1h->heap_region_containing(start), "sanity");
-  assert(hr == g1h->heap_region_containing(mr.last()), "sanity");
   assert(marked_bytes_array != NULL, "pre-condition");
   assert(task_card_bm != NULL, "pre-condition");
 
@@ -116,23 +114,23 @@
   set_card_bitmap_range(task_card_bm, start_idx, end_idx, false /* is_par */);
 }
 
-// Counts the given memory region in the task/worker counting
-// data structures for the given worker id.
-inline void ConcurrentMark::count_region(MemRegion mr,
-                                         HeapRegion* hr,
-                                         uint worker_id) {
-  size_t* marked_bytes_array = count_marked_bytes_array_for(worker_id);
-  BitMap* task_card_bm = count_card_bitmap_for(worker_id);
-  count_region(mr, hr, marked_bytes_array, task_card_bm);
-}
-
 // Counts the given object in the given task/worker counting data structures.
 inline void ConcurrentMark::count_object(oop obj,
                                          HeapRegion* hr,
                                          size_t* marked_bytes_array,
-                                         BitMap* task_card_bm) {
-  MemRegion mr((HeapWord*)obj, obj->size());
-  count_region(mr, hr, marked_bytes_array, task_card_bm);
+                                         BitMap* task_card_bm,
+                                         size_t word_size) {
+  assert(!hr->is_continues_humongous(), "Cannot enter count_object with continues humongous");
+  if (!hr->is_starts_humongous()) {
+    MemRegion mr((HeapWord*)obj, word_size);
+    count_region(mr, hr, marked_bytes_array, task_card_bm);
+  } else {
+    do {
+      MemRegion mr(hr->bottom(), hr->top());
+      count_region(mr, hr, marked_bytes_array, task_card_bm);
+      hr = _g1h->next_region_in_humongous(hr);
+    } while (hr != NULL);
+  }
 }
 
 // Attempts to mark the given object and, if successful, counts
@@ -141,10 +139,9 @@
                                                HeapRegion* hr,
                                                size_t* marked_bytes_array,
                                                BitMap* task_card_bm) {
-  HeapWord* addr = (HeapWord*)obj;
-  if (_nextMarkBitMap->parMark(addr)) {
+  if (_nextMarkBitMap->parMark((HeapWord*)obj)) {
     // Update the task specific count data for the object.
-    count_object(obj, hr, marked_bytes_array, task_card_bm);
+    count_object(obj, hr, marked_bytes_array, task_card_bm, obj->size());
     return true;
   }
   return false;
@@ -157,10 +154,10 @@
                                                size_t word_size,
                                                HeapRegion* hr,
                                                uint worker_id) {
-  HeapWord* addr = (HeapWord*)obj;
-  if (_nextMarkBitMap->parMark(addr)) {
-    MemRegion mr(addr, word_size);
-    count_region(mr, hr, worker_id);
+  if (_nextMarkBitMap->parMark((HeapWord*)obj)) {
+    size_t* marked_bytes_array = count_marked_bytes_array_for(worker_id);
+    BitMap* task_card_bm = count_card_bitmap_for(worker_id);
+    count_object(obj, hr, marked_bytes_array, task_card_bm, word_size);
     return true;
   }
   return false;
@@ -242,19 +239,9 @@
   assert(!_g1h->is_obj_ill(obj), "invariant");
   assert(_nextMarkBitMap->isMarked(objAddr), "invariant");
 
-  if (_cm->verbose_high()) {
-    gclog_or_tty->print_cr("[%u] pushing " PTR_FORMAT, _worker_id, p2i((void*) obj));
-  }
-
   if (!_task_queue->push(obj)) {
     // The local task queue looks full. We need to push some entries
     // to the global stack.
-
-    if (_cm->verbose_medium()) {
-      gclog_or_tty->print_cr("[%u] task queue overflow, "
-                             "moving entries to the global stack",
-                             _worker_id);
-    }
     move_entries_to_global_stack();
 
     // this should succeed since, even if we overflow the global
@@ -263,12 +250,6 @@
     bool success = _task_queue->push(obj);
     assert(success, "invariant");
   }
-
-  statsOnly( size_t tmp_size = (size_t)_task_queue->size();
-             if (tmp_size > _local_max_size) {
-               _local_max_size = tmp_size;
-             }
-             ++_local_pushes );
 }
 
 inline bool CMTask::is_below_finger(oop obj, HeapWord* global_finger) const {
@@ -306,18 +287,12 @@
   assert(scan || obj->is_typeArray(), "Skipping scan of grey non-typeArray");
   assert(_nextMarkBitMap->isMarked((HeapWord*) obj), "invariant");
 
-  if (_cm->verbose_high()) {
-    gclog_or_tty->print_cr("[%u] processing grey object " PTR_FORMAT,
-                           _worker_id, p2i((void*) obj));
-  }
-
   size_t obj_size = obj->size();
   _words_scanned += obj_size;
 
   if (scan) {
     obj->oop_iterate(_cm_oop_closure);
   }
-  statsOnly( ++_objs_scanned );
   check_limits();
 }
 
@@ -325,12 +300,6 @@
 
 inline void CMTask::make_reference_grey(oop obj, HeapRegion* hr) {
   if (_cm->par_mark_and_count(obj, hr, _marked_bytes_array, _card_bm)) {
-
-    if (_cm->verbose_high()) {
-      gclog_or_tty->print_cr("[%u] marked object " PTR_FORMAT,
-                             _worker_id, p2i(obj));
-    }
-
     // No OrderAccess:store_load() is needed. It is implicit in the
     // CAS done in CMBitMap::parMark() call in the routine above.
     HeapWord* global_finger = _cm->finger();
@@ -362,13 +331,6 @@
         // references, and the metadata is built-in.
         process_grey_object<false>(obj);
       } else {
-        if (_cm->verbose_high()) {
-          gclog_or_tty->print_cr("[%u] below a finger (local: " PTR_FORMAT
-                                 ", global: " PTR_FORMAT ") pushing "
-                                 PTR_FORMAT " on mark stack",
-                                 _worker_id, p2i(_finger),
-                                 p2i(global_finger), p2i(obj));
-        }
         push(obj);
       }
     }
@@ -376,11 +338,6 @@
 }
 
 inline void CMTask::deal_with_reference(oop obj) {
-  if (_cm->verbose_high()) {
-    gclog_or_tty->print_cr("[%u] we're dealing with reference = " PTR_FORMAT,
-                           _worker_id, p2i((void*) obj));
-  }
-
   increment_refs_reached();
 
   HeapWord* objAddr = (HeapWord*) obj;
@@ -391,7 +348,7 @@
       // Only get the containing region if the object is not marked on the
       // bitmap (otherwise, it's a waste of time since we won't do
       // anything with it).
-      HeapRegion* hr = _g1h->heap_region_containing_raw(obj);
+      HeapRegion* hr = _g1h->heap_region_containing(obj);
       if (!hr->obj_allocated_since_next_marking(obj)) {
         make_reference_grey(obj, hr);
       }
@@ -411,7 +368,7 @@
   assert(obj != NULL, "pre-condition");
   HeapWord* addr = (HeapWord*) obj;
   if (hr == NULL) {
-    hr = _g1h->heap_region_containing_raw(addr);
+    hr = _g1h->heap_region_containing(addr);
   } else {
     assert(hr->is_in(addr), "pre-condition");
   }
@@ -420,16 +377,6 @@
   // header it's impossible to get back a HC region.
   assert(!hr->is_continues_humongous(), "sanity");
 
-  // We cannot assert that word_size == obj->size() given that obj
-  // might not be in a consistent state (another thread might be in
-  // the process of copying it). So the best thing we can do is to
-  // assert that word_size is under an upper bound which is its
-  // containing region's capacity.
-  assert(word_size * HeapWordSize <= hr->capacity(),
-         "size: " SIZE_FORMAT " capacity: " SIZE_FORMAT " " HR_FORMAT,
-         word_size * HeapWordSize, hr->capacity(),
-         HR_FORMAT_PARAMS(hr));
-
   if (addr < hr->next_top_at_mark_start()) {
     if (!_nextMarkBitMap->isMarked(addr)) {
       par_mark_and_count(obj, word_size, hr, worker_id);
--- a/src/share/vm/gc/g1/dirtyCardQueue.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/dirtyCardQueue.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -32,6 +32,18 @@
 #include "runtime/safepoint.hpp"
 #include "runtime/thread.inline.hpp"
 
+DirtyCardQueue::DirtyCardQueue(DirtyCardQueueSet* qset, bool permanent) :
+  // Dirty card queues are always active, so we create them with their
+  // active field set to true.
+  PtrQueue(qset, permanent, true /* active */)
+{ }
+
+DirtyCardQueue::~DirtyCardQueue() {
+  if (!is_permanent()) {
+    flush();
+  }
+}
+
 bool DirtyCardQueue::apply_closure(CardTableEntryClosure* cl,
                                    bool consume,
                                    uint worker_i) {
@@ -40,7 +52,9 @@
     res = apply_closure_to_buffer(cl, _buf, _index, _sz,
                                   consume,
                                   worker_i);
-    if (res && consume) _index = _sz;
+    if (res && consume) {
+      _index = _sz;
+    }
   }
   return res;
 }
@@ -51,27 +65,27 @@
                                              bool consume,
                                              uint worker_i) {
   if (cl == NULL) return true;
-  for (size_t i = index; i < sz; i += oopSize) {
-    int ind = byte_index_to_index((int)i);
-    jbyte* card_ptr = (jbyte*)buf[ind];
+  size_t limit = byte_index_to_index(sz);
+  for (size_t i = byte_index_to_index(index); i < limit; ++i) {
+    jbyte* card_ptr = static_cast<jbyte*>(buf[i]);
     if (card_ptr != NULL) {
       // Set the entry to null, so we don't do it again (via the test
       // above) if we reconsider this buffer.
-      if (consume) buf[ind] = NULL;
-      if (!cl->do_card_ptr(card_ptr, worker_i)) return false;
+      if (consume) {
+        buf[i] = NULL;
+      }
+      if (!cl->do_card_ptr(card_ptr, worker_i)) {
+        return false;
+      }
     }
   }
   return true;
 }
 
-#ifdef _MSC_VER // the use of 'this' below gets a warning, make it go away
-#pragma warning( disable:4355 ) // 'this' : used in base member initializer list
-#endif // _MSC_VER
-
 DirtyCardQueueSet::DirtyCardQueueSet(bool notify_when_complete) :
   PtrQueueSet(notify_when_complete),
   _mut_process_closure(NULL),
-  _shared_dirty_card_queue(this, true /*perm*/),
+  _shared_dirty_card_queue(this, true /* permanent */),
   _free_ids(NULL),
   _processed_buffers_mut(0), _processed_buffers_rs_thread(0)
 {
@@ -83,13 +97,19 @@
   return (uint)os::processor_count();
 }
 
-void DirtyCardQueueSet::initialize(CardTableEntryClosure* cl, Monitor* cbl_mon, Mutex* fl_lock,
+void DirtyCardQueueSet::initialize(CardTableEntryClosure* cl,
+                                   Monitor* cbl_mon,
+                                   Mutex* fl_lock,
                                    int process_completed_threshold,
                                    int max_completed_queue,
-                                   Mutex* lock, PtrQueueSet* fl_owner) {
+                                   Mutex* lock,
+                                   DirtyCardQueueSet* fl_owner) {
   _mut_process_closure = cl;
-  PtrQueueSet::initialize(cbl_mon, fl_lock, process_completed_threshold,
-                          max_completed_queue, fl_owner);
+  PtrQueueSet::initialize(cbl_mon,
+                          fl_lock,
+                          process_completed_threshold,
+                          max_completed_queue,
+                          fl_owner);
   set_buffer_size(G1UpdateBufferSize);
   _shared_dirty_card_queue.set_lock(lock);
   _free_ids = new FreeIdSet((int) num_par_ids(), _cbl_mon);
@@ -103,7 +123,7 @@
                                                     bool consume,
                                                     uint worker_i) {
   assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
-  for(JavaThread* t = Threads::first(); t; t = t->next()) {
+  for (JavaThread* t = Threads::first(); t; t = t->next()) {
     bool b = t->dirty_card_queue().apply_closure(cl, consume);
     guarantee(b, "Should not be interrupted.");
   }
@@ -160,8 +180,7 @@
 }
 
 
-BufferNode*
-DirtyCardQueueSet::get_completed_buffer(int stop_at) {
+BufferNode* DirtyCardQueueSet::get_completed_buffer(int stop_at) {
   BufferNode* nd = NULL;
   MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
 
@@ -178,14 +197,13 @@
     _n_completed_buffers--;
     assert(_n_completed_buffers >= 0, "Invariant");
   }
-  debug_only(assert_completed_buffer_list_len_correct_locked());
+  DEBUG_ONLY(assert_completed_buffer_list_len_correct_locked());
   return nd;
 }
 
-bool DirtyCardQueueSet::
-apply_closure_to_completed_buffer_helper(CardTableEntryClosure* cl,
-                                         uint worker_i,
-                                         BufferNode* nd) {
+bool DirtyCardQueueSet::apply_closure_to_completed_buffer_helper(CardTableEntryClosure* cl,
+                                                                 uint worker_i,
+                                                                 BufferNode* nd) {
   if (nd != NULL) {
     void **buf = BufferNode::make_buffer_from_node(nd);
     size_t index = nd->index();
@@ -259,7 +277,7 @@
     }
     _n_completed_buffers = 0;
     _completed_buffers_tail = NULL;
-    debug_only(assert_completed_buffer_list_len_correct_locked());
+    DEBUG_ONLY(assert_completed_buffer_list_len_correct_locked());
   }
   while (buffers_to_delete != NULL) {
     BufferNode* nd = buffers_to_delete;
@@ -291,10 +309,11 @@
   for (JavaThread* t = Threads::first(); t; t = t->next()) {
     DirtyCardQueue& dcq = t->dirty_card_queue();
     if (dcq.size() != 0) {
-      void **buf = t->dirty_card_queue().get_buf();
+      void** buf = dcq.get_buf();
       // We must NULL out the unused entries, then enqueue.
-      for (size_t i = 0; i < t->dirty_card_queue().get_index(); i += oopSize) {
-        buf[PtrQueue::byte_index_to_index((int)i)] = NULL;
+      size_t limit = dcq.byte_index_to_index(dcq.get_index());
+      for (size_t i = 0; i < limit; ++i) {
+        buf[i] = NULL;
       }
       enqueue_complete_buffer(dcq.get_buf(), dcq.get_index());
       dcq.reinitialize();
--- a/src/share/vm/gc/g1/dirtyCardQueue.hpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/dirtyCardQueue.hpp	Fri Nov 13 10:35:26 2015 -0800
@@ -29,6 +29,7 @@
 #include "memory/allocation.hpp"
 
 class FreeIdSet;
+class DirtyCardQueueSet;
 
 // A closure class for processing card table entries.  Note that we don't
 // require these closure objects to be stack-allocated.
@@ -42,14 +43,11 @@
 // A ptrQueue whose elements are "oops", pointers to object heads.
 class DirtyCardQueue: public PtrQueue {
 public:
-  DirtyCardQueue(PtrQueueSet* qset_, bool perm = false) :
-    // Dirty card queues are always active, so we create them with their
-    // active field set to true.
-    PtrQueue(qset_, perm, true /* active */) { }
+  DirtyCardQueue(DirtyCardQueueSet* qset, bool permanent = false);
 
   // Flush before destroying; queue may be used to capture pending work while
   // doing something else, with auto-flush on completion.
-  ~DirtyCardQueue() { if (!is_permanent()) flush(); }
+  ~DirtyCardQueue();
 
   // Process queue entries and release resources.
   void flush() { flush_impl(); }
@@ -72,7 +70,6 @@
                                       bool consume = true,
                                       uint worker_i = 0);
   void **get_buf() { return _buf;}
-  void set_buf(void **buf) {_buf = buf;}
   size_t get_index() { return _index;}
   void reinitialize() { _buf = 0; _sz = 0; _index = 0;}
 };
@@ -101,10 +98,13 @@
 public:
   DirtyCardQueueSet(bool notify_when_complete = true);
 
-  void initialize(CardTableEntryClosure* cl, Monitor* cbl_mon, Mutex* fl_lock,
+  void initialize(CardTableEntryClosure* cl,
+                  Monitor* cbl_mon,
+                  Mutex* fl_lock,
                   int process_completed_threshold,
                   int max_completed_queue,
-                  Mutex* lock, PtrQueueSet* fl_owner = NULL);
+                  Mutex* lock,
+                  DirtyCardQueueSet* fl_owner = NULL);
 
   // The number of parallel ids that can be claimed to allow collector or
   // mutator threads to do card-processing work.
--- a/src/share/vm/gc/g1/g1Allocator.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/g1Allocator.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -110,9 +110,6 @@
   if (_retained_old_gc_alloc_region != NULL) {
     _retained_old_gc_alloc_region->record_retained_region();
   }
-
-  _g1h->alloc_buffer_stats(InCSetState::Young)->adjust_desired_plab_sz();
-  _g1h->alloc_buffer_stats(InCSetState::Old)->adjust_desired_plab_sz();
 }
 
 void G1DefaultAllocator::abandon_gc_alloc_regions() {
--- a/src/share/vm/gc/g1/g1BlockOffsetTable.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/g1BlockOffsetTable.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -499,18 +499,14 @@
   return _next_offset_threshold;
 }
 
-void
-G1BlockOffsetArrayContigSpace::set_for_starts_humongous(HeapWord* new_top) {
-  assert(new_top <= _end, "_end should have already been updated");
-
+void G1BlockOffsetArrayContigSpace::set_for_starts_humongous(HeapWord* obj_top) {
   // The first BOT entry should have offset 0.
   reset_bot();
-  alloc_block(_bottom, new_top);
+  alloc_block(_bottom, obj_top);
  }
 
 #ifndef PRODUCT
-void
-G1BlockOffsetArrayContigSpace::print_on(outputStream* out) {
+void G1BlockOffsetArrayContigSpace::print_on(outputStream* out) {
   G1BlockOffsetArray::print_on(out);
   out->print_cr("  next offset threshold: " PTR_FORMAT, p2i(_next_offset_threshold));
   out->print_cr("  next offset index:     " SIZE_FORMAT, _next_offset_index);
--- a/src/share/vm/gc/g1/g1BlockOffsetTable.hpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/g1BlockOffsetTable.hpp	Fri Nov 13 10:35:26 2015 -0800
@@ -361,17 +361,18 @@
   // implementation, that's true because NULL is represented as 0, and thus
   // never exceeds the "_next_offset_threshold".
   void alloc_block(HeapWord* blk_start, HeapWord* blk_end) {
-    if (blk_end > _next_offset_threshold)
+    if (blk_end > _next_offset_threshold) {
       alloc_block_work1(blk_start, blk_end);
+    }
   }
   void alloc_block(HeapWord* blk, size_t size) {
-     alloc_block(blk, blk+size);
+    alloc_block(blk, blk+size);
   }
 
   HeapWord* block_start_unsafe(const void* addr);
   HeapWord* block_start_unsafe_const(const void* addr) const;
 
-  void set_for_starts_humongous(HeapWord* new_top);
+  void set_for_starts_humongous(HeapWord* obj_top);
 
   virtual void print_on(outputStream* out) PRODUCT_RETURN;
 };
--- a/src/share/vm/gc/g1/g1BlockOffsetTable.inline.hpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/g1BlockOffsetTable.inline.hpp	Fri Nov 13 10:35:26 2015 -0800
@@ -123,7 +123,6 @@
     // to go back by.
     size_t n_cards_back = BlockOffsetArray::entry_to_cards_back(offset);
     q -= (N_words * n_cards_back);
-    assert(q >= gsp()->bottom(), "Went below bottom!");
     index -= n_cards_back;
     offset = _array->offset_array(index);
   }
--- a/src/share/vm/gc/g1/g1CodeBlobClosure.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/g1CodeBlobClosure.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -36,7 +36,7 @@
   T oop_or_narrowoop = oopDesc::load_heap_oop(p);
   if (!oopDesc::is_null(oop_or_narrowoop)) {
     oop o = oopDesc::decode_heap_oop_not_null(oop_or_narrowoop);
-    HeapRegion* hr = _g1h->heap_region_containing_raw(o);
+    HeapRegion* hr = _g1h->heap_region_containing(o);
     assert(!_g1h->obj_in_cs(o) || hr->rem_set()->strong_code_roots_list_contains(_nm), "if o still in collection set then evacuation failed and nm must already be in the remset");
     hr->add_strong_code_root(_nm);
   }
--- a/src/share/vm/gc/g1/g1CollectedHeap.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/g1CollectedHeap.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -320,12 +320,8 @@
   // The header of the new object will be placed at the bottom of
   // the first region.
   HeapWord* new_obj = first_hr->bottom();
-  // This will be the new end of the first region in the series that
-  // should also match the end of the last region in the series.
-  HeapWord* new_end = new_obj + word_size_sum;
-  // This will be the new top of the first region that will reflect
-  // this allocation.
-  HeapWord* new_top = new_obj + word_size;
+  // This will be the new top of the new object.
+  HeapWord* obj_top = new_obj + word_size;
 
   // First, we need to zero the header of the space that we will be
   // allocating. When we update top further down, some refinement
@@ -346,7 +342,7 @@
   // will also update the BOT covering all the regions to reflect
   // that there is a single object that starts at the bottom of the
   // first region.
-  first_hr->set_starts_humongous(new_top, new_end);
+  first_hr->set_starts_humongous(obj_top);
   first_hr->set_allocation_context(context);
   // Then, if there are any, we will set up the "continues
   // humongous" regions.
@@ -356,9 +352,6 @@
     hr->set_continues_humongous(first_hr);
     hr->set_allocation_context(context);
   }
-  // If we have "continues humongous" regions (hr != NULL), then the
-  // end of the last one should match new_end.
-  assert(hr == NULL || hr->end() == new_end, "sanity");
 
   // Up to this point no concurrent thread would have been able to
   // do any scanning on any region in this series. All the top
@@ -371,58 +364,39 @@
 
   // Now that the BOT and the object header have been initialized,
   // we can update top of the "starts humongous" region.
-  assert(first_hr->bottom() < new_top && new_top <= first_hr->end(),
-         "new_top should be in this region");
-  first_hr->set_top(new_top);
+  first_hr->set_top(MIN2(first_hr->end(), obj_top));
   if (_hr_printer.is_active()) {
-    HeapWord* bottom = first_hr->bottom();
-    HeapWord* end = first_hr->orig_end();
-    if ((first + 1) == last) {
-      // the series has a single humongous region
-      _hr_printer.alloc(G1HRPrinter::SingleHumongous, first_hr, new_top);
-    } else {
-      // the series has more than one humongous regions
-      _hr_printer.alloc(G1HRPrinter::StartsHumongous, first_hr, end);
-    }
+    _hr_printer.alloc(G1HRPrinter::StartsHumongous, first_hr, first_hr->top());
   }
 
   // Now, we will update the top fields of the "continues humongous"
-  // regions. The reason we need to do this is that, otherwise,
-  // these regions would look empty and this will confuse parts of
-  // G1. For example, the code that looks for a consecutive number
-  // of empty regions will consider them empty and try to
-  // re-allocate them. We can extend is_empty() to also include
-  // !is_continues_humongous(), but it is easier to just update the top
-  // fields here. The way we set top for all regions (i.e., top ==
-  // end for all regions but the last one, top == new_top for the
-  // last one) is actually used when we will free up the humongous
-  // region in free_humongous_region().
+  // regions.
   hr = NULL;
   for (uint i = first + 1; i < last; ++i) {
     hr = region_at(i);
     if ((i + 1) == last) {
       // last continues humongous region
-      assert(hr->bottom() < new_top && new_top <= hr->end(),
+      assert(hr->bottom() < obj_top && obj_top <= hr->end(),
              "new_top should fall on this region");
-      hr->set_top(new_top);
-      _hr_printer.alloc(G1HRPrinter::ContinuesHumongous, hr, new_top);
+      hr->set_top(obj_top);
+      _hr_printer.alloc(G1HRPrinter::ContinuesHumongous, hr, obj_top);
     } else {
       // not last one
-      assert(new_top > hr->end(), "new_top should be above this region");
+      assert(obj_top > hr->end(), "obj_top should be above this region");
       hr->set_top(hr->end());
       _hr_printer.alloc(G1HRPrinter::ContinuesHumongous, hr, hr->end());
     }
   }
-  // If we have continues humongous regions (hr != NULL), then the
-  // end of the last one should match new_end and its top should
-  // match new_top.
-  assert(hr == NULL ||
-         (hr->end() == new_end && hr->top() == new_top), "sanity");
+  // If we have continues humongous regions (hr != NULL), its top should
+  // match obj_top.
+  assert(hr == NULL || (hr->top() == obj_top), "sanity");
   check_bitmaps("Humongous Region Allocation", first_hr);
 
-  assert(first_hr->used() == word_size * HeapWordSize, "invariant");
-  increase_used(first_hr->used());
-  _humongous_set.add(first_hr);
+  increase_used(word_size * HeapWordSize);
+
+  for (uint i = first; i < last; ++i) {
+    _humongous_set.add(region_at(i));
+  }
 
   return new_obj;
 }
@@ -1139,15 +1113,15 @@
   bool doHeapRegion(HeapRegion* r) {
     HeapRegionRemSet* hrrs = r->rem_set();
 
+    _g1h->reset_gc_time_stamps(r);
+
     if (r->is_continues_humongous()) {
       // 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;
+    } else {
+      hrrs->clear();
     }
-
-    _g1h->reset_gc_time_stamps(r);
-    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
@@ -1205,12 +1179,7 @@
     if (hr->is_free()) {
       // We only generate output for non-empty regions.
     } else if (hr->is_starts_humongous()) {
-      if (hr->region_num() == 1) {
-        // single humongous region
-        _hr_printer->post_compaction(hr, G1HRPrinter::SingleHumongous);
-      } else {
-        _hr_printer->post_compaction(hr, G1HRPrinter::StartsHumongous);
-      }
+      _hr_printer->post_compaction(hr, G1HRPrinter::StartsHumongous);
     } else if (hr->is_continues_humongous()) {
       _hr_printer->post_compaction(hr, G1HRPrinter::ContinuesHumongous);
     } else if (hr->is_archive()) {
@@ -1807,16 +1776,10 @@
 
 // Public methods.
 
-#ifdef _MSC_VER // the use of 'this' below gets a warning, make it go away
-#pragma warning( disable:4355 ) // 'this' : used in base member initializer list
-#endif // _MSC_VER
-
-
 G1CollectedHeap::G1CollectedHeap(G1CollectorPolicy* policy_) :
   CollectedHeap(),
   _g1_policy(policy_),
   _dirty_card_queue_set(false),
-  _into_cset_dirty_card_queue_set(false),
   _is_alive_closure_cm(this),
   _is_alive_closure_stw(this),
   _ref_processor_cm(NULL),
@@ -2081,16 +2044,6 @@
                                     Shared_DirtyCardQ_lock,
                                     &JavaThread::dirty_card_queue_set());
 
-  // Initialize the card queue set used to hold cards containing
-  // references into the collection set.
-  _into_cset_dirty_card_queue_set.initialize(NULL, // Should never be called by the Java code
-                                             DirtyCardQ_CBL_mon,
-                                             DirtyCardQ_FL_lock,
-                                             -1, // never trigger processing
-                                             -1, // no limit on length
-                                             Shared_DirtyCardQ_lock,
-                                             &JavaThread::dirty_card_queue_set());
-
   // Here we allocate the dummy HeapRegion that is required by the
   // G1AllocRegion class.
   HeapRegion* dummy_region = _hrm.get_dummy_region();
@@ -2222,17 +2175,7 @@
 }
 
 void G1CollectedHeap::reset_gc_time_stamps(HeapRegion* hr) {
-  assert(!hr->is_continues_humongous(), "pre-condition");
   hr->reset_gc_time_stamp();
-  if (hr->is_starts_humongous()) {
-    uint first_index = hr->hrm_index() + 1;
-    uint last_index = hr->last_hc_index();
-    for (uint i = first_index; i < last_index; i += 1) {
-      HeapRegion* chr = region_at(i);
-      assert(chr->is_continues_humongous(), "sanity");
-      chr->reset_gc_time_stamp();
-    }
-  }
 }
 
 #ifndef PRODUCT
@@ -2300,9 +2243,7 @@
 public:
   SumUsedClosure() : _used(0) {}
   bool doHeapRegion(HeapRegion* r) {
-    if (!r->is_continues_humongous()) {
-      _used += r->used();
-    }
+    _used += r->used();
     return false;
   }
   size_t result() { return _used; }
@@ -2523,9 +2464,9 @@
 bool G1CollectedHeap::is_in(const void* p) const {
   if (_hrm.reserved().contains(p)) {
     // Given that we know that p is in the reserved space,
-    // heap_region_containing_raw() should successfully
+    // heap_region_containing() should successfully
     // return the containing region.
-    HeapRegion* hr = heap_region_containing_raw(p);
+    HeapRegion* hr = heap_region_containing(p);
     return hr->is_in(p);
   } else {
     return false;
@@ -3062,7 +3003,7 @@
       r->verify(_vo, &failures);
       if (failures) {
         _failures = true;
-      } else {
+      } else if (!r->is_starts_humongous()) {
         VerifyObjsInRegionClosure not_dead_yet_cl(r, _vo);
         r->object_iterate(&not_dead_yet_cl);
         if (_vo != VerifyOption_G1UseNextMarking) {
@@ -3613,7 +3554,7 @@
           // The remembered set might contain references to already freed
           // regions. Filter out such entries to avoid failing card table
           // verification.
-          if (!g1h->heap_region_containing(bs->addr_for(card_ptr))->is_free()) {
+          if (g1h->is_in_closed_subset(bs->addr_for(card_ptr))) {
             if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
               *card_ptr = CardTableModRefBS::dirty_card_val();
               _dcq.enqueue(card_ptr);
@@ -3735,8 +3676,7 @@
       gclog_or_tty->print(" (to-space exhausted)");
     }
     gclog_or_tty->print_cr(", %3.7f secs]", pause_time_sec);
-    g1_policy()->phase_times()->note_gc_end();
-    g1_policy()->phase_times()->print(pause_time_sec);
+    g1_policy()->print_phases(pause_time_sec);
     g1_policy()->print_detailed_heap_transition();
   } else {
     if (evacuation_failed()) {
@@ -3827,7 +3767,7 @@
     workers()->set_active_workers(active_workers);
 
     double pause_start_sec = os::elapsedTime();
-    g1_policy()->phase_times()->note_gc_start(active_workers, collector_state()->mark_in_progress());
+    g1_policy()->note_gc_start(active_workers);
     log_gc_header();
 
     TraceCollectorStats tcs(g1mm()->incremental_collection_counters());
@@ -5270,6 +5210,9 @@
 
   record_obj_copy_mem_stats();
 
+  _survivor_evac_stats.adjust_desired_plab_sz();
+  _old_evac_stats.adjust_desired_plab_sz();
+
   // Reset and re-enable the hot card cache.
   // Note the counts for the cards in the regions in the
   // collection set are reset when the collection set is freed.
@@ -5315,30 +5258,16 @@
 }
 
 void G1CollectedHeap::free_humongous_region(HeapRegion* hr,
-                                     FreeRegionList* free_list,
-                                     bool par) {
-  assert(hr->is_starts_humongous(), "this is only for starts humongous regions");
+                                            FreeRegionList* free_list,
+                                            bool par) {
+  assert(hr->is_humongous(), "this is only for humongous regions");
   assert(free_list != NULL, "pre-condition");
-
-  size_t hr_capacity = hr->capacity();
-  // We need to read this before we make the region non-humongous,
-  // otherwise the information will be gone.
-  uint last_index = hr->last_hc_index();
   hr->clear_humongous();
   free_region(hr, free_list, par);
-
-  uint i = hr->hrm_index() + 1;
-  while (i < last_index) {
-    HeapRegion* curr_hr = region_at(i);
-    assert(curr_hr->is_continues_humongous(), "invariant");
-    curr_hr->clear_humongous();
-    free_region(curr_hr, free_list, par);
-    i += 1;
-  }
 }
 
 void G1CollectedHeap::remove_from_old_sets(const HeapRegionSetCount& old_regions_removed,
-                                       const HeapRegionSetCount& humongous_regions_removed) {
+                                           const HeapRegionSetCount& humongous_regions_removed) {
   if (old_regions_removed.length() > 0 || humongous_regions_removed.length() > 0) {
     MutexLockerEx x(OldSets_lock, Mutex::_no_safepoint_check_flag);
     _old_set.bulk_remove(old_regions_removed);
@@ -5498,8 +5427,6 @@
   bool failures() { return _failures; }
 
   virtual bool doHeapRegion(HeapRegion* hr) {
-    if (hr->is_continues_humongous()) return false;
-
     bool result = _g1h->verify_bitmaps(_caller, hr);
     if (!result) {
       _failures = true;
@@ -5773,11 +5700,10 @@
         !r->rem_set()->is_empty()) {
 
       if (G1TraceEagerReclaimHumongousObjects) {
-        gclog_or_tty->print_cr("Live humongous region %u size " SIZE_FORMAT " start " PTR_FORMAT " length %u with remset " SIZE_FORMAT " code roots " SIZE_FORMAT " is marked %d reclaim candidate %d type array %d",
+        gclog_or_tty->print_cr("Live humongous region %u object size " SIZE_FORMAT " start " PTR_FORMAT "  with remset " SIZE_FORMAT " code roots " SIZE_FORMAT " is marked %d reclaim candidate %d type array %d",
                                region_idx,
                                (size_t)obj->size() * HeapWordSize,
                                p2i(r->bottom()),
-                               r->region_num(),
                                r->rem_set()->occupied(),
                                r->rem_set()->strong_code_roots_list_length(),
                                next_bitmap->isMarked(r->bottom()),
@@ -5794,11 +5720,10 @@
               PTR_FORMAT " is not.", p2i(r->bottom()));
 
     if (G1TraceEagerReclaimHumongousObjects) {
-      gclog_or_tty->print_cr("Dead humongous region %u size " SIZE_FORMAT " start " PTR_FORMAT " length %u with remset " SIZE_FORMAT " code roots " SIZE_FORMAT " is marked %d reclaim candidate %d type array %d",
+      gclog_or_tty->print_cr("Dead humongous region %u object size " SIZE_FORMAT " start " PTR_FORMAT " with remset " SIZE_FORMAT " code roots " SIZE_FORMAT " is marked %d reclaim candidate %d type array %d",
                              region_idx,
                              (size_t)obj->size() * HeapWordSize,
                              p2i(r->bottom()),
-                             r->region_num(),
                              r->rem_set()->occupied(),
                              r->rem_set()->strong_code_roots_list_length(),
                              next_bitmap->isMarked(r->bottom()),
@@ -5810,10 +5735,14 @@
     if (next_bitmap->isMarked(r->bottom())) {
       next_bitmap->clear(r->bottom());
     }
-    _freed_bytes += r->used();
-    r->set_containing_set(NULL);
-    _humongous_regions_removed.increment(1u, r->capacity());
-    g1h->free_humongous_region(r, _free_region_list, false);
+    do {
+      HeapRegion* next = g1h->next_region_in_humongous(r);
+      _freed_bytes += r->used();
+      r->set_containing_set(NULL);
+      _humongous_regions_removed.increment(1u, r->capacity());
+      g1h->free_humongous_region(r, _free_region_list, false);
+      r = next;
+    } while (r != NULL);
 
     return false;
   }
@@ -6048,10 +5977,6 @@
   }
 
   bool doHeapRegion(HeapRegion* r) {
-    if (r->is_continues_humongous()) {
-      return false;
-    }
-
     if (r->is_empty()) {
       // Add free regions to the free list
       r->set_free();
@@ -6239,14 +6164,10 @@
     _old_count(), _humongous_count(), _free_count(){ }
 
   bool doHeapRegion(HeapRegion* hr) {
-    if (hr->is_continues_humongous()) {
-      return false;
-    }
-
     if (hr->is_young()) {
       // TODO
-    } else if (hr->is_starts_humongous()) {
-      assert(hr->containing_set() == _humongous_set, "Heap region %u is starts humongous but not in humongous set.", hr->hrm_index());
+    } else if (hr->is_humongous()) {
+      assert(hr->containing_set() == _humongous_set, "Heap region %u is humongous but not in humongous set.", hr->hrm_index());
       _humongous_count.increment(1u, hr->capacity());
     } else if (hr->is_empty()) {
       assert(_hrm->is_free(hr), "Heap region %u is empty but not on the free list.", hr->hrm_index());
--- a/src/share/vm/gc/g1/g1CollectedHeap.hpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/g1CollectedHeap.hpp	Fri Nov 13 10:35:26 2015 -0800
@@ -757,12 +757,6 @@
   // The closure used to refine a single card.
   RefineCardTableEntryClosure* _refine_cte_cl;
 
-  // A DirtyCardQueueSet that is used to hold cards that contain
-  // references into the current collection set. This is used to
-  // update the remembered sets of the regions in the collection
-  // set in the event of an evacuation failure.
-  DirtyCardQueueSet _into_cset_dirty_card_queue_set;
-
   // After a collection pause, make the regions in the CS into free
   // regions.
   void free_collection_set(HeapRegion* cs_head, EvacuationInfo& evacuation_info, const size_t* surviving_young_words);
@@ -952,13 +946,6 @@
   // A set of cards where updates happened during the GC
   DirtyCardQueueSet& dirty_card_queue_set() { return _dirty_card_queue_set; }
 
-  // A DirtyCardQueueSet that is used to hold cards that contain
-  // references into the current collection set. This is used to
-  // update the remembered sets of the regions in the collection
-  // set in the event of an evacuation failure.
-  DirtyCardQueueSet& into_cset_dirty_card_queue_set()
-        { return _into_cset_dirty_card_queue_set; }
-
   // Create a G1CollectedHeap with the specified policy.
   // Must call the initialize method afterwards.
   // May not return if something goes wrong.
@@ -1178,7 +1165,6 @@
   void prepend_to_freelist(FreeRegionList* list);
   void decrement_summary_bytes(size_t bytes);
 
-  // Returns "TRUE" iff "p" points into the committed areas of the heap.
   virtual bool is_in(const void* p) const;
 #ifdef ASSERT
   // Returns whether p is in one of the available areas of the heap. Slow but
@@ -1243,6 +1229,10 @@
   // Return the region with the given index. It assumes the index is valid.
   inline HeapRegion* region_at(uint index) const;
 
+  // Return the next region (by index) that is part of the same
+  // humongous object that hr is part of.
+  inline HeapRegion* next_region_in_humongous(HeapRegion* hr) const;
+
   // Calculate the region index of the given address. Given address must be
   // within the heap.
   inline uint addr_to_region(HeapWord* addr) const;
@@ -1280,11 +1270,6 @@
 
   // Returns the HeapRegion that contains addr. addr must not be NULL.
   template <class T>
-  inline HeapRegion* heap_region_containing_raw(const T addr) const;
-
-  // Returns the HeapRegion that contains addr. addr must not be NULL.
-  // If addr is within a humongous continues region, it returns its humongous start region.
-  template <class T>
   inline HeapRegion* heap_region_containing(const T addr) const;
 
   // A CollectedHeap is divided into a dense sequence of "blocks"; that is,
--- a/src/share/vm/gc/g1/g1CollectedHeap.inline.hpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/g1CollectedHeap.inline.hpp	Fri Nov 13 10:35:26 2015 -0800
@@ -65,6 +65,10 @@
 // Return the region with the given index. It assumes the index is valid.
 inline HeapRegion* G1CollectedHeap::region_at(uint index) const { return _hrm.at(index); }
 
+inline HeapRegion* G1CollectedHeap::next_region_in_humongous(HeapRegion* hr) const {
+  return _hrm.next_region_in_humongous(hr);
+}
+
 inline uint G1CollectedHeap::addr_to_region(HeapWord* addr) const {
   assert(is_in_reserved(addr),
          "Cannot calculate region index for address " PTR_FORMAT " that is outside of the heap [" PTR_FORMAT ", " PTR_FORMAT ")",
@@ -77,7 +81,7 @@
 }
 
 template <class T>
-inline HeapRegion* G1CollectedHeap::heap_region_containing_raw(const T addr) const {
+inline HeapRegion* G1CollectedHeap::heap_region_containing(const T addr) const {
   assert(addr != NULL, "invariant");
   assert(is_in_g1_reserved((const void*) addr),
          "Address " PTR_FORMAT " is outside of the heap ranging from [" PTR_FORMAT " to " PTR_FORMAT ")",
@@ -85,15 +89,6 @@
   return _hrm.addr_to_region((HeapWord*) addr);
 }
 
-template <class T>
-inline HeapRegion* G1CollectedHeap::heap_region_containing(const T addr) const {
-  HeapRegion* hr = heap_region_containing_raw(addr);
-  if (hr->is_continues_humongous()) {
-    return hr->humongous_start_region();
-  }
-  return hr;
-}
-
 inline void G1CollectedHeap::reset_gc_time_stamp() {
   _gc_time_stamp = 0;
   OrderAccess::fence();
@@ -124,9 +119,9 @@
   assert_heap_not_locked();
 
   // Assign the containing region to containing_hr so that we don't
-  // have to keep calling heap_region_containing_raw() in the
+  // have to keep calling heap_region_containing() in the
   // asserts below.
-  DEBUG_ONLY(HeapRegion* containing_hr = heap_region_containing_raw(start);)
+  DEBUG_ONLY(HeapRegion* containing_hr = heap_region_containing(start);)
   assert(word_size > 0, "pre-condition");
   assert(containing_hr->is_in(start), "it should contain start");
   assert(containing_hr->is_young(), "it should be young");
--- a/src/share/vm/gc/g1/g1CollectorPolicy.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/g1CollectorPolicy.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -437,6 +437,10 @@
   start_incremental_cset_building();
 }
 
+void G1CollectorPolicy::note_gc_start(uint num_active_workers) {
+  phase_times()->note_gc_start(num_active_workers);
+}
+
 // Create the jstat counters for the policy.
 void G1CollectorPolicy::initialize_gc_policy_counters() {
   _gc_policy_counters = new GCPolicyCounters("GarbageFirst", 1, 3);
@@ -807,7 +811,7 @@
   // transitions and make sure we start with young GCs after the Full GC.
   collector_state()->set_gcs_are_young(true);
   collector_state()->set_last_young_gc(false);
-  collector_state()->set_initiate_conc_mark_if_possible(false);
+  collector_state()->set_initiate_conc_mark_if_possible(need_to_start_conc_mark("end of Full GC", 0));
   collector_state()->set_during_initial_mark_pause(false);
   collector_state()->set_in_marking_window(false);
   collector_state()->set_in_marking_window_im(false);
@@ -888,7 +892,9 @@
 }
 
 void G1CollectorPolicy::record_concurrent_mark_cleanup_completed() {
-  collector_state()->set_last_young_gc(true);
+  bool should_continue_with_reclaim = next_gc_should_be_mixed("request last young-only gc",
+                                                              "skip last young-only gc");
+  collector_state()->set_last_young_gc(should_continue_with_reclaim);
   collector_state()->set_in_marking_window(false);
 }
 
@@ -903,8 +909,35 @@
   return phase_times()->average_time_ms(phase);
 }
 
+double G1CollectorPolicy::young_other_time_ms() const {
+  return phase_times()->young_cset_choice_time_ms() +
+         phase_times()->young_free_cset_time_ms();
+}
+
+double G1CollectorPolicy::non_young_other_time_ms() const {
+  return phase_times()->non_young_cset_choice_time_ms() +
+         phase_times()->non_young_free_cset_time_ms();
+
+}
+
+double G1CollectorPolicy::other_time_ms(double pause_time_ms) const {
+  return pause_time_ms -
+         average_time_ms(G1GCPhaseTimes::UpdateRS) -
+         average_time_ms(G1GCPhaseTimes::ScanRS) -
+         average_time_ms(G1GCPhaseTimes::ObjCopy) -
+         average_time_ms(G1GCPhaseTimes::Termination);
+}
+
+double G1CollectorPolicy::constant_other_time_ms(double pause_time_ms) const {
+  return other_time_ms(pause_time_ms) - young_other_time_ms() - non_young_other_time_ms();
+}
+
+bool G1CollectorPolicy::about_to_start_mixed_phase() const {
+  return _g1->concurrent_mark()->cmThread()->during_cycle() || collector_state()->last_young_gc();
+}
+
 bool G1CollectorPolicy::need_to_start_conc_mark(const char* source, size_t alloc_word_size) {
-  if (_g1->concurrent_mark()->cmThread()->during_cycle()) {
+  if (about_to_start_mixed_phase()) {
     return false;
   }
 
@@ -972,11 +1005,8 @@
   last_pause_included_initial_mark = collector_state()->during_initial_mark_pause();
   if (last_pause_included_initial_mark) {
     record_concurrent_mark_init_end(0.0);
-  } else if (need_to_start_conc_mark("end of GC")) {
-    // Note: this might have already been set, if during the last
-    // pause we decided to start a cycle but at the beginning of
-    // this pause we decided to postpone it. That's OK.
-    collector_state()->set_initiate_conc_mark_if_possible(true);
+  } else {
+    maybe_start_marking();
   }
 
   _mmu_tracker->add_pause(end_time_sec - pause_time_ms/1000.0, end_time_sec);
@@ -1010,19 +1040,6 @@
     _recent_avg_pause_time_ratio = _recent_gc_times_ms->sum()/interval_ms;
     if (recent_avg_pause_time_ratio() < 0.0 ||
         (recent_avg_pause_time_ratio() - 1.0 > 0.0)) {
-#ifndef PRODUCT
-      // Dump info to allow post-facto debugging
-      gclog_or_tty->print_cr("recent_avg_pause_time_ratio() out of bounds");
-      gclog_or_tty->print_cr("-------------------------------------------");
-      gclog_or_tty->print_cr("Recent GC Times (ms):");
-      _recent_gc_times_ms->dump();
-      gclog_or_tty->print_cr("(End Time=%3.3f) Recent GC End Times (s):", end_time_sec);
-      _recent_prev_end_times_for_all_gcs_sec->dump();
-      gclog_or_tty->print_cr("GC = %3.3f, Interval = %3.3f, Ratio = %3.3f",
-                             _recent_gc_times_ms->sum(), interval_ms, recent_avg_pause_time_ratio());
-      // In debug mode, terminate the JVM if the user wants to debug at this point.
-      assert(!G1FailOnFPError, "Debugging data for CR 6898948 has been dumped above");
-#endif  // !PRODUCT
       // Clip ratio between 0.0 and 1.0, and continue. This will be fixed in
       // CR 6902692 by redoing the manner in which the ratio is incrementally computed.
       if (_recent_avg_pause_time_ratio < 0.0) {
@@ -1044,17 +1061,13 @@
   if (collector_state()->last_young_gc()) {
     // This is supposed to to be the "last young GC" before we start
     // doing mixed GCs. Here we decide whether to start mixed GCs or not.
+    assert(!last_pause_included_initial_mark, "The last young GC is not allowed to be an initial mark GC");
 
-    if (!last_pause_included_initial_mark) {
-      if (next_gc_should_be_mixed("start mixed GCs",
-                                  "do not start mixed GCs")) {
-        collector_state()->set_gcs_are_young(false);
-      }
-    } else {
-      ergo_verbose0(ErgoMixedGCs,
-                    "do not start mixed GCs",
-                    ergo_format_reason("concurrent cycle is about to start"));
+    if (next_gc_should_be_mixed("start mixed GCs",
+                                "do not start mixed GCs")) {
+      collector_state()->set_gcs_are_young(false);
     }
+
     collector_state()->set_last_young_gc(false);
   }
 
@@ -1065,6 +1078,8 @@
     if (!next_gc_should_be_mixed("continue mixed GCs",
                                  "do not continue mixed GCs")) {
       collector_state()->set_gcs_are_young(true);
+
+      maybe_start_marking();
     }
   }
 
@@ -1132,37 +1147,17 @@
       }
     }
 
-    double all_other_time_ms = pause_time_ms -
-      (average_time_ms(G1GCPhaseTimes::UpdateRS) + average_time_ms(G1GCPhaseTimes::ScanRS) +
-       average_time_ms(G1GCPhaseTimes::ObjCopy)  + average_time_ms(G1GCPhaseTimes::Termination));
-
-    double young_other_time_ms = 0.0;
     if (young_cset_region_length() > 0) {
-      young_other_time_ms =
-        phase_times()->young_cset_choice_time_ms() +
-        phase_times()->young_free_cset_time_ms();
-      _young_other_cost_per_region_ms_seq->add(young_other_time_ms /
-                                          (double) young_cset_region_length());
-    }
-    double non_young_other_time_ms = 0.0;
-    if (old_cset_region_length() > 0) {
-      non_young_other_time_ms =
-        phase_times()->non_young_cset_choice_time_ms() +
-        phase_times()->non_young_free_cset_time_ms();
-
-      _non_young_other_cost_per_region_ms_seq->add(non_young_other_time_ms /
-                                            (double) old_cset_region_length());
+      _young_other_cost_per_region_ms_seq->add(young_other_time_ms() /
+                                               young_cset_region_length());
     }
 
-    double constant_other_time_ms = all_other_time_ms -
-      (young_other_time_ms + non_young_other_time_ms);
-    _constant_other_time_ms_seq->add(constant_other_time_ms);
+    if (old_cset_region_length() > 0) {
+      _non_young_other_cost_per_region_ms_seq->add(non_young_other_time_ms() /
+                                                   old_cset_region_length());
+    }
 
-    double survival_ratio = 0.0;
-    if (_collection_set_bytes_used_before > 0) {
-      survival_ratio = (double) _bytes_copied_during_gc /
-                                   (double) _collection_set_bytes_used_before;
-    }
+    _constant_other_time_ms_seq->add(constant_other_time_ms(pause_time_ms));
 
     _pending_cards_seq->add((double) _pending_cards);
     _rs_lengths_seq->add((double) _max_rs_lengths);
@@ -1271,6 +1266,10 @@
   gclog_or_tty->cr();
 }
 
+void G1CollectorPolicy::print_phases(double pause_time_sec) {
+  phase_times()->print(pause_time_sec);
+}
+
 void G1CollectorPolicy::adjust_concurrent_refinement(double update_rs_time,
                                                      double update_rs_processed_buffers,
                                                      double goal_ms) {
@@ -1588,8 +1587,10 @@
         HeapRegion::GrainWords * _max_survivor_regions, counters());
 }
 
-bool G1CollectorPolicy::force_initial_mark_if_outside_cycle(
-                                                     GCCause::Cause gc_cause) {
+bool G1CollectorPolicy::force_initial_mark_if_outside_cycle(GCCause::Cause gc_cause) {
+  // We actually check whether we are marking here and not if we are in a
+  // reclamation phase. This means that we will schedule a concurrent mark
+  // even while we are still in the process of reclaiming memory.
   bool during_cycle = _g1->concurrent_mark()->cmThread()->during_cycle();
   if (!during_cycle) {
     ergo_verbose1(ErgoConcCycles,
@@ -1609,8 +1610,7 @@
   }
 }
 
-void
-G1CollectorPolicy::decide_on_conc_mark_initiation() {
+void G1CollectorPolicy::decide_on_conc_mark_initiation() {
   // We are about to decide on whether this pause will be an
   // initial-mark pause.
 
@@ -1625,21 +1625,11 @@
     // gone over the initiating threshold and we should start a
     // concurrent marking cycle. So we might initiate one.
 
-    bool during_cycle = _g1->concurrent_mark()->cmThread()->during_cycle();
-    if (!during_cycle) {
-      // The concurrent marking thread is not "during a cycle", i.e.,
-      // it has completed the last one. So we can go ahead and
-      // initiate a new cycle.
+    if (!about_to_start_mixed_phase() && collector_state()->gcs_are_young()) {
+      // Initiate a new initial mark only if there is no marking or reclamation going
+      // on.
 
       collector_state()->set_during_initial_mark_pause(true);
-      // We do not allow mixed GCs during marking.
-      if (!collector_state()->gcs_are_young()) {
-        collector_state()->set_gcs_are_young(true);
-        ergo_verbose0(ErgoMixedGCs,
-                      "end mixed GCs",
-                      ergo_format_reason("concurrent cycle is about to start"));
-      }
-
       // And we can now clear initiate_conc_mark_if_possible() as
       // we've already acted on it.
       collector_state()->set_initiate_conc_mark_if_possible(false);
@@ -1943,6 +1933,15 @@
   return (double) reclaimable_bytes * 100.0 / (double) capacity_bytes;
 }
 
+void G1CollectorPolicy::maybe_start_marking() {
+  if (need_to_start_conc_mark("end of GC")) {
+    // Note: this might have already been set, if during the last
+    // pause we decided to start a cycle but at the beginning of
+    // this pause we decided to postpone it. That's OK.
+    collector_state()->set_initiate_conc_mark_if_possible(true);
+  }
+}
+
 bool G1CollectorPolicy::next_gc_should_be_mixed(const char* true_action_str,
                                                 const char* false_action_str) const {
   CollectionSetChooser* cset_chooser = _collectionSetChooser;
--- a/src/share/vm/gc/g1/g1CollectorPolicy.hpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/g1CollectorPolicy.hpp	Fri Nov 13 10:35:26 2015 -0800
@@ -380,6 +380,11 @@
 
 protected:
   virtual double average_time_ms(G1GCPhaseTimes::GCParPhases phase) const;
+  virtual double other_time_ms(double pause_time_ms) const;
+
+  double young_other_time_ms() const;
+  double non_young_other_time_ms() const;
+  double constant_other_time_ms(double pause_time_ms) const;
 
 private:
   // Statistics kept per GC stoppage, pause or full.
@@ -529,6 +534,8 @@
   // as a percentage of the current heap capacity.
   double reclaimable_bytes_perc(size_t reclaimable_bytes) const;
 
+  // Sets up marking if proper conditions are met.
+  void maybe_start_marking();
 public:
 
   G1CollectorPolicy();
@@ -549,6 +556,8 @@
 
   void init();
 
+  virtual void note_gc_start(uint num_active_workers);
+
   // Create jstat counters for the policy.
   virtual void initialize_gc_policy_counters();
 
@@ -563,6 +572,8 @@
 
   bool need_to_start_conc_mark(const char* source, size_t alloc_word_size = 0);
 
+  bool about_to_start_mixed_phase() const;
+
   // Record the start and end of an evacuation pause.
   void record_collection_pause_start(double start_time_sec);
   void record_collection_pause_end(double pause_time_ms, size_t cards_scanned);
@@ -593,6 +604,8 @@
   void print_heap_transition() const;
   void print_detailed_heap_transition(bool full = false) const;
 
+  virtual void print_phases(double pause_time_sec);
+
   void record_stop_world_start();
   void record_concurrent_pause();
 
--- a/src/share/vm/gc/g1/g1GCPhaseTimes.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/g1GCPhaseTimes.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -136,7 +136,7 @@
   _gc_par_phases[RedirtyCards]->link_thread_work_items(_redirtied_cards);
 }
 
-void G1GCPhaseTimes::note_gc_start(uint active_gc_threads, bool mark_in_progress) {
+void G1GCPhaseTimes::note_gc_start(uint active_gc_threads) {
   assert(active_gc_threads > 0, "The number of threads must be > 0");
   assert(active_gc_threads <= _max_gc_threads, "The number of active threads must be <= the max number of threads");
   _active_gc_threads = active_gc_threads;
@@ -362,6 +362,8 @@
 };
 
 void G1GCPhaseTimes::print(double pause_time_sec) {
+  note_gc_end();
+
   G1GCParPhasePrinter par_phase_printer(this);
 
   if (_root_region_scan_wait_time_ms > 0.0) {
--- a/src/share/vm/gc/g1/g1GCPhaseTimes.hpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/g1GCPhaseTimes.hpp	Fri Nov 13 10:35:26 2015 -0800
@@ -121,10 +121,11 @@
   void print_stats(int level, const char* str, size_t value);
   void print_stats(int level, const char* str, double value, uint workers);
 
+  void note_gc_end();
+
  public:
   G1GCPhaseTimes(uint max_gc_threads);
-  void note_gc_start(uint active_gc_threads, bool mark_in_progress);
-  void note_gc_end();
+  void note_gc_start(uint active_gc_threads);
   void print(double pause_time_sec);
 
   // record the time a phase took in seconds
--- a/src/share/vm/gc/g1/g1HRPrinter.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/g1HRPrinter.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -51,7 +51,6 @@
     case Eden:               return "Eden";
     case Survivor:           return "Survivor";
     case Old:                return "Old";
-    case SingleHumongous:    return "SingleH";
     case StartsHumongous:    return "StartsH";
     case ContinuesHumongous: return "ContinuesH";
     case Archive:            return "Archive";
--- a/src/share/vm/gc/g1/g1HRPrinter.hpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/g1HRPrinter.hpp	Fri Nov 13 10:35:26 2015 -0800
@@ -50,7 +50,6 @@
     Eden,
     Survivor,
     Old,
-    SingleHumongous,
     StartsHumongous,
     ContinuesHumongous,
     Archive
--- a/src/share/vm/gc/g1/g1MarkSweep.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/g1MarkSweep.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -279,8 +279,8 @@
         } else {
           assert(hr->is_empty(), "Should have been cleared in phase 2.");
         }
-        hr->reset_during_compaction();
       }
+      hr->reset_during_compaction();
     } else if (!hr->is_pinned()) {
       hr->compact();
     }
@@ -334,9 +334,6 @@
   HeapWord* end = hr->end();
   FreeRegionList dummy_free_list("Dummy Free List for G1MarkSweep");
 
-  assert(hr->is_starts_humongous(),
-         "Only the start of a humongous region should be freed.");
-
   hr->set_containing_set(NULL);
   _humongous_regions_removed.increment(1u, hr->capacity());
 
@@ -373,15 +370,12 @@
 
 bool G1PrepareCompactClosure::doHeapRegion(HeapRegion* hr) {
   if (hr->is_humongous()) {
-    if (hr->is_starts_humongous()) {
-      oop obj = oop(hr->bottom());
-      if (obj->is_gc_marked()) {
-        obj->forward_to(obj);
-      } else  {
-        free_humongous_region(hr);
-      }
-    } else {
-      assert(hr->is_continues_humongous(), "Invalid humongous.");
+    oop obj = oop(hr->humongous_start_region()->bottom());
+    if (hr->is_starts_humongous() && obj->is_gc_marked()) {
+      obj->forward_to(obj);
+    }
+    if (!obj->is_gc_marked()) {
+      free_humongous_region(hr);
     }
   } else if (!hr->is_pinned()) {
     prepare_for_compaction(hr, hr->end());
--- a/src/share/vm/gc/g1/g1OopClosures.inline.hpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/g1OopClosures.inline.hpp	Fri Nov 13 10:35:26 2015 -0800
@@ -117,11 +117,6 @@
 template <class T>
 inline void G1CMOopClosure::do_oop_nv(T* p) {
   oop obj = oopDesc::load_decode_heap_oop(p);
-  if (_cm->verbose_high()) {
-    gclog_or_tty->print_cr("[%u] we're looking at location "
-                           "*" PTR_FORMAT " = " PTR_FORMAT,
-                           _task->worker_id(), p2i(p), p2i((void*) obj));
-  }
   _task->deal_with_reference(obj);
 }
 
@@ -227,7 +222,7 @@
 
 template <class T>
 void G1ParCopyHelper::do_klass_barrier(T* p, oop new_obj) {
-  if (_g1->heap_region_containing_raw(new_obj)->is_young()) {
+  if (_g1->heap_region_containing(new_obj)->is_young()) {
     _scanned_klass->record_modified_oops();
   }
 }
--- a/src/share/vm/gc/g1/g1ParScanThreadState.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/g1ParScanThreadState.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -216,7 +216,7 @@
                                                  oop const old,
                                                  markOop const old_mark) {
   const size_t word_sz = old->size();
-  HeapRegion* const from_region = _g1h->heap_region_containing_raw(old);
+  HeapRegion* const from_region = _g1h->heap_region_containing(old);
   // +1 to make the -1 indexes valid...
   const int young_index = from_region->young_index_in_cset()+1;
   assert( (from_region->is_young() && young_index >  0) ||
@@ -294,9 +294,9 @@
     if (G1StringDedup::is_enabled()) {
       const bool is_from_young = state.is_young();
       const bool is_to_young = dest_state.is_young();
-      assert(is_from_young == _g1h->heap_region_containing_raw(old)->is_young(),
+      assert(is_from_young == _g1h->heap_region_containing(old)->is_young(),
              "sanity");
-      assert(is_to_young == _g1h->heap_region_containing_raw(obj)->is_young(),
+      assert(is_to_young == _g1h->heap_region_containing(obj)->is_young(),
              "sanity");
       G1StringDedup::enqueue_from_evacuation(is_from_young,
                                              is_to_young,
@@ -314,7 +314,7 @@
       oop* old_p = set_partial_array_mask(old);
       push_on_queue(old_p);
     } else {
-      HeapRegion* const to_region = _g1h->heap_region_containing_raw(obj_ptr);
+      HeapRegion* const to_region = _g1h->heap_region_containing(obj_ptr);
       _scanner.set_region(to_region);
       obj->oop_iterate_backwards(&_scanner);
     }
--- a/src/share/vm/gc/g1/g1ParScanThreadState.inline.hpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/g1ParScanThreadState.inline.hpp	Fri Nov 13 10:35:26 2015 -0800
@@ -101,7 +101,7 @@
     // so that the heap remains parsable in case of evacuation failure.
     to_obj_array->set_length(end);
   }
-  _scanner.set_region(_g1h->heap_region_containing_raw(to_obj));
+  _scanner.set_region(_g1h->heap_region_containing(to_obj));
   // Process indexes [start,end). It will also process the header
   // along with the first chunk (i.e., the chunk with start == 0).
   // Note that at this point the length field of to_obj_array is not
@@ -115,10 +115,7 @@
 
 template <class T> inline void G1ParScanThreadState::deal_with_reference(T* ref_to_scan) {
   if (!has_partial_array_mask(ref_to_scan)) {
-    // Note: we can use "raw" versions of "region_containing" because
-    // "obj_to_scan" is definitely in the heap, and is not in a
-    // humongous region.
-    HeapRegion* r = _g1h->heap_region_containing_raw(ref_to_scan);
+    HeapRegion* r = _g1h->heap_region_containing(ref_to_scan);
     do_oop_evac(ref_to_scan, r);
   } else {
     do_oop_partial_array((oop*)ref_to_scan);
--- a/src/share/vm/gc/g1/g1RemSet.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/g1RemSet.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -40,42 +40,13 @@
 #include "utilities/intHisto.hpp"
 #include "utilities/stack.inline.hpp"
 
-#define CARD_REPEAT_HISTO 0
-
-#if CARD_REPEAT_HISTO
-static size_t ct_freq_sz;
-static jbyte* ct_freq = NULL;
-
-void init_ct_freq_table(size_t heap_sz_bytes) {
-  if (ct_freq == NULL) {
-    ct_freq_sz = heap_sz_bytes/CardTableModRefBS::card_size;
-    ct_freq = new jbyte[ct_freq_sz];
-    for (size_t j = 0; j < ct_freq_sz; j++) ct_freq[j] = 0;
-  }
-}
-
-void ct_freq_note_card(size_t index) {
-  assert(0 <= index && index < ct_freq_sz, "Bounds error.");
-  if (ct_freq[index] < 100) { ct_freq[index]++; }
-}
-
-static IntHistogram card_repeat_count(10, 10);
-
-void ct_freq_update_histo_and_reset() {
-  for (size_t j = 0; j < ct_freq_sz; j++) {
-    card_repeat_count.add_entry(ct_freq[j]);
-    ct_freq[j] = 0;
-  }
-
-}
-#endif
-
 G1RemSet::G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs)
   : _g1(g1), _conc_refine_cards(0),
     _ct_bs(ct_bs), _g1p(_g1->g1_policy()),
     _cg1r(g1->concurrent_g1_refine()),
     _cset_rs_update_cl(NULL),
-    _prev_period_summary()
+    _prev_period_summary(),
+    _into_cset_dirty_card_queue_set(false)
 {
   _cset_rs_update_cl = NEW_C_HEAP_ARRAY(G1ParPushHeapRSClosure*, n_workers(), mtGC);
   for (uint i = 0; i < n_workers(); i++) {
@@ -84,6 +55,15 @@
   if (G1SummarizeRSetStats) {
     _prev_period_summary.initialize(this);
   }
+  // Initialize the card queue set used to hold cards containing
+  // references into the collection set.
+  _into_cset_dirty_card_queue_set.initialize(NULL, // Should never be called by the Java code
+                                             DirtyCardQ_CBL_mon,
+                                             DirtyCardQ_FL_lock,
+                                             -1, // never trigger processing
+                                             -1, // no limit on length
+                                             Shared_DirtyCardQ_lock,
+                                             &JavaThread::dirty_card_queue_set());
 }
 
 G1RemSet::~G1RemSet() {
@@ -272,7 +252,7 @@
     if (_g1rs->refine_card(card_ptr, worker_i, true)) {
       // 'card_ptr' contains references that point into the collection
       // set. We need to record the card in the DCQS
-      // (G1CollectedHeap::into_cset_dirty_card_queue_set())
+      // (_into_cset_dirty_card_queue_set)
       // that's used for that purpose.
       //
       // Enqueue the card
@@ -302,10 +282,6 @@
 size_t G1RemSet::oops_into_collection_set_do(G1ParPushHeapRSClosure* oc,
                                              CodeBlobClosure* heap_region_codeblobs,
                                              uint worker_i) {
-#if CARD_REPEAT_HISTO
-  ct_freq_update_histo_and_reset();
-#endif
-
   // We cache the value of 'oc' closure into the appropriate slot in the
   // _cset_rs_update_cl for this worker
   assert(worker_i < n_workers(), "sanity");
@@ -320,7 +296,7 @@
   // are wholly 'free' of live objects. In the event of an evacuation
   // failure the cards/buffers in this queue set are passed to the
   // DirtyCardQueueSet that is used to manage RSet updates
-  DirtyCardQueue into_cset_dcq(&_g1->into_cset_dirty_card_queue_set());
+  DirtyCardQueue into_cset_dcq(&_into_cset_dirty_card_queue_set);
 
   updateRS(&into_cset_dcq, worker_i);
   size_t cards_scanned = scanRS(oc, heap_region_codeblobs, worker_i);
@@ -343,7 +319,7 @@
   // Set all cards back to clean.
   _g1->cleanUpCardTable();
 
-  DirtyCardQueueSet& into_cset_dcqs = _g1->into_cset_dirty_card_queue_set();
+  DirtyCardQueueSet& into_cset_dcqs = _into_cset_dirty_card_queue_set;
   int into_cset_n_buffers = into_cset_dcqs.completed_buffers_num();
 
   if (_g1->evacuation_failed()) {
@@ -359,10 +335,10 @@
 
   // Free any completed buffers in the DirtyCardQueueSet used to hold cards
   // which contain references that point into the collection.
-  _g1->into_cset_dirty_card_queue_set().clear();
-  assert(_g1->into_cset_dirty_card_queue_set().completed_buffers_num() == 0,
+  _into_cset_dirty_card_queue_set.clear();
+  assert(_into_cset_dirty_card_queue_set.completed_buffers_num() == 0,
          "all buffers should be freed");
-  _g1->into_cset_dirty_card_queue_set().clear_n_completed_buffers();
+  _into_cset_dirty_card_queue_set.clear_n_completed_buffers();
 }
 
 class ScrubRSClosure: public HeapRegionClosure {
@@ -498,11 +474,6 @@
   HeapWord* end   = start + CardTableModRefBS::card_size_in_words;
   MemRegion dirtyRegion(start, end);
 
-#if CARD_REPEAT_HISTO
-  init_ct_freq_table(_g1->max_capacity());
-  ct_freq_note_card(_ct_bs->index_for(start));
-#endif
-
   G1ParPushHeapRSClosure* oops_in_heap_closure = NULL;
   if (check_for_refs_into_cset) {
     // ConcurrentG1RefineThreads have worker numbers larger than what
@@ -607,12 +578,6 @@
     gclog_or_tty->print_cr("%s", header);
   }
 
-#if CARD_REPEAT_HISTO
-  gclog_or_tty->print_cr("\nG1 card_repeat count histogram: ");
-  gclog_or_tty->print_cr("  # of repeats --> # of cards with that number.");
-  card_repeat_count.print_on(gclog_or_tty);
-#endif
-
   summary->print_on(gclog_or_tty);
 }
 
@@ -631,9 +596,9 @@
     bool use_hot_card_cache = hot_card_cache->use_cache();
     hot_card_cache->set_use_cache(false);
 
-    DirtyCardQueue into_cset_dcq(&_g1->into_cset_dirty_card_queue_set());
+    DirtyCardQueue into_cset_dcq(&_into_cset_dirty_card_queue_set);
     updateRS(&into_cset_dcq, 0);
-    _g1->into_cset_dirty_card_queue_set().clear();
+    _into_cset_dirty_card_queue_set.clear();
 
     hot_card_cache->set_use_cache(use_hot_card_cache);
     assert(JavaThread::dirty_card_queue_set().completed_buffers_num() == 0, "All should be consumed");
--- a/src/share/vm/gc/g1/g1RemSet.hpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/g1RemSet.hpp	Fri Nov 13 10:35:26 2015 -0800
@@ -41,6 +41,13 @@
 class G1RemSet: public CHeapObj<mtGC> {
 private:
   G1RemSetSummary _prev_period_summary;
+
+  // A DirtyCardQueueSet that is used to hold cards that contain
+  // references into the current collection set. This is used to
+  // update the remembered sets of the regions in the collection
+  // set in the event of an evacuation failure.
+  DirtyCardQueueSet _into_cset_dirty_card_queue_set;
+
 protected:
   G1CollectedHeap* _g1;
   size_t _conc_refine_cards;
--- a/src/share/vm/gc/g1/g1RemSet.inline.hpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/g1RemSet.inline.hpp	Fri Nov 13 10:35:26 2015 -0800
@@ -60,7 +60,7 @@
   assert(_g1->is_in_reserved(obj), "must be in heap");
 #endif // ASSERT
 
-  assert(from == NULL || from->is_in_reserved(p), "p is not in from");
+  assert(from->is_in_reserved(p) || from->is_starts_humongous(), "p is not in from");
 
   HeapRegion* to = _g1->heap_region_containing(obj);
   if (from != to) {
--- a/src/share/vm/gc/g1/g1SATBCardTableModRefBS.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/g1SATBCardTableModRefBS.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -26,7 +26,7 @@
 #include "gc/g1/g1CollectedHeap.inline.hpp"
 #include "gc/g1/g1SATBCardTableModRefBS.hpp"
 #include "gc/g1/heapRegion.hpp"
-#include "gc/g1/satbQueue.hpp"
+#include "gc/g1/satbMarkQueue.hpp"
 #include "gc/shared/memset_with_concurrent_readers.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/atomic.inline.hpp"
@@ -189,21 +189,6 @@
 }
 
 void
-G1SATBCardTableLoggingModRefBS::write_ref_field_static(void* field,
-                                                       oop new_val) {
-  uintptr_t field_uint = (uintptr_t)field;
-  uintptr_t new_val_uint = cast_from_oop<uintptr_t>(new_val);
-  uintptr_t comb = field_uint ^ new_val_uint;
-  comb = comb >> HeapRegion::LogOfHRGrainBytes;
-  if (comb == 0) return;
-  if (new_val == NULL) return;
-  // Otherwise, log it.
-  G1SATBCardTableLoggingModRefBS* g1_bs =
-    barrier_set_cast<G1SATBCardTableLoggingModRefBS>(G1CollectedHeap::heap()->barrier_set());
-  g1_bs->write_ref_field_work(field, new_val, false);
-}
-
-void
 G1SATBCardTableLoggingModRefBS::invalidate(MemRegion mr, bool whole_heap) {
   volatile jbyte* byte = byte_for(mr.start());
   jbyte* last_byte = byte_for(mr.last());
--- a/src/share/vm/gc/g1/g1SATBCardTableModRefBS.hpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/g1SATBCardTableModRefBS.hpp	Fri Nov 13 10:35:26 2015 -0800
@@ -56,21 +56,15 @@
 
   virtual bool has_write_ref_pre_barrier() { return true; }
 
-  // This notes that we don't need to access any BarrierSet data
-  // structures, so this can be called from a static context.
-  template <class T> static void write_ref_field_pre_static(T* field, oop newVal) {
+  // We export this to make it available in cases where the static
+  // type of the barrier set is known.  Note that it is non-virtual.
+  template <class T> inline void inline_write_ref_field_pre(T* field, oop newVal) {
     T heap_oop = oopDesc::load_heap_oop(field);
     if (!oopDesc::is_null(heap_oop)) {
       enqueue(oopDesc::decode_heap_oop(heap_oop));
     }
   }
 
-  // We export this to make it available in cases where the static
-  // type of the barrier set is known.  Note that it is non-virtual.
-  template <class T> inline void inline_write_ref_field_pre(T* field, oop newVal) {
-    write_ref_field_pre_static(field, newVal);
-  }
-
   // These are the more general virtual versions.
   virtual void write_ref_field_pre_work(oop* field, oop new_val) {
     inline_write_ref_field_pre(field, new_val);
@@ -173,9 +167,6 @@
 
   virtual void resize_covered_region(MemRegion new_region) { ShouldNotReachHere(); }
 
-  // Can be called from static contexts.
-  static void write_ref_field_static(void* field, oop new_val);
-
   // NB: if you do a whole-heap invalidation, the "usual invariant" defined
   // above no longer applies.
   void invalidate(MemRegion mr, bool whole_heap = false);
--- a/src/share/vm/gc/g1/g1StringDedup.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/g1StringDedup.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -52,7 +52,7 @@
 
 bool G1StringDedup::is_candidate_from_mark(oop obj) {
   if (java_lang_String::is_instance_inlined(obj)) {
-    bool from_young = G1CollectedHeap::heap()->heap_region_containing_raw(obj)->is_young();
+    bool from_young = G1CollectedHeap::heap()->heap_region_containing(obj)->is_young();
     if (from_young && obj->age() < StringDeduplicationAgeThreshold) {
       // Candidate found. String is being evacuated from young to old but has not
       // reached the deduplication age threshold, i.e. has not previously been a
--- a/src/share/vm/gc/g1/g1_globals.hpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/g1_globals.hpp	Fri Nov 13 10:35:26 2015 -0800
@@ -48,9 +48,6 @@
   develop(bool, G1TraceMarkStackOverflow, false,                            \
           "If true, extra debugging code for CM restart for ovflw.")        \
                                                                             \
-  develop(bool, G1TraceHeapRegionRememberedSet, false,                      \
-          "Enables heap region remembered set debug logs")                  \
-                                                                            \
   diagnostic(bool, G1SummarizeConcMark, false,                              \
           "Summarize concurrent mark info")                                 \
                                                                             \
@@ -187,12 +184,6 @@
           range(0, max_jint/wordSize)                                       \
           constraint(G1RSetSparseRegionEntriesConstraintFunc,AfterErgo)     \
                                                                             \
-  develop(bool, G1RecordHRRSOops, false,                                    \
-          "When true, record recent calls to rem set operations.")          \
-                                                                            \
-  develop(bool, G1RecordHRRSEvents, false,                                  \
-          "When true, record recent calls to rem set operations.")          \
-                                                                            \
   develop(intx, G1MaxVerifyFailures, -1,                                    \
           "The maximum number of verification failures to print.  "         \
           "-1 means print all.")                                            \
@@ -228,10 +219,6 @@
   develop(bool, G1HRRSFlushLogBuffersOnVerify, false,                       \
           "Forces flushing of log buffers before verification.")            \
                                                                             \
-  develop(bool, G1FailOnFPError, false,                                     \
-          "When set, G1 will fail when it encounters an FP 'error', "       \
-          "so as to allow debugging")                                       \
-                                                                            \
   product(size_t, G1HeapRegionSize, 0,                                      \
           "Size of the G1 regions.")                                        \
           range(0, 32*M)                                                    \
--- a/src/share/vm/gc/g1/heapRegion.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/heapRegion.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -67,7 +67,7 @@
   // not considered dead, either because it is marked (in the mark bitmap)
   // or it was allocated after marking finished, then we add it. Otherwise
   // we can safely ignore the object.
-  if (!g1h->is_obj_dead(oop(cur), _hr)) {
+  if (!g1h->is_obj_dead(oop(cur))) {
     oop_size = oop(cur)->oop_iterate_size(_rs_scan, mr);
   } else {
     oop_size = _hr->block_size(cur);
@@ -81,7 +81,7 @@
     HeapWord* next_obj = cur + oop_size;
     while (next_obj < top) {
       // Keep filtering the remembered set.
-      if (!g1h->is_obj_dead(cur_oop, _hr)) {
+      if (!g1h->is_obj_dead(cur_oop)) {
         // Bottom lies entirely below top, so we can call the
         // non-memRegion version of oop_iterate below.
         cur_oop->oop_iterate(_rs_scan);
@@ -93,7 +93,7 @@
     }
 
     // Last object. Need to do dead-obj filtering here too.
-    if (!g1h->is_obj_dead(oop(cur), _hr)) {
+    if (!g1h->is_obj_dead(oop(cur))) {
       oop(cur)->oop_iterate(_rs_scan, mr);
     }
   }
@@ -162,8 +162,6 @@
 void HeapRegion::hr_clear(bool par, bool clear_space, bool locked) {
   assert(_humongous_start_region == NULL,
          "we should have already filtered out humongous regions");
-  assert(_end == orig_end(),
-         "we should have already filtered out humongous regions");
   assert(!in_collection_set(),
          "Should not clear heap region %u in the collection set", hrm_index());
 
@@ -213,24 +211,18 @@
   _gc_efficiency = (double) reclaimable_bytes() / region_elapsed_time_ms;
 }
 
-void HeapRegion::set_starts_humongous(HeapWord* new_top, HeapWord* new_end) {
+void HeapRegion::set_starts_humongous(HeapWord* obj_top) {
   assert(!is_humongous(), "sanity / pre-condition");
-  assert(end() == orig_end(),
-         "Should be normal before the humongous object allocation");
   assert(top() == bottom(), "should be empty");
-  assert(bottom() <= new_top && new_top <= new_end, "pre-condition");
 
   _type.set_starts_humongous();
   _humongous_start_region = this;
 
-  set_end(new_end);
-  _offsets.set_for_starts_humongous(new_top);
+  _offsets.set_for_starts_humongous(obj_top);
 }
 
 void HeapRegion::set_continues_humongous(HeapRegion* first_hr) {
   assert(!is_humongous(), "sanity / pre-condition");
-  assert(end() == orig_end(),
-         "Should be normal before the humongous object allocation");
   assert(top() == bottom(), "should be empty");
   assert(first_hr->is_starts_humongous(), "pre-condition");
 
@@ -241,18 +233,6 @@
 void HeapRegion::clear_humongous() {
   assert(is_humongous(), "pre-condition");
 
-  if (is_starts_humongous()) {
-    assert(top() <= end(), "pre-condition");
-    set_end(orig_end());
-    if (top() > end()) {
-      // at least one "continues humongous" region after it
-      set_top(end());
-    }
-  } else {
-    // continues humongous
-    assert(end() == orig_end(), "sanity");
-  }
-
   assert(capacity() == HeapRegion::GrainBytes, "pre-condition");
   _humongous_start_region = NULL;
 }
@@ -290,11 +270,6 @@
   hr_clear(false /*par*/, false /*clear_space*/);
   set_top(bottom());
   record_timestamp();
-
-  assert(mr.end() == orig_end(),
-         "Given region end address " PTR_FORMAT " should match exactly "
-         "bottom plus one region size, i.e. " PTR_FORMAT,
-         p2i(mr.end()), p2i(orig_end()));
 }
 
 CompactibleSpace* HeapRegion::next_compaction_space() const {
@@ -832,7 +807,14 @@
     _offsets.verify();
   }
 
-  if (p != top()) {
+  if (is_region_humongous) {
+    oop obj = oop(this->humongous_start_region()->bottom());
+    if ((HeapWord*)obj > bottom() || (HeapWord*)obj + obj->size() < bottom()) {
+      gclog_or_tty->print_cr("this humongous region is not part of its' humongous object " PTR_FORMAT, p2i(obj));
+    }
+  }
+
+  if (!is_region_humongous && p != top()) {
     gclog_or_tty->print_cr("end of last object " PTR_FORMAT " "
                            "does not match top " PTR_FORMAT, p2i(p), p2i(top()));
     *failures = true;
@@ -840,7 +822,6 @@
   }
 
   HeapWord* the_end = end();
-  assert(p == top(), "it should still hold");
   // Do some extra BOT consistency checking for addresses in the
   // range [top, end). BOT look-ups in this range should yield
   // top. No point in doing that if top == end (there's nothing there).
@@ -931,6 +912,7 @@
 }
 
 void G1OffsetTableContigSpace::set_end(HeapWord* new_end) {
+  assert(new_end == _bottom + HeapRegion::GrainWords, "set_end should only ever be set to _bottom + HeapRegion::GrainWords");
   Space::set_end(new_end);
   _offsets.resize(new_end - bottom());
 }
--- a/src/share/vm/gc/g1/heapRegion.hpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/heapRegion.hpp	Fri Nov 13 10:35:26 2015 -0800
@@ -43,6 +43,15 @@
 // The solution is to remove this method from the definition
 // of a Space.
 
+// Each heap region is self contained. top() and end() can never
+// be set beyond the end of the region. For humongous objects,
+// the first region is a StartsHumongous region. If the humongous
+// object is larger than a heap region, the following regions will
+// be of type ContinuesHumongous. In this case the top() of the
+// StartHumongous region and all ContinuesHumongous regions except
+// the last will point to their own end. For the last ContinuesHumongous
+// region, top() will equal the object's top.
+
 class G1CollectedHeap;
 class HeapRegionRemSet;
 class HeapRegionRemSetIterator;
@@ -389,8 +398,6 @@
   size_t garbage_bytes() {
     size_t used_at_mark_start_bytes =
       (prev_top_at_mark_start() - bottom()) * HeapWordSize;
-    assert(used_at_mark_start_bytes >= marked_bytes(),
-           "Can't mark more than we have.");
     return used_at_mark_start_bytes - marked_bytes();
   }
 
@@ -409,7 +416,6 @@
 
   void add_to_marked_bytes(size_t incr_bytes) {
     _next_marked_bytes = _next_marked_bytes + incr_bytes;
-    assert(_next_marked_bytes <= used(), "invariant" );
   }
 
   void zero_marked_bytes()      {
@@ -445,57 +451,13 @@
     return _humongous_start_region;
   }
 
-  // Return the number of distinct regions that are covered by this region:
-  // 1 if the region is not humongous, >= 1 if the region is humongous.
-  uint region_num() const {
-    if (!is_humongous()) {
-      return 1U;
-    } else {
-      assert(is_starts_humongous(), "doesn't make sense on HC regions");
-      assert(capacity() % HeapRegion::GrainBytes == 0, "sanity");
-      return (uint) (capacity() >> HeapRegion::LogOfHRGrainBytes);
-    }
-  }
-
-  // Return the index + 1 of the last HC regions that's associated
-  // with this HS region.
-  uint last_hc_index() const {
-    assert(is_starts_humongous(), "don't call this otherwise");
-    return hrm_index() + region_num();
-  }
-
-  // Same as Space::is_in_reserved, but will use the original size of the region.
-  // The original size is different only for start humongous regions. They get
-  // their _end set up to be the end of the last continues region of the
-  // corresponding humongous object.
-  bool is_in_reserved_raw(const void* p) const {
-    return _bottom <= p && p < orig_end();
-  }
-
   // Makes the current region be a "starts humongous" region, i.e.,
   // the first region in a series of one or more contiguous regions
-  // that will contain a single "humongous" object. The two parameters
-  // are as follows:
+  // that will contain a single "humongous" object.
   //
-  // new_top : The new value of the top field of this region which
-  // points to the end of the humongous object that's being
-  // allocated. If there is more than one region in the series, top
-  // will lie beyond this region's original end field and on the last
-  // region in the series.
-  //
-  // new_end : The new value of the end field of this region which
-  // points to the end of the last region in the series. If there is
-  // one region in the series (namely: this one) end will be the same
-  // as the original end of this region.
-  //
-  // Updating top and end as described above makes this region look as
-  // if it spans the entire space taken up by all the regions in the
-  // series and an single allocation moved its top to new_top. This
-  // ensures that the space (capacity / allocated) taken up by all
-  // humongous regions can be calculated by just looking at the
-  // "starts humongous" regions and by ignoring the "continues
-  // humongous" regions.
-  void set_starts_humongous(HeapWord* new_top, HeapWord* new_end);
+  // obj_top : points to the end of the humongous object that's being
+  // allocated.
+  void set_starts_humongous(HeapWord* obj_top);
 
   // Makes the current region be a "continues humongous'
   // region. first_hr is the "start humongous" region of the series
@@ -566,9 +528,6 @@
   void set_next_dirty_cards_region(HeapRegion* hr) { _next_dirty_cards_region = hr; }
   bool is_on_dirty_cards_region_list() const { return get_next_dirty_cards_region() != NULL; }
 
-  // For the start region of a humongous sequence, it's original end().
-  HeapWord* orig_end() const { return _bottom + GrainWords; }
-
   // Reset HR stuff to default values.
   void hr_clear(bool par, bool clear_space, bool locked = false);
   void par_clear();
@@ -614,8 +573,8 @@
   bool is_marked() { return _prev_top_at_mark_start != bottom(); }
 
   void reset_during_compaction() {
-    assert(is_starts_humongous(),
-           "should only be called for starts humongous regions");
+    assert(is_humongous(),
+           "should only be called for humongous regions");
 
     zero_marked_bytes();
     init_top_at_mark_start();
--- a/src/share/vm/gc/g1/heapRegion.inline.hpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/heapRegion.inline.hpp	Fri Nov 13 10:35:26 2015 -0800
@@ -115,6 +115,11 @@
 inline bool
 HeapRegion::block_is_obj(const HeapWord* p) const {
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
+
+  if (!this->is_in(p)) {
+    assert(is_continues_humongous(), "This case can only happen for humongous regions");
+    return (p == humongous_start_region()->bottom());
+  }
   if (ClassUnloadingWithConcurrentMark) {
     return !g1h->is_obj_dead(oop(p), this);
   }
@@ -176,10 +181,6 @@
   _prev_top_at_mark_start = _next_top_at_mark_start;
   _prev_marked_bytes = _next_marked_bytes;
   _next_marked_bytes = 0;
-
-  assert(_prev_marked_bytes <=
-         (size_t) pointer_delta(prev_top_at_mark_start(), bottom()) *
-         HeapWordSize, "invariant");
 }
 
 inline void HeapRegion::note_start_of_copying(bool during_initial_mark) {
--- a/src/share/vm/gc/g1/heapRegionManager.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/heapRegionManager.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -343,63 +343,18 @@
       continue;
     }
     HeapRegion* r = _regions.get_by_index(index);
-    // We'll ignore "continues humongous" regions (we'll process them
-    // when we come across their corresponding "start humongous"
-    // region) and regions already claimed.
+    // We'll ignore regions already claimed.
     // However, if the iteration is specified as concurrent, the values for
     // is_starts_humongous and is_continues_humongous can not be trusted,
     // and we should just blindly iterate over regions regardless of their
     // humongous status.
-    if (hrclaimer->is_region_claimed(index) || (!concurrent && r->is_continues_humongous())) {
+    if (hrclaimer->is_region_claimed(index)) {
       continue;
     }
     // OK, try to claim it
     if (!hrclaimer->claim_region(index)) {
       continue;
     }
-    // Success!
-    // As mentioned above, special treatment of humongous regions can only be
-    // done if we are iterating non-concurrently.
-    if (!concurrent && r->is_starts_humongous()) {
-      // If the region is "starts humongous" we'll iterate over its
-      // "continues humongous" first; in fact we'll do them
-      // first. The order is important. In one case, calling the
-      // closure on the "starts humongous" region might de-allocate
-      // and clear all its "continues humongous" regions and, as a
-      // result, we might end up processing them twice. So, we'll do
-      // them first (note: most closures will ignore them anyway) and
-      // then we'll do the "starts humongous" region.
-      for (uint ch_index = index + 1; ch_index < index + r->region_num(); ch_index++) {
-        HeapRegion* chr = _regions.get_by_index(ch_index);
-
-        assert(chr->is_continues_humongous(), "Must be humongous region");
-        assert(chr->humongous_start_region() == r,
-               "Must work on humongous continuation of the original start region "
-               PTR_FORMAT ", but is " PTR_FORMAT, p2i(r), p2i(chr));
-        assert(!hrclaimer->is_region_claimed(ch_index),
-               "Must not have been claimed yet because claiming of humongous continuation first claims the start region");
-
-        // Claim the region so no other worker tries to process the region. When a worker processes a
-        // starts_humongous region it may also process the associated continues_humongous regions.
-        // The continues_humongous regions can be changed to free regions. Unless this worker claims
-        // all of these regions, other workers might try claim and process these newly free regions.
-        bool claim_result = hrclaimer->claim_region(ch_index);
-        guarantee(claim_result, "We should always be able to claim the continuesHumongous part of the humongous object");
-
-        bool res2 = blk->doHeapRegion(chr);
-        if (res2) {
-          return;
-        }
-
-        // Right now, this holds (i.e., no closure that actually
-        // does something with "continues humongous" regions
-        // clears them). We might have to weaken it in the future,
-        // but let's leave these two asserts here for extra safety.
-        assert(chr->is_continues_humongous(), "should still be the case");
-        assert(chr->humongous_start_region() == r, "sanity");
-      }
-    }
-
     bool res = blk->doHeapRegion(r);
     if (res) {
       return;
@@ -508,11 +463,7 @@
     // this method may be called, we have only completed allocation of the regions,
     // but not put into a region set.
     prev_committed = true;
-    if (hr->is_starts_humongous()) {
-      prev_end = hr->orig_end();
-    } else {
-      prev_end = hr->end();
-    }
+    prev_end = hr->end();
   }
   for (uint i = _allocated_heapregions_length; i < max_length(); i++) {
     guarantee(_regions.get_by_index(i) == NULL, "invariant i: %u", i);
--- a/src/share/vm/gc/g1/heapRegionManager.hpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/heapRegionManager.hpp	Fri Nov 13 10:35:26 2015 -0800
@@ -150,6 +150,10 @@
   // is valid.
   inline HeapRegion* at(uint index) const;
 
+  // Return the next region (by index) that is part of the same
+  // humongous object that hr is part of.
+  inline HeapRegion* next_region_in_humongous(HeapRegion* hr) const;
+
   // If addr is within the committed space return its corresponding
   // HeapRegion, otherwise return NULL.
   inline HeapRegion* addr_to_region(HeapWord* addr) const;
--- a/src/share/vm/gc/g1/heapRegionManager.inline.hpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/heapRegionManager.inline.hpp	Fri Nov 13 10:35:26 2015 -0800
@@ -47,6 +47,18 @@
   return hr;
 }
 
+inline HeapRegion* HeapRegionManager::next_region_in_humongous(HeapRegion* hr) const {
+  uint index = hr->hrm_index();
+  assert(is_available(index), "pre-condition");
+  assert(hr->is_humongous(), "next_region_in_humongous should only be called for a humongous region.");
+  index++;
+  if (index < max_length() && is_available(index) && at(index)->is_continues_humongous()) {
+    return at(index);
+  } else {
+    return NULL;
+  }
+}
+
 inline void HeapRegionManager::insert_into_free_list(HeapRegion* hr) {
   _free_list.add_ordered(hr);
 }
--- a/src/share/vm/gc/g1/heapRegionRemSet.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/heapRegionRemSet.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -89,14 +89,6 @@
     // Must make this robust in case "from" is not in "_hr", because of
     // concurrency.
 
-    if (G1TraceHeapRegionRememberedSet) {
-      gclog_or_tty->print_cr("    PRT::Add_reference_work(" PTR_FORMAT "->" PTR_FORMAT ").",
-                             p2i(from),
-                             UseCompressedOops
-                             ? p2i(oopDesc::load_decode_heap_oop((narrowOop*)from))
-                             : p2i(oopDesc::load_decode_heap_oop((oop*)from)));
-    }
-
     HeapRegion* loc_hr = hr();
     // If the test below fails, then this table was reused concurrently
     // with this operation.  This is OK, since the old table was coarsened,
@@ -105,7 +97,7 @@
     // now reused for the corresponding start humongous region, we need to
     // make sure that we detect this. Thus, we call is_in_reserved_raw()
     // instead of just is_in_reserved() here.
-    if (loc_hr->is_in_reserved_raw(from)) {
+    if (loc_hr->is_in_reserved(from)) {
       size_t hw_offset = pointer_delta((HeapWord*)from, loc_hr->bottom());
       CardIdx_t from_card = (CardIdx_t)
           hw_offset >> (CardTableModRefBS::card_shift - LogHeapWordSize);
@@ -408,39 +400,19 @@
 void OtherRegionsTable::add_reference(OopOrNarrowOopStar from, uint tid) {
   uint cur_hrm_ind = _hr->hrm_index();
 
-  if (G1TraceHeapRegionRememberedSet) {
-    gclog_or_tty->print_cr("ORT::add_reference_work(" PTR_FORMAT "->" PTR_FORMAT ").",
-                                                    p2i(from),
-                                                    UseCompressedOops
-                                                    ? p2i(oopDesc::load_decode_heap_oop((narrowOop*)from))
-                                                    : p2i(oopDesc::load_decode_heap_oop((oop*)from)));
-  }
-
   int from_card = (int)(uintptr_t(from) >> CardTableModRefBS::card_shift);
 
-  if (G1TraceHeapRegionRememberedSet) {
-    gclog_or_tty->print_cr("Table for [" PTR_FORMAT "...): card %d (cache = %d)",
-                  p2i(_hr->bottom()), from_card,
-                  FromCardCache::at(tid, cur_hrm_ind));
-  }
-
   if (FromCardCache::contains_or_replace(tid, cur_hrm_ind, from_card)) {
-    if (G1TraceHeapRegionRememberedSet) {
-      gclog_or_tty->print_cr("  from-card cache hit.");
-    }
     assert(contains_reference(from), "We just added it!");
     return;
   }
 
   // Note that this may be a continued H region.
-  HeapRegion* from_hr = _g1h->heap_region_containing_raw(from);
+  HeapRegion* from_hr = _g1h->heap_region_containing(from);
   RegionIdx_t from_hrm_ind = (RegionIdx_t) from_hr->hrm_index();
 
   // If the region is already coarsened, return.
   if (_coarse_map.at(from_hrm_ind)) {
-    if (G1TraceHeapRegionRememberedSet) {
-      gclog_or_tty->print_cr("  coarse map hit.");
-    }
     assert(contains_reference(from), "We just added it!");
     return;
   }
@@ -462,27 +434,8 @@
              "Must be in range.");
       if (G1HRRSUseSparseTable &&
           _sparse_table.add_card(from_hrm_ind, card_index)) {
-        if (G1RecordHRRSOops) {
-          HeapRegionRemSet::record(_hr, from);
-          if (G1TraceHeapRegionRememberedSet) {
-            gclog_or_tty->print("   Added card " PTR_FORMAT " to region "
-                                "[" PTR_FORMAT "...) for ref " PTR_FORMAT ".\n",
-                                align_size_down(uintptr_t(from),
-                                                CardTableModRefBS::card_size),
-                                p2i(_hr->bottom()), p2i(from));
-          }
-        }
-        if (G1TraceHeapRegionRememberedSet) {
-          gclog_or_tty->print_cr("   added card to sparse table.");
-        }
         assert(contains_reference_locked(from), "We just added it!");
         return;
-      } else {
-        if (G1TraceHeapRegionRememberedSet) {
-          gclog_or_tty->print_cr("   [tid %u] sparse table entry "
-                        "overflow(f: %d, t: %u)",
-                        tid, from_hrm_ind, cur_hrm_ind);
-        }
       }
 
       if (_n_fine_entries == _max_fine_entries) {
@@ -531,17 +484,6 @@
   assert(prt != NULL, "Inv");
 
   prt->add_reference(from);
-
-  if (G1RecordHRRSOops) {
-    HeapRegionRemSet::record(_hr, from);
-    if (G1TraceHeapRegionRememberedSet) {
-      gclog_or_tty->print("Added card " PTR_FORMAT " to region "
-                          "[" PTR_FORMAT "...) for ref " PTR_FORMAT ".\n",
-                          align_size_down(uintptr_t(from),
-                                          CardTableModRefBS::card_size),
-                          p2i(_hr->bottom()), p2i(from));
-    }
-  }
   assert(contains_reference(from), "We just added it!");
 }
 
@@ -606,13 +548,6 @@
   if (!_coarse_map.at(max_hrm_index)) {
     _coarse_map.at_put(max_hrm_index, true);
     _n_coarse_entries++;
-    if (G1TraceHeapRegionRememberedSet) {
-      gclog_or_tty->print("Coarsened entry in region [" PTR_FORMAT "...] "
-                 "for region [" PTR_FORMAT "...] (" SIZE_FORMAT " coarse entries).\n",
-                 p2i(_hr->bottom()),
-                 p2i(max->hr()->bottom()),
-                 _n_coarse_entries);
-    }
   }
 
   // Unsplice.
@@ -786,7 +721,7 @@
 }
 
 bool OtherRegionsTable::contains_reference_locked(OopOrNarrowOopStar from) const {
-  HeapRegion* hr = _g1h->heap_region_containing_raw(from);
+  HeapRegion* hr = _g1h->heap_region_containing(from);
   RegionIdx_t hr_ind = (RegionIdx_t) hr->hrm_index();
   // Is this region in the coarse map?
   if (_coarse_map.at(hr_ind)) return true;
@@ -1071,99 +1006,6 @@
   return false;
 }
 
-
-
-OopOrNarrowOopStar* HeapRegionRemSet::_recorded_oops = NULL;
-HeapWord**          HeapRegionRemSet::_recorded_cards = NULL;
-HeapRegion**        HeapRegionRemSet::_recorded_regions = NULL;
-int                 HeapRegionRemSet::_n_recorded = 0;
-
-HeapRegionRemSet::Event* HeapRegionRemSet::_recorded_events = NULL;
-int*         HeapRegionRemSet::_recorded_event_index = NULL;
-int          HeapRegionRemSet::_n_recorded_events = 0;
-
-void HeapRegionRemSet::record(HeapRegion* hr, OopOrNarrowOopStar f) {
-  if (_recorded_oops == NULL) {
-    assert(_n_recorded == 0
-           && _recorded_cards == NULL
-           && _recorded_regions == NULL,
-           "Inv");
-    _recorded_oops    = NEW_C_HEAP_ARRAY(OopOrNarrowOopStar, MaxRecorded, mtGC);
-    _recorded_cards   = NEW_C_HEAP_ARRAY(HeapWord*,          MaxRecorded, mtGC);
-    _recorded_regions = NEW_C_HEAP_ARRAY(HeapRegion*,        MaxRecorded, mtGC);
-  }
-  if (_n_recorded == MaxRecorded) {
-    gclog_or_tty->print_cr("Filled up 'recorded' (%d).", MaxRecorded);
-  } else {
-    _recorded_cards[_n_recorded] =
-      (HeapWord*)align_size_down(uintptr_t(f),
-                                 CardTableModRefBS::card_size);
-    _recorded_oops[_n_recorded] = f;
-    _recorded_regions[_n_recorded] = hr;
-    _n_recorded++;
-  }
-}
-
-void HeapRegionRemSet::record_event(Event evnt) {
-  if (!G1RecordHRRSEvents) return;
-
-  if (_recorded_events == NULL) {
-    assert(_n_recorded_events == 0
-           && _recorded_event_index == NULL,
-           "Inv");
-    _recorded_events = NEW_C_HEAP_ARRAY(Event, MaxRecordedEvents, mtGC);
-    _recorded_event_index = NEW_C_HEAP_ARRAY(int, MaxRecordedEvents, mtGC);
-  }
-  if (_n_recorded_events == MaxRecordedEvents) {
-    gclog_or_tty->print_cr("Filled up 'recorded_events' (%d).", MaxRecordedEvents);
-  } else {
-    _recorded_events[_n_recorded_events] = evnt;
-    _recorded_event_index[_n_recorded_events] = _n_recorded;
-    _n_recorded_events++;
-  }
-}
-
-void HeapRegionRemSet::print_event(outputStream* str, Event evnt) {
-  switch (evnt) {
-  case Event_EvacStart:
-    str->print("Evac Start");
-    break;
-  case Event_EvacEnd:
-    str->print("Evac End");
-    break;
-  case Event_RSUpdateEnd:
-    str->print("RS Update End");
-    break;
-  }
-}
-
-void HeapRegionRemSet::print_recorded() {
-  int cur_evnt = 0;
-  Event cur_evnt_kind = Event_illegal;
-  int cur_evnt_ind = 0;
-  if (_n_recorded_events > 0) {
-    cur_evnt_kind = _recorded_events[cur_evnt];
-    cur_evnt_ind = _recorded_event_index[cur_evnt];
-  }
-
-  for (int i = 0; i < _n_recorded; i++) {
-    while (cur_evnt < _n_recorded_events && i == cur_evnt_ind) {
-      gclog_or_tty->print("Event: ");
-      print_event(gclog_or_tty, cur_evnt_kind);
-      gclog_or_tty->cr();
-      cur_evnt++;
-      if (cur_evnt < MaxRecordedEvents) {
-        cur_evnt_kind = _recorded_events[cur_evnt];
-        cur_evnt_ind = _recorded_event_index[cur_evnt];
-      }
-    }
-    gclog_or_tty->print("Added card " PTR_FORMAT " to region [" PTR_FORMAT "...]"
-                        " for ref " PTR_FORMAT ".\n",
-                        p2i(_recorded_cards[i]), p2i(_recorded_regions[i]->bottom()),
-                        p2i(_recorded_oops[i]));
-  }
-}
-
 void HeapRegionRemSet::reset_for_cleanup_tasks() {
   SparsePRT::reset_for_cleanup_tasks();
 }
--- a/src/share/vm/gc/g1/heapRegionRemSet.hpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/heapRegionRemSet.hpp	Fri Nov 13 10:35:26 2015 -0800
@@ -220,11 +220,6 @@
   friend class VMStructs;
   friend class HeapRegionRemSetIterator;
 
-public:
-  enum Event {
-    Event_EvacStart, Event_EvacEnd, Event_RSUpdateEnd, Event_illegal
-  };
-
 private:
   G1BlockOffsetSharedArray* _bosa;
 
@@ -240,21 +235,6 @@
   volatile ParIterState _iter_state;
   volatile size_t _iter_claimed;
 
-  // Unused unless G1RecordHRRSOops is true.
-
-  static const int MaxRecorded = 1000000;
-  static OopOrNarrowOopStar* _recorded_oops;
-  static HeapWord**          _recorded_cards;
-  static HeapRegion**        _recorded_regions;
-  static int                 _n_recorded;
-
-  static const int MaxRecordedEvents = 1000;
-  static Event*       _recorded_events;
-  static int*         _recorded_event_index;
-  static int          _n_recorded_events;
-
-  static void print_event(outputStream* str, Event evnt);
-
 public:
   HeapRegionRemSet(G1BlockOffsetSharedArray* bosa, HeapRegion* hr);
 
@@ -404,10 +384,6 @@
   }
 #endif
 
-  static void record(HeapRegion* hr, OopOrNarrowOopStar f);
-  static void print_recorded();
-  static void record_event(Event evnt);
-
   // These are wrappers for the similarly-named methods on
   // SparsePRT. Look at sparsePRT.hpp for more details.
   static void reset_for_cleanup_tasks();
--- a/src/share/vm/gc/g1/heapRegionSet.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/heapRegionSet.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -29,12 +29,6 @@
 
 uint FreeRegionList::_unrealistically_long_length = 0;
 
-void HeapRegionSetBase::fill_in_ext_msg(hrs_ext_msg* msg, const char* message) {
-  msg->append("[%s] %s ln: %u cy: " SIZE_FORMAT,
-              name(), message, length(), total_capacity_bytes());
-  fill_in_ext_msg_extra(msg);
-}
-
 #ifndef PRODUCT
 void HeapRegionSetBase::verify_region(HeapRegion* hr) {
   assert(hr->containing_set() == this, "Inconsistent containing set for %u", hr->hrm_index());
@@ -55,16 +49,15 @@
   // verification might fail and send us on a wild goose chase.
   check_mt_safety();
 
-  guarantee(( is_empty() && length() == 0 && total_capacity_bytes() == 0) ||
-            (!is_empty() && length() > 0  && total_capacity_bytes() > 0) ,
-            "%s", hrs_ext_msg(this, "invariant").buffer());
+  guarantee_heap_region_set(( is_empty() && length() == 0 && total_capacity_bytes() == 0) ||
+                            (!is_empty() && length() > 0  && total_capacity_bytes() > 0) ,
+                            "invariant");
 }
 
 void HeapRegionSetBase::verify_start() {
   // See comment in verify() about MT safety and verification.
   check_mt_safety();
-  assert(!_verify_in_progress,
-         "%s", hrs_ext_msg(this, "verification should not be in progress").buffer());
+  assert_heap_region_set(!_verify_in_progress, "verification should not be in progress");
 
   // Do the basic verification first before we do the checks over the regions.
   HeapRegionSetBase::verify();
@@ -75,8 +68,7 @@
 void HeapRegionSetBase::verify_end() {
   // See comment in verify() about MT safety and verification.
   check_mt_safety();
-  assert(_verify_in_progress,
-         "%s", hrs_ext_msg(this, "verification should be in progress").buffer());
+  assert_heap_region_set(_verify_in_progress, "verification should be in progress");
 
   _verify_in_progress = false;
 }
@@ -104,10 +96,6 @@
   _unrealistically_long_length = len;
 }
 
-void FreeRegionList::fill_in_ext_msg_extra(hrs_ext_msg* msg) {
-  msg->append(" hd: " PTR_FORMAT " tl: " PTR_FORMAT, p2i(_head), p2i(_tail));
-}
-
 void FreeRegionList::remove_all() {
   check_mt_safety();
   verify_optional();
@@ -151,7 +139,7 @@
   #endif // ASSERT
 
   if (is_empty()) {
-    assert(length() == 0 && _tail == NULL, "%s", hrs_ext_msg(this, "invariant").buffer());
+    assert_free_region_list(length() == 0 && _tail == NULL, "invariant");
     _head = from_list->_head;
     _tail = from_list->_tail;
   } else {
@@ -198,8 +186,8 @@
 
 void FreeRegionList::remove_starting_at(HeapRegion* first, uint num_regions) {
   check_mt_safety();
-  assert(num_regions >= 1, "%s", hrs_ext_msg(this, "pre-condition").buffer());
-  assert(!is_empty(), "%s", hrs_ext_msg(this, "pre-condition").buffer());
+  assert_free_region_list(num_regions >= 1, "pre-condition");
+  assert_free_region_list(!is_empty(), "pre-condition");
 
   verify_optional();
   DEBUG_ONLY(uint old_length = length();)
@@ -212,25 +200,25 @@
     HeapRegion* prev = curr->prev();
 
     assert(count < num_regions,
-           "%s", hrs_err_msg("[%s] should not come across more regions "
-                             "pending for removal than num_regions: %u",
-                             name(), num_regions).buffer());
+           "[%s] should not come across more regions "
+           "pending for removal than num_regions: %u",
+           name(), num_regions);
 
     if (prev == NULL) {
-      assert(_head == curr, "%s", hrs_ext_msg(this, "invariant").buffer());
+      assert_free_region_list(_head == curr, "invariant");
       _head = next;
     } else {
-      assert(_head != curr, "%s", hrs_ext_msg(this, "invariant").buffer());
+      assert_free_region_list(_head != curr, "invariant");
       prev->set_next(next);
     }
     if (next == NULL) {
-      assert(_tail == curr, "%s", hrs_ext_msg(this, "invariant").buffer());
+      assert_free_region_list(_tail == curr, "invariant");
       _tail = prev;
     } else {
-      assert(_tail != curr, "%s", hrs_ext_msg(this, "invariant").buffer());
+      assert_free_region_list(_tail != curr, "invariant");
       next->set_prev(prev);
     }
-    if (_last = curr) {
+    if (_last == curr) {
       _last = NULL;
     }
 
@@ -243,12 +231,12 @@
   }
 
   assert(count == num_regions,
-         "%s", hrs_err_msg("[%s] count: %u should be == num_regions: %u",
-                           name(), count, num_regions).buffer());
+         "[%s] count: %u should be == num_regions: %u",
+         name(), count, num_regions);
   assert(length() + num_regions == old_length,
-         "%s", hrs_err_msg("[%s] new length should be consistent "
-                           "new length: %u old length: %u num_regions: %u",
-                           name(), length(), old_length, num_regions).buffer());
+         "[%s] new length should be consistent "
+         "new length: %u old length: %u num_regions: %u",
+         name(), length(), old_length, num_regions);
 
   verify_optional();
 }
@@ -305,8 +293,8 @@
 
     count++;
     guarantee(count < _unrealistically_long_length,
-        "%s", hrs_err_msg("[%s] the calculated length: %u seems very long, is there maybe a cycle? curr: " PTR_FORMAT " prev0: " PTR_FORMAT " " "prev1: " PTR_FORMAT " length: %u",
-              name(), count, p2i(curr), p2i(prev0), p2i(prev1), length()).buffer());
+              "[%s] the calculated length: %u seems very long, is there maybe a cycle? curr: " PTR_FORMAT " prev0: " PTR_FORMAT " " "prev1: " PTR_FORMAT " length: %u",
+              name(), count, p2i(curr), p2i(prev0), p2i(prev1), length());
 
     if (curr->next() != NULL) {
       guarantee(curr->next()->prev() == curr, "Next or prev pointers messed up");
--- a/src/share/vm/gc/g1/heapRegionSet.hpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/heapRegionSet.hpp	Fri Nov 13 10:35:26 2015 -0800
@@ -27,9 +27,24 @@
 
 #include "gc/g1/heapRegion.hpp"
 
-// Large buffer for some cases where the output might be larger than normal.
-#define HRS_ERR_MSG_BUFSZ 512
-typedef FormatBuffer<HRS_ERR_MSG_BUFSZ> hrs_err_msg;
+#define assert_heap_region_set(p, message)                        \
+  do {                                                            \
+    assert((p), "[%s] %s ln: %u cy: " SIZE_FORMAT,                \
+           name(), message, length(), total_capacity_bytes());    \
+  } while (0)
+
+#define guarantee_heap_region_set(p, message)                     \
+  do {                                                            \
+    guarantee((p), "[%s] %s ln: %u cy: " SIZE_FORMAT,             \
+              name(), message, length(), total_capacity_bytes()); \
+  } while (0)
+
+#define assert_free_region_list(p, message)                                              \
+  do {                                                                                   \
+    assert((p), "[%s] %s ln: %u cy: " SIZE_FORMAT " hd: " PTR_FORMAT " tl: " PTR_FORMAT, \
+           name(), message, length(), total_capacity_bytes(), p2i(_head), p2i(_tail));   \
+  } while (0)
+
 
 // Set verification will be forced either if someone defines
 // HEAP_REGION_SET_FORCE_VERIFY to be 1, or in builds in which
@@ -38,8 +53,6 @@
 #define HEAP_REGION_SET_FORCE_VERIFY defined(ASSERT)
 #endif // HEAP_REGION_SET_FORCE_VERIFY
 
-class hrs_ext_msg;
-
 class HRSMtSafeChecker : public CHeapObj<mtGC> {
 public:
   virtual void check() = 0;
@@ -112,8 +125,6 @@
     }
   }
 
-  virtual void fill_in_ext_msg_extra(hrs_ext_msg* msg) { }
-
   HeapRegionSetBase(const char* name, bool humongous, bool free, HRSMtSafeChecker* mt_safety_checker);
 
 public:
@@ -135,11 +146,6 @@
   // from the set and tags the region appropriately.
   inline void remove(HeapRegion* hr);
 
-  // fill_in_ext_msg() writes the the values of the set's attributes
-  // in the custom err_msg (hrs_ext_msg). fill_in_ext_msg_extra()
-  // allows subclasses to append further information.
-  void fill_in_ext_msg(hrs_ext_msg* msg, const char* message);
-
   virtual void verify();
   void verify_start();
   void verify_next_region(HeapRegion* hr);
@@ -156,24 +162,13 @@
   virtual void print_on(outputStream* out, bool print_contents = false);
 };
 
-// Customized err_msg for heap region sets. Apart from a
-// assert/guarantee-specific message it also prints out the values of
-// the fields of the associated set. This can be very helpful in
-// diagnosing failures.
-class hrs_ext_msg : public hrs_err_msg {
-public:
-  hrs_ext_msg(HeapRegionSetBase* set, const char* message) : hrs_err_msg("%s", "") {
-    set->fill_in_ext_msg(this, message);
-  }
-};
-
-#define hrs_assert_sets_match(_set1_, _set2_)                                 \
-  do {                                                                        \
-    assert(((_set1_)->regions_humongous() ==                                  \
-                                            (_set2_)->regions_humongous()) && \
-           ((_set1_)->regions_free() == (_set2_)->regions_free()),            \
-           hrs_err_msg("the contents of set %s and set %s should match",      \
-                       (_set1_)->name(), (_set2_)->name()));                  \
+#define hrs_assert_sets_match(_set1_, _set2_)                                  \
+  do {                                                                         \
+    assert(((_set1_)->regions_humongous() == (_set2_)->regions_humongous()) && \
+           ((_set1_)->regions_free() == (_set2_)->regions_free()),             \
+           "the contents of set %s and set %s should match",                   \
+           (_set1_)->name(),                                                   \
+           (_set2_)->name());                                                  \
   } while (0)
 
 // This class represents heap region sets whose members are not
@@ -215,8 +210,6 @@
   inline HeapRegion* remove_from_tail_impl();
 
 protected:
-  virtual void fill_in_ext_msg_extra(hrs_ext_msg* msg);
-
   // See the comment for HeapRegionSetBase::clear()
   virtual void clear();
 
--- a/src/share/vm/gc/g1/heapRegionSet.inline.hpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/heapRegionSet.inline.hpp	Fri Nov 13 10:35:26 2015 -0800
@@ -29,9 +29,9 @@
 
 inline void HeapRegionSetBase::add(HeapRegion* hr) {
   check_mt_safety();
-  assert(hr->containing_set() == NULL, "%s", hrs_ext_msg(this, "should not already have a containing set %u").buffer());
-  assert(hr->next() == NULL, "%s", hrs_ext_msg(this, "should not already be linked").buffer());
-  assert(hr->prev() == NULL, "%s", hrs_ext_msg(this, "should not already be linked").buffer());
+  assert_heap_region_set(hr->containing_set() == NULL, "should not already have a containing set");
+  assert_heap_region_set(hr->next() == NULL, "should not already be linked");
+  assert_heap_region_set(hr->prev() == NULL, "should not already be linked");
 
   _count.increment(1u, hr->capacity());
   hr->set_containing_set(this);
@@ -41,18 +41,18 @@
 inline void HeapRegionSetBase::remove(HeapRegion* hr) {
   check_mt_safety();
   verify_region(hr);
-  assert(hr->next() == NULL, "%s", hrs_ext_msg(this, "should already be unlinked").buffer());
-  assert(hr->prev() == NULL, "%s", hrs_ext_msg(this, "should already be unlinked").buffer());
+  assert_heap_region_set(hr->next() == NULL, "should already be unlinked");
+  assert_heap_region_set(hr->prev() == NULL, "should already be unlinked");
 
   hr->set_containing_set(NULL);
-  assert(_count.length() > 0, "%s", hrs_ext_msg(this, "pre-condition").buffer());
+  assert_heap_region_set(_count.length() > 0, "pre-condition");
   _count.decrement(1u, hr->capacity());
 }
 
 inline void FreeRegionList::add_ordered(HeapRegion* hr) {
-  assert((length() == 0 && _head == NULL && _tail == NULL && _last == NULL) ||
-         (length() >  0 && _head != NULL && _tail != NULL),
-         "%s", hrs_ext_msg(this, "invariant").buffer());
+  assert_free_region_list((length() == 0 && _head == NULL && _tail == NULL && _last == NULL) ||
+                          (length() >  0 && _head != NULL && _tail != NULL),
+                          "invariant");
   // add() will verify the region and check mt safety.
   add(hr);
 
@@ -128,8 +128,7 @@
   if (is_empty()) {
     return NULL;
   }
-  assert(length() > 0 && _head != NULL && _tail != NULL,
-         "%s", hrs_ext_msg(this, "invariant").buffer());
+  assert_free_region_list(length() > 0 && _head != NULL && _tail != NULL, "invariant");
 
   HeapRegion* hr;
 
--- a/src/share/vm/gc/g1/ptrQueue.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/ptrQueue.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -30,24 +30,25 @@
 #include "runtime/mutexLocker.hpp"
 #include "runtime/thread.inline.hpp"
 
-PtrQueue::PtrQueue(PtrQueueSet* qset, bool perm, bool active) :
+PtrQueue::PtrQueue(PtrQueueSet* qset, bool permanent, bool active) :
   _qset(qset), _buf(NULL), _index(0), _sz(0), _active(active),
-  _perm(perm), _lock(NULL)
+  _permanent(permanent), _lock(NULL)
 {}
 
 PtrQueue::~PtrQueue() {
-  assert(_perm || (_buf == NULL), "queue must be flushed before delete");
+  assert(_permanent || (_buf == NULL), "queue must be flushed before delete");
 }
 
 void PtrQueue::flush_impl() {
-  if (!_perm && _buf != NULL) {
+  if (!_permanent && _buf != NULL) {
     if (_index == _sz) {
       // No work to do.
       qset()->deallocate_buffer(_buf);
     } else {
       // We must NULL out the unused entries, then enqueue.
-      for (size_t i = 0; i < _index; i += oopSize) {
-        _buf[byte_index_to_index((int)i)] = NULL;
+      size_t limit = byte_index_to_index(_index);
+      for (size_t i = 0; i < limit; ++i) {
+        _buf[i] = NULL;
       }
       qset()->enqueue_complete_buffer(_buf);
     }
@@ -66,8 +67,8 @@
   }
 
   assert(_index > 0, "postcondition");
-  _index -= oopSize;
-  _buf[byte_index_to_index((int)_index)] = ptr;
+  _index -= sizeof(void*);
+  _buf[byte_index_to_index(_index)] = ptr;
   assert(_index <= _sz, "Invariant.");
 }
 
@@ -100,6 +101,26 @@
   _fl_owner = this;
 }
 
+PtrQueueSet::~PtrQueueSet() {
+  // There are presently only a couple (derived) instances ever
+  // created, and they are permanent, so no harm currently done by
+  // doing nothing here.
+}
+
+void PtrQueueSet::initialize(Monitor* cbl_mon,
+                             Mutex* fl_lock,
+                             int process_completed_threshold,
+                             int max_completed_queue,
+                             PtrQueueSet *fl_owner) {
+  _max_completed_queue = max_completed_queue;
+  _process_completed_threshold = process_completed_threshold;
+  _completed_queue_padding = 0;
+  assert(cbl_mon != NULL && fl_lock != NULL, "Init order issue?");
+  _cbl_mon = cbl_mon;
+  _fl_lock = fl_lock;
+  _fl_owner = (fl_owner != NULL) ? fl_owner : this;
+}
+
 void** PtrQueueSet::allocate_buffer() {
   assert(_sz > 0, "Didn't set a buffer size.");
   MutexLockerEx x(_fl_owner->_fl_lock, Mutex::_no_safepoint_check_flag);
@@ -233,7 +254,7 @@
     if (_notify_when_complete)
       _cbl_mon->notify();
   }
-  debug_only(assert_completed_buffer_list_len_correct_locked());
+  DEBUG_ONLY(assert_completed_buffer_list_len_correct_locked());
 }
 
 int PtrQueueSet::completed_buffers_list_length() {
@@ -258,7 +279,7 @@
 
 void PtrQueueSet::set_buffer_size(size_t sz) {
   assert(_sz == 0 && sz > 0, "Should be called only once.");
-  _sz = sz * oopSize;
+  _sz = sz * sizeof(void*);
 }
 
 // Merge lists of buffers. Notify the processing threads.
--- a/src/share/vm/gc/g1/ptrQueue.hpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/ptrQueue.hpp	Fri Nov 13 10:35:26 2015 -0800
@@ -40,44 +40,49 @@
 class PtrQueue VALUE_OBJ_CLASS_SPEC {
   friend class VMStructs;
 
-protected:
+  // Noncopyable - not defined.
+  PtrQueue(const PtrQueue&);
+  PtrQueue& operator=(const PtrQueue&);
+
   // The ptr queue set to which this queue belongs.
-  PtrQueueSet* _qset;
+  PtrQueueSet* const _qset;
 
   // Whether updates should be logged.
   bool _active;
 
+  // If true, the queue is permanent, and doesn't need to deallocate
+  // its buffer in the destructor (since that obtains a lock which may not
+  // be legally locked by then.
+  const bool _permanent;
+
+protected:
   // The buffer.
   void** _buf;
-  // The index at which an object was last enqueued.  Starts at "_sz"
+  // The (byte) index at which an object was last enqueued.  Starts at "_sz"
   // (indicating an empty buffer) and goes towards zero.
   size_t _index;
 
-  // The size of the buffer.
+  // The (byte) size of the buffer.
   size_t _sz;
 
-  // If true, the queue is permanent, and doesn't need to deallocate
-  // its buffer in the destructor (since that obtains a lock which may not
-  // be legally locked by then.
-  bool _perm;
-
   // If there is a lock associated with this buffer, this is that lock.
   Mutex* _lock;
 
   PtrQueueSet* qset() { return _qset; }
-  bool is_permanent() const { return _perm; }
+  bool is_permanent() const { return _permanent; }
 
   // Process queue entries and release resources, if not permanent.
   void flush_impl();
 
-public:
   // Initialize this queue to contain a null buffer, and be part of the
   // given PtrQueueSet.
-  PtrQueue(PtrQueueSet* qset, bool perm = false, bool active = false);
+  PtrQueue(PtrQueueSet* qset, bool permanent = false, bool active = false);
 
   // Requires queue flushed or permanent.
   ~PtrQueue();
 
+public:
+
   // Associate a lock with a ptr queue.
   void set_lock(Mutex* lock) { _lock = lock; }
 
@@ -129,13 +134,9 @@
 
   bool is_active() { return _active; }
 
-  static int byte_index_to_index(int ind) {
-    assert((ind % oopSize) == 0, "Invariant.");
-    return ind / oopSize;
-  }
-
-  static int index_to_byte_index(int byte_ind) {
-    return byte_ind * oopSize;
+  static size_t byte_index_to_index(size_t ind) {
+    assert((ind % sizeof(void*)) == 0, "Invariant.");
+    return ind / sizeof(void*);
   }
 
   // To support compiler.
@@ -246,26 +247,21 @@
     return false;
   }
 
-public:
   // Create an empty ptr queue set.
   PtrQueueSet(bool notify_when_complete = false);
+  ~PtrQueueSet();
 
   // Because of init-order concerns, we can't pass these as constructor
   // arguments.
-  void initialize(Monitor* cbl_mon, Mutex* fl_lock,
+  void initialize(Monitor* cbl_mon,
+                  Mutex* fl_lock,
                   int process_completed_threshold,
                   int max_completed_queue,
-                  PtrQueueSet *fl_owner = NULL) {
-    _max_completed_queue = max_completed_queue;
-    _process_completed_threshold = process_completed_threshold;
-    _completed_queue_padding = 0;
-    assert(cbl_mon != NULL && fl_lock != NULL, "Init order issue?");
-    _cbl_mon = cbl_mon;
-    _fl_lock = fl_lock;
-    _fl_owner = (fl_owner != NULL) ? fl_owner : this;
-  }
+                  PtrQueueSet *fl_owner = NULL);
 
-  // Return an empty oop array of size _sz (required to be non-zero).
+public:
+
+  // Return an empty array of size _sz (required to be non-zero).
   void** allocate_buffer();
 
   // Return an empty buffer to the free list.  The "buf" argument is
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc/g1/satbMarkQueue.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -0,0 +1,370 @@
+/*
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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/g1/g1CollectedHeap.inline.hpp"
+#include "gc/g1/satbMarkQueue.hpp"
+#include "gc/shared/collectedHeap.hpp"
+#include "memory/allocation.inline.hpp"
+#include "oops/oop.inline.hpp"
+#include "runtime/mutexLocker.hpp"
+#include "runtime/safepoint.hpp"
+#include "runtime/thread.hpp"
+#include "runtime/vmThread.hpp"
+
+SATBMarkQueue::SATBMarkQueue(SATBMarkQueueSet* qset, bool permanent) :
+  // SATB queues are only active during marking cycles. We create
+  // them with their active field set to false. If a thread is
+  // created during a cycle and its SATB queue needs to be activated
+  // before the thread starts running, we'll need to set its active
+  // field to true. This is done in JavaThread::initialize_queues().
+  PtrQueue(qset, permanent, false /* active */)
+{ }
+
+void SATBMarkQueue::flush() {
+  // Filter now to possibly save work later.  If filtering empties the
+  // buffer then flush_impl can deallocate the buffer.
+  filter();
+  flush_impl();
+}
+
+// Return true if a SATB buffer entry refers to an object that
+// requires marking.
+//
+// The entry must point into the G1 heap.  In particular, it must not
+// be a NULL pointer.  NULL pointers are pre-filtered and never
+// inserted into a SATB buffer.
+//
+// An entry that is below the NTAMS pointer for the containing heap
+// region requires marking. Such an entry must point to a valid object.
+//
+// An entry that is at least the NTAMS pointer for the containing heap
+// region might be any of the following, none of which should be marked.
+//
+// * A reference to an object allocated since marking started.
+//   According to SATB, such objects are implicitly kept live and do
+//   not need to be dealt with via SATB buffer processing.
+//
+// * A reference to a young generation object. Young objects are
+//   handled separately and are not marked by concurrent marking.
+//
+// * A stale reference to a young generation object. If a young
+//   generation object reference is recorded and not filtered out
+//   before being moved by a young collection, the reference becomes
+//   stale.
+//
+// * A stale reference to an eagerly reclaimed humongous object.  If a
+//   humongous object is recorded and then reclaimed, the reference
+//   becomes stale.
+//
+// The stale reference cases are implicitly handled by the NTAMS
+// comparison. Because of the possibility of stale references, buffer
+// processing must be somewhat circumspect and not assume entries
+// in an unfiltered buffer refer to valid objects.
+
+inline bool requires_marking(const void* entry, G1CollectedHeap* heap) {
+  // Includes rejection of NULL pointers.
+  assert(heap->is_in_reserved(entry),
+         "Non-heap pointer in SATB buffer: " PTR_FORMAT, p2i(entry));
+
+  HeapRegion* region = heap->heap_region_containing(entry);
+  assert(region != NULL, "No region for " PTR_FORMAT, p2i(entry));
+  if (entry >= region->next_top_at_mark_start()) {
+    return false;
+  }
+
+  assert(((oop)entry)->is_oop(true /* ignore mark word */),
+         "Invalid oop in SATB buffer: " PTR_FORMAT, p2i(entry));
+
+  return true;
+}
+
+// This method removes entries from a SATB buffer that will not be
+// useful to the concurrent marking threads.  Entries are retained if
+// they require marking and are not already marked. Retained entries
+// are compacted toward the top of the buffer.
+
+void SATBMarkQueue::filter() {
+  G1CollectedHeap* g1h = G1CollectedHeap::heap();
+  void** buf = _buf;
+
+  if (buf == NULL) {
+    // nothing to do
+    return;
+  }
+
+  // Used for sanity checking at the end of the loop.
+  DEBUG_ONLY(size_t entries = 0; size_t retained = 0;)
+
+  assert(_index <= _sz, "invariant");
+  void** limit = &buf[byte_index_to_index(_index)];
+  void** src = &buf[byte_index_to_index(_sz)];
+  void** dst = src;
+
+  while (limit < src) {
+    DEBUG_ONLY(entries += 1;)
+    --src;
+    void* entry = *src;
+    // NULL the entry so that unused parts of the buffer contain NULLs
+    // at the end. If we are going to retain it we will copy it to its
+    // final place. If we have retained all entries we have visited so
+    // far, we'll just end up copying it to the same place.
+    *src = NULL;
+
+    if (requires_marking(entry, g1h) && !g1h->isMarkedNext((oop)entry)) {
+      --dst;
+      assert(*dst == NULL, "filtering destination should be clear");
+      *dst = entry;
+      DEBUG_ONLY(retained += 1;);
+    }
+  }
+  size_t new_index = pointer_delta(dst, buf, 1);
+
+#ifdef ASSERT
+  size_t entries_calc = (_sz - _index) / sizeof(void*);
+  assert(entries == entries_calc, "the number of entries we counted "
+         "should match the number of entries we calculated");
+  size_t retained_calc = (_sz - new_index) / sizeof(void*);
+  assert(retained == retained_calc, "the number of retained entries we counted "
+         "should match the number of retained entries we calculated");
+#endif // ASSERT
+
+  _index = new_index;
+}
+
+// This method will first apply the above filtering to the buffer. If
+// post-filtering a large enough chunk of the buffer has been cleared
+// we can re-use the buffer (instead of enqueueing it) and we can just
+// allow the mutator to carry on executing using the same buffer
+// instead of replacing it.
+
+bool SATBMarkQueue::should_enqueue_buffer() {
+  assert(_lock == NULL || _lock->owned_by_self(),
+         "we should have taken the lock before calling this");
+
+  // If G1SATBBufferEnqueueingThresholdPercent == 0 we could skip filtering.
+
+  // This method should only be called if there is a non-NULL buffer
+  // that is full.
+  assert(_index == 0, "pre-condition");
+  assert(_buf != NULL, "pre-condition");
+
+  filter();
+
+  size_t percent_used = ((_sz - _index) * 100) / _sz;
+  bool should_enqueue = percent_used > G1SATBBufferEnqueueingThresholdPercent;
+  return should_enqueue;
+}
+
+void SATBMarkQueue::apply_closure_and_empty(SATBBufferClosure* cl) {
+  assert(SafepointSynchronize::is_at_safepoint(),
+         "SATB queues must only be processed at safepoints");
+  if (_buf != NULL) {
+    assert(_index % sizeof(void*) == 0, "invariant");
+    assert(_sz % sizeof(void*) == 0, "invariant");
+    assert(_index <= _sz, "invariant");
+    cl->do_buffer(_buf + byte_index_to_index(_index),
+                  byte_index_to_index(_sz - _index));
+    _index = _sz;
+  }
+}
+
+#ifndef PRODUCT
+// Helpful for debugging
+
+void SATBMarkQueue::print(const char* name) {
+  print(name, _buf, _index, _sz);
+}
+
+void SATBMarkQueue::print(const char* name,
+                          void** buf, size_t index, size_t sz) {
+  gclog_or_tty->print_cr("  SATB BUFFER [%s] buf: " PTR_FORMAT " "
+                         "index: " SIZE_FORMAT " sz: " SIZE_FORMAT,
+                         name, p2i(buf), index, sz);
+}
+#endif // PRODUCT
+
+SATBMarkQueueSet::SATBMarkQueueSet() :
+  PtrQueueSet(),
+  _shared_satb_queue(this, true /* permanent */) { }
+
+void SATBMarkQueueSet::initialize(Monitor* cbl_mon, Mutex* fl_lock,
+                                  int process_completed_threshold,
+                                  Mutex* lock) {
+  PtrQueueSet::initialize(cbl_mon, fl_lock, process_completed_threshold, -1);
+  _shared_satb_queue.set_lock(lock);
+}
+
+void SATBMarkQueueSet::handle_zero_index_for_thread(JavaThread* t) {
+  t->satb_mark_queue().handle_zero_index();
+}
+
+#ifdef ASSERT
+void SATBMarkQueueSet::dump_active_states(bool expected_active) {
+  gclog_or_tty->print_cr("Expected SATB active state: %s",
+                         expected_active ? "ACTIVE" : "INACTIVE");
+  gclog_or_tty->print_cr("Actual SATB active states:");
+  gclog_or_tty->print_cr("  Queue set: %s", is_active() ? "ACTIVE" : "INACTIVE");
+  for (JavaThread* t = Threads::first(); t; t = t->next()) {
+    gclog_or_tty->print_cr("  Thread \"%s\" queue: %s", t->name(),
+                           t->satb_mark_queue().is_active() ? "ACTIVE" : "INACTIVE");
+  }
+  gclog_or_tty->print_cr("  Shared queue: %s",
+                         shared_satb_queue()->is_active() ? "ACTIVE" : "INACTIVE");
+}
+
+void SATBMarkQueueSet::verify_active_states(bool expected_active) {
+  // Verify queue set state
+  if (is_active() != expected_active) {
+    dump_active_states(expected_active);
+    guarantee(false, "SATB queue set has an unexpected active state");
+  }
+
+  // Verify thread queue states
+  for (JavaThread* t = Threads::first(); t; t = t->next()) {
+    if (t->satb_mark_queue().is_active() != expected_active) {
+      dump_active_states(expected_active);
+      guarantee(false, "Thread SATB queue has an unexpected active state");
+    }
+  }
+
+  // Verify shared queue state
+  if (shared_satb_queue()->is_active() != expected_active) {
+    dump_active_states(expected_active);
+    guarantee(false, "Shared SATB queue has an unexpected active state");
+  }
+}
+#endif // ASSERT
+
+void SATBMarkQueueSet::set_active_all_threads(bool active, bool expected_active) {
+  assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
+#ifdef ASSERT
+  verify_active_states(expected_active);
+#endif // ASSERT
+  _all_active = active;
+  for (JavaThread* t = Threads::first(); t; t = t->next()) {
+    t->satb_mark_queue().set_active(active);
+  }
+  shared_satb_queue()->set_active(active);
+}
+
+void SATBMarkQueueSet::filter_thread_buffers() {
+  for(JavaThread* t = Threads::first(); t; t = t->next()) {
+    t->satb_mark_queue().filter();
+  }
+  shared_satb_queue()->filter();
+}
+
+bool SATBMarkQueueSet::apply_closure_to_completed_buffer(SATBBufferClosure* cl) {
+  BufferNode* nd = NULL;
+  {
+    MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
+    if (_completed_buffers_head != NULL) {
+      nd = _completed_buffers_head;
+      _completed_buffers_head = nd->next();
+      if (_completed_buffers_head == NULL) _completed_buffers_tail = NULL;
+      _n_completed_buffers--;
+      if (_n_completed_buffers == 0) _process_completed = false;
+    }
+  }
+  if (nd != NULL) {
+    void **buf = BufferNode::make_buffer_from_node(nd);
+    // Skip over NULL entries at beginning (e.g. push end) of buffer.
+    // Filtering can result in non-full completed buffers; see
+    // should_enqueue_buffer.
+    assert(_sz % sizeof(void*) == 0, "invariant");
+    size_t limit = SATBMarkQueue::byte_index_to_index(_sz);
+    for (size_t i = 0; i < limit; ++i) {
+      if (buf[i] != NULL) {
+        // Found the end of the block of NULLs; process the remainder.
+        cl->do_buffer(buf + i, limit - i);
+        break;
+      }
+    }
+    deallocate_buffer(buf);
+    return true;
+  } else {
+    return false;
+  }
+}
+
+#ifndef PRODUCT
+// Helpful for debugging
+
+#define SATB_PRINTER_BUFFER_SIZE 256
+
+void SATBMarkQueueSet::print_all(const char* msg) {
+  char buffer[SATB_PRINTER_BUFFER_SIZE];
+  assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
+
+  gclog_or_tty->cr();
+  gclog_or_tty->print_cr("SATB BUFFERS [%s]", msg);
+
+  BufferNode* nd = _completed_buffers_head;
+  int i = 0;
+  while (nd != NULL) {
+    void** buf = BufferNode::make_buffer_from_node(nd);
+    jio_snprintf(buffer, SATB_PRINTER_BUFFER_SIZE, "Enqueued: %d", i);
+    SATBMarkQueue::print(buffer, buf, 0, _sz);
+    nd = nd->next();
+    i += 1;
+  }
+
+  for (JavaThread* t = Threads::first(); t; t = t->next()) {
+    jio_snprintf(buffer, SATB_PRINTER_BUFFER_SIZE, "Thread: %s", t->name());
+    t->satb_mark_queue().print(buffer);
+  }
+
+  shared_satb_queue()->print("Shared");
+
+  gclog_or_tty->cr();
+}
+#endif // PRODUCT
+
+void SATBMarkQueueSet::abandon_partial_marking() {
+  BufferNode* buffers_to_delete = NULL;
+  {
+    MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
+    while (_completed_buffers_head != NULL) {
+      BufferNode* nd = _completed_buffers_head;
+      _completed_buffers_head = nd->next();
+      nd->set_next(buffers_to_delete);
+      buffers_to_delete = nd;
+    }
+    _completed_buffers_tail = NULL;
+    _n_completed_buffers = 0;
+    DEBUG_ONLY(assert_completed_buffer_list_len_correct_locked());
+  }
+  while (buffers_to_delete != NULL) {
+    BufferNode* nd = buffers_to_delete;
+    buffers_to_delete = nd->next();
+    deallocate_buffer(BufferNode::make_buffer_from_node(nd));
+  }
+  assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
+  // So we can safely manipulate these queues.
+  for (JavaThread* t = Threads::first(); t; t = t->next()) {
+    t->satb_mark_queue().reset();
+  }
+ shared_satb_queue()->reset();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc/g1/satbMarkQueue.hpp	Fri Nov 13 10:35:26 2015 -0800
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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_G1_SATBMARKQUEUE_HPP
+#define SHARE_VM_GC_G1_SATBMARKQUEUE_HPP
+
+#include "gc/g1/ptrQueue.hpp"
+#include "memory/allocation.hpp"
+
+class JavaThread;
+class SATBMarkQueueSet;
+
+// Base class for processing the contents of a SATB buffer.
+class SATBBufferClosure : public StackObj {
+protected:
+  ~SATBBufferClosure() { }
+
+public:
+  // Process the SATB entries in the designated buffer range.
+  virtual void do_buffer(void** buffer, size_t size) = 0;
+};
+
+// A PtrQueue whose elements are (possibly stale) pointers to object heads.
+class SATBMarkQueue: public PtrQueue {
+  friend class SATBMarkQueueSet;
+
+private:
+  // Filter out unwanted entries from the buffer.
+  void filter();
+
+public:
+  SATBMarkQueue(SATBMarkQueueSet* qset, bool permanent = false);
+
+  // Process queue entries and free resources.
+  void flush();
+
+  // Apply cl to the active part of the buffer.
+  // Prerequisite: Must be at a safepoint.
+  void apply_closure_and_empty(SATBBufferClosure* cl);
+
+  // Overrides PtrQueue::should_enqueue_buffer(). See the method's
+  // definition for more information.
+  virtual bool should_enqueue_buffer();
+
+#ifndef PRODUCT
+  // Helpful for debugging
+  void print(const char* name);
+  static void print(const char* name, void** buf, size_t index, size_t sz);
+#endif // PRODUCT
+};
+
+class SATBMarkQueueSet: public PtrQueueSet {
+  SATBMarkQueue _shared_satb_queue;
+
+#ifdef ASSERT
+  void dump_active_states(bool expected_active);
+  void verify_active_states(bool expected_active);
+#endif // ASSERT
+
+public:
+  SATBMarkQueueSet();
+
+  void initialize(Monitor* cbl_mon, Mutex* fl_lock,
+                  int process_completed_threshold,
+                  Mutex* lock);
+
+  static void handle_zero_index_for_thread(JavaThread* t);
+
+  // Apply "set_active(active)" to all SATB queues in the set. It should be
+  // called only with the world stopped. The method will assert that the
+  // SATB queues of all threads it visits, as well as the SATB queue
+  // set itself, has an active value same as expected_active.
+  void set_active_all_threads(bool active, bool expected_active);
+
+  // Filter all the currently-active SATB buffers.
+  void filter_thread_buffers();
+
+  // If there exists some completed buffer, pop and process it, and
+  // return true.  Otherwise return false.  Processing a buffer
+  // consists of applying the closure to the buffer range starting
+  // with the first non-NULL entry to the end of the buffer; the
+  // leading entries may be NULL due to filtering.
+  bool apply_closure_to_completed_buffer(SATBBufferClosure* cl);
+
+#ifndef PRODUCT
+  // Helpful for debugging
+  void print_all(const char* msg);
+#endif // PRODUCT
+
+  SATBMarkQueue* shared_satb_queue() { return &_shared_satb_queue; }
+
+  // If a marking is being abandoned, reset any unprocessed log buffers.
+  void abandon_partial_marking();
+};
+
+#endif // SHARE_VM_GC_G1_SATBMARKQUEUE_HPP
--- a/src/share/vm/gc/g1/satbQueue.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,375 +0,0 @@
-/*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * 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/g1/g1CollectedHeap.inline.hpp"
-#include "gc/g1/satbQueue.hpp"
-#include "gc/shared/collectedHeap.hpp"
-#include "memory/allocation.inline.hpp"
-#include "oops/oop.inline.hpp"
-#include "runtime/mutexLocker.hpp"
-#include "runtime/safepoint.hpp"
-#include "runtime/thread.hpp"
-#include "runtime/vmThread.hpp"
-
-void ObjPtrQueue::flush() {
-  // Filter now to possibly save work later.  If filtering empties the
-  // buffer then flush_impl can deallocate the buffer.
-  filter();
-  flush_impl();
-}
-
-// Return true if a SATB buffer entry refers to an object that
-// requires marking.
-//
-// The entry must point into the G1 heap.  In particular, it must not
-// be a NULL pointer.  NULL pointers are pre-filtered and never
-// inserted into a SATB buffer.
-//
-// An entry that is below the NTAMS pointer for the containing heap
-// region requires marking. Such an entry must point to a valid object.
-//
-// An entry that is at least the NTAMS pointer for the containing heap
-// region might be any of the following, none of which should be marked.
-//
-// * A reference to an object allocated since marking started.
-//   According to SATB, such objects are implicitly kept live and do
-//   not need to be dealt with via SATB buffer processing.
-//
-// * A reference to a young generation object. Young objects are
-//   handled separately and are not marked by concurrent marking.
-//
-// * A stale reference to a young generation object. If a young
-//   generation object reference is recorded and not filtered out
-//   before being moved by a young collection, the reference becomes
-//   stale.
-//
-// * A stale reference to an eagerly reclaimed humongous object.  If a
-//   humongous object is recorded and then reclaimed, the reference
-//   becomes stale.
-//
-// The stale reference cases are implicitly handled by the NTAMS
-// comparison. Because of the possibility of stale references, buffer
-// processing must be somewhat circumspect and not assume entries
-// in an unfiltered buffer refer to valid objects.
-
-inline bool requires_marking(const void* entry, G1CollectedHeap* heap) {
-  // Includes rejection of NULL pointers.
-  assert(heap->is_in_reserved(entry),
-         "Non-heap pointer in SATB buffer: " PTR_FORMAT, p2i(entry));
-
-  HeapRegion* region = heap->heap_region_containing_raw(entry);
-  assert(region != NULL, "No region for " PTR_FORMAT, p2i(entry));
-  if (entry >= region->next_top_at_mark_start()) {
-    return false;
-  }
-
-  assert(((oop)entry)->is_oop(true /* ignore mark word */),
-         "Invalid oop in SATB buffer: " PTR_FORMAT, p2i(entry));
-
-  return true;
-}
-
-// This method removes entries from a SATB buffer that will not be
-// useful to the concurrent marking threads.  Entries are retained if
-// they require marking and are not already marked. Retained entries
-// are compacted toward the top of the buffer.
-
-void ObjPtrQueue::filter() {
-  G1CollectedHeap* g1h = G1CollectedHeap::heap();
-  void** buf = _buf;
-  size_t sz = _sz;
-
-  if (buf == NULL) {
-    // nothing to do
-    return;
-  }
-
-  // Used for sanity checking at the end of the loop.
-  debug_only(size_t entries = 0; size_t retained = 0;)
-
-  size_t i = sz;
-  size_t new_index = sz;
-
-  while (i > _index) {
-    assert(i > 0, "we should have at least one more entry to process");
-    i -= oopSize;
-    debug_only(entries += 1;)
-    void** p = &buf[byte_index_to_index((int) i)];
-    void* entry = *p;
-    // NULL the entry so that unused parts of the buffer contain NULLs
-    // at the end. If we are going to retain it we will copy it to its
-    // final place. If we have retained all entries we have visited so
-    // far, we'll just end up copying it to the same place.
-    *p = NULL;
-
-    if (requires_marking(entry, g1h) && !g1h->isMarkedNext((oop)entry)) {
-      assert(new_index > 0, "we should not have already filled up the buffer");
-      new_index -= oopSize;
-      assert(new_index >= i,
-             "new_index should never be below i, as we always compact 'up'");
-      void** new_p = &buf[byte_index_to_index((int) new_index)];
-      assert(new_p >= p, "the destination location should never be below "
-             "the source as we always compact 'up'");
-      assert(*new_p == NULL,
-             "we should have already cleared the destination location");
-      *new_p = entry;
-      debug_only(retained += 1;)
-    }
-  }
-
-#ifdef ASSERT
-  size_t entries_calc = (sz - _index) / oopSize;
-  assert(entries == entries_calc, "the number of entries we counted "
-         "should match the number of entries we calculated");
-  size_t retained_calc = (sz - new_index) / oopSize;
-  assert(retained == retained_calc, "the number of retained entries we counted "
-         "should match the number of retained entries we calculated");
-#endif // ASSERT
-
-  _index = new_index;
-}
-
-// This method will first apply the above filtering to the buffer. If
-// post-filtering a large enough chunk of the buffer has been cleared
-// we can re-use the buffer (instead of enqueueing it) and we can just
-// allow the mutator to carry on executing using the same buffer
-// instead of replacing it.
-
-bool ObjPtrQueue::should_enqueue_buffer() {
-  assert(_lock == NULL || _lock->owned_by_self(),
-         "we should have taken the lock before calling this");
-
-  // If G1SATBBufferEnqueueingThresholdPercent == 0 we could skip filtering.
-
-  // This method should only be called if there is a non-NULL buffer
-  // that is full.
-  assert(_index == 0, "pre-condition");
-  assert(_buf != NULL, "pre-condition");
-
-  filter();
-
-  size_t sz = _sz;
-  size_t all_entries = sz / oopSize;
-  size_t retained_entries = (sz - _index) / oopSize;
-  size_t perc = retained_entries * 100 / all_entries;
-  bool should_enqueue = perc > (size_t) G1SATBBufferEnqueueingThresholdPercent;
-  return should_enqueue;
-}
-
-void ObjPtrQueue::apply_closure_and_empty(SATBBufferClosure* cl) {
-  assert(SafepointSynchronize::is_at_safepoint(),
-         "SATB queues must only be processed at safepoints");
-  if (_buf != NULL) {
-    assert(_index % sizeof(void*) == 0, "invariant");
-    assert(_sz % sizeof(void*) == 0, "invariant");
-    assert(_index <= _sz, "invariant");
-    cl->do_buffer(_buf + byte_index_to_index((int)_index),
-                  byte_index_to_index((int)(_sz - _index)));
-    _index = _sz;
-  }
-}
-
-#ifndef PRODUCT
-// Helpful for debugging
-
-void ObjPtrQueue::print(const char* name) {
-  print(name, _buf, _index, _sz);
-}
-
-void ObjPtrQueue::print(const char* name,
-                        void** buf, size_t index, size_t sz) {
-  gclog_or_tty->print_cr("  SATB BUFFER [%s] buf: " PTR_FORMAT " "
-                         "index: " SIZE_FORMAT " sz: " SIZE_FORMAT,
-                         name, p2i(buf), index, sz);
-}
-#endif // PRODUCT
-
-#ifdef _MSC_VER // the use of 'this' below gets a warning, make it go away
-#pragma warning( disable:4355 ) // 'this' : used in base member initializer list
-#endif // _MSC_VER
-
-SATBMarkQueueSet::SATBMarkQueueSet() :
-  PtrQueueSet(),
-  _shared_satb_queue(this, true /*perm*/) { }
-
-void SATBMarkQueueSet::initialize(Monitor* cbl_mon, Mutex* fl_lock,
-                                  int process_completed_threshold,
-                                  Mutex* lock) {
-  PtrQueueSet::initialize(cbl_mon, fl_lock, process_completed_threshold, -1);
-  _shared_satb_queue.set_lock(lock);
-}
-
-void SATBMarkQueueSet::handle_zero_index_for_thread(JavaThread* t) {
-  t->satb_mark_queue().handle_zero_index();
-}
-
-#ifdef ASSERT
-void SATBMarkQueueSet::dump_active_states(bool expected_active) {
-  gclog_or_tty->print_cr("Expected SATB active state: %s",
-                         expected_active ? "ACTIVE" : "INACTIVE");
-  gclog_or_tty->print_cr("Actual SATB active states:");
-  gclog_or_tty->print_cr("  Queue set: %s", is_active() ? "ACTIVE" : "INACTIVE");
-  for (JavaThread* t = Threads::first(); t; t = t->next()) {
-    gclog_or_tty->print_cr("  Thread \"%s\" queue: %s", t->name(),
-                           t->satb_mark_queue().is_active() ? "ACTIVE" : "INACTIVE");
-  }
-  gclog_or_tty->print_cr("  Shared queue: %s",
-                         shared_satb_queue()->is_active() ? "ACTIVE" : "INACTIVE");
-}
-
-void SATBMarkQueueSet::verify_active_states(bool expected_active) {
-  // Verify queue set state
-  if (is_active() != expected_active) {
-    dump_active_states(expected_active);
-    guarantee(false, "SATB queue set has an unexpected active state");
-  }
-
-  // Verify thread queue states
-  for (JavaThread* t = Threads::first(); t; t = t->next()) {
-    if (t->satb_mark_queue().is_active() != expected_active) {
-      dump_active_states(expected_active);
-      guarantee(false, "Thread SATB queue has an unexpected active state");
-    }
-  }
-
-  // Verify shared queue state
-  if (shared_satb_queue()->is_active() != expected_active) {
-    dump_active_states(expected_active);
-    guarantee(false, "Shared SATB queue has an unexpected active state");
-  }
-}
-#endif // ASSERT
-
-void SATBMarkQueueSet::set_active_all_threads(bool active, bool expected_active) {
-  assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
-#ifdef ASSERT
-  verify_active_states(expected_active);
-#endif // ASSERT
-  _all_active = active;
-  for (JavaThread* t = Threads::first(); t; t = t->next()) {
-    t->satb_mark_queue().set_active(active);
-  }
-  shared_satb_queue()->set_active(active);
-}
-
-void SATBMarkQueueSet::filter_thread_buffers() {
-  for(JavaThread* t = Threads::first(); t; t = t->next()) {
-    t->satb_mark_queue().filter();
-  }
-  shared_satb_queue()->filter();
-}
-
-bool SATBMarkQueueSet::apply_closure_to_completed_buffer(SATBBufferClosure* cl) {
-  BufferNode* nd = NULL;
-  {
-    MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
-    if (_completed_buffers_head != NULL) {
-      nd = _completed_buffers_head;
-      _completed_buffers_head = nd->next();
-      if (_completed_buffers_head == NULL) _completed_buffers_tail = NULL;
-      _n_completed_buffers--;
-      if (_n_completed_buffers == 0) _process_completed = false;
-    }
-  }
-  if (nd != NULL) {
-    void **buf = BufferNode::make_buffer_from_node(nd);
-    // Skip over NULL entries at beginning (e.g. push end) of buffer.
-    // Filtering can result in non-full completed buffers; see
-    // should_enqueue_buffer.
-    assert(_sz % sizeof(void*) == 0, "invariant");
-    size_t limit = ObjPtrQueue::byte_index_to_index((int)_sz);
-    for (size_t i = 0; i < limit; ++i) {
-      if (buf[i] != NULL) {
-        // Found the end of the block of NULLs; process the remainder.
-        cl->do_buffer(buf + i, limit - i);
-        break;
-      }
-    }
-    deallocate_buffer(buf);
-    return true;
-  } else {
-    return false;
-  }
-}
-
-#ifndef PRODUCT
-// Helpful for debugging
-
-#define SATB_PRINTER_BUFFER_SIZE 256
-
-void SATBMarkQueueSet::print_all(const char* msg) {
-  char buffer[SATB_PRINTER_BUFFER_SIZE];
-  assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
-
-  gclog_or_tty->cr();
-  gclog_or_tty->print_cr("SATB BUFFERS [%s]", msg);
-
-  BufferNode* nd = _completed_buffers_head;
-  int i = 0;
-  while (nd != NULL) {
-    void** buf = BufferNode::make_buffer_from_node(nd);
-    jio_snprintf(buffer, SATB_PRINTER_BUFFER_SIZE, "Enqueued: %d", i);
-    ObjPtrQueue::print(buffer, buf, 0, _sz);
-    nd = nd->next();
-    i += 1;
-  }
-
-  for (JavaThread* t = Threads::first(); t; t = t->next()) {
-    jio_snprintf(buffer, SATB_PRINTER_BUFFER_SIZE, "Thread: %s", t->name());
-    t->satb_mark_queue().print(buffer);
-  }
-
-  shared_satb_queue()->print("Shared");
-
-  gclog_or_tty->cr();
-}
-#endif // PRODUCT
-
-void SATBMarkQueueSet::abandon_partial_marking() {
-  BufferNode* buffers_to_delete = NULL;
-  {
-    MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
-    while (_completed_buffers_head != NULL) {
-      BufferNode* nd = _completed_buffers_head;
-      _completed_buffers_head = nd->next();
-      nd->set_next(buffers_to_delete);
-      buffers_to_delete = nd;
-    }
-    _completed_buffers_tail = NULL;
-    _n_completed_buffers = 0;
-    DEBUG_ONLY(assert_completed_buffer_list_len_correct_locked());
-  }
-  while (buffers_to_delete != NULL) {
-    BufferNode* nd = buffers_to_delete;
-    buffers_to_delete = nd->next();
-    deallocate_buffer(BufferNode::make_buffer_from_node(nd));
-  }
-  assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
-  // So we can safely manipulate these queues.
-  for (JavaThread* t = Threads::first(); t; t = t->next()) {
-    t->satb_mark_queue().reset();
-  }
- shared_satb_queue()->reset();
-}
--- a/src/share/vm/gc/g1/satbQueue.hpp	Thu Nov 12 14:13:49 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,123 +0,0 @@
-/*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * 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_G1_SATBQUEUE_HPP
-#define SHARE_VM_GC_G1_SATBQUEUE_HPP
-
-#include "gc/g1/ptrQueue.hpp"
-#include "memory/allocation.hpp"
-
-class JavaThread;
-class SATBMarkQueueSet;
-
-// Base class for processing the contents of a SATB buffer.
-class SATBBufferClosure : public StackObj {
-protected:
-  ~SATBBufferClosure() { }
-
-public:
-  // Process the SATB entries in the designated buffer range.
-  virtual void do_buffer(void** buffer, size_t size) = 0;
-};
-
-// A ptrQueue whose elements are "oops", pointers to object heads.
-class ObjPtrQueue: public PtrQueue {
-  friend class SATBMarkQueueSet;
-
-private:
-  // Filter out unwanted entries from the buffer.
-  void filter();
-
-public:
-  ObjPtrQueue(PtrQueueSet* qset, bool perm = false) :
-    // SATB queues are only active during marking cycles. We create
-    // them with their active field set to false. If a thread is
-    // created during a cycle and its SATB queue needs to be activated
-    // before the thread starts running, we'll need to set its active
-    // field to true. This is done in JavaThread::initialize_queues().
-    PtrQueue(qset, perm, false /* active */) { }
-
-  // Process queue entries and free resources.
-  void flush();
-
-  // Apply cl to the active part of the buffer.
-  // Prerequisite: Must be at a safepoint.
-  void apply_closure_and_empty(SATBBufferClosure* cl);
-
-  // Overrides PtrQueue::should_enqueue_buffer(). See the method's
-  // definition for more information.
-  virtual bool should_enqueue_buffer();
-
-#ifndef PRODUCT
-  // Helpful for debugging
-  void print(const char* name);
-  static void print(const char* name, void** buf, size_t index, size_t sz);
-#endif // PRODUCT
-};
-
-class SATBMarkQueueSet: public PtrQueueSet {
-  ObjPtrQueue _shared_satb_queue;
-
-#ifdef ASSERT
-  void dump_active_states(bool expected_active);
-  void verify_active_states(bool expected_active);
-#endif // ASSERT
-
-public:
-  SATBMarkQueueSet();
-
-  void initialize(Monitor* cbl_mon, Mutex* fl_lock,
-                  int process_completed_threshold,
-                  Mutex* lock);
-
-  static void handle_zero_index_for_thread(JavaThread* t);
-
-  // Apply "set_active(active)" to all SATB queues in the set. It should be
-  // called only with the world stopped. The method will assert that the
-  // SATB queues of all threads it visits, as well as the SATB queue
-  // set itself, has an active value same as expected_active.
-  void set_active_all_threads(bool active, bool expected_active);
-
-  // Filter all the currently-active SATB buffers.
-  void filter_thread_buffers();
-
-  // If there exists some completed buffer, pop and process it, and
-  // return true.  Otherwise return false.  Processing a buffer
-  // consists of applying the closure to the buffer range starting
-  // with the first non-NULL entry to the end of the buffer; the
-  // leading entries may be NULL due to filtering.
-  bool apply_closure_to_completed_buffer(SATBBufferClosure* cl);
-
-#ifndef PRODUCT
-  // Helpful for debugging
-  void print_all(const char* msg);
-#endif // PRODUCT
-
-  ObjPtrQueue* shared_satb_queue() { return &_shared_satb_queue; }
-
-  // If a marking is being abandoned, reset any unprocessed log buffers.
-  void abandon_partial_marking();
-};
-
-#endif // SHARE_VM_GC_G1_SATBQUEUE_HPP
--- a/src/share/vm/gc/g1/sparsePRT.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/g1/sparsePRT.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -32,8 +32,6 @@
 #include "runtime/atomic.inline.hpp"
 #include "runtime/mutexLocker.hpp"
 
-#define SPARSE_PRT_VERBOSE 0
-
 void SparsePRTEntry::init(RegionIdx_t region_ind) {
   _region_ind = region_ind;
   _next_index = NullEntry;
@@ -121,11 +119,6 @@
          "Postcondition of call above.");
   SparsePRTEntry::AddCardResult res = e->add_card(card_index);
   if (res == SparsePRTEntry::added) _occupied_cards++;
-#if SPARSE_PRT_VERBOSE
-  gclog_or_tty->print_cr("       after add_card[%d]: valid-cards = %d.",
-                         pointer_delta(e, _entries, SparsePRTEntry::size()),
-                         e->num_valid_cards());
-#endif
   assert(e->num_valid_cards() > 0, "Postcondition");
   return res != SparsePRTEntry::overflow;
 }
@@ -387,10 +380,6 @@
 }
 
 bool SparsePRT::add_card(RegionIdx_t region_id, CardIdx_t card_index) {
-#if SPARSE_PRT_VERBOSE
-  gclog_or_tty->print_cr("  Adding card %d from region %d to region %u sparse.",
-                         card_index, region_id, _hr->hrm_index());
-#endif
   if (_next->occupied_entries() * 2 > _next->capacity()) {
     expand();
   }
@@ -438,18 +427,9 @@
 void SparsePRT::expand() {
   RSHashTable* last = _next;
   _next = new RSHashTable(last->capacity() * 2);
-
-#if SPARSE_PRT_VERBOSE
-  gclog_or_tty->print_cr("  Expanded sparse table for %u to %d.",
-                         _hr->hrm_index(), _next->capacity());
-#endif
   for (size_t i = 0; i < last->capacity(); i++) {
     SparsePRTEntry* e = last->entry((int)i);
     if (e->valid_entry()) {
-#if SPARSE_PRT_VERBOSE
-      gclog_or_tty->print_cr("    During expansion, transferred entry for %d.",
-                    e->r_ind());
-#endif
       _next->add_entry(e);
     }
   }
--- a/src/share/vm/gc/parallel/psParallelCompact.hpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/gc/parallel/psParallelCompact.hpp	Fri Nov 13 10:35:26 2015 -0800
@@ -347,7 +347,7 @@
     HeapWord*            _partial_obj_addr;
     region_sz_t          _partial_obj_size;
     region_sz_t volatile _dc_and_los;
-    bool                 _blocks_filled;
+    bool        volatile _blocks_filled;
 
 #ifdef ASSERT
     size_t               _blocks_filled_count;   // Number of block table fills.
@@ -498,7 +498,9 @@
 inline bool
 ParallelCompactData::RegionData::blocks_filled() const
 {
-  return _blocks_filled;
+  bool result = _blocks_filled;
+  OrderAccess::acquire();
+  return result;
 }
 
 #ifdef ASSERT
@@ -512,6 +514,7 @@
 inline void
 ParallelCompactData::RegionData::set_blocks_filled()
 {
+  OrderAccess::release();
   _blocks_filled = true;
   // Debug builds count the number of times the table was filled.
   DEBUG_ONLY(Atomic::inc_ptr(&_blocks_filled_count));
--- a/src/share/vm/interpreter/bytecodeInterpreter.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/interpreter/bytecodeInterpreter.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -2190,7 +2190,7 @@
                 result->set_mark(markOopDesc::prototype());
               }
               result->set_klass_gap(0);
-              result->set_klass(k_entry);
+              result->set_klass(ik);
               // Must prevent reordering of stores for object initialization
               // with stores that publish the new object.
               OrderAccess::storestore();
--- a/src/share/vm/libadt/dict.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/libadt/dict.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -126,37 +126,37 @@
 void Dict::doubhash(void) {
   uint oldsize = _size;
   _size <<= 1;                  // Double in size
-  _bin = (bucket*)_arena->Arealloc( _bin, sizeof(bucket)*oldsize, sizeof(bucket)*_size );
-  memset( &_bin[oldsize], 0, oldsize*sizeof(bucket) );
+  _bin = (bucket*)_arena->Arealloc(_bin, sizeof(bucket) * oldsize, sizeof(bucket) * _size);
+  memset(&_bin[oldsize], 0, oldsize * sizeof(bucket));
   // Rehash things to spread into new table
-  for( uint i=0; i < oldsize; i++) { // For complete OLD table do
-    bucket *b = &_bin[i];       // Handy shortcut for _bin[i]
-    if( !b->_keyvals ) continue;        // Skip empties fast
+  for (uint i = 0; i < oldsize; i++) { // For complete OLD table do
+    bucket *b = &_bin[i];              // Handy shortcut for _bin[i]
+    if (!b->_keyvals) continue;        // Skip empties fast
 
-    bucket *nb = &_bin[i+oldsize];  // New bucket shortcut
-    uint j = b->_max;               // Trim new bucket to nearest power of 2
-    while( j > b->_cnt ) j >>= 1;   // above old bucket _cnt
-    if( !j ) j = 1;             // Handle zero-sized buckets
-    nb->_max = j<<1;
+    bucket *nb = &_bin[i+oldsize];     // New bucket shortcut
+    uint j = b->_max;                  // Trim new bucket to nearest power of 2
+    while (j > b->_cnt) { j >>= 1; }   // above old bucket _cnt
+    if (!j) { j = 1; }                 // Handle zero-sized buckets
+    nb->_max = j << 1;
     // Allocate worst case space for key-value pairs
-    nb->_keyvals = (void**)_arena->Amalloc_4( sizeof(void *)*nb->_max*2 );
+    nb->_keyvals = (void**)_arena->Amalloc_4(sizeof(void *) * nb->_max * 2);
     uint nbcnt = 0;
 
-    for( j=0; j<b->_cnt; j++ ) {  // Rehash all keys in this bucket
-      void *key = b->_keyvals[j+j];
-      if( (_hash( key ) & (_size-1)) != i ) { // Moving to hi bucket?
-        nb->_keyvals[nbcnt+nbcnt] = key;
-        nb->_keyvals[nbcnt+nbcnt+1] = b->_keyvals[j+j+1];
-        nb->_cnt = nbcnt = nbcnt+1;
-        b->_cnt--;              // Remove key/value from lo bucket
-        b->_keyvals[j+j  ] = b->_keyvals[b->_cnt+b->_cnt  ];
-        b->_keyvals[j+j+1] = b->_keyvals[b->_cnt+b->_cnt+1];
-        j--;                    // Hash compacted element also
+    for (j = 0; j < b->_cnt; ) {           // Rehash all keys in this bucket
+      void *key = b->_keyvals[j + j];
+      if ((_hash(key) & (_size-1)) != i) { // Moving to hi bucket?
+        nb->_keyvals[nbcnt + nbcnt] = key;
+        nb->_keyvals[nbcnt + nbcnt + 1] = b->_keyvals[j + j + 1];
+        nb->_cnt = nbcnt = nbcnt + 1;
+        b->_cnt--;                         // Remove key/value from lo bucket
+        b->_keyvals[j + j] = b->_keyvals[b->_cnt + b->_cnt];
+        b->_keyvals[j + j + 1] = b->_keyvals[b->_cnt + b->_cnt + 1];
+        // Don't increment j, hash compacted element also.
+      } else {
+        j++; // Iterate.
       }
     } // End of for all key-value pairs in bucket
   } // End of for all buckets
-
-
 }
 
 //------------------------------Dict-----------------------------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/logging/log.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+
+/////////////// Unit tests ///////////////
+
+#ifndef PRODUCT
+
+#include "logging/log.hpp"
+#include "logging/logConfiguration.hpp"
+#include "memory/resourceArea.hpp"
+
+void Test_log_length() {
+  remove("loglengthoutput.txt");
+
+  // Write long message to output file
+  MutexLocker ml(LogConfiguration_lock);
+  LogConfiguration::parse_log_arguments("loglengthoutput.txt", "logging=develop",
+    NULL, NULL, NULL);
+  ResourceMark rm;
+  outputStream* logstream = LogHandle(logging)::develop_stream();
+  logstream->print_cr("01:1234567890-"
+                      "02:1234567890-"
+                      "03:1234567890-"
+                      "04:1234567890-"
+                      "05:1234567890-"
+                      "06:1234567890-"
+                      "07:1234567890-"
+                      "08:1234567890-"
+                      "09:1234567890-"
+                      "10:1234567890-"
+                      "11:1234567890-"
+                      "12:1234567890-"
+                      "13:1234567890-"
+                      "14:1234567890-"
+                      "15:1234567890-"
+                      "16:1234567890-"
+                      "17:1234567890-"
+                      "18:1234567890-"
+                      "19:1234567890-"
+                      "20:1234567890-"
+                      "21:1234567890-"
+                      "22:1234567890-"
+                      "23:1234567890-"
+                      "24:1234567890-"
+                      "25:1234567890-"
+                      "26:1234567890-"
+                      "27:1234567890-"
+                      "28:1234567890-"
+                      "29:1234567890-"
+                      "30:1234567890-"
+                      "31:1234567890-"
+                      "32:1234567890-"
+                      "33:1234567890-"
+                      "34:1234567890-"
+                      "35:1234567890-"
+                      "36:1234567890-"
+                      "37:1234567890-");
+
+  // Look for end of message in output file
+  FILE* fp;
+  fp = fopen("loglengthoutput.txt", "r");
+  assert (fp, "File read error");
+  char output[600];
+  if (fgets(output, 600, fp) != NULL) {
+    assert(strstr(output, "37:1234567890-"), "logging print size error");
+  }
+  fclose(fp);
+  remove("loglengthoutput.txt");
+}
+#endif // PRODUCT
+
--- a/src/share/vm/logging/log.hpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/logging/log.hpp	Fri Nov 13 10:35:26 2015 -0800
@@ -29,6 +29,8 @@
 #include "logging/logTagSet.hpp"
 #include "logging/logTag.hpp"
 #include "memory/allocation.hpp"
+#include "memory/allocation.inline.hpp"
+#include "runtime/os.hpp"
 #include "utilities/debug.hpp"
 #include "utilities/ostream.hpp"
 
@@ -104,9 +106,20 @@
   static void vwrite(const char* fmt, va_list args) {
     char buf[LogBufferSize];
     size_t prefix_len = LogPrefix<T0, T1, T2, T3, T4>::prefix(buf, sizeof(buf));
-    int ret = vsnprintf(buf + prefix_len, sizeof(buf) - prefix_len, fmt, args);
-    assert(ret >= 0 && (size_t)ret < sizeof(buf), "Log message too long");
-    puts<Level>(buf);
+    // Check that string fits in buffer; resize buffer if necessary
+    int ret = os::log_vsnprintf(buf + prefix_len, sizeof(buf) - prefix_len, fmt, args);
+    assert(ret >= 0, "Log message buffer issue");
+    if ((size_t)ret > sizeof(buf)) {
+      size_t newbuf_len = prefix_len + ret + 1;
+      char* newbuf = NEW_C_HEAP_ARRAY(char, newbuf_len, mtLogging);
+      prefix_len = LogPrefix<T0, T1, T2, T3, T4>::prefix(newbuf, newbuf_len);
+      ret = os::log_vsnprintf(newbuf + prefix_len, newbuf_len - prefix_len, fmt, args);
+      assert(ret >= 0, "Log message buffer issue");
+      puts<Level>(newbuf);
+      FREE_C_HEAP_ARRAY(char, newbuf);
+    } else {
+      puts<Level>(buf);
+    }
   }
 
   template <LogLevelType Level>
--- a/src/share/vm/logging/logTag.hpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/logging/logTag.hpp	Fri Nov 13 10:35:26 2015 -0800
@@ -31,7 +31,9 @@
 // (The tags 'all', 'disable' and 'help' are special tags that can
 // not be used in log calls, and should not be listed below.)
 #define LOG_TAG_LIST \
-  LOG_TAG(logging)
+  LOG_TAG(defaultmethods) \
+  LOG_TAG(logging) \
+  LOG_TAG(safepoint)
 
 #define PREFIX_LOG_TAG(T) (LogTag::T)
 
--- a/src/share/vm/precompiled/precompiled.hpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/precompiled/precompiled.hpp	Fri Nov 13 10:35:26 2015 -0800
@@ -304,7 +304,7 @@
 # include "gc/g1/g1OopClosures.hpp"
 # include "gc/g1/g1_globals.hpp"
 # include "gc/g1/ptrQueue.hpp"
-# include "gc/g1/satbQueue.hpp"
+# include "gc/g1/satbMarkQueue.hpp"
 # include "gc/parallel/gcAdaptivePolicyCounters.hpp"
 # include "gc/parallel/objectStartArray.hpp"
 # include "gc/parallel/parMarkBitMap.hpp"
--- a/src/share/vm/prims/jni.cpp	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/prims/jni.cpp	Fri Nov 13 10:35:26 2015 -0800
@@ -3893,7 +3893,9 @@
 void TestBitMap_test();
 void TestAsUtf8();
 void Test_linked_list();
+void TestResourcehash_test();
 void TestChunkedList_test();
+void Test_log_length();
 #if INCLUDE_ALL_GCS
 void TestOldFreeSpaceCalculation_test();
 void TestG1BiasedArray_test();
@@ -3930,10 +3932,12 @@
     run_unit_test(TestKlass_test());
     run_unit_test(TestBitMap_test());
     run_unit_test(TestAsUtf8());
+    run_unit_test(TestResourcehash_test());
     run_unit_test(ObjectMonitor::sanity_checks());
     run_unit_test(Test_linked_list());
     run_unit_test(TestChunkedList_test());
     run_unit_test(JSONTest::test());
+    run_unit_test(Test_log_length());
     run_unit_test(DirectivesParser::test());
 #if INCLUDE_VM_STRUCTS
     run_unit_test(VMStructs::test());
--- a/src/share/vm/prims/jvmtiGen.java	Thu Nov 12 14:13:49 2015 -0800
+++ b/src/share/vm/prims/jvmtiGen.java	Fri Nov 13 10:35:26 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,52 +22,60 @@
  *
  */
 
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.FactoryConfigurationError;
 import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.transform.stream.StreamResult;
 
+import org.xml.sax.ErrorHandler;
 import org.xml.sax.SAXException;
 import org.xml.sax.SAXParseException;
 import org.w3c.dom.Document;
 import org.w3c.dom.DOMException;
-// For write operation
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamSource;
-import javax.xml.transform.stream.StreamResult;
-
-import java.io.*;
 
 public class jvmtiGen
 {
+    private static final int EXIT_FAILURE_ERROR = 1;
+    private static final int EXIT_FAILURE_BADARGUMENTS = 2;
+
+    private static boolean verbose = false;
+
     /**
      * Write out usage and exit.
      */
     private static void showUsage() {
         System.err.println("usage:");
         System.err.println("  java jvmtiGen " +
+                           "[-verbose] " +
                            "-IN <input XML file name> " +
                            "-XSL <XSL file> " +
                            "-OUT <output file name> " +
                            "[-PARAM <name> <expression> ...]");
-        System.exit(0);         // There is no returning from showUsage()
+        System.exit(EXIT_FAILURE_BADARGUMENTS); // There is no returning from showUsage()
     }
 
-    // Global value so it can be ref'd by the tree-adapter
-    static Document document;
-
-    public static void main (String argv [])
-    {
-        String inFileName=null;
-        String xslFileName=null;
-        String outFileName=null;
-        java.util.Vector<String> params=new java.util.Vector<String>();
+    public static void main (String argv []) {
+        String inFileName = null;
+        String xslFileName = null;
+        String outFileName = null;
+        final List<String> params = new ArrayList<String>();
         for (int ii = 0; ii < argv.length; ii++) {
-            if (argv[ii].equals("-IN")) {
+            if (argv[ii].equals("-verbose")) {
+                verbose = true;
+            } else if (argv[ii].equals("-IN")) {
                 inFileName = argv[++ii];
             } else if (argv[ii].equals("-XSL")) {
                 xslFileName = argv[++ii];
@@ -75,10 +83,10 @@
                 outFileName = argv[++ii];
             } else if (argv[ii].equals("-PARAM")) {
                 if (ii + 2 < argv.length) {
-                    String name = argv[++ii];
-                    params.addElement(name);
-                    String expression = argv[++ii];
-                    params.addElement(expression);
+                    final String name = argv[++ii];
+                    params.add(name);
+                    final String expression = argv[++ii];
+                    params.add(expression);
                 } else {
                     showUsage();
                 }
@@ -86,109 +94,54 @@
                 showUsage();
             }
         }
-        if (inFileName==null || xslFileName==null || outFileName==null){
+        if (inFileName == null || xslFileName == null || outFileName == null) {
             showUsage();
         }
 
-        /*
-         * Due to JAXP breakage in some intermediate Tiger builds, the
-         * com.sun.org.apache..... parser may throw an exception:
-         *   com.sun.org.apache.xml.internal.utils.WrappedRuntimeException:
-         *     org.apache.xalan.serialize.SerializerToText
-         *
-         * To work around the problem, this program uses the
-         * org.apache.xalan....  version if it is available.  It is
-         * available in J2SE 1.4.x and early builds of 1.5 (Tiger).
-         * It was removed at the same time the thrown exception issue
-         * above was fixed, so if the class is not found we can proceed
-         * and use the default parser.
-         */
-        final String parserProperty =
-            "javax.xml.transform.TransformerFactory";
-        final String workaroundParser =
-            "org.apache.xalan.processor.TransformerFactoryImpl";
-
-        try {
-            java.lang.Class cls = java.lang.Class.forName(workaroundParser);
-            /*
-             * If we get here, we found the class.  Use it.
-             */
-            System.setProperty(parserProperty, workaroundParser);
-            System.out.println("Info: jvmtiGen using " + parserProperty +
-                               " = " + workaroundParser);
-        } catch (ClassNotFoundException cnfex) {
-            /*
-             * We didn't find workaroundParser.  Ignore the
-             * exception and proceed with default settings.
-             */
-        }
-
-        DocumentBuilderFactory factory =
-            DocumentBuilderFactory.newInstance();
+        final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
 
         factory.setNamespaceAware(true);
         factory.setValidating(true);
         factory.setXIncludeAware(true);
 
-        try {
-            File datafile   = new File(inFileName);
-            File stylesheet = new File(xslFileName);
+        final File datafile   = new File(inFileName);
+        final File stylesheet = new File(xslFileName);
 
-            DocumentBuilder builder = factory.newDocumentBuilder();
-            document = builder.parse(datafile);
-
+        try (
+            final OutputStream os = new BufferedOutputStream(new FileOutputStream(outFileName));
+        ) {
+            final StreamSource stylesource = new StreamSource(stylesheet);
             // Use a Transformer for output
-            TransformerFactory tFactory =
-                TransformerFactory.newInstance();
-            StreamSource stylesource = new StreamSource(stylesheet);
-            Transformer transformer = tFactory.newTransformer(stylesource);
-            for (int ii = 0; ii < params.size(); ii += 2){
-                transformer.setParameter((String) params.elementAt(ii),
-                                         (String) params.elementAt(ii + 1));
+            final Transformer transformer =
+                TransformerFactory.newInstance().newTransformer(stylesource);
+            for (int ii = 0; ii < params.size(); ii += 2) {
+                transformer.setParameter(params.get(ii), params.get(ii + 1));
             }
-            DOMSource source = new DOMSource(document);
-
-            PrintStream ps = new PrintStream( new FileOutputStream(outFileName));
-            StreamResult result = new StreamResult(ps);
+            final DocumentBuilder builder = factory.newDocumentBuilder();
+            builder.setErrorHandler(new ErrorHandler() {
+                    public void fatalError(SAXParseException exn) throws SAXException {
+                        throw new SAXException(exn);
+                    }
+                    public void error(SAXParseException exn) throws SAXException {
+                        fatalError(exn);
+                    }
+                    public void warning(SAXParseException exn) throws SAXException {
+                        if (verbose) {
+                            System.err.println("jvmtiGen warning: " + exn.getMessage());
+                        }
+                    }
+                });
+            final Document document = builder.parse(datafile);
+            final DOMSource source = new DOMSource(document);
+            final StreamResult result = new StreamResult(os);
             transformer.transform(source, result);
-
-        } catch (TransformerConfigurationException tce) {
-           // Error generated by the parser
-           System.out.println ("\n** Transformer Factory error");
-           System.out.println("   " + tce.getMessage() );
-
-           // Use the contained exception, if any
-           Throwable x = tce;
-           if (tce.getException() != null)
-               x = tce.getException();
-           x.printStackTrace();
-
-        } catch (TransformerException te) {
-           // Error generated by the parser
-           System.out.println ("\n** Transformation error");
-           System.out.println("   " + te.getMessage() );
-
-           // Use the contained exception, if any
-           Throwable x = te;
-           if (te.getException() != null)
-               x = te.getException();
-           x.printStackTrace();
-
-         } catch (SAXException sxe) {
-           // Error generated by this application
-           // (or a parser-initialization error)
-           Exception  x = sxe;
-           if (sxe.getException() != null)
-               x = sxe.getException();