changeset 10173:6231dc9a7946

Merge
author jwilhelm
date Wed, 03 Feb 2016 01:35:25 +0100
parents 1edcfb47e131 04a9132aa6e4
children f1c3681c4174
files src/cpu/aarch64/vm/macroAssembler_aarch64.cpp src/cpu/ppc/vm/macroAssembler_ppc.cpp src/cpu/ppc/vm/ppc.ad src/cpu/ppc/vm/templateTable_ppc_64.cpp src/cpu/ppc/vm/vtableStubs_ppc_64.cpp src/cpu/sparc/vm/macroAssembler_sparc.cpp src/cpu/x86/vm/macroAssembler_x86.cpp src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java src/share/vm/interpreter/interpreterRuntime.cpp src/share/vm/interpreter/linkResolver.cpp src/share/vm/jvmci/jvmciCompilerToVM.cpp src/share/vm/jvmci/jvmciCompilerToVM.hpp src/share/vm/jvmci/vmStructs_jvmci.cpp src/share/vm/oops/cpCache.cpp src/share/vm/oops/klass.cpp src/share/vm/oops/klass.hpp src/share/vm/oops/method.cpp src/share/vm/opto/library_call.cpp src/share/vm/runtime/globals.hpp src/share/vm/runtime/vmStructs.cpp src/share/vm/utilities/debug.cpp src/share/vm/utilities/vmError.cpp
diffstat 192 files changed, 4261 insertions(+), 2011 deletions(-) [+]
line wrap: on
line diff
--- a/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -898,23 +898,18 @@
          "caller must use same register for non-constant itable index as for method");
 
   // Compute start of first itableOffsetEntry (which is at the end of the vtable)
-  int vtable_base = InstanceKlass::vtable_start_offset() * wordSize;
+  int vtable_base = in_bytes(Klass::vtable_start_offset());
   int itentry_off = itableMethodEntry::method_offset_in_bytes();
   int scan_step   = itableOffsetEntry::size() * wordSize;
-  int vte_size    = vtableEntry::size() * wordSize;
+  int vte_size    = vtableEntry::size_in_bytes();
   assert(vte_size == wordSize, "else adjust times_vte_scale");
 
-  ldrw(scan_temp, Address(recv_klass, InstanceKlass::vtable_length_offset() * wordSize));
+  ldrw(scan_temp, Address(recv_klass, Klass::vtable_length_offset()));
 
   // %%% Could store the aligned, prescaled offset in the klassoop.
   // lea(scan_temp, Address(recv_klass, scan_temp, times_vte_scale, vtable_base));
   lea(scan_temp, Address(recv_klass, scan_temp, Address::lsl(3)));
   add(scan_temp, scan_temp, vtable_base);
-  if (HeapWordsPerLong > 1) {
-    // Round up to align_object_offset boundary
-    // see code for instanceKlass::start_of_itable!
-    round_to(scan_temp, BytesPerLong);
-  }
 
   // Adjust recv_klass by scaled itable_index, so we can free itable_index.
   assert(itableMethodEntry::size() * wordSize == wordSize, "adjust the scaling in the code below");
@@ -963,7 +958,7 @@
 void MacroAssembler::lookup_virtual_method(Register recv_klass,
                                            RegisterOrConstant vtable_index,
                                            Register method_result) {
-  const int base = InstanceKlass::vtable_start_offset() * wordSize;
+  const int base = in_bytes(Klass::vtable_start_offset());
   assert(vtableEntry::size() * wordSize == 8,
          "adjust the scaling in the code below");
   int vtable_offset_in_bytes = base + vtableEntry::method_offset_in_bytes();
--- a/src/cpu/aarch64/vm/vtableStubs_aarch64.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/cpu/aarch64/vm/vtableStubs_aarch64.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2014, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -73,7 +73,7 @@
   if (DebugVtables) {
     Label L;
     // check offset vs vtable length
-    __ ldrw(rscratch1, Address(r19, InstanceKlass::vtable_length_offset() * wordSize));
+    __ ldrw(rscratch1, Address(r19, Klass::vtable_length_offset()));
     __ cmpw(rscratch1, vtable_index * vtableEntry::size());
     __ br(Assembler::GT, L);
     __ enter();
--- a/src/cpu/ppc/vm/macroAssembler_ppc.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/cpu/ppc/vm/macroAssembler_ppc.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1583,13 +1583,13 @@
          "caller must use same register for non-constant itable index as for method");
 
   // Compute start of first itableOffsetEntry (which is at the end of the vtable).
-  int vtable_base = InstanceKlass::vtable_start_offset() * wordSize;
+  int vtable_base = in_bytes(Klass::vtable_start_offset());
   int itentry_off = itableMethodEntry::method_offset_in_bytes();
   int logMEsize   = exact_log2(itableMethodEntry::size() * wordSize);
   int scan_step   = itableOffsetEntry::size() * wordSize;
-  int log_vte_size= exact_log2(vtableEntry::size() * wordSize);
-
-  lwz(scan_temp, InstanceKlass::vtable_length_offset() * wordSize, recv_klass);
+  int log_vte_size= exact_log2(vtableEntry::size_in_bytes());
+
+  lwz(scan_temp, in_bytes(Klass::vtable_length_offset()), recv_klass);
   // %%% We should store the aligned, prescaled offset in the klassoop.
   // Then the next several instructions would fold away.
 
@@ -1657,7 +1657,7 @@
 
   assert_different_registers(recv_klass, method_result, vtable_index.register_or_noreg());
 
-  const int base = InstanceKlass::vtable_start_offset() * wordSize;
+  const int base = in_bytes(Klass::vtable_start_offset());
   assert(vtableEntry::size() * wordSize == wordSize, "adjust the scaling in the code below");
 
   if (vtable_index.is_register()) {
--- a/src/cpu/ppc/vm/ppc.ad	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/cpu/ppc/vm/ppc.ad	Wed Feb 03 01:35:25 2016 +0100
@@ -3568,8 +3568,8 @@
 
       __ load_klass(R11_scratch1, R3);
 
-      int entry_offset = InstanceKlass::vtable_start_offset() + _vtable_index * vtableEntry::size();
-      int v_off = entry_offset * wordSize + vtableEntry::method_offset_in_bytes();
+      int entry_offset = in_bytes(Klass::vtable_start_offset()) + _vtable_index * vtableEntry::size_in_bytes();
+      int v_off = entry_offset + vtableEntry::method_offset_in_bytes();
       __ li(R19_method, v_off);
       __ ldx(R19_method/*method oop*/, R19_method/*method offset*/, R11_scratch1/*class*/);
       // NOTE: for vtable dispatches, the vtable entry will never be
--- a/src/cpu/ppc/vm/templateTable_ppc_64.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/cpu/ppc/vm/templateTable_ppc_64.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2013, 2015 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -3282,9 +3282,9 @@
   const Register Rtarget_method = Rindex;
 
   // Get target method & entry point.
-  const int base = InstanceKlass::vtable_start_offset() * wordSize;
+  const int base = in_bytes(Klass::vtable_start_offset());
   // Calc vtable addr scale the vtable index by 8.
-  __ sldi(Rindex, Rindex, exact_log2(vtableEntry::size() * wordSize));
+  __ sldi(Rindex, Rindex, exact_log2(vtableEntry::size_in_bytes()));
   // Load target.
   __ addi(Rrecv_klass, Rrecv_klass, base + vtableEntry::method_offset_in_bytes());
   __ ldx(Rtarget_method, Rindex, Rrecv_klass);
--- a/src/cpu/ppc/vm/vtableStubs_ppc_64.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/cpu/ppc/vm/vtableStubs_ppc_64.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2012, 2015 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -80,14 +80,14 @@
   __ load_klass(rcvr_klass, R3);
 
  // Set method (in case of interpreted method), and destination address.
-  int entry_offset = InstanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size();
+  int entry_offset = in_bytes(Klass::vtable_start_offset()) + vtable_index*vtableEntry::size_in_bytes();
 
 #ifndef PRODUCT
   if (DebugVtables) {
     Label L;
     // Check offset vs vtable length.
     const Register vtable_len = R12_scratch2;
-    __ lwz(vtable_len, InstanceKlass::vtable_length_offset()*wordSize, rcvr_klass);
+    __ lwz(vtable_len, in_bytes(Klass::vtable_length_offset()), rcvr_klass);
     __ cmpwi(CCR0, vtable_len, vtable_index*vtableEntry::size());
     __ bge(CCR0, L);
     __ li(R12_scratch2, vtable_index);
@@ -96,7 +96,7 @@
   }
 #endif
 
-  int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes();
+  int v_off = entry_offset + vtableEntry::method_offset_in_bytes();
 
   __ ld(R19_method, v_off, rcvr_klass);
 
@@ -163,13 +163,13 @@
   __ load_klass(rcvr_klass, R3_ARG1);
 
   BLOCK_COMMENT("Load start of itable entries into itable_entry.");
-  __ lwz(vtable_len, InstanceKlass::vtable_length_offset() * wordSize, rcvr_klass);
-  __ slwi(vtable_len, vtable_len, exact_log2(vtableEntry::size() * wordSize));
+  __ lwz(vtable_len, in_bytes(Klass::vtable_length_offset()), rcvr_klass);
+  __ slwi(vtable_len, vtable_len, exact_log2(vtableEntry::size_in_bytes()));
   __ add(itable_entry_addr, vtable_len, rcvr_klass);
 
   // Loop over all itable entries until desired interfaceOop(Rinterface) found.
   BLOCK_COMMENT("Increment itable_entry_addr in loop.");
-  const int vtable_base_offset = InstanceKlass::vtable_start_offset() * wordSize;
+  const int vtable_base_offset = in_bytes(Klass::vtable_start_offset());
   __ addi(itable_entry_addr, itable_entry_addr, vtable_base_offset + itableOffsetEntry::interface_offset_in_bytes());
 
   const int itable_offset_search_inc = itableOffsetEntry::size() * wordSize;
--- a/src/cpu/sparc/vm/copy_sparc.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/cpu/sparc/vm/copy_sparc.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -180,6 +180,9 @@
 
 typedef void (*_zero_Fn)(HeapWord* to, size_t count);
 
+// Only used for heap objects, so align_object_offset.
+// All other platforms pd_fill_to_aligned_words simply calls pd_fill_to_words, don't
+// know why this one is different.
 static void pd_fill_to_aligned_words(HeapWord* tohw, size_t count, juint value) {
   assert(MinObjAlignmentInBytes >= BytesPerLong, "need alternate implementation");
 
--- a/src/cpu/sparc/vm/macroAssembler_sparc.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/cpu/sparc/vm/macroAssembler_sparc.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -2188,30 +2188,18 @@
   }
 
   // Compute start of first itableOffsetEntry (which is at the end of the vtable)
-  int vtable_base = InstanceKlass::vtable_start_offset() * wordSize;
+  int vtable_base = in_bytes(Klass::vtable_start_offset());
   int scan_step   = itableOffsetEntry::size() * wordSize;
-  int vte_size    = vtableEntry::size() * wordSize;
-
-  lduw(recv_klass, InstanceKlass::vtable_length_offset() * wordSize, scan_temp);
+  int vte_size    = vtableEntry::size_in_bytes();
+
+  lduw(recv_klass, in_bytes(Klass::vtable_length_offset()), scan_temp);
   // %%% We should store the aligned, prescaled offset in the klassoop.
   // Then the next several instructions would fold away.
 
-  int round_to_unit = ((HeapWordsPerLong > 1) ? BytesPerLong : 0);
   int itb_offset = vtable_base;
-  if (round_to_unit != 0) {
-    // hoist first instruction of round_to(scan_temp, BytesPerLong):
-    itb_offset += round_to_unit - wordSize;
-  }
-  int itb_scale = exact_log2(vtableEntry::size() * wordSize);
+  int itb_scale = exact_log2(vtableEntry::size_in_bytes());
   sll(scan_temp, itb_scale,  scan_temp);
   add(scan_temp, itb_offset, scan_temp);
-  if (round_to_unit != 0) {
-    // Round up to align_object_offset boundary
-    // see code for InstanceKlass::start_of_itable!
-    // Was: round_to(scan_temp, BytesPerLong);
-    // Hoisted: add(scan_temp, BytesPerLong-1, scan_temp);
-    and3(scan_temp, -round_to_unit, scan_temp);
-  }
   add(recv_klass, scan_temp, scan_temp);
 
   // Adjust recv_klass by scaled itable_index, so we can free itable_index.
@@ -2280,16 +2268,16 @@
                                            Register method_result) {
   assert_different_registers(recv_klass, method_result, vtable_index.register_or_noreg());
   Register sethi_temp = method_result;
-  const int base = (InstanceKlass::vtable_start_offset() * wordSize +
-                    // method pointer offset within the vtable entry:
-                    vtableEntry::method_offset_in_bytes());
+  const int base = in_bytes(Klass::vtable_start_offset()) +
+                   // method pointer offset within the vtable entry:
+                   vtableEntry::method_offset_in_bytes();
   RegisterOrConstant vtable_offset = vtable_index;
   // Each of the following three lines potentially generates an instruction.
   // But the total number of address formation instructions will always be
   // at most two, and will often be zero.  In any case, it will be optimal.
   // If vtable_index is a register, we will have (sll_ptr N,x; inc_ptr B,x; ld_ptr k,x).
   // If vtable_index is a constant, we will have at most (set B+X<<N,t; ld_ptr k,t).
-  vtable_offset = regcon_sll_ptr(vtable_index, exact_log2(vtableEntry::size() * wordSize), vtable_offset);
+  vtable_offset = regcon_sll_ptr(vtable_index, exact_log2(vtableEntry::size_in_bytes()), vtable_offset);
   vtable_offset = regcon_inc_ptr(vtable_offset, base, vtable_offset, sethi_temp);
   Address vtable_entry_addr(recv_klass, ensure_simm13_or_reg(vtable_offset, sethi_temp));
   ld_ptr(vtable_entry_addr, method_result);
--- a/src/cpu/sparc/vm/sparc.ad	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/cpu/sparc/vm/sparc.ad	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 1998, 2016, 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
@@ -601,8 +601,8 @@
            NativeCall::instruction_size);  // sethi; setlo; call; delay slot
   } else {
     assert(!UseInlineCaches, "expect vtable calls only if not using ICs");
-    int entry_offset = InstanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size();
-    int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes();
+    int entry_offset = in_bytes(Klass::vtable_start_offset()) + vtable_index*vtableEntry::size_in_bytes();
+    int v_off = entry_offset + vtableEntry::method_offset_in_bytes();
     int klass_load_size;
     if (UseCompressedClassPointers) {
       assert(Universe::heap() != NULL, "java heap should be initialized");
@@ -2658,8 +2658,8 @@
       } else {
         klass_load_size = 1*BytesPerInstWord;
       }
-      int entry_offset = InstanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size();
-      int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes();
+      int entry_offset = in_bytes(Klass::vtable_start_offset()) + vtable_index*vtableEntry::size_in_bytes();
+      int v_off = entry_offset + vtableEntry::method_offset_in_bytes();
       if (Assembler::is_simm13(v_off)) {
         __ ld_ptr(G3, v_off, G5_method);
       } else {
--- a/src/cpu/sparc/vm/templateTable_sparc.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/cpu/sparc/vm/templateTable_sparc.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -3153,14 +3153,11 @@
   //
 
   // compute start of first itableOffsetEntry (which is at end of vtable)
-  const int base = InstanceKlass::vtable_start_offset() * wordSize;
+  const int base = in_bytes(Klass::vtable_start_offset());
   Label search;
   Register Rtemp = O1_flags;
 
-  __ ld(O2_Klass, InstanceKlass::vtable_length_offset() * wordSize, Rtemp);
-  if (align_object_offset(1) > 1) {
-    __ round_to(Rtemp, align_object_offset(1));
-  }
+  __ ld(O2_Klass, in_bytes(Klass::vtable_length_offset()), Rtemp);
   __ sll(Rtemp, LogBytesPerWord, Rtemp);   // Rscratch *= 4;
   if (Assembler::is_simm13(base)) {
     __ add(Rtemp, base, Rtemp);
--- a/src/cpu/sparc/vm/vtableStubs_sparc.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/cpu/sparc/vm/vtableStubs_sparc.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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,7 +78,7 @@
   if (DebugVtables) {
     Label L;
     // check offset vs vtable length
-    __ ld(G3_scratch, InstanceKlass::vtable_length_offset()*wordSize, G5);
+    __ ld(G3_scratch, in_bytes(Klass::vtable_length_offset()), G5);
     __ cmp_and_br_short(G5, vtable_index*vtableEntry::size(), Assembler::greaterUnsigned, Assembler::pt, L);
     __ set(vtable_index, O2);
     __ call_VM(noreg, CAST_FROM_FN_PTR(address, bad_compiled_vtable_index), O0, O2);
--- a/src/cpu/x86/vm/macroAssembler_x86.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/cpu/x86/vm/macroAssembler_x86.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -5867,22 +5867,17 @@
          "caller must use same register for non-constant itable index as for method");
 
   // Compute start of first itableOffsetEntry (which is at the end of the vtable)
-  int vtable_base = InstanceKlass::vtable_start_offset() * wordSize;
+  int vtable_base = in_bytes(Klass::vtable_start_offset());
   int itentry_off = itableMethodEntry::method_offset_in_bytes();
   int scan_step   = itableOffsetEntry::size() * wordSize;
-  int vte_size    = vtableEntry::size() * wordSize;
+  int vte_size    = vtableEntry::size_in_bytes();
   Address::ScaleFactor times_vte_scale = Address::times_ptr;
   assert(vte_size == wordSize, "else adjust times_vte_scale");
 
-  movl(scan_temp, Address(recv_klass, InstanceKlass::vtable_length_offset() * wordSize));
+  movl(scan_temp, Address(recv_klass, Klass::vtable_length_offset()));
 
   // %%% Could store the aligned, prescaled offset in the klassoop.
   lea(scan_temp, Address(recv_klass, scan_temp, times_vte_scale, vtable_base));
-  if (HeapWordsPerLong > 1) {
-    // Round up to align_object_offset boundary
-    // see code for InstanceKlass::start_of_itable!
-    round_to(scan_temp, BytesPerLong);
-  }
 
   // Adjust recv_klass by scaled itable_index, so we can free itable_index.
   assert(itableMethodEntry::size() * wordSize == wordSize, "adjust the scaling in the code below");
@@ -5930,7 +5925,7 @@
 void MacroAssembler::lookup_virtual_method(Register recv_klass,
                                            RegisterOrConstant vtable_index,
                                            Register method_result) {
-  const int base = InstanceKlass::vtable_start_offset() * wordSize;
+  const int base = in_bytes(Klass::vtable_start_offset());
   assert(vtableEntry::size() * wordSize == wordSize, "else adjust the scaling in the code below");
   Address vtable_entry_addr(recv_klass,
                             vtable_index, Address::times_ptr,
--- a/src/cpu/x86/vm/vtableStubs_x86_32.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/cpu/x86/vm/vtableStubs_x86_32.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -85,7 +85,7 @@
   if (DebugVtables) {
     Label L;
     // check offset vs vtable length
-    __ cmpl(Address(rax, InstanceKlass::vtable_length_offset()*wordSize), vtable_index*vtableEntry::size());
+    __ cmpl(Address(rax, Klass::vtable_length_offset()), vtable_index*vtableEntry::size());
     __ jcc(Assembler::greater, L);
     __ movl(rbx, vtable_index);
     __ call_VM(noreg, CAST_FROM_FN_PTR(address, bad_compiled_vtable_index), rcx, rbx);
--- a/src/cpu/x86/vm/vtableStubs_x86_64.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/cpu/x86/vm/vtableStubs_x86_64.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -77,7 +77,7 @@
   if (DebugVtables) {
     Label L;
     // check offset vs vtable length
-    __ cmpl(Address(rax, InstanceKlass::vtable_length_offset() * wordSize),
+    __ cmpl(Address(rax, Klass::vtable_length_offset()),
             vtable_index * vtableEntry::size());
     __ jcc(Assembler::greater, L);
     __ movl(rbx, vtable_index);
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HSDB.java	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HSDB.java	Wed Feb 03 01:35:25 2016 +0100
@@ -141,15 +141,19 @@
         return;
     }
 
+    // Create frame first, to catch any GUI creation issues
+    // before we initialize agent
+
+    frame = new JFrame("HSDB - HotSpot Debugger");
+    frame.setSize(800, 600);
+    frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
+    frame.addWindowListener(new CloseUI());
+
     agent = new HotSpotAgent();
     workerThread = new WorkerThread();
     attachMenuItems = new java.util.ArrayList();
     detachMenuItems = new java.util.ArrayList();
 
-    frame = new JFrame("HSDB - HotSpot Debugger");
-    frame.setSize(800, 600);
-    frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
-    frame.addWindowListener(new CloseUI());
 
     JMenuBar menuBar = new JMenuBar();
 
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ArrayKlass.java	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ArrayKlass.java	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -48,7 +48,6 @@
     dimension          = new CIntField(type.getCIntegerField("_dimension"), 0);
     higherDimension    = new MetadataField(type.getAddressField("_higher_dimension"), 0);
     lowerDimension     = new MetadataField(type.getAddressField("_lower_dimension"), 0);
-    vtableLen          = new CIntField(type.getCIntegerField("_vtable_len"), 0);
     javaLangCloneableName = null;
     javaLangObjectName = null;
     javaIoSerializableName = null;
@@ -61,7 +60,6 @@
   private static CIntField dimension;
   private static MetadataField  higherDimension;
   private static MetadataField  lowerDimension;
-  private static CIntField vtableLen;
 
   public Klass getJavaSuper() {
     SystemDictionary sysDict = VM.getVM().getSystemDictionary();
@@ -71,7 +69,6 @@
   public long  getDimension()       { return         dimension.getValue(this); }
   public Klass getHigherDimension() { return (Klass) higherDimension.getValue(this); }
   public Klass getLowerDimension()  { return (Klass) lowerDimension.getValue(this); }
-  public long  getVtableLen()       { return         vtableLen.getValue(this); }
 
   // constant class names - javaLangCloneable, javaIoSerializable, javaLangObject
   // Initialized lazily to avoid initialization ordering dependencies between ArrayKlass and SymbolTable
@@ -140,6 +137,5 @@
       visitor.doCInt(dimension, true);
     visitor.doMetadata(higherDimension, true);
     visitor.doMetadata(lowerDimension, true);
-      visitor.doCInt(vtableLen, true);
     }
   }
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ConstantPool.java	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ConstantPool.java	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -696,7 +696,7 @@
   }
 
   public long getSize() {
-    return Oop.alignObjectSize(headerSize + getLength());
+    return alignSize(headerSize + getLength());
   }
 
   //----------------------------------------------------------------------
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ConstantPoolCache.java	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ConstantPoolCache.java	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -70,7 +70,7 @@
   public ConstantPool getConstants() { return (ConstantPool) constants.getValue(this); }
 
   public long getSize() {
-    return Oop.alignObjectSize(baseOffset + getLength() * elementSize);
+    return alignSize(baseOffset + getLength() * elementSize);
   }
 
   public ConstantPoolCacheEntry getEntryAt(int i) {
@@ -79,8 +79,7 @@
   }
 
   public int getIntAt(int entry, int fld) {
-    //alignObjectSize ?
-    long offset = baseOffset + /*alignObjectSize*/entry * elementSize + fld * intSize;
+    long offset = baseOffset + entry * elementSize + fld * intSize;
     return (int) getAddress().getCIntegerAt(offset, intSize, true );
   }
 
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -84,13 +84,12 @@
     nonstaticOopMapSize  = new CIntField(type.getCIntegerField("_nonstatic_oop_map_size"), 0);
     isMarkedDependent    = new CIntField(type.getCIntegerField("_is_marked_dependent"), 0);
     initState            = new CIntField(type.getCIntegerField("_init_state"), 0);
-    vtableLen            = new CIntField(type.getCIntegerField("_vtable_len"), 0);
     itableLen            = new CIntField(type.getCIntegerField("_itable_len"), 0);
     breakpoints          = type.getAddressField("_breakpoints");
     genericSignatureIndex = new CIntField(type.getCIntegerField("_generic_signature_index"), 0);
     majorVersion         = new CIntField(type.getCIntegerField("_major_version"), 0);
     minorVersion         = new CIntField(type.getCIntegerField("_minor_version"), 0);
-    headerSize           = Oop.alignObjectOffset(type.getSize());
+    headerSize           = type.getSize();
 
     // read field offset constants
     ACCESS_FLAGS_OFFSET            = db.lookupIntConstant("FieldInfo::access_flags_offset").intValue();
@@ -143,7 +142,6 @@
   private static CIntField nonstaticOopMapSize;
   private static CIntField isMarkedDependent;
   private static CIntField initState;
-  private static CIntField vtableLen;
   private static CIntField itableLen;
   private static AddressField breakpoints;
   private static CIntField genericSignatureIndex;
@@ -242,8 +240,7 @@
   }
 
   public long getSize() {
-    return Oop.alignObjectSize(getHeaderSize() + Oop.alignObjectOffset(getVtableLen()) +
-                               Oop.alignObjectOffset(getItableLen()) + Oop.alignObjectOffset(getNonstaticOopMapSize()));
+    return alignSize(getHeaderSize() + getVtableLen() + getItableLen() + getNonstaticOopMapSize());
   }
 
   public static long getHeaderSize() { return headerSize; }
@@ -352,7 +349,6 @@
   public long      getStaticOopFieldCount() { return                staticOopFieldCount.getValue(this); }
   public long      getNonstaticOopMapSize() { return                nonstaticOopMapSize.getValue(this); }
   public boolean   getIsMarkedDependent()   { return                isMarkedDependent.getValue(this) != 0; }
-  public long      getVtableLen()           { return                vtableLen.getValue(this); }
   public long      getItableLen()           { return                itableLen.getValue(this); }
   public long      majorVersion()           { return                majorVersion.getValue(this); }
   public long      minorVersion()           { return                minorVersion.getValue(this); }
@@ -548,7 +544,6 @@
       visitor.doCInt(nonstaticOopMapSize, true);
       visitor.doCInt(isMarkedDependent, true);
       visitor.doCInt(initState, true);
-      visitor.doCInt(vtableLen, true);
       visitor.doCInt(itableLen, true);
     }
 
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Klass.java	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Klass.java	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -61,6 +61,7 @@
     }
     subklass     = new MetadataField(type.getAddressField("_subklass"), 0);
     nextSibling  = new MetadataField(type.getAddressField("_next_sibling"), 0);
+    vtableLen    = new CIntField(type.getCIntegerField("_vtable_len"), 0);
 
     LH_INSTANCE_SLOW_PATH_BIT  = db.lookupIntConstant("Klass::_lh_instance_slow_path_bit").intValue();
     LH_LOG2_ELEMENT_SIZE_SHIFT = db.lookupIntConstant("Klass::_lh_log2_element_size_shift").intValue();
@@ -71,6 +72,7 @@
     LH_ARRAY_TAG_OBJ_VALUE     = db.lookupIntConstant("Klass::_lh_array_tag_obj_value").intValue();
   }
 
+
   public Klass(Address addr) {
     super(addr);
   }
@@ -91,6 +93,7 @@
   private static MetadataField  subklass;
   private static MetadataField  nextSibling;
   private static sun.jvm.hotspot.types.Field traceIDField;
+  private static CIntField vtableLen;
 
   private Address getValue(AddressField field) {
     return addr.getAddressAt(field.getOffset());
@@ -111,6 +114,7 @@
   public AccessFlags getAccessFlagsObj(){ return new AccessFlags(getAccessFlags());      }
   public Klass    getSubklassKlass()    { return (Klass)    subklass.getValue(this);     }
   public Klass    getNextSiblingKlass() { return (Klass)    nextSibling.getValue(this);  }
+  public long     getVtableLen()        { return            vtableLen.getValue(this); }
 
   public long traceID() {
     if (traceIDField == null) return 0;
@@ -179,6 +183,7 @@
       visitor.doCInt(accessFlags, true);
     visitor.doMetadata(subklass, true);
     visitor.doMetadata(nextSibling, true);
+    visitor.doCInt(vtableLen, true);
     }
 
   public long getObjectSize() {
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Metadata.java	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Metadata.java	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -44,6 +44,11 @@
     super(addr);
   }
 
+  public static long alignSize(long size) {
+    // natural word size.
+    return VM.getVM().alignUp(size, VM.getVM().getBytesPerWord());
+  }
+
   private static VirtualBaseConstructor<Metadata> metadataConstructor;
 
   private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/MethodData.java	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/MethodData.java	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -252,7 +252,7 @@
   }
 
   int size() {
-    return (int)Oop.alignObjectSize(VM.getVM().alignUp(sizeInBytes(), VM.getVM().getBytesPerWord())/VM.getVM().getBytesPerWord());
+    return (int)alignSize(VM.getVM().alignUp(sizeInBytes(), VM.getVM().getBytesPerWord())/VM.getVM().getBytesPerWord());
   }
 
   ParametersTypeData<Klass,Method> parametersTypeData() {
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/WorkerThread.java	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/WorkerThread.java	Wed Feb 03 01:35:25 2016 +0100
@@ -35,7 +35,11 @@
   public WorkerThread() {
     mqb = new MessageQueueBackend();
     mq = mqb.getFirstQueue();
-    new Thread(new MainLoop()).start();
+
+    // Enable to terminate this worker during runnning by daemonize.
+    Thread mqthread = new Thread(new MainLoop());
+    mqthread.setDaemon(true);
+    mqthread.start();
   }
 
   /** Runs the given Runnable in the thread represented by this
--- a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -597,7 +597,7 @@
         }
         HotSpotVMConfig config = config();
         final int vtableIndex = getVtableIndex((HotSpotResolvedObjectTypeImpl) resolved);
-        return config.instanceKlassVtableStartOffset() + vtableIndex * config.vtableEntrySize + config.vtableEntryMethodOffset;
+        return config.klassVtableStartOffset + vtableIndex * config.vtableEntrySize + config.vtableEntryMethodOffset;
     }
 
     @Override
--- a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -472,8 +472,8 @@
             /* Everything has the core vtable of java.lang.Object */
             return config.baseVtableLength();
         }
-        int result = UNSAFE.getInt(getMetaspaceKlass() + config.instanceKlassVtableLengthOffset) / (config.vtableEntrySize / config.heapWordSize);
-        assert result >= config.baseVtableLength() : UNSAFE.getInt(getMetaspaceKlass() + config.instanceKlassVtableLengthOffset) + " " + config.vtableEntrySize;
+        int result = UNSAFE.getInt(getMetaspaceKlass() + config.klassVtableLengthOffset) / (config.vtableEntrySize / config.heapWordSize);
+        assert result >= config.baseVtableLength() : UNSAFE.getInt(getMetaspaceKlass() + config.klassVtableLengthOffset) + " " + config.vtableEntrySize;
         return result;
     }
 
--- a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -1031,19 +1031,12 @@
     @HotSpotVMField(name = "InstanceKlass::_init_state", type = "u1", get = HotSpotVMField.Type.OFFSET) @Stable public int instanceKlassInitStateOffset;
     @HotSpotVMField(name = "InstanceKlass::_constants", type = "ConstantPool*", get = HotSpotVMField.Type.OFFSET) @Stable public int instanceKlassConstantsOffset;
     @HotSpotVMField(name = "InstanceKlass::_fields", type = "Array<u2>*", get = HotSpotVMField.Type.OFFSET) @Stable public int instanceKlassFieldsOffset;
-    @HotSpotVMField(name = "CompilerToVM::Data::InstanceKlass_vtable_start_offset", type = "int", get = HotSpotVMField.Type.VALUE) @Stable public int instanceKlassVtableStartOffset;
-    @HotSpotVMField(name = "CompilerToVM::Data::InstanceKlass_vtable_length_offset", type = "int", get = HotSpotVMField.Type.VALUE) @Stable public int instanceKlassVtableLengthOffset;
+    @HotSpotVMField(name = "CompilerToVM::Data::Klass_vtable_start_offset", type = "int", get = HotSpotVMField.Type.VALUE) @Stable public int klassVtableStartOffset;
+    @HotSpotVMField(name = "CompilerToVM::Data::Klass_vtable_length_offset", type = "int", get = HotSpotVMField.Type.VALUE) @Stable public int klassVtableLengthOffset;
 
     @HotSpotVMConstant(name = "InstanceKlass::linked") @Stable public int instanceKlassStateLinked;
     @HotSpotVMConstant(name = "InstanceKlass::fully_initialized") @Stable public int instanceKlassStateFullyInitialized;
 
-    /**
-     * See {@code InstanceKlass::vtable_start_offset()}.
-     */
-    public final int instanceKlassVtableStartOffset() {
-        return instanceKlassVtableStartOffset * heapWordSize;
-    }
-
     @HotSpotVMType(name = "arrayOopDesc", get = HotSpotVMType.Type.SIZE) @Stable public int arrayOopDescSize;
 
     /**
--- a/src/os/linux/vm/globals_linux.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/os/linux/vm/globals_linux.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -48,7 +48,10 @@
           "Load DLLs with executable-stack attribute in the VM Thread") \
                                                                         \
   product(bool, UseSHM, false,                                          \
-          "Use SYSV shared memory for large pages")
+          "Use SYSV shared memory for large pages")                     \
+                                                                        \
+  diagnostic(bool, UseCpuAllocPath, false,                              \
+             "Use CPU_ALLOC code path in os::active_processor_count ")
 
 //
 // Defines Linux-specific default values. The flags are available on all
--- a/src/os/linux/vm/os_linux.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/os/linux/vm/os_linux.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,6 +32,7 @@
 #include "compiler/disassembler.hpp"
 #include "interpreter/interpreter.hpp"
 #include "jvm_linux.h"
+#include "logging/log.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/filemap.hpp"
 #include "mutex_linux.inline.hpp"
@@ -106,6 +107,14 @@
 # include <inttypes.h>
 # include <sys/ioctl.h>
 
+#ifndef _GNU_SOURCE
+  #define _GNU_SOURCE
+  #include <sched.h>
+  #undef _GNU_SOURCE
+#else
+  #include <sched.h>
+#endif
+
 // if RUSAGE_THREAD for getrusage() has not been defined, do it here. The code calling
 // getrusage() is prepared to handle the associated failure.
 #ifndef RUSAGE_THREAD
@@ -4762,12 +4771,72 @@
   }
 }
 
+// Get the current number of available processors for this process.
+// This value can change at any time during a process's lifetime.
+// sched_getaffinity gives an accurate answer as it accounts for cpusets.
+// If it appears there may be more than 1024 processors then we do a
+// dynamic check - see 6515172 for details.
+// If anything goes wrong we fallback to returning the number of online
+// processors - which can be greater than the number available to the process.
 int os::active_processor_count() {
-  // Linux doesn't yet have a (official) notion of processor sets,
-  // so just return the number of online processors.
-  int online_cpus = ::sysconf(_SC_NPROCESSORS_ONLN);
-  assert(online_cpus > 0 && online_cpus <= processor_count(), "sanity check");
-  return online_cpus;
+  cpu_set_t cpus;  // can represent at most 1024 (CPU_SETSIZE) processors
+  cpu_set_t* cpus_p = &cpus;
+  int cpus_size = sizeof(cpu_set_t);
+
+  int configured_cpus = processor_count();  // upper bound on available cpus
+  int cpu_count = 0;
+
+  // To enable easy testing of the dynamic path on different platforms we
+  // introduce a diagnostic flag: UseCpuAllocPath
+  if (configured_cpus >= CPU_SETSIZE || UseCpuAllocPath) {
+    // kernel may use a mask bigger than cpu_set_t
+    log_trace(os)("active_processor_count: using dynamic path %s"
+                  "- configured processors: %d",
+                  UseCpuAllocPath ? "(forced) " : "",
+                  configured_cpus);
+    cpus_p = CPU_ALLOC(configured_cpus);
+    if (cpus_p != NULL) {
+      cpus_size = CPU_ALLOC_SIZE(configured_cpus);
+      // zero it just to be safe
+      CPU_ZERO_S(cpus_size, cpus_p);
+    }
+    else {
+       // failed to allocate so fallback to online cpus
+       int online_cpus = ::sysconf(_SC_NPROCESSORS_ONLN);
+       log_trace(os)("active_processor_count: "
+                     "CPU_ALLOC failed (%s) - using "
+                     "online processor count: %d",
+                     strerror(errno), online_cpus);
+       return online_cpus;
+    }
+  }
+  else {
+    log_trace(os)("active_processor_count: using static path - configured processors: %d",
+                  configured_cpus);
+  }
+
+  // pid 0 means the current thread - which we have to assume represents the process
+  if (sched_getaffinity(0, cpus_size, cpus_p) == 0) {
+    if (cpus_p != &cpus) {
+      cpu_count = CPU_COUNT_S(cpus_size, cpus_p);
+    }
+    else {
+      cpu_count = CPU_COUNT(cpus_p);
+    }
+    log_trace(os)("active_processor_count: sched_getaffinity processor count: %d", cpu_count);
+  }
+  else {
+    cpu_count = ::sysconf(_SC_NPROCESSORS_ONLN);
+    warning("sched_getaffinity failed (%s)- using online processor count (%d) "
+            "which may exceed available processors", strerror(errno), cpu_count);
+  }
+
+  if (cpus_p != &cpus) {
+    CPU_FREE(cpus_p);
+  }
+
+  assert(cpu_count > 0 && cpu_count <= processor_count(), "sanity check");
+  return cpu_count;
 }
 
 void os::set_native_thread_name(const char *name) {
--- a/src/os/windows/vm/os_windows.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/os/windows/vm/os_windows.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -5267,8 +5267,29 @@
 
 
 bool os::find(address addr, outputStream* st) {
-  // Nothing yet
-  return false;
+  int offset = -1;
+  bool result = false;
+  char buf[256];
+  if (os::dll_address_to_library_name(addr, buf, sizeof(buf), &offset)) {
+    st->print(PTR_FORMAT " ", addr);
+    if (strlen(buf) < sizeof(buf) - 1) {
+      char* p = strrchr(buf, '\\');
+      if (p) {
+        st->print("%s", p + 1);
+      } else {
+        st->print("%s", buf);
+      }
+    } else {
+        // The library name is probably truncated. Let's omit the library name.
+        // See also JDK-8147512.
+    }
+    if (os::dll_address_to_function_name(addr, buf, sizeof(buf), &offset)) {
+      st->print("::%s + 0x%x", buf, offset);
+    }
+    st->cr();
+    result = true;
+  }
+  return result;
 }
 
 LONG WINAPI os::win32::serialize_fault_filter(struct _EXCEPTION_POINTERS* e) {
--- a/src/os_cpu/windows_x86/vm/os_windows_x86.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/os_cpu/windows_x86/vm/os_windows_x86.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -599,6 +599,7 @@
   // this is only for the "general purpose" registers
 
 #ifdef AMD64
+  st->print("RIP="); print_location(st, uc->Rip);
   st->print("RAX="); print_location(st, uc->Rax);
   st->print("RBX="); print_location(st, uc->Rbx);
   st->print("RCX="); print_location(st, uc->Rcx);
@@ -616,6 +617,7 @@
   st->print("R14="); print_location(st, uc->R14);
   st->print("R15="); print_location(st, uc->R15);
 #else
+  st->print("EIP="); print_location(st, uc->Eip);
   st->print("EAX="); print_location(st, uc->Eax);
   st->print("EBX="); print_location(st, uc->Ebx);
   st->print("ECX="); print_location(st, uc->Ecx);
--- a/src/share/vm/c1/c1_LIRGenerator.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/c1/c1_LIRGenerator.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -2972,8 +2972,8 @@
                           SharedRuntime::get_resolve_virtual_call_stub(),
                           arg_list, info);
       } else {
-        int entry_offset = InstanceKlass::vtable_start_offset() + x->vtable_index() * vtableEntry::size();
-        int vtable_offset = entry_offset * wordSize + vtableEntry::method_offset_in_bytes();
+        int entry_offset = in_bytes(Klass::vtable_start_offset()) + x->vtable_index() * vtableEntry::size_in_bytes();
+        int vtable_offset = entry_offset + vtableEntry::method_offset_in_bytes();
         __ call_virtual(target, receiver, result_register, vtable_offset, arg_list, info);
       }
       break;
--- a/src/share/vm/classfile/classFileParser.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/classfile/classFileParser.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -2705,7 +2705,7 @@
                                      ConstMethod::NORMAL,
                                      CHECK_NULL);
 
-  ClassLoadingService::add_class_method_size(m->size()*HeapWordSize);
+  ClassLoadingService::add_class_method_size(m->size()*wordSize);
 
   // Fill in information from fixed part (access_flags already set)
   m->set_constants(_cp);
@@ -4602,8 +4602,8 @@
       }
     } else if (major_gte_15) {
       // Class file version in the interval [JAVA_1_5_VERSION, JAVA_8_VERSION)
-      if (!is_public || is_static || is_final || is_synchronized ||
-          is_native || !is_abstract || is_strict) {
+      if (!is_public || is_private || is_protected || is_static || is_final ||
+          is_synchronized || is_native || !is_abstract || is_strict) {
         is_illegal = true;
       }
     } else {
--- a/src/share/vm/classfile/compactHashtable.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/classfile/compactHashtable.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -365,14 +365,14 @@
 }
 
 int HashtableTextDump::skip(char must_be_char) {
-  corrupted_if(remain() < 1);
-  corrupted_if(*_p++ != must_be_char);
+  corrupted_if(remain() < 1, "Truncated");
+  corrupted_if(*_p++ != must_be_char, "Unexpected character");
   return 0;
 }
 
 void HashtableTextDump::skip_past(char c) {
   for (;;) {
-    corrupted_if(remain() < 1);
+    corrupted_if(remain() < 1, "Truncated");
     if (*_p++ == c) {
       return;
     }
@@ -381,7 +381,7 @@
 
 void HashtableTextDump::check_version(const char* ver) {
   int len = (int)strlen(ver);
-  corrupted_if(remain() < len);
+  corrupted_if(remain() < len, "Truncated");
   if (strncmp(_p, ver, len) != 0) {
     quit("wrong version of hashtable dump file", _filename);
   }
@@ -451,7 +451,7 @@
 jchar HashtableTextDump::unescape(const char* from, const char* end, int count) {
   jchar value = 0;
 
-  corrupted_if(from + count > end);
+  corrupted_if(from + count > end, "Truncated");
 
   for (int i=0; i<count; i++) {
     char c = *from++;
@@ -486,7 +486,7 @@
     if (*from != '\\') {
       *to++ = *from++;
     } else {
-      corrupted_if(from + 2 > end);
+      corrupted_if(from + 2 > end, "Truncated");
       char c = from[1];
       from += 2;
       switch (c) {
@@ -507,7 +507,7 @@
       }
     }
   }
-  corrupted_if(n > 0); // expected more chars but file has ended
+  corrupted_if(n > 0, "Truncated"); // expected more chars but file has ended
   _p = from;
   skip_newline();
 }
--- a/src/share/vm/classfile/compactHashtable.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/classfile/compactHashtable.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -276,9 +276,9 @@
 
   void corrupted(const char *p, const char *msg);
 
-  inline void corrupted_if(bool cond) {
+  inline void corrupted_if(bool cond, const char *msg) {
     if (cond) {
-      corrupted(_p, NULL);
+      corrupted(_p, msg);
     }
   }
 
@@ -287,27 +287,30 @@
   void skip_past(char c);
   void check_version(const char* ver);
 
-  inline bool get_num(char delim, int *utf8_length) {
+  inline void get_num(char delim, int *num) {
     const char* p   = _p;
     const char* end = _end;
-    int num = 0;
+    u8 n = 0;
 
     while (p < end) {
       char c = *p ++;
       if ('0' <= c && c <= '9') {
-        num = num * 10 + (c - '0');
+        n = n * 10 + (c - '0');
+        if (n > (u8)INT_MAX) {
+          corrupted(_p, "Num overflow");
+        }
       } else if (c == delim) {
         _p = p;
-        *utf8_length = num;
-        return true;
+        *num = (int)n;
+        return;
       } else {
         // Not [0-9], not 'delim'
-        return false;
+        corrupted(_p, "Unrecognized format");;
       }
     }
+
     corrupted(_end, "Incorrect format");
     ShouldNotReachHere();
-    return false;
   }
 
   void scan_prefix_type();
--- a/src/share/vm/classfile/stringTable.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/classfile/stringTable.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -737,7 +737,7 @@
     return false;
   }
   ch_table.dump(top, end);
-  *top = (char*)align_pointer_up(*top, sizeof(void*));
+  *top = (char*)align_ptr_up(*top, sizeof(void*));
 
 #endif
   return true;
@@ -760,7 +760,7 @@
   juint *p = (juint*)buffer;
   const char* end = _shared_table.init(
           CompactHashtable<oop, char>::_string_table, (char*)p);
-  const char* aligned_end = (const char*)align_pointer_up(end, sizeof(void*));
+  const char* aligned_end = (const char*)align_ptr_up(end, sizeof(void*));
 
   if (_ignore_shared_strings) {
     _shared_table.reset();
--- a/src/share/vm/classfile/symbolTable.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/classfile/symbolTable.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -544,7 +544,7 @@
 
   ch_table.dump(top, end);
 
-  *top = (char*)align_pointer_up(*top, sizeof(void*));
+  *top = (char*)align_ptr_up(*top, sizeof(void*));
 #endif
   return true;
 }
@@ -552,7 +552,7 @@
 const char* SymbolTable::init_shared_table(const char* buffer) {
   const char* end = _shared_table.init(
           CompactHashtable<Symbol*, char>::_symbol_table, buffer);
-  return (const char*)align_pointer_up(end, sizeof(void*));
+  return (const char*)align_ptr_up(end, sizeof(void*));
 }
 
 //---------------------------------------------------------------------------
@@ -600,7 +600,7 @@
   tty->print_cr("Symbol Table Histogram:");
   tty->print_cr("  Total number of symbols  %7d", total_count);
   tty->print_cr("  Total size in memory     %7dK",
-          (total_size*HeapWordSize)/1024);
+          (total_size*wordSize)/1024);
   tty->print_cr("  Total counted            %7d", _symbols_counted);
   tty->print_cr("  Total removed            %7d", _symbols_removed);
   if (_symbols_counted > 0) {
@@ -617,11 +617,11 @@
   tty->print_cr("    %6s %10s %10s", "Length", "#Symbols", "Size");
   for (i = 0; i < results_length; i++) {
     if (counts[i] > 0) {
-      tty->print_cr("    %6d %10d %10dK", i, counts[i], (sizes[i]*HeapWordSize)/1024);
+      tty->print_cr("    %6d %10d %10dK", i, counts[i], (sizes[i]*wordSize)/1024);
     }
   }
   tty->print_cr("  >=%6d %10d %10dK\n", results_length,
-          out_of_range_count, (out_of_range_size*HeapWordSize)/1024);
+          out_of_range_count, (out_of_range_size*wordSize)/1024);
 }
 
 void SymbolTable::print() {
--- a/src/share/vm/classfile/verifier.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/classfile/verifier.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, 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
@@ -651,6 +651,7 @@
   int ex_max = -1;
   // Look through each item on the exception table. Each of the fields must refer
   // to a legal instruction.
+  if (was_recursively_verified()) return;
   verify_exception_handler_table(
     code_length, code_data, ex_min, ex_max, CHECK_VERIFY(this));
 
@@ -737,11 +738,14 @@
       // should be used for this check.  So, do the check here before a possible
       // local is added to the type state.
       if (Bytecodes::is_store_into_local(opcode) && bci >= ex_min && bci < ex_max) {
+        if (was_recursively_verified()) return;
         verify_exception_handler_targets(
           bci, this_uninit, &current_frame, &stackmap_table, CHECK_VERIFY(this));
         verified_exc_handlers = true;
       }
 
+      if (was_recursively_verified()) return;
+
       switch (opcode) {
         case Bytecodes::_nop :
           no_control_flow = false; break;
@@ -1730,6 +1734,7 @@
     assert(!(verified_exc_handlers && this_uninit),
       "Exception handler targets got verified before this_uninit got set");
     if (!verified_exc_handlers && bci >= ex_min && bci < ex_max) {
+      if (was_recursively_verified()) return;
       verify_exception_handler_targets(
         bci, this_uninit, &current_frame, &stackmap_table, CHECK_VERIFY(this));
     }
@@ -1767,6 +1772,9 @@
   return code_data;
 }
 
+// Since this method references the constant pool, call was_recursively_verified()
+// before calling this method to make sure a prior class load did not cause the
+// current class to get verified.
 void ClassVerifier::verify_exception_handler_table(u4 code_length, char* code_data, int& min, int& max, TRAPS) {
   ExceptionTable exhandlers(_method());
   int exlength = exhandlers.length();
@@ -1874,7 +1882,11 @@
   return stackmap_index;
 }
 
-void ClassVerifier::verify_exception_handler_targets(u2 bci, bool this_uninit, StackMapFrame* current_frame,
+// Since this method references the constant pool, call was_recursively_verified()
+// before calling this method to make sure a prior class load did not cause the
+// current class to get verified.
+void ClassVerifier::verify_exception_handler_targets(u2 bci, bool this_uninit,
+                                                     StackMapFrame* current_frame,
                                                      StackMapTable* stackmap_table, TRAPS) {
   constantPoolHandle cp (THREAD, _method->constants());
   ExceptionTable exhandlers(_method());
@@ -1889,6 +1901,7 @@
       if (this_uninit) {  flags |= FLAG_THIS_UNINIT; }
       StackMapFrame* new_frame = current_frame->frame_in_exception_handler(flags);
       if (catch_type_index != 0) {
+        if (was_recursively_verified()) return;
         // We know that this index refers to a subclass of Throwable
         VerificationType catch_type = cp_index_to_type(
           catch_type_index, cp, CHECK_VERIFY(this));
@@ -2269,6 +2282,7 @@
     check_protected: {
       if (_this_type == stack_object_type)
         break; // stack_object_type must be assignable to _current_class_type
+      if (was_recursively_verified()) return;
       Symbol* ref_class_name =
         cp->klass_name_at(cp->klass_ref_index_at(index));
       if (!name_in_supers(ref_class_name, current_class()))
@@ -2531,6 +2545,7 @@
       // Check the exception handler target stackmaps with the locals from the
       // incoming stackmap (before initialize_object() changes them to outgoing
       // state).
+      if (was_recursively_verified()) return;
       verify_exception_handler_targets(bci, true, current_frame,
                                        stackmap_table, CHECK_VERIFY(this));
     } // in_try_block
@@ -2548,6 +2563,7 @@
       return;
     }
     u2 new_class_index = Bytes::get_Java_u2(new_bcp + 1);
+    if (was_recursively_verified()) return;
     verify_cp_class_type(bci, new_class_index, cp, CHECK_VERIFY(this));
 
     // The method must be an <init> method of the indicated class
@@ -2567,6 +2583,7 @@
     VerificationType objectref_type = new_class_type;
     if (name_in_supers(ref_class_type.name(), current_class())) {
       Klass* ref_klass = load_class(ref_class_type.name(), CHECK);
+      if (was_recursively_verified()) return;
       Method* m = InstanceKlass::cast(ref_klass)->uncached_lookup_method(
         vmSymbols::object_initializer_name(),
         cp->signature_ref_at(bcs->get_index_u2()),
@@ -2591,6 +2608,7 @@
     // incoming stackmap (before initialize_object() changes them to outgoing
     // state).
     if (in_try_block) {
+      if (was_recursively_verified()) return;
       verify_exception_handler_targets(bci, *this_uninit, current_frame,
                                        stackmap_table, CHECK_VERIFY(this));
     }
@@ -2791,6 +2809,7 @@
       verify_invoke_init(bcs, index, ref_class_type, current_frame,
         code_length, in_try_block, this_uninit, cp, stackmap_table,
         CHECK_VERIFY(this));
+      if (was_recursively_verified()) return;
     } else {   // other methods
       // Ensures that target class is assignable to method class.
       if (opcode == Bytecodes::_invokespecial) {
@@ -2816,6 +2835,7 @@
         VerificationType stack_object_type =
           current_frame->pop_stack(ref_class_type, CHECK_VERIFY(this));
         if (current_type() != stack_object_type) {
+          if (was_recursively_verified()) return;
           assert(cp->cache() == NULL, "not rewritten yet");
           Symbol* ref_class_name =
             cp->klass_name_at(cp->klass_ref_index_at(index));
@@ -2894,6 +2914,7 @@
   current_frame->pop_stack(
     VerificationType::integer_type(), CHECK_VERIFY(this));
 
+  if (was_recursively_verified()) return;
   VerificationType component_type =
     cp_index_to_type(index, cp, CHECK_VERIFY(this));
   int length;
--- a/src/share/vm/gc/cms/cmsCollectorPolicy.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/cms/cmsCollectorPolicy.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,6 +35,7 @@
 #include "gc/shared/space.hpp"
 #include "gc/shared/vmGCOperations.hpp"
 #include "memory/universe.hpp"
+#include "oops/oop.inline.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/globals_extension.hpp"
 #include "runtime/handles.inline.hpp"
--- a/src/share/vm/gc/cms/cmsOopClosures.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/cms/cmsOopClosures.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2016, 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
@@ -40,15 +40,9 @@
 class ParMarkFromRootsClosure;
 
 // Decode the oop and call do_oop on it.
-#define DO_OOP_WORK_DEFN \
-  void do_oop(oop obj);                                   \
-  template <class T> inline void do_oop_work(T* p) {      \
-    T heap_oop = oopDesc::load_heap_oop(p);               \
-    if (!oopDesc::is_null(heap_oop)) {                    \
-      oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);       \
-      do_oop(obj);                                        \
-    }                                                     \
-  }
+#define DO_OOP_WORK_DEFN                             \
+  void do_oop(oop obj);                              \
+  template <class T> inline void do_oop_work(T* p);
 
 // TODO: This duplication of the MetadataAwareOopClosure class is only needed
 //       because some CMS OopClosures derive from OopsInGenClosure. It would be
@@ -131,8 +125,8 @@
                      bool concurrent_precleaning);
   virtual void do_oop(oop* p);
   virtual void do_oop(narrowOop* p);
-  inline void do_oop_nv(oop* p)       { PushAndMarkClosure::do_oop_work(p); }
-  inline void do_oop_nv(narrowOop* p) { PushAndMarkClosure::do_oop_work(p); }
+  inline void do_oop_nv(oop* p);
+  inline void do_oop_nv(narrowOop* p);
 };
 
 // In the parallel case, the bit map and the
@@ -157,8 +151,8 @@
                         OopTaskQueue* work_queue);
   virtual void do_oop(oop* p);
   virtual void do_oop(narrowOop* p);
-  inline void do_oop_nv(oop* p)       { ParPushAndMarkClosure::do_oop_work(p); }
-  inline void do_oop_nv(narrowOop* p) { ParPushAndMarkClosure::do_oop_work(p); }
+  inline void do_oop_nv(oop* p);
+  inline void do_oop_nv(narrowOop* p);
 };
 
 // The non-parallel version (the parallel version appears further below).
@@ -186,8 +180,8 @@
                              bool concurrent_precleaning);
   virtual void do_oop(oop* p);
   virtual void do_oop(narrowOop* p);
-  inline void do_oop_nv(oop* p)       { MarkRefsIntoAndScanClosure::do_oop_work(p); }
-  inline void do_oop_nv(narrowOop* p) { MarkRefsIntoAndScanClosure::do_oop_work(p); }
+  inline void do_oop_nv(oop* p);
+  inline void do_oop_nv(narrowOop* p);
 
   void set_freelistLock(Mutex* m) {
     _freelistLock = m;
@@ -220,8 +214,8 @@
                                  OopTaskQueue* work_queue);
   virtual void do_oop(oop* p);
   virtual void do_oop(narrowOop* p);
-  inline void do_oop_nv(oop* p)       { ParMarkRefsIntoAndScanClosure::do_oop_work(p); }
-  inline void do_oop_nv(narrowOop* p) { ParMarkRefsIntoAndScanClosure::do_oop_work(p); }
+  inline void do_oop_nv(oop* p);
+  inline void do_oop_nv(narrowOop* p);
 
   void trim_queue(uint size);
 };
@@ -249,8 +243,8 @@
                     MarkFromRootsClosure* parent);
   virtual void do_oop(oop* p);
   virtual void do_oop(narrowOop* p);
-  inline void do_oop_nv(oop* p)       { PushOrMarkClosure::do_oop_work(p); }
-  inline void do_oop_nv(narrowOop* p) { PushOrMarkClosure::do_oop_work(p); }
+  inline void do_oop_nv(oop* p);
+  inline void do_oop_nv(narrowOop* p);
 
   // Deal with a stack overflow condition
   void handle_stack_overflow(HeapWord* lost);
@@ -287,8 +281,8 @@
                        ParMarkFromRootsClosure* parent);
   virtual void do_oop(oop* p);
   virtual void do_oop(narrowOop* p);
-  inline void do_oop_nv(oop* p)       { ParPushOrMarkClosure::do_oop_work(p); }
-  inline void do_oop_nv(narrowOop* p) { ParPushOrMarkClosure::do_oop_work(p); }
+  inline void do_oop_nv(oop* p);
+  inline void do_oop_nv(narrowOop* p);
 
   // Deal with a stack overflow condition
   void handle_stack_overflow(HeapWord* lost);
@@ -318,8 +312,8 @@
   bool    concurrent_precleaning() const { return _concurrent_precleaning; }
   virtual void do_oop(oop* p);
   virtual void do_oop(narrowOop* p);
-  inline void do_oop_nv(oop* p)       { CMSKeepAliveClosure::do_oop_work(p); }
-  inline void do_oop_nv(narrowOop* p) { CMSKeepAliveClosure::do_oop_work(p); }
+  inline void do_oop_nv(oop* p);
+  inline void do_oop_nv(narrowOop* p);
 };
 
 class CMSInnerParMarkAndPushClosure: public MetadataAwareOopClosure {
@@ -336,8 +330,8 @@
                                 OopTaskQueue* work_queue);
   virtual void do_oop(oop* p);
   virtual void do_oop(narrowOop* p);
-  inline void do_oop_nv(oop* p)       { CMSInnerParMarkAndPushClosure::do_oop_work(p); }
-  inline void do_oop_nv(narrowOop* p) { CMSInnerParMarkAndPushClosure::do_oop_work(p); }
+  inline void do_oop_nv(oop* p);
+  inline void do_oop_nv(narrowOop* p);
 };
 
 // A parallel (MT) version of the above, used when
--- a/src/share/vm/gc/cms/cmsOopClosures.inline.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/cms/cmsOopClosures.inline.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,21 +30,6 @@
 #include "gc/shared/taskqueue.inline.hpp"
 #include "oops/oop.inline.hpp"
 
-// Trim our work_queue so its length is below max at return
-inline void ParMarkRefsIntoAndScanClosure::trim_queue(uint max) {
-  while (_work_queue->size() > max) {
-    oop newOop;
-    if (_work_queue->pop_local(newOop)) {
-      assert(newOop->is_oop(), "Expected an oop");
-      assert(_bit_map->isMarked((HeapWord*)newOop),
-             "only grey objects on this stack");
-      // iterate over the oops in this oop, marking and pushing
-      // the ones in CMS heap (i.e. in _span).
-      newOop->oop_iterate(&_parPushAndMarkClosure);
-    }
-  }
-}
-
 // MetadataAwareOopClosure and MetadataAwareOopsInGenClosure are duplicated,
 // until we get rid of OopsInGenClosure.
 
@@ -61,4 +46,48 @@
   cld->oops_do(_klass_closure._oop_closure, &_klass_closure, claim);
 }
 
+// Decode the oop and call do_oop on it.
+#define DO_OOP_WORK_IMPL(cls)                                 \
+  template <class T> void cls::do_oop_work(T* p) {            \
+    T heap_oop = oopDesc::load_heap_oop(p);                   \
+    if (!oopDesc::is_null(heap_oop)) {                        \
+      oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);  \
+      do_oop(obj);                                            \
+    }                                                         \
+  }
+
+#define DO_OOP_WORK_NV_IMPL(cls)                              \
+  DO_OOP_WORK_IMPL(cls)                                       \
+  void cls::do_oop_nv(oop* p)       { cls::do_oop_work(p); }  \
+  void cls::do_oop_nv(narrowOop* p) { cls::do_oop_work(p); }
+
+DO_OOP_WORK_IMPL(MarkRefsIntoClosure)
+DO_OOP_WORK_IMPL(ParMarkRefsIntoClosure)
+DO_OOP_WORK_IMPL(MarkRefsIntoVerifyClosure)
+DO_OOP_WORK_NV_IMPL(PushAndMarkClosure)
+DO_OOP_WORK_NV_IMPL(ParPushAndMarkClosure)
+DO_OOP_WORK_NV_IMPL(MarkRefsIntoAndScanClosure)
+DO_OOP_WORK_NV_IMPL(ParMarkRefsIntoAndScanClosure)
+
+// Trim our work_queue so its length is below max at return
+inline void ParMarkRefsIntoAndScanClosure::trim_queue(uint max) {
+  while (_work_queue->size() > max) {
+    oop newOop;
+    if (_work_queue->pop_local(newOop)) {
+      assert(newOop->is_oop(), "Expected an oop");
+      assert(_bit_map->isMarked((HeapWord*)newOop),
+             "only grey objects on this stack");
+      // iterate over the oops in this oop, marking and pushing
+      // the ones in CMS heap (i.e. in _span).
+      newOop->oop_iterate(&_parPushAndMarkClosure);
+    }
+  }
+}
+
+DO_OOP_WORK_NV_IMPL(PushOrMarkClosure)
+DO_OOP_WORK_NV_IMPL(ParPushOrMarkClosure)
+DO_OOP_WORK_NV_IMPL(CMSKeepAliveClosure)
+DO_OOP_WORK_NV_IMPL(CMSInnerParMarkAndPushClosure)
+DO_OOP_WORK_IMPL(CMSParKeepAliveClosure)
+
 #endif // SHARE_VM_GC_CMS_CMSOOPCLOSURES_INLINE_HPP
--- a/src/share/vm/gc/cms/compactibleFreeListSpace.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/cms/compactibleFreeListSpace.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, 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
@@ -219,6 +219,10 @@
   }
 }
 
+size_t CompactibleFreeListSpace::obj_size(const HeapWord* addr) const {
+  return adjustObjectSize(oop(addr)->size());
+}
+
 void CompactibleFreeListSpace::resetIndexedFreeListArray() {
   for (size_t i = 1; i < IndexSetSize; i++) {
     assert(_indexedFreeList[i].size() == (size_t) i,
--- a/src/share/vm/gc/cms/compactibleFreeListSpace.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/cms/compactibleFreeListSpace.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, 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
@@ -313,9 +313,7 @@
     return adjustObjectSize(size);
   }
 
-  inline size_t obj_size(const HeapWord* addr) const {
-    return adjustObjectSize(oop(addr)->size());
-  }
+  inline size_t obj_size(const HeapWord* addr) const;
 
  protected:
   // Reset the indexed free list to its initial empty condition.
--- a/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, 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
@@ -3324,6 +3324,8 @@
   }
 };
 
+DO_OOP_WORK_IMPL(ParConcMarkingClosure)
+
 // Grey object scanning during work stealing phase --
 // the salient assumption here is that any references
 // that are in these stolen objects being scanned must
--- a/src/share/vm/gc/cms/parNewGeneration.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/cms/parNewGeneration.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,7 @@
 #include "gc/cms/parOopClosures.inline.hpp"
 #include "gc/serial/defNewGeneration.inline.hpp"
 #include "gc/shared/adaptiveSizePolicy.hpp"
-#include "gc/shared/ageTable.hpp"
+#include "gc/shared/ageTable.inline.hpp"
 #include "gc/shared/copyFailedInfo.hpp"
 #include "gc/shared/gcHeapSummary.hpp"
 #include "gc/shared/gcTimer.hpp"
@@ -414,7 +414,7 @@
 }
 
 void ParScanThreadStateSet::print_taskqueue_stats() {
-  if (!develop_log_is_enabled(Trace, gc, task, stats)) {
+  if (!log_develop_is_enabled(Trace, gc, task, stats)) {
     return;
   }
   LogHandle(gc, task, stats) log;
--- a/src/share/vm/gc/cms/promotionInfo.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/cms/promotionInfo.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,6 +34,31 @@
 /////////////////////////////////////////////////////////////////////////
 
 
+PromotedObject* PromotedObject::next() const {
+  assert(!((FreeChunk*)this)->is_free(), "Error");
+  PromotedObject* res;
+  if (UseCompressedOops) {
+    // The next pointer is a compressed oop stored in the top 32 bits
+    res = (PromotedObject*)oopDesc::decode_heap_oop(_data._narrow_next);
+  } else {
+    res = (PromotedObject*)(_next & next_mask);
+  }
+  assert(oop(res)->is_oop_or_null(true /* ignore mark word */), "Expected an oop or NULL at " PTR_FORMAT, p2i(oop(res)));
+  return res;
+}
+
+inline void PromotedObject::setNext(PromotedObject* x) {
+  assert(((intptr_t)x & ~next_mask) == 0, "Conflict in bit usage, "
+         "or insufficient alignment of objects");
+  if (UseCompressedOops) {
+    assert(_data._narrow_next == 0, "Overwrite?");
+    _data._narrow_next = oopDesc::encode_heap_oop(oop(x));
+  } else {
+    _next |= (intptr_t)x;
+  }
+  assert(!((FreeChunk*)this)->is_free(), "Error");
+}
+
 //////////////////////////////////////////////////////////////////////////////
 // We go over the list of promoted objects, removing each from the list,
 // and applying the closure (this may, in turn, add more elements to
--- a/src/share/vm/gc/cms/promotionInfo.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/cms/promotionInfo.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2016, 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
@@ -64,29 +64,8 @@
     Data     _data;
   };
  public:
-  inline PromotedObject* next() const {
-    assert(!((FreeChunk*)this)->is_free(), "Error");
-    PromotedObject* res;
-    if (UseCompressedOops) {
-      // The next pointer is a compressed oop stored in the top 32 bits
-      res = (PromotedObject*)oopDesc::decode_heap_oop(_data._narrow_next);
-    } else {
-      res = (PromotedObject*)(_next & next_mask);
-    }
-    assert(oop(res)->is_oop_or_null(true /* ignore mark word */), "Expected an oop or NULL at " PTR_FORMAT, p2i(oop(res)));
-    return res;
-  }
-  inline void setNext(PromotedObject* x) {
-    assert(((intptr_t)x & ~next_mask) == 0, "Conflict in bit usage, "
-           "or insufficient alignment of objects");
-    if (UseCompressedOops) {
-      assert(_data._narrow_next == 0, "Overwrite?");
-      _data._narrow_next = oopDesc::encode_heap_oop(oop(x));
-    } else {
-      _next |= (intptr_t)x;
-    }
-    assert(!((FreeChunk*)this)->is_free(), "Error");
-  }
+  PromotedObject* next() const;
+  void setNext(PromotedObject* x);
   inline void setPromotedMark() {
     _next |= promoted_mask;
     assert(!((FreeChunk*)this)->is_free(), "Error");
--- a/src/share/vm/gc/g1/concurrentMark.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/g1/concurrentMark.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -31,6 +31,7 @@
 #include "gc/g1/g1CollectedHeap.inline.hpp"
 #include "gc/g1/g1CollectorPolicy.hpp"
 #include "gc/g1/g1CollectorState.hpp"
+#include "gc/g1/g1HeapVerifier.hpp"
 #include "gc/g1/g1OopClosures.inline.hpp"
 #include "gc/g1/g1StringDedup.hpp"
 #include "gc/g1/heapRegion.inline.hpp"
@@ -1062,7 +1063,7 @@
     g1h->prepare_for_verify();
     Universe::verify(VerifyOption_G1UsePrevMarking, "During GC (before)");
   }
-  g1h->check_bitmaps("Remark Start");
+  g1h->verifier()->check_bitmaps("Remark Start");
 
   G1CollectorPolicy* g1p = g1h->g1_policy();
   g1p->record_concurrent_mark_remark_start();
@@ -1111,7 +1112,7 @@
       g1h->prepare_for_verify();
       Universe::verify(VerifyOption_G1UseNextMarking, "During GC (after)");
     }
-    g1h->check_bitmaps("Remark End");
+    g1h->verifier()->check_bitmaps("Remark End");
     assert(!restart_for_overflow(), "sanity");
     // Completely reset the marking state since marking completed
     set_non_marking_state();
@@ -1605,14 +1606,14 @@
     return;
   }
 
-  g1h->verify_region_sets_optional();
+  g1h->verifier()->verify_region_sets_optional();
 
   if (VerifyDuringGC) {
     HandleMark hm;  // handle scope
     g1h->prepare_for_verify();
     Universe::verify(VerifyOption_G1UsePrevMarking, "During GC (before)");
   }
-  g1h->check_bitmaps("Cleanup Start");
+  g1h->verifier()->check_bitmaps("Cleanup Start");
 
   G1CollectorPolicy* g1p = g1h->g1_policy();
   g1p->record_concurrent_mark_cleanup_start();
@@ -1702,9 +1703,9 @@
     Universe::verify(VerifyOption_G1UsePrevMarking, "During GC (after)");
   }
 
-  g1h->check_bitmaps("Cleanup End");
-
-  g1h->verify_region_sets_optional();
+  g1h->verifier()->check_bitmaps("Cleanup End");
+
+  g1h->verifier()->verify_region_sets_optional();
 
   // We need to make this be a "collection" so any collection pause that
   // races with it goes around and waits for completeCleanup to finish.
--- a/src/share/vm/gc/g1/concurrentMark.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/g1/concurrentMark.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, 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
@@ -96,12 +96,7 @@
   }
 
   // The argument addr should be the start address of a valid object
-  HeapWord* nextObject(HeapWord* addr) {
-    oop obj = (oop) addr;
-    HeapWord* res =  addr + obj->size();
-    assert(offsetToHeapWord(heapWordToOffset(res)) == res, "sanity");
-    return res;
-  }
+  inline HeapWord* nextObject(HeapWord* addr);
 
   void print_on_error(outputStream* st, const char* prefix) const;
 
@@ -627,14 +622,7 @@
   // If marking is not in progress, it's a no-op.
   void verify_no_cset_oops() PRODUCT_RETURN;
 
-  bool isPrevMarked(oop p) const {
-    assert(p != NULL && p->is_oop(), "expected an oop");
-    HeapWord* addr = (HeapWord*)p;
-    assert(addr >= _prevMarkBitMap->startWord() ||
-           addr < _prevMarkBitMap->endWord(), "in a region");
-
-    return _prevMarkBitMap->isMarked(addr);
-  }
+  inline bool isPrevMarked(oop p) const;
 
   inline bool do_yield_check(uint worker_i = 0);
 
--- a/src/share/vm/gc/g1/concurrentMark.inline.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/g1/concurrentMark.inline.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, 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
@@ -185,6 +185,14 @@
   return true;
 }
 
+// The argument addr should be the start address of a valid object
+HeapWord* CMBitMapRO::nextObject(HeapWord* addr) {
+  oop obj = (oop) addr;
+  HeapWord* res =  addr + obj->size();
+  assert(offsetToHeapWord(heapWordToOffset(res)) == res, "sanity");
+  return res;
+}
+
 #define check_mark(addr)                                                       \
   assert(_bmStartWord <= (addr) && (addr) < (_bmStartWord + _bmWordSize),      \
          "outside underlying space?");                                         \
@@ -353,6 +361,15 @@
   ((CMBitMap*)_prevMarkBitMap)->mark((HeapWord*) p);
 }
 
+bool ConcurrentMark::isPrevMarked(oop p) const {
+  assert(p != NULL && p->is_oop(), "expected an oop");
+  HeapWord* addr = (HeapWord*)p;
+  assert(addr >= _prevMarkBitMap->startWord() ||
+         addr < _prevMarkBitMap->endWord(), "in a region");
+
+  return _prevMarkBitMap->isMarked(addr);
+}
+
 inline void ConcurrentMark::grayRoot(oop obj, size_t word_size,
                                      uint worker_id, HeapRegion* hr) {
   assert(obj != NULL, "pre-condition");
--- a/src/share/vm/gc/g1/g1Allocator.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/g1/g1Allocator.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, 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
@@ -438,7 +438,7 @@
   // If an end alignment was requested, insert filler objects.
   if (end_alignment_in_bytes != 0) {
     HeapWord* currtop = _allocation_region->top();
-    HeapWord* newtop = (HeapWord*)align_pointer_up(currtop, end_alignment_in_bytes);
+    HeapWord* newtop = (HeapWord*)align_ptr_up(currtop, end_alignment_in_bytes);
     size_t fill_size = pointer_delta(newtop, currtop);
     if (fill_size != 0) {
       if (fill_size < CollectedHeap::min_fill_size()) {
@@ -447,8 +447,8 @@
         // region boundary because the max supported alignment is smaller than the min
         // region size, and because the allocation code never leaves space smaller than
         // the min_fill_size at the top of the current allocation region.
-        newtop = (HeapWord*)align_pointer_up(currtop + CollectedHeap::min_fill_size(),
-                                             end_alignment_in_bytes);
+        newtop = (HeapWord*)align_ptr_up(currtop + CollectedHeap::min_fill_size(),
+                                         end_alignment_in_bytes);
         fill_size = pointer_delta(newtop, currtop);
       }
       HeapWord* fill = archive_mem_allocate(fill_size);
--- a/src/share/vm/gc/g1/g1CodeCacheRemSet.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/g1/g1CodeCacheRemSet.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, 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
@@ -74,10 +74,16 @@
   static size_t static_mem_size() {
     return sizeof(_purge_list);
   }
+
+  size_t mem_size();
 };
 
 CodeRootSetTable* volatile CodeRootSetTable::_purge_list = NULL;
 
+size_t CodeRootSetTable::mem_size() {
+  return sizeof(CodeRootSetTable) + (entry_size() * number_of_entries()) + (sizeof(HashtableBucket<mtGC>) * table_size());
+}
+
 CodeRootSetTable::Entry* CodeRootSetTable::new_entry(nmethod* nm) {
   unsigned int hash = compute_hash(nm);
   Entry* entry = (Entry*) new_entry_free_list();
@@ -232,7 +238,6 @@
   OrderAccess::release_store_ptr(&_table, temp);
 }
 
-
 void G1CodeRootSet::purge() {
   CodeRootSetTable::purge();
 }
@@ -247,12 +252,13 @@
     allocate_small_table();
   }
   added = _table->add(method);
-  if (_length == Threshold) {
-    move_to_large();
-  }
   if (added) {
+    if (_length == Threshold) {
+      move_to_large();
+    }
     ++_length;
   }
+  assert(_length == (size_t)_table->number_of_entries(), "sizes should match");
 }
 
 bool G1CodeRootSet::remove(nmethod* method) {
@@ -266,11 +272,13 @@
       clear();
     }
   }
+  assert((_length == 0 && _table == NULL) ||
+         (_length == (size_t)_table->number_of_entries()), "sizes should match");
   return removed;
 }
 
 bool G1CodeRootSet::contains(nmethod* method) {
-  CodeRootSetTable* table = load_acquire_table();
+  CodeRootSetTable* table = load_acquire_table(); // contains() may be called outside of lock, so ensure mem sync.
   if (table != NULL) {
     return table->contains(method);
   }
@@ -284,8 +292,7 @@
 }
 
 size_t G1CodeRootSet::mem_size() {
-  return sizeof(*this) +
-      (_table != NULL ? sizeof(CodeRootSetTable) + _table->entry_size() * _length : 0);
+  return sizeof(*this) + (_table != NULL ? _table->mem_size() : 0);
 }
 
 void G1CodeRootSet::nmethods_do(CodeBlobClosure* blk) const {
--- a/src/share/vm/gc/g1/g1CollectedHeap.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/g1/g1CollectedHeap.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -38,6 +38,8 @@
 #include "gc/g1/g1CollectorState.hpp"
 #include "gc/g1/g1EvacStats.inline.hpp"
 #include "gc/g1/g1GCPhaseTimes.hpp"
+#include "gc/g1/g1HeapTransition.hpp"
+#include "gc/g1/g1HeapVerifier.hpp"
 #include "gc/g1/g1MarkSweep.hpp"
 #include "gc/g1/g1OopClosures.inline.hpp"
 #include "gc/g1/g1ParScanThreadState.inline.hpp"
@@ -60,7 +62,7 @@
 #include "gc/shared/gcTraceTime.inline.hpp"
 #include "gc/shared/generationSpec.hpp"
 #include "gc/shared/isGCActiveMark.hpp"
-#include "gc/shared/referenceProcessor.hpp"
+#include "gc/shared/referenceProcessor.inline.hpp"
 #include "gc/shared/taskqueue.inline.hpp"
 #include "logging/log.hpp"
 #include "memory/allocation.hpp"
@@ -399,7 +401,7 @@
   assert(hr->bottom() < obj_top && obj_top <= hr->end(),
          "obj_top should be in last region");
 
-  check_bitmaps("Humongous Region Allocation", first_hr);
+  _verifier->check_bitmaps("Humongous Region Allocation", first_hr);
 
   assert(words_not_fillable == 0 ||
          first_hr->bottom() + word_size_sum - words_not_fillable == hr->top(),
@@ -427,7 +429,7 @@
 HeapWord* G1CollectedHeap::humongous_obj_allocate(size_t word_size, AllocationContext_t context) {
   assert_heap_locked_or_at_safepoint(true /* should_be_vm_thread */);
 
-  verify_region_sets_optional();
+  _verifier->verify_region_sets_optional();
 
   uint first = G1_NO_HRM_INDEX;
   uint obj_regions = (uint) humongous_obj_size_in_regions(word_size);
@@ -501,7 +503,7 @@
     g1mm()->update_sizes();
   }
 
-  verify_region_sets_optional();
+  _verifier->verify_region_sets_optional();
 
   return result;
 }
@@ -1230,7 +1232,7 @@
 
   size_t metadata_prev_used = MetaspaceAux::used_bytes();
 
-  verify_region_sets_optional();
+  _verifier->verify_region_sets_optional();
 
   const bool do_clear_all_soft_refs = clear_all_soft_refs ||
                            collector_policy()->should_clear_all_soft_refs();
@@ -1249,6 +1251,7 @@
       TraceCollectorStats tcs(g1mm()->full_collection_counters());
       TraceMemoryManagerStats tms(true /* fullGC */, gc_cause());
 
+      G1HeapTransition heap_transition(this);
       g1_policy()->record_full_collection_start();
 
       // Note: When we have a more flexible GC logging framework that
@@ -1271,9 +1274,9 @@
 
       assert(used() == recalculate_used(), "Should be equal");
 
-      verify_before_gc();
-
-      check_bitmaps("Full GC Start");
+      _verifier->verify_before_gc();
+
+      _verifier->check_bitmaps("Full GC Start");
       pre_full_gc_dump(gc_timer);
 
 #if defined(COMPILER2) || INCLUDE_JVMCI
@@ -1408,9 +1411,9 @@
       increment_old_marking_cycles_completed(false /* concurrent */);
 
       _hrm.verify_optional();
-      verify_region_sets_optional();
-
-      verify_after_gc();
+      _verifier->verify_region_sets_optional();
+
+      _verifier->verify_after_gc();
 
       // Clear the previous marking bitmap, if needed for bitmap verification.
       // Note we cannot do this when we clear the next marking bitmap in
@@ -1422,7 +1425,7 @@
       if (G1VerifyBitmaps) {
         ((CMBitMap*) concurrent_mark()->prevMarkBitMap())->clearAll();
       }
-      check_bitmaps("Full GC End");
+      _verifier->check_bitmaps("Full GC End");
 
       // Start a new incremental collection set for the next pause
       assert(g1_policy()->collection_set() == NULL, "must be");
@@ -1441,15 +1444,15 @@
       g1mm()->update_sizes();
 
       gc_epilogue(true);
+
+      heap_transition.print();
+
+      print_heap_after_gc();
+      trace_heap_after_gc(gc_tracer);
+
+      post_full_gc_dump(gc_timer);
     }
 
-    g1_policy()->print_detailed_heap_transition();
-
-    print_heap_after_gc();
-    trace_heap_after_gc(gc_tracer);
-
-    post_full_gc_dump(gc_timer);
-
     gc_timer->register_gc_end();
     gc_tracer->report_gc_end(gc_timer->gc_end(), gc_timer->time_partitions());
   }
@@ -1639,7 +1642,7 @@
 HeapWord* G1CollectedHeap::expand_and_allocate(size_t word_size, AllocationContext_t context) {
   assert_at_safepoint(true /* should_be_vm_thread */);
 
-  verify_region_sets_optional();
+  _verifier->verify_region_sets_optional();
 
   size_t expand_bytes = MAX2(word_size * HeapWordSize, MinHeapDeltaBytes);
   log_debug(gc, ergo, heap)("Attempt heap expansion (allocation request failed). Allocation request: " SIZE_FORMAT "B",
@@ -1648,7 +1651,7 @@
 
   if (expand(expand_bytes)) {
     _hrm.verify_optional();
-    verify_region_sets_optional();
+    _verifier->verify_region_sets_optional();
     return attempt_allocation_at_safepoint(word_size,
                                            context,
                                            false /* expect_null_mutator_alloc_region */);
@@ -1717,7 +1720,7 @@
 }
 
 void G1CollectedHeap::shrink(size_t shrink_bytes) {
-  verify_region_sets_optional();
+  _verifier->verify_region_sets_optional();
 
   // We should only reach here at the end of a Full GC which means we
   // should not not be holding to any GC alloc regions. The method
@@ -1732,7 +1735,7 @@
   rebuild_region_sets(true /* free_list_only */);
 
   _hrm.verify_optional();
-  verify_region_sets_optional();
+  _verifier->verify_region_sets_optional();
 }
 
 // Public methods.
@@ -1778,6 +1781,7 @@
                           /* are_GC_task_threads */true,
                           /* are_ConcurrentGC_threads */false);
   _workers->initialize_workers();
+  _verifier = new G1HeapVerifier(this);
 
   _allocator = G1Allocator::create_allocator(this);
   _humongous_object_threshold_in_words = humongous_threshold_for(HeapRegion::GrainWords);
@@ -2667,452 +2671,11 @@
 }
 
 void G1CollectedHeap::prepare_for_verify() {
-  if (SafepointSynchronize::is_at_safepoint() || ! UseTLAB) {
-    ensure_parsability(false);
-  }
-  g1_rem_set()->prepare_for_verify();
+  _verifier->prepare_for_verify();
 }
 
-bool G1CollectedHeap::allocated_since_marking(oop obj, HeapRegion* hr,
-                                              VerifyOption vo) {
-  switch (vo) {
-  case VerifyOption_G1UsePrevMarking:
-    return hr->obj_allocated_since_prev_marking(obj);
-  case VerifyOption_G1UseNextMarking:
-    return hr->obj_allocated_since_next_marking(obj);
-  case VerifyOption_G1UseMarkWord:
-    return false;
-  default:
-    ShouldNotReachHere();
-  }
-  return false; // keep some compilers happy
-}
-
-HeapWord* G1CollectedHeap::top_at_mark_start(HeapRegion* hr, VerifyOption vo) {
-  switch (vo) {
-  case VerifyOption_G1UsePrevMarking: return hr->prev_top_at_mark_start();
-  case VerifyOption_G1UseNextMarking: return hr->next_top_at_mark_start();
-  case VerifyOption_G1UseMarkWord:    return NULL;
-  default:                            ShouldNotReachHere();
-  }
-  return NULL; // keep some compilers happy
-}
-
-bool G1CollectedHeap::is_marked(oop obj, VerifyOption vo) {
-  switch (vo) {
-  case VerifyOption_G1UsePrevMarking: return isMarkedPrev(obj);
-  case VerifyOption_G1UseNextMarking: return isMarkedNext(obj);
-  case VerifyOption_G1UseMarkWord:    return obj->is_gc_marked();
-  default:                            ShouldNotReachHere();
-  }
-  return false; // keep some compilers happy
-}
-
-const char* G1CollectedHeap::top_at_mark_start_str(VerifyOption vo) {
-  switch (vo) {
-  case VerifyOption_G1UsePrevMarking: return "PTAMS";
-  case VerifyOption_G1UseNextMarking: return "NTAMS";
-  case VerifyOption_G1UseMarkWord:    return "NONE";
-  default:                            ShouldNotReachHere();
-  }
-  return NULL; // keep some compilers happy
-}
-
-class VerifyRootsClosure: public OopClosure {
-private:
-  G1CollectedHeap* _g1h;
-  VerifyOption     _vo;
-  bool             _failures;
-public:
-  // _vo == UsePrevMarking -> use "prev" marking information,
-  // _vo == UseNextMarking -> use "next" marking information,
-  // _vo == UseMarkWord    -> use mark word from object header.
-  VerifyRootsClosure(VerifyOption vo) :
-    _g1h(G1CollectedHeap::heap()),
-    _vo(vo),
-    _failures(false) { }
-
-  bool failures() { return _failures; }
-
-  template <class T> void do_oop_nv(T* p) {
-    T heap_oop = oopDesc::load_heap_oop(p);
-    if (!oopDesc::is_null(heap_oop)) {
-      oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
-      if (_g1h->is_obj_dead_cond(obj, _vo)) {
-        LogHandle(gc, verify) log;
-        log.info("Root location " PTR_FORMAT " points to dead obj " PTR_FORMAT, p2i(p), p2i(obj));
-        if (_vo == VerifyOption_G1UseMarkWord) {
-          log.info("  Mark word: " PTR_FORMAT, p2i(obj->mark()));
-        }
-        ResourceMark rm;
-        obj->print_on(log.info_stream());
-        _failures = true;
-      }
-    }
-  }
-
-  void do_oop(oop* p)       { do_oop_nv(p); }
-  void do_oop(narrowOop* p) { do_oop_nv(p); }
-};
-
-class G1VerifyCodeRootOopClosure: public OopClosure {
-  G1CollectedHeap* _g1h;
-  OopClosure* _root_cl;
-  nmethod* _nm;
-  VerifyOption _vo;
-  bool _failures;
-
-  template <class T> void do_oop_work(T* p) {
-    // First verify that this root is live
-    _root_cl->do_oop(p);
-
-    if (!G1VerifyHeapRegionCodeRoots) {
-      // We're not verifying the code roots attached to heap region.
-      return;
-    }
-
-    // Don't check the code roots during marking verification in a full GC
-    if (_vo == VerifyOption_G1UseMarkWord) {
-      return;
-    }
-
-    // Now verify that the current nmethod (which contains p) is
-    // in the code root list of the heap region containing the
-    // object referenced by p.
-
-    T heap_oop = oopDesc::load_heap_oop(p);
-    if (!oopDesc::is_null(heap_oop)) {
-      oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
-
-      // Now fetch the region containing the object
-      HeapRegion* hr = _g1h->heap_region_containing(obj);
-      HeapRegionRemSet* hrrs = hr->rem_set();
-      // Verify that the strong code root list for this region
-      // contains the nmethod
-      if (!hrrs->strong_code_roots_list_contains(_nm)) {
-        log_info(gc, verify)("Code root location " PTR_FORMAT " "
-                             "from nmethod " PTR_FORMAT " not in strong "
-                             "code roots for region [" PTR_FORMAT "," PTR_FORMAT ")",
-                             p2i(p), p2i(_nm), p2i(hr->bottom()), p2i(hr->end()));
-        _failures = true;
-      }
-    }
-  }
-
-public:
-  G1VerifyCodeRootOopClosure(G1CollectedHeap* g1h, OopClosure* root_cl, VerifyOption vo):
-    _g1h(g1h), _root_cl(root_cl), _vo(vo), _nm(NULL), _failures(false) {}
-
-  void do_oop(oop* p) { do_oop_work(p); }
-  void do_oop(narrowOop* p) { do_oop_work(p); }
-
-  void set_nmethod(nmethod* nm) { _nm = nm; }
-  bool failures() { return _failures; }
-};
-
-class G1VerifyCodeRootBlobClosure: public CodeBlobClosure {
-  G1VerifyCodeRootOopClosure* _oop_cl;
-
-public:
-  G1VerifyCodeRootBlobClosure(G1VerifyCodeRootOopClosure* oop_cl):
-    _oop_cl(oop_cl) {}
-
-  void do_code_blob(CodeBlob* cb) {
-    nmethod* nm = cb->as_nmethod_or_null();
-    if (nm != NULL) {
-      _oop_cl->set_nmethod(nm);
-      nm->oops_do(_oop_cl);
-    }
-  }
-};
-
-class YoungRefCounterClosure : public OopClosure {
-  G1CollectedHeap* _g1h;
-  int              _count;
- public:
-  YoungRefCounterClosure(G1CollectedHeap* g1h) : _g1h(g1h), _count(0) {}
-  void do_oop(oop* p)       { if (_g1h->is_in_young(*p)) { _count++; } }
-  void do_oop(narrowOop* p) { ShouldNotReachHere(); }
-
-  int count() { return _count; }
-  void reset_count() { _count = 0; };
-};
-
-class VerifyKlassClosure: public KlassClosure {
-  YoungRefCounterClosure _young_ref_counter_closure;
-  OopClosure *_oop_closure;
- public:
-  VerifyKlassClosure(G1CollectedHeap* g1h, OopClosure* cl) : _young_ref_counter_closure(g1h), _oop_closure(cl) {}
-  void do_klass(Klass* k) {
-    k->oops_do(_oop_closure);
-
-    _young_ref_counter_closure.reset_count();
-    k->oops_do(&_young_ref_counter_closure);
-    if (_young_ref_counter_closure.count() > 0) {
-      guarantee(k->has_modified_oops(), "Klass " PTR_FORMAT ", has young refs but is not dirty.", p2i(k));
-    }
-  }
-};
-
-class VerifyLivenessOopClosure: public OopClosure {
-  G1CollectedHeap* _g1h;
-  VerifyOption _vo;
-public:
-  VerifyLivenessOopClosure(G1CollectedHeap* g1h, VerifyOption vo):
-    _g1h(g1h), _vo(vo)
-  { }
-  void do_oop(narrowOop *p) { do_oop_work(p); }
-  void do_oop(      oop *p) { do_oop_work(p); }
-
-  template <class T> void do_oop_work(T *p) {
-    oop obj = oopDesc::load_decode_heap_oop(p);
-    guarantee(obj == NULL || !_g1h->is_obj_dead_cond(obj, _vo),
-              "Dead object referenced by a not dead object");
-  }
-};
-
-class VerifyObjsInRegionClosure: public ObjectClosure {
-private:
-  G1CollectedHeap* _g1h;
-  size_t _live_bytes;
-  HeapRegion *_hr;
-  VerifyOption _vo;
-public:
-  // _vo == UsePrevMarking -> use "prev" marking information,
-  // _vo == UseNextMarking -> use "next" marking information,
-  // _vo == UseMarkWord    -> use mark word from object header.
-  VerifyObjsInRegionClosure(HeapRegion *hr, VerifyOption vo)
-    : _live_bytes(0), _hr(hr), _vo(vo) {
-    _g1h = G1CollectedHeap::heap();
-  }
-  void do_object(oop o) {
-    VerifyLivenessOopClosure isLive(_g1h, _vo);
-    assert(o != NULL, "Huh?");
-    if (!_g1h->is_obj_dead_cond(o, _vo)) {
-      // If the object is alive according to the mark word,
-      // then verify that the marking information agrees.
-      // Note we can't verify the contra-positive of the
-      // above: if the object is dead (according to the mark
-      // word), it may not be marked, or may have been marked
-      // but has since became dead, or may have been allocated
-      // since the last marking.
-      if (_vo == VerifyOption_G1UseMarkWord) {
-        guarantee(!_g1h->is_obj_dead(o), "mark word and concurrent mark mismatch");
-      }
-
-      o->oop_iterate_no_header(&isLive);
-      if (!_hr->obj_allocated_since_prev_marking(o)) {
-        size_t obj_size = o->size();    // Make sure we don't overflow
-        _live_bytes += (obj_size * HeapWordSize);
-      }
-    }
-  }
-  size_t live_bytes() { return _live_bytes; }
-};
-
-class VerifyArchiveOopClosure: public OopClosure {
-public:
-  VerifyArchiveOopClosure(HeapRegion *hr) { }
-  void do_oop(narrowOop *p) { do_oop_work(p); }
-  void do_oop(      oop *p) { do_oop_work(p); }
-
-  template <class T> void do_oop_work(T *p) {
-    oop obj = oopDesc::load_decode_heap_oop(p);
-    guarantee(obj == NULL || G1MarkSweep::in_archive_range(obj),
-              "Archive object at " PTR_FORMAT " references a non-archive object at " PTR_FORMAT,
-              p2i(p), p2i(obj));
-  }
-};
-
-class VerifyArchiveRegionClosure: public ObjectClosure {
-public:
-  VerifyArchiveRegionClosure(HeapRegion *hr) { }
-  // Verify that all object pointers are to archive regions.
-  void do_object(oop o) {
-    VerifyArchiveOopClosure checkOop(NULL);
-    assert(o != NULL, "Should not be here for NULL oops");
-    o->oop_iterate_no_header(&checkOop);
-  }
-};
-
-class VerifyRegionClosure: public HeapRegionClosure {
-private:
-  bool             _par;
-  VerifyOption     _vo;
-  bool             _failures;
-public:
-  // _vo == UsePrevMarking -> use "prev" marking information,
-  // _vo == UseNextMarking -> use "next" marking information,
-  // _vo == UseMarkWord    -> use mark word from object header.
-  VerifyRegionClosure(bool par, VerifyOption vo)
-    : _par(par),
-      _vo(vo),
-      _failures(false) {}
-
-  bool failures() {
-    return _failures;
-  }
-
-  bool doHeapRegion(HeapRegion* r) {
-    // For archive regions, verify there are no heap pointers to
-    // non-pinned regions. For all others, verify liveness info.
-    if (r->is_archive()) {
-      VerifyArchiveRegionClosure verify_oop_pointers(r);
-      r->object_iterate(&verify_oop_pointers);
-      return true;
-    }
-    if (!r->is_continues_humongous()) {
-      bool failures = false;
-      r->verify(_vo, &failures);
-      if (failures) {
-        _failures = true;
-      } else if (!r->is_starts_humongous()) {
-        VerifyObjsInRegionClosure not_dead_yet_cl(r, _vo);
-        r->object_iterate(&not_dead_yet_cl);
-        if (_vo != VerifyOption_G1UseNextMarking) {
-          if (r->max_live_bytes() < not_dead_yet_cl.live_bytes()) {
-            log_info(gc, verify)("[" PTR_FORMAT "," PTR_FORMAT "] max_live_bytes " SIZE_FORMAT " < calculated " SIZE_FORMAT,
-                                 p2i(r->bottom()), p2i(r->end()), r->max_live_bytes(), not_dead_yet_cl.live_bytes());
-            _failures = true;
-          }
-        } else {
-          // When vo == UseNextMarking we cannot currently do a sanity
-          // check on the live bytes as the calculation has not been
-          // finalized yet.
-        }
-      }
-    }
-    return false; // stop the region iteration if we hit a failure
-  }
-};
-
-// This is the task used for parallel verification of the heap regions
-
-class G1ParVerifyTask: public AbstractGangTask {
-private:
-  G1CollectedHeap*  _g1h;
-  VerifyOption      _vo;
-  bool              _failures;
-  HeapRegionClaimer _hrclaimer;
-
-public:
-  // _vo == UsePrevMarking -> use "prev" marking information,
-  // _vo == UseNextMarking -> use "next" marking information,
-  // _vo == UseMarkWord    -> use mark word from object header.
-  G1ParVerifyTask(G1CollectedHeap* g1h, VerifyOption vo) :
-      AbstractGangTask("Parallel verify task"),
-      _g1h(g1h),
-      _vo(vo),
-      _failures(false),
-      _hrclaimer(g1h->workers()->active_workers()) {}
-
-  bool failures() {
-    return _failures;
-  }
-
-  void work(uint worker_id) {
-    HandleMark hm;
-    VerifyRegionClosure blk(true, _vo);
-    _g1h->heap_region_par_iterate(&blk, worker_id, &_hrclaimer);
-    if (blk.failures()) {
-      _failures = true;
-    }
-  }
-};
-
 void G1CollectedHeap::verify(VerifyOption vo) {
-  if (!SafepointSynchronize::is_at_safepoint()) {
-    log_info(gc, verify)("Skipping verification. Not at safepoint.");
-  }
-
-  assert(Thread::current()->is_VM_thread(),
-         "Expected to be executed serially by the VM thread at this point");
-
-  log_debug(gc, verify)("Roots");
-  VerifyRootsClosure rootsCl(vo);
-  VerifyKlassClosure klassCl(this, &rootsCl);
-  CLDToKlassAndOopClosure cldCl(&klassCl, &rootsCl, false);
-
-  // We apply the relevant closures to all the oops in the
-  // system dictionary, class loader data graph, the string table
-  // and the nmethods in the code cache.
-  G1VerifyCodeRootOopClosure codeRootsCl(this, &rootsCl, vo);
-  G1VerifyCodeRootBlobClosure blobsCl(&codeRootsCl);
-
-  {
-    G1RootProcessor root_processor(this, 1);
-    root_processor.process_all_roots(&rootsCl,
-                                     &cldCl,
-                                     &blobsCl);
-  }
-
-  bool failures = rootsCl.failures() || codeRootsCl.failures();
-
-  if (vo != VerifyOption_G1UseMarkWord) {
-    // If we're verifying during a full GC then the region sets
-    // will have been torn down at the start of the GC. Therefore
-    // verifying the region sets will fail. So we only verify
-    // the region sets when not in a full GC.
-    log_debug(gc, verify)("HeapRegionSets");
-    verify_region_sets();
-  }
-
-  log_debug(gc, verify)("HeapRegions");
-  if (GCParallelVerificationEnabled && ParallelGCThreads > 1) {
-
-    G1ParVerifyTask task(this, vo);
-    workers()->run_task(&task);
-    if (task.failures()) {
-      failures = true;
-    }
-
-  } else {
-    VerifyRegionClosure blk(false, vo);
-    heap_region_iterate(&blk);
-    if (blk.failures()) {
-      failures = true;
-    }
-  }
-
-  if (G1StringDedup::is_enabled()) {
-    log_debug(gc, verify)("StrDedup");
-    G1StringDedup::verify();
-  }
-
-  if (failures) {
-    log_info(gc, verify)("Heap after failed verification:");
-    // It helps to have the per-region information in the output to
-    // help us track down what went wrong. This is why we call
-    // print_extended_on() instead of print_on().
-    LogHandle(gc, verify) log;
-    ResourceMark rm;
-    print_extended_on(log.info_stream());
-  }
-  guarantee(!failures, "there should not have been any failures");
-}
-
-double G1CollectedHeap::verify(bool guard, const char* msg) {
-  double verify_time_ms = 0.0;
-
-  if (guard && total_collections() >= VerifyGCStartAt) {
-    double verify_start = os::elapsedTime();
-    HandleMark hm;  // Discard invalid handles created during verification
-    prepare_for_verify();
-    Universe::verify(VerifyOption_G1UsePrevMarking, msg);
-    verify_time_ms = (os::elapsedTime() - verify_start) * 1000;
-  }
-
-  return verify_time_ms;
-}
-
-void G1CollectedHeap::verify_before_gc() {
-  double verify_time_ms = verify(VerifyBeforeGC, "Before GC");
-  g1_policy()->phase_times()->record_verify_before_time_ms(verify_time_ms);
-}
-
-void G1CollectedHeap::verify_after_gc() {
-  double verify_time_ms = verify(VerifyAfterGC, "After GC");
-  g1_policy()->phase_times()->record_verify_after_time_ms(verify_time_ms);
+  _verifier->verify(vo);
 }
 
 class PrintRegionClosure: public HeapRegionClosure {
@@ -3580,7 +3143,7 @@
 }
 
 void G1CollectedHeap::print_taskqueue_stats() const {
-  if (!develop_log_is_enabled(Trace, gc, task, stats)) {
+  if (!log_develop_is_enabled(Trace, gc, task, stats)) {
     return;
   }
   LogHandle(gc, task, stats) log;
@@ -3608,18 +3171,6 @@
 }
 #endif // TASKQUEUE_STATS
 
-void G1CollectedHeap::log_gc_footer(jlong pause_time_counter) {
-  if (evacuation_failed()) {
-    log_info(gc)("To-space exhausted");
-  }
-
-  double pause_time_ms = TimeHelper::counter_to_millis(pause_time_counter);
-  g1_policy()->print_phases(pause_time_ms);
-
-  g1_policy()->print_detailed_heap_transition();
-}
-
-
 void G1CollectedHeap::wait_for_root_region_scanning() {
   double scan_wait_start = os::elapsedTime();
   // We have to wait until the CM threads finish scanning the
@@ -3657,8 +3208,8 @@
   print_heap_before_gc();
   trace_heap_before_gc(_gc_tracer_stw);
 
-  verify_region_sets_optional();
-  verify_dirty_young_regions();
+  _verifier->verify_region_sets_optional();
+  _verifier->verify_dirty_young_regions();
 
   // This call will decide whether this pause is an initial-mark
   // pause. If it is, during_initial_mark_pause() will return true
@@ -3706,7 +3257,6 @@
     }
     GCTraceTime(Info, gc) tm(gc_string, NULL, gc_cause(), true);
 
-    jlong pause_start_counter = os::elapsed_counter();
     g1_policy()->note_gc_start(active_workers);
 
     TraceCollectorStats tcs(g1mm()->incremental_collection_counters());
@@ -3722,6 +3272,9 @@
       append_secondary_free_list_if_not_empty_with_lock();
     }
 
+    G1HeapTransition heap_transition(this);
+    size_t heap_used_bytes_before_gc = used();
+
     assert(check_young_list_well_formed(), "young list should be well formed");
 
     // Don't dynamically change the number of GC threads this early.  A value of
@@ -3741,9 +3294,9 @@
         heap_region_iterate(&v_cl);
       }
 
-      verify_before_gc();
-
-      check_bitmaps("GC Start");
+      _verifier->verify_before_gc();
+
+      _verifier->check_bitmaps("GC Start");
 
 #if defined(COMPILER2) || INCLUDE_JVMCI
       DerivedPointerTable::clear();
@@ -3801,7 +3354,7 @@
 
         register_humongous_regions_with_cset();
 
-        assert(check_cset_fast_test(), "Inconsistency in the InCSetState table.");
+        assert(_verifier->check_cset_fast_test(), "Inconsistency in the InCSetState table.");
 
         _cm->note_start_of_gc();
         // We call this after finalize_cset() to
@@ -3915,7 +3468,7 @@
         double sample_end_time_sec = os::elapsedTime();
         double pause_time_ms = (sample_end_time_sec - sample_start_time_sec) * MILLIUNITS;
         size_t total_cards_scanned = per_thread_states.total_cards_scanned();
-        g1_policy()->record_collection_pause_end(pause_time_ms, total_cards_scanned);
+        g1_policy()->record_collection_pause_end(pause_time_ms, total_cards_scanned, heap_used_bytes_before_gc);
 
         evacuation_info.set_collectionset_used_before(g1_policy()->collection_set_bytes_used_before());
         evacuation_info.set_bytes_copied(g1_policy()->bytes_copied_during_gc());
@@ -3951,8 +3504,8 @@
           heap_region_iterate(&v_cl);
         }
 
-        verify_after_gc();
-        check_bitmaps("GC End");
+        _verifier->verify_after_gc();
+        _verifier->check_bitmaps("GC End");
 
         assert(!ref_processor_stw()->discovery_enabled(), "Postcondition");
         ref_processor_stw()->verify_no_references_recorded();
@@ -3968,7 +3521,12 @@
     }
 
     // Print the remainder of the GC log output.
-    log_gc_footer(os::elapsed_counter() - pause_start_counter);
+    if (evacuation_failed()) {
+      log_info(gc)("To-space exhausted");
+    }
+
+    g1_policy()->print_phases();
+    heap_transition.print();
 
     // It is not yet to safe to tell the concurrent mark to
     // start as we have some optional output below. We don't want the
@@ -3976,7 +3534,7 @@
     // logging output either.
 
     _hrm.verify_optional();
-    verify_region_sets_optional();
+    _verifier->verify_region_sets_optional();
 
     TASKQUEUE_STATS_ONLY(print_taskqueue_stats());
     TASKQUEUE_STATS_ONLY(reset_taskqueue_stats());
@@ -5245,197 +4803,6 @@
   }
 };
 
-#ifndef PRODUCT
-class G1VerifyCardTableCleanup: public HeapRegionClosure {
-  G1CollectedHeap* _g1h;
-  G1SATBCardTableModRefBS* _ct_bs;
-public:
-  G1VerifyCardTableCleanup(G1CollectedHeap* g1h, G1SATBCardTableModRefBS* ct_bs)
-    : _g1h(g1h), _ct_bs(ct_bs) { }
-  virtual bool doHeapRegion(HeapRegion* r) {
-    if (r->is_survivor()) {
-      _g1h->verify_dirty_region(r);
-    } else {
-      _g1h->verify_not_dirty_region(r);
-    }
-    return false;
-  }
-};
-
-void G1CollectedHeap::verify_not_dirty_region(HeapRegion* hr) {
-  // All of the region should be clean.
-  G1SATBCardTableModRefBS* ct_bs = g1_barrier_set();
-  MemRegion mr(hr->bottom(), hr->end());
-  ct_bs->verify_not_dirty_region(mr);
-}
-
-void G1CollectedHeap::verify_dirty_region(HeapRegion* hr) {
-  // We cannot guarantee that [bottom(),end()] is dirty.  Threads
-  // dirty allocated blocks as they allocate them. The thread that
-  // retires each region and replaces it with a new one will do a
-  // maximal allocation to fill in [pre_dummy_top(),end()] but will
-  // not dirty that area (one less thing to have to do while holding
-  // a lock). So we can only verify that [bottom(),pre_dummy_top()]
-  // is dirty.
-  G1SATBCardTableModRefBS* ct_bs = g1_barrier_set();
-  MemRegion mr(hr->bottom(), hr->pre_dummy_top());
-  if (hr->is_young()) {
-    ct_bs->verify_g1_young_region(mr);
-  } else {
-    ct_bs->verify_dirty_region(mr);
-  }
-}
-
-void G1CollectedHeap::verify_dirty_young_list(HeapRegion* head) {
-  G1SATBCardTableModRefBS* ct_bs = g1_barrier_set();
-  for (HeapRegion* hr = head; hr != NULL; hr = hr->get_next_young_region()) {
-    verify_dirty_region(hr);
-  }
-}
-
-void G1CollectedHeap::verify_dirty_young_regions() {
-  verify_dirty_young_list(_young_list->first_region());
-}
-
-bool G1CollectedHeap::verify_no_bits_over_tams(const char* bitmap_name, CMBitMapRO* bitmap,
-                                               HeapWord* tams, HeapWord* end) {
-  guarantee(tams <= end,
-            "tams: " PTR_FORMAT " end: " PTR_FORMAT, p2i(tams), p2i(end));
-  HeapWord* result = bitmap->getNextMarkedWordAddress(tams, end);
-  if (result < end) {
-    log_info(gc, verify)("## wrong marked address on %s bitmap: " PTR_FORMAT, bitmap_name, p2i(result));
-    log_info(gc, verify)("## %s tams: " PTR_FORMAT " end: " PTR_FORMAT, bitmap_name, p2i(tams), p2i(end));
-    return false;
-  }
-  return true;
-}
-
-bool G1CollectedHeap::verify_bitmaps(const char* caller, HeapRegion* hr) {
-  CMBitMapRO* prev_bitmap = concurrent_mark()->prevMarkBitMap();
-  CMBitMapRO* next_bitmap = (CMBitMapRO*) concurrent_mark()->nextMarkBitMap();
-
-  HeapWord* bottom = hr->bottom();
-  HeapWord* ptams  = hr->prev_top_at_mark_start();
-  HeapWord* ntams  = hr->next_top_at_mark_start();
-  HeapWord* end    = hr->end();
-
-  bool res_p = verify_no_bits_over_tams("prev", prev_bitmap, ptams, end);
-
-  bool res_n = true;
-  // We reset mark_in_progress() before we reset _cmThread->in_progress() and in this window
-  // we do the clearing of the next bitmap concurrently. Thus, we can not verify the bitmap
-  // if we happen to be in that state.
-  if (collector_state()->mark_in_progress() || !_cmThread->in_progress()) {
-    res_n = verify_no_bits_over_tams("next", next_bitmap, ntams, end);
-  }
-  if (!res_p || !res_n) {
-    log_info(gc, verify)("#### Bitmap verification failed for " HR_FORMAT, HR_FORMAT_PARAMS(hr));
-    log_info(gc, verify)("#### Caller: %s", caller);
-    return false;
-  }
-  return true;
-}
-
-void G1CollectedHeap::check_bitmaps(const char* caller, HeapRegion* hr) {
-  if (!G1VerifyBitmaps) return;
-
-  guarantee(verify_bitmaps(caller, hr), "bitmap verification");
-}
-
-class G1VerifyBitmapClosure : public HeapRegionClosure {
-private:
-  const char* _caller;
-  G1CollectedHeap* _g1h;
-  bool _failures;
-
-public:
-  G1VerifyBitmapClosure(const char* caller, G1CollectedHeap* g1h) :
-    _caller(caller), _g1h(g1h), _failures(false) { }
-
-  bool failures() { return _failures; }
-
-  virtual bool doHeapRegion(HeapRegion* hr) {
-    bool result = _g1h->verify_bitmaps(_caller, hr);
-    if (!result) {
-      _failures = true;
-    }
-    return false;
-  }
-};
-
-void G1CollectedHeap::check_bitmaps(const char* caller) {
-  if (!G1VerifyBitmaps) return;
-
-  G1VerifyBitmapClosure cl(caller, this);
-  heap_region_iterate(&cl);
-  guarantee(!cl.failures(), "bitmap verification");
-}
-
-class G1CheckCSetFastTableClosure : public HeapRegionClosure {
- private:
-  bool _failures;
- public:
-  G1CheckCSetFastTableClosure() : HeapRegionClosure(), _failures(false) { }
-
-  virtual bool doHeapRegion(HeapRegion* hr) {
-    uint i = hr->hrm_index();
-    InCSetState cset_state = (InCSetState) G1CollectedHeap::heap()->_in_cset_fast_test.get_by_index(i);
-    if (hr->is_humongous()) {
-      if (hr->in_collection_set()) {
-        log_info(gc, verify)("## humongous region %u in CSet", i);
-        _failures = true;
-        return true;
-      }
-      if (cset_state.is_in_cset()) {
-        log_info(gc, verify)("## inconsistent cset state " CSETSTATE_FORMAT " for humongous region %u", cset_state.value(), i);
-        _failures = true;
-        return true;
-      }
-      if (hr->is_continues_humongous() && cset_state.is_humongous()) {
-        log_info(gc, verify)("## inconsistent cset state " CSETSTATE_FORMAT " for continues humongous region %u", cset_state.value(), i);
-        _failures = true;
-        return true;
-      }
-    } else {
-      if (cset_state.is_humongous()) {
-        log_info(gc, verify)("## inconsistent cset state " CSETSTATE_FORMAT " for non-humongous region %u", cset_state.value(), i);
-        _failures = true;
-        return true;
-      }
-      if (hr->in_collection_set() != cset_state.is_in_cset()) {
-        log_info(gc, verify)("## in CSet %d / cset state " CSETSTATE_FORMAT " inconsistency for region %u",
-                             hr->in_collection_set(), cset_state.value(), i);
-        _failures = true;
-        return true;
-      }
-      if (cset_state.is_in_cset()) {
-        if (hr->is_young() != (cset_state.is_young())) {
-          log_info(gc, verify)("## is_young %d / cset state " CSETSTATE_FORMAT " inconsistency for region %u",
-                               hr->is_young(), cset_state.value(), i);
-          _failures = true;
-          return true;
-        }
-        if (hr->is_old() != (cset_state.is_old())) {
-          log_info(gc, verify)("## is_old %d / cset state " CSETSTATE_FORMAT " inconsistency for region %u",
-                               hr->is_old(), cset_state.value(), i);
-          _failures = true;
-          return true;
-        }
-      }
-    }
-    return false;
-  }
-
-  bool failures() const { return _failures; }
-};
-
-bool G1CollectedHeap::check_cset_fast_test() {
-  G1CheckCSetFastTableClosure cl;
-  _hrm.iterate(&cl);
-  return !cl.failures();
-}
-#endif // PRODUCT
-
 class G1ParScrubRemSetTask: public AbstractGangTask {
 protected:
   G1RemSet* _g1rs;
@@ -5473,10 +4840,7 @@
 
     workers()->run_task(&cleanup_task);
 #ifndef PRODUCT
-    if (G1VerifyCTCleanup || VerifyAfterGC) {
-      G1VerifyCardTableCleanup cleanup_verifier(this, ct_bs);
-      heap_region_iterate(&cleanup_verifier);
-    }
+    _verifier->verify_card_table_cleanup();
 #endif
   }
 
@@ -5998,7 +5362,7 @@
     if (new_alloc_region != NULL) {
       set_region_short_lived_locked(new_alloc_region);
       _hr_printer.alloc(new_alloc_region, young_list_full);
-      check_bitmaps("Mutator Region Allocation", new_alloc_region);
+      _verifier->check_bitmaps("Mutator Region Allocation", new_alloc_region);
       return new_alloc_region;
     }
   }
@@ -6038,10 +5402,10 @@
       new_alloc_region->record_timestamp();
       if (is_survivor) {
         new_alloc_region->set_survivor();
-        check_bitmaps("Survivor Region Allocation", new_alloc_region);
+        _verifier->check_bitmaps("Survivor Region Allocation", new_alloc_region);
       } else {
         new_alloc_region->set_old();
-        check_bitmaps("Old Region Allocation", new_alloc_region);
+        _verifier->check_bitmaps("Old Region Allocation", new_alloc_region);
       }
       _hr_printer.alloc(new_alloc_region);
       bool during_im = collector_state()->during_initial_mark_pause();
@@ -6081,93 +5445,6 @@
   return NULL;
 }
 
-// Heap region set verification
-
-class VerifyRegionListsClosure : public HeapRegionClosure {
-private:
-  HeapRegionSet*   _old_set;
-  HeapRegionSet*   _humongous_set;
-  HeapRegionManager*   _hrm;
-
-public:
-  uint _old_count;
-  uint _humongous_count;
-  uint _free_count;
-
-  VerifyRegionListsClosure(HeapRegionSet* old_set,
-                           HeapRegionSet* humongous_set,
-                           HeapRegionManager* hrm) :
-    _old_set(old_set), _humongous_set(humongous_set), _hrm(hrm),
-    _old_count(), _humongous_count(), _free_count(){ }
-
-  bool doHeapRegion(HeapRegion* hr) {
-    if (hr->is_young()) {
-      // TODO
-    } 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++;
-    } else if (hr->is_empty()) {
-      assert(_hrm->is_free(hr), "Heap region %u is empty but not on the free list.", hr->hrm_index());
-      _free_count++;
-    } else if (hr->is_old()) {
-      assert(hr->containing_set() == _old_set, "Heap region %u is old but not in the old set.", hr->hrm_index());
-      _old_count++;
-    } else {
-      // There are no other valid region types. Check for one invalid
-      // one we can identify: pinned without old or humongous set.
-      assert(!hr->is_pinned(), "Heap region %u is pinned but not old (archive) or humongous.", hr->hrm_index());
-      ShouldNotReachHere();
-    }
-    return false;
-  }
-
-  void verify_counts(HeapRegionSet* old_set, HeapRegionSet* humongous_set, HeapRegionManager* free_list) {
-    guarantee(old_set->length() == _old_count, "Old set count mismatch. Expected %u, actual %u.", old_set->length(), _old_count);
-    guarantee(humongous_set->length() == _humongous_count, "Hum set count mismatch. Expected %u, actual %u.", humongous_set->length(), _humongous_count);
-    guarantee(free_list->num_free_regions() == _free_count, "Free list count mismatch. Expected %u, actual %u.", free_list->num_free_regions(), _free_count);
-  }
-};
-
-void G1CollectedHeap::verify_region_sets() {
-  assert_heap_locked_or_at_safepoint(true /* should_be_vm_thread */);
-
-  // First, check the explicit lists.
-  _hrm.verify();
-  {
-    // Given that a concurrent operation might be adding regions to
-    // the secondary free list we have to take the lock before
-    // verifying it.
-    MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag);
-    _secondary_free_list.verify_list();
-  }
-
-  // If a concurrent region freeing operation is in progress it will
-  // be difficult to correctly attributed any free regions we come
-  // across to the correct free list given that they might belong to
-  // one of several (free_list, secondary_free_list, any local lists,
-  // etc.). So, if that's the case we will skip the rest of the
-  // verification operation. Alternatively, waiting for the concurrent
-  // operation to complete will have a non-trivial effect on the GC's
-  // operation (no concurrent operation will last longer than the
-  // interval between two calls to verification) and it might hide
-  // any issues that we would like to catch during testing.
-  if (free_regions_coming()) {
-    return;
-  }
-
-  // Make sure we append the secondary_free_list on the free_list so
-  // that all free regions we will come across can be safely
-  // attributed to the free_list.
-  append_secondary_free_list_if_not_empty_with_lock();
-
-  // Finally, make sure that the region accounting in the lists is
-  // consistent with what we see in the heap.
-
-  VerifyRegionListsClosure cl(&_old_set, &_humongous_set, &_hrm);
-  heap_region_iterate(&cl);
-  cl.verify_counts(&_old_set, &_humongous_set, &_hrm);
-}
-
 // Optimized nmethod scanning
 
 class RegisterNMethodOopClosure: public OopClosure {
--- a/src/share/vm/gc/g1/g1CollectedHeap.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/g1/g1CollectedHeap.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -82,6 +82,7 @@
 class WorkGang;
 class G1Allocator;
 class G1ArchiveAllocator;
+class G1HeapVerifier;
 
 typedef OverflowTaskQueue<StarTask, mtGC>         RefToScanQueue;
 typedef GenericTaskQueueSet<RefToScanQueue, mtGC> RefToScanQueueSet;
@@ -118,6 +119,7 @@
   friend class VMStructs;
   friend class MutatorAllocRegion;
   friend class G1GCAllocRegion;
+  friend class G1HeapVerifier;
 
   // Closures used in implementation.
   friend class G1ParScanThreadState;
@@ -181,6 +183,9 @@
   // Manages all allocations with regions except humongous object allocations.
   G1Allocator* _allocator;
 
+  // Manages all heap verification.
+  G1HeapVerifier* _verifier;
+
   // Outside of GC pauses, the number of bytes used in all regions other
   // than the current allocation region(s).
   size_t _summary_bytes_used;
@@ -286,12 +291,6 @@
                                                          size_t size,
                                                          size_t translation_factor);
 
-  double verify(bool guard, const char* msg);
-  void verify_before_gc();
-  void verify_after_gc();
-
-  void log_gc_footer(jlong pause_time_counter);
-
   void trace_heap(GCWhen::Type when, const GCTracer* tracer);
 
   void process_weak_jni_handles();
@@ -527,6 +526,10 @@
     return _allocator;
   }
 
+  G1HeapVerifier* verifier() {
+    return _verifier;
+  }
+
   G1MonitoringSupport* g1mm() {
     assert(_g1mm != NULL, "should have been initialized");
     return _g1mm;
@@ -1056,54 +1059,6 @@
   // The number of regions that are not completely free.
   uint num_used_regions() const { return num_regions() - num_free_regions(); }
 
-  void verify_not_dirty_region(HeapRegion* hr) PRODUCT_RETURN;
-  void verify_dirty_region(HeapRegion* hr) PRODUCT_RETURN;
-  void verify_dirty_young_list(HeapRegion* head) PRODUCT_RETURN;
-  void verify_dirty_young_regions() PRODUCT_RETURN;
-
-#ifndef PRODUCT
-  // Make sure that the given bitmap has no marked objects in the
-  // range [from,limit). If it does, print an error message and return
-  // false. Otherwise, just return true. bitmap_name should be "prev"
-  // or "next".
-  bool verify_no_bits_over_tams(const char* bitmap_name, CMBitMapRO* bitmap,
-                                HeapWord* from, HeapWord* limit);
-
-  // Verify that the prev / next bitmap range [tams,end) for the given
-  // region has no marks. Return true if all is well, false if errors
-  // are detected.
-  bool verify_bitmaps(const char* caller, HeapRegion* hr);
-#endif // PRODUCT
-
-  // If G1VerifyBitmaps is set, verify that the marking bitmaps for
-  // the given region do not have any spurious marks. If errors are
-  // detected, print appropriate error messages and crash.
-  void check_bitmaps(const char* caller, HeapRegion* hr) PRODUCT_RETURN;
-
-  // If G1VerifyBitmaps is set, verify that the marking bitmaps do not
-  // have any spurious marks. If errors are detected, print
-  // appropriate error messages and crash.
-  void check_bitmaps(const char* caller) PRODUCT_RETURN;
-
-  // Do sanity check on the contents of the in-cset fast test table.
-  bool check_cset_fast_test() PRODUCT_RETURN_( return true; );
-
-  // verify_region_sets() performs verification over the region
-  // lists. It will be compiled in the product code to be used when
-  // necessary (i.e., during heap verification).
-  void verify_region_sets();
-
-  // verify_region_sets_optional() is planted in the code for
-  // list verification in non-product builds (and it can be enabled in
-  // product builds by defining HEAP_REGION_SET_FORCE_VERIFY to be 1).
-#if HEAP_REGION_SET_FORCE_VERIFY
-  void verify_region_sets_optional() {
-    verify_region_sets();
-  }
-#else // HEAP_REGION_SET_FORCE_VERIFY
-  void verify_region_sets_optional() { }
-#endif // HEAP_REGION_SET_FORCE_VERIFY
-
 #ifdef ASSERT
   bool is_on_master_free_list(HeapRegion* hr) {
     return _hrm.is_free(hr);
@@ -1425,11 +1380,6 @@
 
   inline bool is_obj_ill(const oop obj) const;
 
-  bool allocated_since_marking(oop obj, HeapRegion* hr, VerifyOption vo);
-  HeapWord* top_at_mark_start(HeapRegion* hr, VerifyOption vo);
-  bool is_marked(oop obj, VerifyOption vo);
-  const char* top_at_mark_start_str(VerifyOption vo);
-
   ConcurrentMark* concurrent_mark() const { return _cm; }
 
   // Refinement
--- a/src/share/vm/gc/g1/g1CollectorPolicy.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/g1/g1CollectorPolicy.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -117,15 +117,6 @@
   _rs_lengths_prediction(0),
   _max_survivor_regions(0),
 
-  _eden_used_bytes_before_gc(0),
-  _survivor_used_bytes_before_gc(0),
-  _old_used_bytes_before_gc(0),
-  _humongous_used_bytes_before_gc(0),
-  _heap_used_bytes_before_gc(0),
-  _metaspace_used_bytes_before_gc(0),
-  _eden_capacity_bytes_before_gc(0),
-  _heap_capacity_bytes_before_gc(0),
-
   _eden_cset_region_length(0),
   _survivor_cset_region_length(0),
   _old_cset_region_length(0),
@@ -809,7 +800,6 @@
 
 void G1CollectorPolicy::record_full_collection_start() {
   _full_collection_start_sec = os::elapsedTime();
-  record_heap_size_info_at_start(true /* full */);
   // Release the future to-space so that it is available for compaction into.
   collector_state()->set_full_collection(true);
 }
@@ -871,8 +861,6 @@
   _trace_young_gen_time_data.record_start_collection(s_w_t_ms);
   _stop_world_start = 0.0;
 
-  record_heap_size_info_at_start(false /* full */);
-
   phase_times()->record_cur_collection_start_sec(start_time_sec);
   _pending_cards = _g1->pending_card_num();
 
@@ -987,7 +975,7 @@
 // Anything below that is considered to be zero
 #define MIN_TIMER_GRANULARITY 0.0000001
 
-void G1CollectorPolicy::record_collection_pause_end(double pause_time_ms, size_t cards_scanned) {
+void G1CollectorPolicy::record_collection_pause_end(double pause_time_ms, size_t cards_scanned, size_t heap_used_bytes_before_gc) {
   double end_time_sec = os::elapsedTime();
 
   size_t cur_used_bytes = _g1->used();
@@ -1138,7 +1126,7 @@
     }
     _rs_length_diff_seq->add((double) rs_length_diff);
 
-    size_t freed_bytes = _heap_used_bytes_before_gc - cur_used_bytes;
+    size_t freed_bytes = heap_used_bytes_before_gc - cur_used_bytes;
     size_t copied_bytes = _collection_set_bytes_used_before - freed_bytes;
     double cost_per_byte_ms = 0.0;
 
@@ -1260,51 +1248,8 @@
   _ihop_control->print();
 }
 
-#define EXT_SIZE_FORMAT "%.1f%s"
-#define EXT_SIZE_PARAMS(bytes)                                  \
-  byte_size_in_proper_unit((double)(bytes)),                    \
-  proper_unit_for_byte_size((bytes))
-
-void G1CollectorPolicy::record_heap_size_info_at_start(bool full) {
-  YoungList* young_list = _g1->young_list();
-  _eden_used_bytes_before_gc = young_list->eden_used_bytes();
-  _survivor_used_bytes_before_gc = young_list->survivor_used_bytes();
-  _heap_capacity_bytes_before_gc = _g1->capacity();
-  _old_used_bytes_before_gc = _g1->old_regions_count() * HeapRegion::GrainBytes;
-  _humongous_used_bytes_before_gc = _g1->humongous_regions_count() * HeapRegion::GrainBytes;
-  _heap_used_bytes_before_gc = _g1->used();
-  _eden_capacity_bytes_before_gc = (_young_list_target_length * HeapRegion::GrainBytes) - _survivor_used_bytes_before_gc;
-  _metaspace_used_bytes_before_gc = MetaspaceAux::used_bytes();
-}
-
-void G1CollectorPolicy::print_detailed_heap_transition() const {
-  YoungList* young_list = _g1->young_list();
-
-  size_t eden_used_bytes_after_gc = young_list->eden_used_bytes();
-  size_t survivor_used_bytes_after_gc = young_list->survivor_used_bytes();
-  size_t heap_used_bytes_after_gc = _g1->used();
-  size_t old_used_bytes_after_gc = _g1->old_regions_count() * HeapRegion::GrainBytes;
-  size_t humongous_used_bytes_after_gc = _g1->humongous_regions_count() * HeapRegion::GrainBytes;
-
-  size_t heap_capacity_bytes_after_gc = _g1->capacity();
-  size_t eden_capacity_bytes_after_gc =
-    (_young_list_target_length * HeapRegion::GrainBytes) - survivor_used_bytes_after_gc;
-  size_t survivor_capacity_bytes_after_gc = _max_survivor_regions * HeapRegion::GrainBytes;
-
-  log_info(gc, heap)("Eden: " SIZE_FORMAT "K->" SIZE_FORMAT "K("  SIZE_FORMAT "K)",
-                     _eden_used_bytes_before_gc / K, eden_used_bytes_after_gc /K, eden_capacity_bytes_after_gc /K);
-  log_info(gc, heap)("Survivor: " SIZE_FORMAT "K->" SIZE_FORMAT "K("  SIZE_FORMAT "K)",
-                     _survivor_used_bytes_before_gc / K, survivor_used_bytes_after_gc /K, survivor_capacity_bytes_after_gc /K);
-  log_info(gc, heap)("Old: " SIZE_FORMAT "K->" SIZE_FORMAT "K",
-                     _old_used_bytes_before_gc / K, old_used_bytes_after_gc /K);
-  log_info(gc, heap)("Humongous: " SIZE_FORMAT "K->" SIZE_FORMAT "K",
-                     _humongous_used_bytes_before_gc / K, humongous_used_bytes_after_gc /K);
-
-  MetaspaceAux::print_metaspace_change(_metaspace_used_bytes_before_gc);
-}
-
-void G1CollectorPolicy::print_phases(double pause_time_ms) {
-  phase_times()->print(pause_time_ms);
+void G1CollectorPolicy::print_phases() {
+  phase_times()->print();
 }
 
 void G1CollectorPolicy::adjust_concurrent_refinement(double update_rs_time,
@@ -2310,7 +2255,7 @@
       // whether we added any apparently expensive regions or not, to
       // avoid generating output per region.
       log_debug(gc, ergo, cset)("Added expensive regions to CSet (old CSet region num not reached min)."
-                                "old %u regions, expensive: %u regions, min %u regions, remaining time: %1.2fms",
+                                "old: %u regions, expensive: %u regions, min: %u regions, remaining time: %1.2fms",
                                 old_cset_region_length(), expensive_region_num, min_old_cset_length, time_remaining_ms);
     }
 
@@ -2319,7 +2264,7 @@
 
   stop_incremental_cset_building();
 
-  log_debug(gc, ergo, cset)("Finish choosing CSet. old %u regions, predicted old region time: %1.2fms, time remaining: %1.2f",
+  log_debug(gc, ergo, cset)("Finish choosing CSet. old: %u regions, predicted old region time: %1.2fms, time remaining: %1.2f",
                             old_cset_region_length(), predicted_old_time_ms, time_remaining_ms);
 
   double non_young_end_time_sec = os::elapsedTime();
--- a/src/share/vm/gc/g1/g1CollectorPolicy.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/g1/g1CollectorPolicy.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -636,7 +636,7 @@
 
   // 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);
+  void record_collection_pause_end(double pause_time_ms, size_t cards_scanned, size_t heap_used_bytes_before_gc);
 
   // Record the start and end of a full collection.
   void record_full_collection_start();
@@ -654,15 +654,7 @@
   void record_concurrent_mark_cleanup_end();
   void record_concurrent_mark_cleanup_completed();
 
-  // Records the information about the heap size for reporting in
-  // print_detailed_heap_transition
-  void record_heap_size_info_at_start(bool full);
-
-  // Print heap sizing transition (with less and more detail).
-
-  void print_detailed_heap_transition() const;
-
-  virtual void print_phases(double pause_time_ms);
+  virtual void print_phases();
 
   void record_stop_world_start();
   void record_concurrent_pause();
@@ -825,16 +817,6 @@
   // The value of _heap_bytes_before_gc is also used to calculate
   // the cost of copying.
 
-  size_t _eden_used_bytes_before_gc;         // Eden occupancy before GC
-  size_t _survivor_used_bytes_before_gc;     // Survivor occupancy before GC
-  size_t _old_used_bytes_before_gc;          // Old occupancy before GC
-  size_t _humongous_used_bytes_before_gc;    // Humongous occupancy before GC
-  size_t _heap_used_bytes_before_gc;         // Heap occupancy before GC
-  size_t _metaspace_used_bytes_before_gc;    // Metaspace occupancy before GC
-
-  size_t _eden_capacity_bytes_before_gc;     // Eden capacity before GC
-  size_t _heap_capacity_bytes_before_gc;     // Heap capacity before GC
-
   // The amount of survivor regions after a collection.
   uint _recorded_survivor_regions;
   // List of survivor regions.
@@ -846,6 +828,10 @@
 public:
   uint tenuring_threshold() const { return _tenuring_threshold; }
 
+  uint max_survivor_regions() {
+    return _max_survivor_regions;
+  }
+
   static const uint REGIONS_UNLIMITED = (uint) -1;
 
   uint max_regions(InCSetState dest) const {
--- a/src/share/vm/gc/g1/g1EvacFailure.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/g1/g1EvacFailure.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -28,6 +28,7 @@
 #include "gc/g1/g1CollectedHeap.inline.hpp"
 #include "gc/g1/g1CollectorState.hpp"
 #include "gc/g1/g1EvacFailure.hpp"
+#include "gc/g1/g1HeapVerifier.hpp"
 #include "gc/g1/g1OopClosures.inline.hpp"
 #include "gc/g1/g1_globals.hpp"
 #include "gc/g1/heapRegion.hpp"
@@ -223,7 +224,7 @@
       if (hr->evacuation_failed()) {
         hr->note_self_forwarding_removal_start(during_initial_mark,
                                                during_conc_mark);
-        _g1h->check_bitmaps("Self-Forwarding Ptr Removal", hr);
+        _g1h->verifier()->check_bitmaps("Self-Forwarding Ptr Removal", hr);
 
         // In the common case (i.e. when there is no evacuation
         // failure) we make sure that the following is done when
--- a/src/share/vm/gc/g1/g1GCPhaseTimes.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/g1/g1GCPhaseTimes.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -30,6 +30,7 @@
 #include "gc/g1/workerDataArray.inline.hpp"
 #include "memory/allocation.hpp"
 #include "logging/log.hpp"
+#include "runtime/timer.hpp"
 #include "runtime/os.hpp"
 
 // Helper class for avoiding interleaved logging
@@ -125,7 +126,7 @@
   _gc_par_phases[StringDedupQueueFixup] = new WorkerDataArray<double>(max_gc_threads, "Queue Fixup:", true, 2);
   _gc_par_phases[StringDedupTableFixup] = new WorkerDataArray<double>(max_gc_threads, "Table Fixup:", true, 2);
 
-  _gc_par_phases[RedirtyCards] = new WorkerDataArray<double>(max_gc_threads, "Parallel Redirty", true, 3);
+  _gc_par_phases[RedirtyCards] = new WorkerDataArray<double>(max_gc_threads, "Parallel Redirty:", true, 3);
   _redirtied_cards = new WorkerDataArray<size_t>(max_gc_threads, "Redirtied Cards:", true, 3);
   _gc_par_phases[RedirtyCards]->link_thread_work_items(_redirtied_cards);
 }
@@ -133,6 +134,7 @@
 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");
+  _gc_start_counter = os::elapsed_counter();
   _active_gc_threads = active_gc_threads;
   _cur_expand_heap_time_ms = 0.0;
   _external_accounted_time_ms = 0.0;
@@ -146,6 +148,7 @@
 }
 
 void G1GCPhaseTimes::note_gc_end() {
+  _gc_pause_time_ms = TimeHelper::counter_to_millis(os::elapsed_counter() - _gc_start_counter);
   for (uint i = 0; i < _active_gc_threads; i++) {
     double worker_time = _gc_par_phases[GCWorkerEnd]->get(i) - _gc_par_phases[GCWorkerStart]->get(i);
     record_time_secs(GCWorkerTotal, i , worker_time);
@@ -349,7 +352,7 @@
   }
 };
 
-void G1GCPhaseTimes::print(double pause_time_ms) {
+void G1GCPhaseTimes::print() {
   note_gc_end();
 
   G1GCParPhasePrinter par_phase_printer(this);
@@ -373,7 +376,7 @@
   }
   print_stats(Indents[1], "Clear CT", _cur_clear_ct_time_ms);
   print_stats(Indents[1], "Expand Heap After Collection", _cur_expand_heap_time_ms);
-  double misc_time_ms = pause_time_ms - accounted_time_ms();
+  double misc_time_ms = _gc_pause_time_ms - accounted_time_ms();
   print_stats(Indents[1], "Other", misc_time_ms);
   if (_cur_verify_before_time_ms > 0.0) {
     print_stats(Indents[2], "Verify Before", _cur_verify_before_time_ms);
--- a/src/share/vm/gc/g1/g1GCPhaseTimes.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/g1/g1GCPhaseTimes.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -36,6 +36,8 @@
 
   uint _active_gc_threads;
   uint _max_gc_threads;
+  jlong _gc_start_counter;
+  double _gc_pause_time_ms;
 
  public:
   enum GCParPhases {
@@ -126,7 +128,7 @@
  public:
   G1GCPhaseTimes(uint max_gc_threads);
   void note_gc_start(uint active_gc_threads);
-  void print(double pause_time_ms);
+  void print();
 
   // record the time a phase took in seconds
   void record_time_secs(GCParPhases phase, uint worker_i, double secs);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc/g1/g1HeapTransition.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2016, 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.hpp"
+#include "gc/g1/g1CollectorPolicy.hpp"
+#include "gc/g1/g1HeapTransition.hpp"
+#include "logging/log.hpp"
+#include "memory/metaspace.hpp"
+
+G1HeapTransition::Data::Data(G1CollectedHeap* g1_heap) {
+  YoungList* young_list = g1_heap->young_list();
+  _eden_length = young_list->eden_length();
+  _survivor_length = young_list->survivor_length();
+  _old_length = g1_heap->old_regions_count();
+  _humongous_length = g1_heap->humongous_regions_count();
+  _metaspace_used_bytes = MetaspaceAux::used_bytes();
+}
+
+G1HeapTransition::G1HeapTransition(G1CollectedHeap* g1_heap) : _g1_heap(g1_heap), _before(g1_heap) { }
+
+struct DetailedUsage : public StackObj {
+  size_t _eden_used;
+  size_t _survivor_used;
+  size_t _old_used;
+  size_t _humongous_used;
+
+  size_t _eden_region_count;
+  size_t _survivor_region_count;
+  size_t _old_region_count;
+  size_t _humongous_region_count;
+
+  DetailedUsage() :
+    _eden_used(0), _survivor_used(0), _old_used(0), _humongous_used(0),
+    _eden_region_count(0), _survivor_region_count(0), _old_region_count(0), _humongous_region_count(0) {}
+};
+
+class DetailedUsageClosure: public HeapRegionClosure {
+public:
+  DetailedUsage _usage;
+  bool doHeapRegion(HeapRegion* r) {
+    if (r->is_old()) {
+      _usage._old_used += r->used();
+      _usage._old_region_count++;
+    } else if (r->is_survivor()) {
+      _usage._survivor_used += r->used();
+      _usage._survivor_region_count++;
+    } else if (r->is_eden()) {
+      _usage._eden_used += r->used();
+      _usage._eden_region_count++;
+    } else if (r->is_humongous()) {
+      _usage._humongous_used += r->used();
+      _usage._humongous_region_count++;
+    } else {
+      assert(r->used() == 0, "Expected used to be 0 but it was " SIZE_FORMAT, r->used());
+    }
+    return false;
+  }
+};
+
+void G1HeapTransition::print() {
+  Data after(_g1_heap);
+
+  size_t eden_capacity_bytes_after_gc = _g1_heap->g1_policy()->young_list_target_length() - after._survivor_length;
+  size_t survivor_capacity_bytes_after_gc = _g1_heap->g1_policy()->max_survivor_regions();
+
+  DetailedUsage usage;
+  if (log_is_enabled(Trace, gc, heap)) {
+    DetailedUsageClosure blk;
+    _g1_heap->heap_region_iterate(&blk);
+    usage = blk._usage;
+    assert(usage._eden_region_count == 0, "Expected no eden regions, but got " SIZE_FORMAT, usage._eden_region_count);
+    assert(usage._survivor_region_count == after._survivor_length, "Expected survivors to be " SIZE_FORMAT " but was " SIZE_FORMAT,
+        after._survivor_length, usage._survivor_region_count);
+    assert(usage._old_region_count == after._old_length, "Expected old to be " SIZE_FORMAT " but was " SIZE_FORMAT,
+        after._old_length, usage._old_region_count);
+    assert(usage._humongous_region_count == after._humongous_length, "Expected humongous to be " SIZE_FORMAT " but was " SIZE_FORMAT,
+        after._humongous_length, usage._humongous_region_count);
+  }
+
+  log_info(gc, heap)("Eden regions: " SIZE_FORMAT "->" SIZE_FORMAT "("  SIZE_FORMAT ")",
+                     _before._eden_length, after._eden_length, eden_capacity_bytes_after_gc);
+  log_trace(gc, heap)(" Used: 0K, Waste: 0K");
+
+  log_info(gc, heap)("Survivor regions: " SIZE_FORMAT "->" SIZE_FORMAT "("  SIZE_FORMAT ")",
+                     _before._survivor_length, after._survivor_length, survivor_capacity_bytes_after_gc);
+  log_trace(gc, heap)(" Used: " SIZE_FORMAT "K, Waste: " SIZE_FORMAT "K",
+      usage._survivor_used / K, ((after._survivor_length * HeapRegion::GrainBytes) - usage._survivor_used) / K);
+
+  log_info(gc, heap)("Old regions: " SIZE_FORMAT "->" SIZE_FORMAT,
+                     _before._old_length, after._old_length);
+  log_trace(gc, heap)(" Used: " SIZE_FORMAT "K, Waste: " SIZE_FORMAT "K",
+      usage._old_used / K, ((after._old_length * HeapRegion::GrainBytes) - usage._old_used) / K);
+
+  log_info(gc, heap)("Humongous regions: " SIZE_FORMAT "->" SIZE_FORMAT,
+                     _before._humongous_length, after._humongous_length);
+  log_trace(gc, heap)(" Used: " SIZE_FORMAT "K, Waste: " SIZE_FORMAT "K",
+      usage._humongous_used / K, ((after._humongous_length * HeapRegion::GrainBytes) - usage._humongous_used) / K);
+
+  MetaspaceAux::print_metaspace_change(_before._metaspace_used_bytes);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc/g1/g1HeapTransition.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2016, 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_G1HEAPTRANSITION_HPP
+#define SHARE_VM_GC_G1_G1HEAPTRANSITION_HPP
+
+#include "gc/shared/plab.hpp"
+
+class G1CollectedHeap;
+
+class G1HeapTransition {
+  struct Data {
+    size_t _eden_length;
+    size_t _survivor_length;
+    size_t _old_length;
+    size_t _humongous_length;
+    size_t _metaspace_used_bytes;
+
+    Data(G1CollectedHeap* g1_heap);
+  };
+
+  G1CollectedHeap* _g1_heap;
+  Data _before;
+
+public:
+  G1HeapTransition(G1CollectedHeap* g1_heap);
+
+  void print();
+};
+
+#endif // SHARE_VM_GC_G1_G1HEAPTRANSITION_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc/g1/g1HeapVerifier.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -0,0 +1,731 @@
+/*
+ * Copyright (c) 2016, 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 "logging/log.hpp"
+#include "gc/g1/concurrentMarkThread.hpp"
+#include "gc/g1/g1CollectedHeap.hpp"
+#include "gc/g1/g1CollectedHeap.inline.hpp"
+#include "gc/g1/g1HeapVerifier.hpp"
+#include "gc/g1/g1MarkSweep.hpp"
+#include "gc/g1/g1RemSet.hpp"
+#include "gc/g1/g1RootProcessor.hpp"
+#include "gc/g1/heapRegion.hpp"
+#include "gc/g1/heapRegion.inline.hpp"
+#include "gc/g1/heapRegionRemSet.hpp"
+#include "gc/g1/g1StringDedup.hpp"
+#include "gc/g1/youngList.hpp"
+#include "memory/resourceArea.hpp"
+#include "oops/oop.inline.hpp"
+
+class VerifyRootsClosure: public OopClosure {
+private:
+  G1CollectedHeap* _g1h;
+  VerifyOption     _vo;
+  bool             _failures;
+public:
+  // _vo == UsePrevMarking -> use "prev" marking information,
+  // _vo == UseNextMarking -> use "next" marking information,
+  // _vo == UseMarkWord    -> use mark word from object header.
+  VerifyRootsClosure(VerifyOption vo) :
+    _g1h(G1CollectedHeap::heap()),
+    _vo(vo),
+    _failures(false) { }
+
+  bool failures() { return _failures; }
+
+  template <class T> void do_oop_nv(T* p) {
+    T heap_oop = oopDesc::load_heap_oop(p);
+    if (!oopDesc::is_null(heap_oop)) {
+      oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+      if (_g1h->is_obj_dead_cond(obj, _vo)) {
+        LogHandle(gc, verify) log;
+        log.info("Root location " PTR_FORMAT " points to dead obj " PTR_FORMAT, p2i(p), p2i(obj));
+        if (_vo == VerifyOption_G1UseMarkWord) {
+          log.info("  Mark word: " PTR_FORMAT, p2i(obj->mark()));
+        }
+        ResourceMark rm;
+        obj->print_on(log.info_stream());
+        _failures = true;
+      }
+    }
+  }
+
+  void do_oop(oop* p)       { do_oop_nv(p); }
+  void do_oop(narrowOop* p) { do_oop_nv(p); }
+};
+
+class G1VerifyCodeRootOopClosure: public OopClosure {
+  G1CollectedHeap* _g1h;
+  OopClosure* _root_cl;
+  nmethod* _nm;
+  VerifyOption _vo;
+  bool _failures;
+
+  template <class T> void do_oop_work(T* p) {
+    // First verify that this root is live
+    _root_cl->do_oop(p);
+
+    if (!G1VerifyHeapRegionCodeRoots) {
+      // We're not verifying the code roots attached to heap region.
+      return;
+    }
+
+    // Don't check the code roots during marking verification in a full GC
+    if (_vo == VerifyOption_G1UseMarkWord) {
+      return;
+    }
+
+    // Now verify that the current nmethod (which contains p) is
+    // in the code root list of the heap region containing the
+    // object referenced by p.
+
+    T heap_oop = oopDesc::load_heap_oop(p);
+    if (!oopDesc::is_null(heap_oop)) {
+      oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+
+      // Now fetch the region containing the object
+      HeapRegion* hr = _g1h->heap_region_containing(obj);
+      HeapRegionRemSet* hrrs = hr->rem_set();
+      // Verify that the strong code root list for this region
+      // contains the nmethod
+      if (!hrrs->strong_code_roots_list_contains(_nm)) {
+        log_info(gc, verify)("Code root location " PTR_FORMAT " "
+                             "from nmethod " PTR_FORMAT " not in strong "
+                             "code roots for region [" PTR_FORMAT "," PTR_FORMAT ")",
+                             p2i(p), p2i(_nm), p2i(hr->bottom()), p2i(hr->end()));
+        _failures = true;
+      }
+    }
+  }
+
+public:
+  G1VerifyCodeRootOopClosure(G1CollectedHeap* g1h, OopClosure* root_cl, VerifyOption vo):
+    _g1h(g1h), _root_cl(root_cl), _vo(vo), _nm(NULL), _failures(false) {}
+
+  void do_oop(oop* p) { do_oop_work(p); }
+  void do_oop(narrowOop* p) { do_oop_work(p); }
+
+  void set_nmethod(nmethod* nm) { _nm = nm; }
+  bool failures() { return _failures; }
+};
+
+class G1VerifyCodeRootBlobClosure: public CodeBlobClosure {
+  G1VerifyCodeRootOopClosure* _oop_cl;
+
+public:
+  G1VerifyCodeRootBlobClosure(G1VerifyCodeRootOopClosure* oop_cl):
+    _oop_cl(oop_cl) {}
+
+  void do_code_blob(CodeBlob* cb) {
+    nmethod* nm = cb->as_nmethod_or_null();
+    if (nm != NULL) {
+      _oop_cl->set_nmethod(nm);
+      nm->oops_do(_oop_cl);
+    }
+  }
+};
+
+class YoungRefCounterClosure : public OopClosure {
+  G1CollectedHeap* _g1h;
+  int              _count;
+ public:
+  YoungRefCounterClosure(G1CollectedHeap* g1h) : _g1h(g1h), _count(0) {}
+  void do_oop(oop* p)       { if (_g1h->is_in_young(*p)) { _count++; } }
+  void do_oop(narrowOop* p) { ShouldNotReachHere(); }
+
+  int count() { return _count; }
+  void reset_count() { _count = 0; };
+};
+
+class VerifyKlassClosure: public KlassClosure {
+  YoungRefCounterClosure _young_ref_counter_closure;
+  OopClosure *_oop_closure;
+ public:
+  VerifyKlassClosure(G1CollectedHeap* g1h, OopClosure* cl) : _young_ref_counter_closure(g1h), _oop_closure(cl) {}
+  void do_klass(Klass* k) {
+    k->oops_do(_oop_closure);
+
+    _young_ref_counter_closure.reset_count();
+    k->oops_do(&_young_ref_counter_closure);
+    if (_young_ref_counter_closure.count() > 0) {
+      guarantee(k->has_modified_oops(), "Klass " PTR_FORMAT ", has young refs but is not dirty.", p2i(k));
+    }
+  }
+};
+
+class VerifyLivenessOopClosure: public OopClosure {
+  G1CollectedHeap* _g1h;
+  VerifyOption _vo;
+public:
+  VerifyLivenessOopClosure(G1CollectedHeap* g1h, VerifyOption vo):
+    _g1h(g1h), _vo(vo)
+  { }
+  void do_oop(narrowOop *p) { do_oop_work(p); }
+  void do_oop(      oop *p) { do_oop_work(p); }
+
+  template <class T> void do_oop_work(T *p) {
+    oop obj = oopDesc::load_decode_heap_oop(p);
+    guarantee(obj == NULL || !_g1h->is_obj_dead_cond(obj, _vo),
+              "Dead object referenced by a not dead object");
+  }
+};
+
+class VerifyObjsInRegionClosure: public ObjectClosure {
+private:
+  G1CollectedHeap* _g1h;
+  size_t _live_bytes;
+  HeapRegion *_hr;
+  VerifyOption _vo;
+public:
+  // _vo == UsePrevMarking -> use "prev" marking information,
+  // _vo == UseNextMarking -> use "next" marking information,
+  // _vo == UseMarkWord    -> use mark word from object header.
+  VerifyObjsInRegionClosure(HeapRegion *hr, VerifyOption vo)
+    : _live_bytes(0), _hr(hr), _vo(vo) {
+    _g1h = G1CollectedHeap::heap();
+  }
+  void do_object(oop o) {
+    VerifyLivenessOopClosure isLive(_g1h, _vo);
+    assert(o != NULL, "Huh?");
+    if (!_g1h->is_obj_dead_cond(o, _vo)) {
+      // If the object is alive according to the mark word,
+      // then verify that the marking information agrees.
+      // Note we can't verify the contra-positive of the
+      // above: if the object is dead (according to the mark
+      // word), it may not be marked, or may have been marked
+      // but has since became dead, or may have been allocated
+      // since the last marking.
+      if (_vo == VerifyOption_G1UseMarkWord) {
+        guarantee(!_g1h->is_obj_dead(o), "mark word and concurrent mark mismatch");
+      }
+
+      o->oop_iterate_no_header(&isLive);
+      if (!_hr->obj_allocated_since_prev_marking(o)) {
+        size_t obj_size = o->size();    // Make sure we don't overflow
+        _live_bytes += (obj_size * HeapWordSize);
+      }
+    }
+  }
+  size_t live_bytes() { return _live_bytes; }
+};
+
+class VerifyArchiveOopClosure: public OopClosure {
+public:
+  VerifyArchiveOopClosure(HeapRegion *hr) { }
+  void do_oop(narrowOop *p) { do_oop_work(p); }
+  void do_oop(      oop *p) { do_oop_work(p); }
+
+  template <class T> void do_oop_work(T *p) {
+    oop obj = oopDesc::load_decode_heap_oop(p);
+    guarantee(obj == NULL || G1MarkSweep::in_archive_range(obj),
+              "Archive object at " PTR_FORMAT " references a non-archive object at " PTR_FORMAT,
+              p2i(p), p2i(obj));
+  }
+};
+
+class VerifyArchiveRegionClosure: public ObjectClosure {
+public:
+  VerifyArchiveRegionClosure(HeapRegion *hr) { }
+  // Verify that all object pointers are to archive regions.
+  void do_object(oop o) {
+    VerifyArchiveOopClosure checkOop(NULL);
+    assert(o != NULL, "Should not be here for NULL oops");
+    o->oop_iterate_no_header(&checkOop);
+  }
+};
+
+class VerifyRegionClosure: public HeapRegionClosure {
+private:
+  bool             _par;
+  VerifyOption     _vo;
+  bool             _failures;
+public:
+  // _vo == UsePrevMarking -> use "prev" marking information,
+  // _vo == UseNextMarking -> use "next" marking information,
+  // _vo == UseMarkWord    -> use mark word from object header.
+  VerifyRegionClosure(bool par, VerifyOption vo)
+    : _par(par),
+      _vo(vo),
+      _failures(false) {}
+
+  bool failures() {
+    return _failures;
+  }
+
+  bool doHeapRegion(HeapRegion* r) {
+    // For archive regions, verify there are no heap pointers to
+    // non-pinned regions. For all others, verify liveness info.
+    if (r->is_archive()) {
+      VerifyArchiveRegionClosure verify_oop_pointers(r);
+      r->object_iterate(&verify_oop_pointers);
+      return true;
+    }
+    if (!r->is_continues_humongous()) {
+      bool failures = false;
+      r->verify(_vo, &failures);
+      if (failures) {
+        _failures = true;
+      } else if (!r->is_starts_humongous()) {
+        VerifyObjsInRegionClosure not_dead_yet_cl(r, _vo);
+        r->object_iterate(&not_dead_yet_cl);
+        if (_vo != VerifyOption_G1UseNextMarking) {
+          if (r->max_live_bytes() < not_dead_yet_cl.live_bytes()) {
+            log_info(gc, verify)("[" PTR_FORMAT "," PTR_FORMAT "] max_live_bytes " SIZE_FORMAT " < calculated " SIZE_FORMAT,
+                                 p2i(r->bottom()), p2i(r->end()), r->max_live_bytes(), not_dead_yet_cl.live_bytes());
+            _failures = true;
+          }
+        } else {
+          // When vo == UseNextMarking we cannot currently do a sanity
+          // check on the live bytes as the calculation has not been
+          // finalized yet.
+        }
+      }
+    }
+    return false; // stop the region iteration if we hit a failure
+  }
+};
+
+// This is the task used for parallel verification of the heap regions
+
+class G1ParVerifyTask: public AbstractGangTask {
+private:
+  G1CollectedHeap*  _g1h;
+  VerifyOption      _vo;
+  bool              _failures;
+  HeapRegionClaimer _hrclaimer;
+
+public:
+  // _vo == UsePrevMarking -> use "prev" marking information,
+  // _vo == UseNextMarking -> use "next" marking information,
+  // _vo == UseMarkWord    -> use mark word from object header.
+  G1ParVerifyTask(G1CollectedHeap* g1h, VerifyOption vo) :
+      AbstractGangTask("Parallel verify task"),
+      _g1h(g1h),
+      _vo(vo),
+      _failures(false),
+      _hrclaimer(g1h->workers()->active_workers()) {}
+
+  bool failures() {
+    return _failures;
+  }
+
+  void work(uint worker_id) {
+    HandleMark hm;
+    VerifyRegionClosure blk(true, _vo);
+    _g1h->heap_region_par_iterate(&blk, worker_id, &_hrclaimer);
+    if (blk.failures()) {
+      _failures = true;
+    }
+  }
+};
+
+
+void G1HeapVerifier::verify(VerifyOption vo) {
+  if (!SafepointSynchronize::is_at_safepoint()) {
+    log_info(gc, verify)("Skipping verification. Not at safepoint.");
+  }
+
+  assert(Thread::current()->is_VM_thread(),
+         "Expected to be executed serially by the VM thread at this point");
+
+  log_debug(gc, verify)("Roots");
+  VerifyRootsClosure rootsCl(vo);
+  VerifyKlassClosure klassCl(_g1h, &rootsCl);
+  CLDToKlassAndOopClosure cldCl(&klassCl, &rootsCl, false);
+
+  // We apply the relevant closures to all the oops in the
+  // system dictionary, class loader data graph, the string table
+  // and the nmethods in the code cache.
+  G1VerifyCodeRootOopClosure codeRootsCl(_g1h, &rootsCl, vo);
+  G1VerifyCodeRootBlobClosure blobsCl(&codeRootsCl);
+
+  {
+    G1RootProcessor root_processor(_g1h, 1);
+    root_processor.process_all_roots(&rootsCl,
+                                     &cldCl,
+                                     &blobsCl);
+  }
+
+  bool failures = rootsCl.failures() || codeRootsCl.failures();
+
+  if (vo != VerifyOption_G1UseMarkWord) {
+    // If we're verifying during a full GC then the region sets
+    // will have been torn down at the start of the GC. Therefore
+    // verifying the region sets will fail. So we only verify
+    // the region sets when not in a full GC.
+    log_debug(gc, verify)("HeapRegionSets");
+    verify_region_sets();
+  }
+
+  log_debug(gc, verify)("HeapRegions");
+  if (GCParallelVerificationEnabled && ParallelGCThreads > 1) {
+
+    G1ParVerifyTask task(_g1h, vo);
+    _g1h->workers()->run_task(&task);
+    if (task.failures()) {
+      failures = true;
+    }
+
+  } else {
+    VerifyRegionClosure blk(false, vo);
+    _g1h->heap_region_iterate(&blk);
+    if (blk.failures()) {
+      failures = true;
+    }
+  }
+
+  if (G1StringDedup::is_enabled()) {
+    log_debug(gc, verify)("StrDedup");
+    G1StringDedup::verify();
+  }
+
+  if (failures) {
+    log_info(gc, verify)("Heap after failed verification:");
+    // It helps to have the per-region information in the output to
+    // help us track down what went wrong. This is why we call
+    // print_extended_on() instead of print_on().
+    LogHandle(gc, verify) log;
+    ResourceMark rm;
+    _g1h->print_extended_on(log.info_stream());
+  }
+  guarantee(!failures, "there should not have been any failures");
+}
+
+// Heap region set verification
+
+class VerifyRegionListsClosure : public HeapRegionClosure {
+private:
+  HeapRegionSet*   _old_set;
+  HeapRegionSet*   _humongous_set;
+  HeapRegionManager*   _hrm;
+
+public:
+  uint _old_count;
+  uint _humongous_count;
+  uint _free_count;
+
+  VerifyRegionListsClosure(HeapRegionSet* old_set,
+                           HeapRegionSet* humongous_set,
+                           HeapRegionManager* hrm) :
+    _old_set(old_set), _humongous_set(humongous_set), _hrm(hrm),
+    _old_count(), _humongous_count(), _free_count(){ }
+
+  bool doHeapRegion(HeapRegion* hr) {
+    if (hr->is_young()) {
+      // TODO
+    } 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++;
+    } else if (hr->is_empty()) {
+      assert(_hrm->is_free(hr), "Heap region %u is empty but not on the free list.", hr->hrm_index());
+      _free_count++;
+    } else if (hr->is_old()) {
+      assert(hr->containing_set() == _old_set, "Heap region %u is old but not in the old set.", hr->hrm_index());
+      _old_count++;
+    } else {
+      // There are no other valid region types. Check for one invalid
+      // one we can identify: pinned without old or humongous set.
+      assert(!hr->is_pinned(), "Heap region %u is pinned but not old (archive) or humongous.", hr->hrm_index());
+      ShouldNotReachHere();
+    }
+    return false;
+  }
+
+  void verify_counts(HeapRegionSet* old_set, HeapRegionSet* humongous_set, HeapRegionManager* free_list) {
+    guarantee(old_set->length() == _old_count, "Old set count mismatch. Expected %u, actual %u.", old_set->length(), _old_count);
+    guarantee(humongous_set->length() == _humongous_count, "Hum set count mismatch. Expected %u, actual %u.", humongous_set->length(), _humongous_count);
+    guarantee(free_list->num_free_regions() == _free_count, "Free list count mismatch. Expected %u, actual %u.", free_list->num_free_regions(), _free_count);
+  }
+};
+
+void G1HeapVerifier::verify_region_sets() {
+  assert_heap_locked_or_at_safepoint(true /* should_be_vm_thread */);
+
+  // First, check the explicit lists.
+  _g1h->_hrm.verify();
+  {
+    // Given that a concurrent operation might be adding regions to
+    // the secondary free list we have to take the lock before
+    // verifying it.
+    MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag);
+    _g1h->_secondary_free_list.verify_list();
+  }
+
+  // If a concurrent region freeing operation is in progress it will
+  // be difficult to correctly attributed any free regions we come
+  // across to the correct free list given that they might belong to
+  // one of several (free_list, secondary_free_list, any local lists,
+  // etc.). So, if that's the case we will skip the rest of the
+  // verification operation. Alternatively, waiting for the concurrent
+  // operation to complete will have a non-trivial effect on the GC's
+  // operation (no concurrent operation will last longer than the
+  // interval between two calls to verification) and it might hide
+  // any issues that we would like to catch during testing.
+  if (_g1h->free_regions_coming()) {
+    return;
+  }
+
+  // Make sure we append the secondary_free_list on the free_list so
+  // that all free regions we will come across can be safely
+  // attributed to the free_list.
+  _g1h->append_secondary_free_list_if_not_empty_with_lock();
+
+  // Finally, make sure that the region accounting in the lists is
+  // consistent with what we see in the heap.
+
+  VerifyRegionListsClosure cl(&_g1h->_old_set, &_g1h->_humongous_set, &_g1h->_hrm);
+  _g1h->heap_region_iterate(&cl);
+  cl.verify_counts(&_g1h->_old_set, &_g1h->_humongous_set, &_g1h->_hrm);
+}
+
+void G1HeapVerifier::prepare_for_verify() {
+  if (SafepointSynchronize::is_at_safepoint() || ! UseTLAB) {
+    _g1h->ensure_parsability(false);
+  }
+  _g1h->g1_rem_set()->prepare_for_verify();
+}
+
+double G1HeapVerifier::verify(bool guard, const char* msg) {
+  double verify_time_ms = 0.0;
+
+  if (guard && _g1h->total_collections() >= VerifyGCStartAt) {
+    double verify_start = os::elapsedTime();
+    HandleMark hm;  // Discard invalid handles created during verification
+    prepare_for_verify();
+    Universe::verify(VerifyOption_G1UsePrevMarking, msg);
+    verify_time_ms = (os::elapsedTime() - verify_start) * 1000;
+  }
+
+  return verify_time_ms;
+}
+
+void G1HeapVerifier::verify_before_gc() {
+  double verify_time_ms = verify(VerifyBeforeGC, "Before GC");
+  _g1h->g1_policy()->phase_times()->record_verify_before_time_ms(verify_time_ms);
+}
+
+void G1HeapVerifier::verify_after_gc() {
+  double verify_time_ms = verify(VerifyAfterGC, "After GC");
+  _g1h->g1_policy()->phase_times()->record_verify_after_time_ms(verify_time_ms);
+}
+
+
+#ifndef PRODUCT
+class G1VerifyCardTableCleanup: public HeapRegionClosure {
+  G1HeapVerifier* _verifier;
+  G1SATBCardTableModRefBS* _ct_bs;
+public:
+  G1VerifyCardTableCleanup(G1HeapVerifier* verifier, G1SATBCardTableModRefBS* ct_bs)
+    : _verifier(verifier), _ct_bs(ct_bs) { }
+  virtual bool doHeapRegion(HeapRegion* r) {
+    if (r->is_survivor()) {
+      _verifier->verify_dirty_region(r);
+    } else {
+      _verifier->verify_not_dirty_region(r);
+    }
+    return false;
+  }
+};
+
+void G1HeapVerifier::verify_card_table_cleanup() {
+  if (G1VerifyCTCleanup || VerifyAfterGC) {
+    G1VerifyCardTableCleanup cleanup_verifier(this, _g1h->g1_barrier_set());
+    _g1h->heap_region_iterate(&cleanup_verifier);
+  }
+}
+
+void G1HeapVerifier::verify_not_dirty_region(HeapRegion* hr) {
+  // All of the region should be clean.
+  G1SATBCardTableModRefBS* ct_bs = _g1h->g1_barrier_set();
+  MemRegion mr(hr->bottom(), hr->end());
+  ct_bs->verify_not_dirty_region(mr);
+}
+
+void G1HeapVerifier::verify_dirty_region(HeapRegion* hr) {
+  // We cannot guarantee that [bottom(),end()] is dirty.  Threads
+  // dirty allocated blocks as they allocate them. The thread that
+  // retires each region and replaces it with a new one will do a
+  // maximal allocation to fill in [pre_dummy_top(),end()] but will
+  // not dirty that area (one less thing to have to do while holding
+  // a lock). So we can only verify that [bottom(),pre_dummy_top()]
+  // is dirty.
+  G1SATBCardTableModRefBS* ct_bs = _g1h->g1_barrier_set();
+  MemRegion mr(hr->bottom(), hr->pre_dummy_top());
+  if (hr->is_young()) {
+    ct_bs->verify_g1_young_region(mr);
+  } else {
+    ct_bs->verify_dirty_region(mr);
+  }
+}
+
+void G1HeapVerifier::verify_dirty_young_list(HeapRegion* head) {
+  G1SATBCardTableModRefBS* ct_bs = _g1h->g1_barrier_set();
+  for (HeapRegion* hr = head; hr != NULL; hr = hr->get_next_young_region()) {
+    verify_dirty_region(hr);
+  }
+}
+
+void G1HeapVerifier::verify_dirty_young_regions() {
+  verify_dirty_young_list(_g1h->young_list()->first_region());
+}
+
+bool G1HeapVerifier::verify_no_bits_over_tams(const char* bitmap_name, CMBitMapRO* bitmap,
+                                               HeapWord* tams, HeapWord* end) {
+  guarantee(tams <= end,
+            "tams: " PTR_FORMAT " end: " PTR_FORMAT, p2i(tams), p2i(end));
+  HeapWord* result = bitmap->getNextMarkedWordAddress(tams, end);
+  if (result < end) {
+    log_info(gc, verify)("## wrong marked address on %s bitmap: " PTR_FORMAT, bitmap_name, p2i(result));
+    log_info(gc, verify)("## %s tams: " PTR_FORMAT " end: " PTR_FORMAT, bitmap_name, p2i(tams), p2i(end));
+    return false;
+  }
+  return true;
+}
+
+bool G1HeapVerifier::verify_bitmaps(const char* caller, HeapRegion* hr) {
+  CMBitMapRO* prev_bitmap = _g1h->concurrent_mark()->prevMarkBitMap();
+  CMBitMapRO* next_bitmap = (CMBitMapRO*) _g1h->concurrent_mark()->nextMarkBitMap();
+
+  HeapWord* bottom = hr->bottom();
+  HeapWord* ptams  = hr->prev_top_at_mark_start();
+  HeapWord* ntams  = hr->next_top_at_mark_start();
+  HeapWord* end    = hr->end();
+
+  bool res_p = verify_no_bits_over_tams("prev", prev_bitmap, ptams, end);
+
+  bool res_n = true;
+  // We reset mark_in_progress() before we reset _cmThread->in_progress() and in this window
+  // we do the clearing of the next bitmap concurrently. Thus, we can not verify the bitmap
+  // if we happen to be in that state.
+  if (_g1h->collector_state()->mark_in_progress() || !_g1h->_cmThread->in_progress()) {
+    res_n = verify_no_bits_over_tams("next", next_bitmap, ntams, end);
+  }
+  if (!res_p || !res_n) {
+    log_info(gc, verify)("#### Bitmap verification failed for " HR_FORMAT, HR_FORMAT_PARAMS(hr));
+    log_info(gc, verify)("#### Caller: %s", caller);
+    return false;
+  }
+  return true;
+}
+
+void G1HeapVerifier::check_bitmaps(const char* caller, HeapRegion* hr) {
+  if (!G1VerifyBitmaps) return;
+
+  guarantee(verify_bitmaps(caller, hr), "bitmap verification");
+}
+
+class G1VerifyBitmapClosure : public HeapRegionClosure {
+private:
+  const char* _caller;
+  G1HeapVerifier* _verifier;
+  bool _failures;
+
+public:
+  G1VerifyBitmapClosure(const char* caller, G1HeapVerifier* verifier) :
+    _caller(caller), _verifier(verifier), _failures(false) { }
+
+  bool failures() { return _failures; }
+
+  virtual bool doHeapRegion(HeapRegion* hr) {
+    bool result = _verifier->verify_bitmaps(_caller, hr);
+    if (!result) {
+      _failures = true;
+    }
+    return false;
+  }
+};
+
+void G1HeapVerifier::check_bitmaps(const char* caller) {
+  if (!G1VerifyBitmaps) return;
+
+  G1VerifyBitmapClosure cl(caller, this);
+  _g1h->heap_region_iterate(&cl);
+  guarantee(!cl.failures(), "bitmap verification");
+}
+
+class G1CheckCSetFastTableClosure : public HeapRegionClosure {
+ private:
+  bool _failures;
+ public:
+  G1CheckCSetFastTableClosure() : HeapRegionClosure(), _failures(false) { }
+
+  virtual bool doHeapRegion(HeapRegion* hr) {
+    uint i = hr->hrm_index();
+    InCSetState cset_state = (InCSetState) G1CollectedHeap::heap()->_in_cset_fast_test.get_by_index(i);
+    if (hr->is_humongous()) {
+      if (hr->in_collection_set()) {
+        log_info(gc, verify)("## humongous region %u in CSet", i);
+        _failures = true;
+        return true;
+      }
+      if (cset_state.is_in_cset()) {
+        log_info(gc, verify)("## inconsistent cset state " CSETSTATE_FORMAT " for humongous region %u", cset_state.value(), i);
+        _failures = true;
+        return true;
+      }
+      if (hr->is_continues_humongous() && cset_state.is_humongous()) {
+        log_info(gc, verify)("## inconsistent cset state " CSETSTATE_FORMAT " for continues humongous region %u", cset_state.value(), i);
+        _failures = true;
+        return true;
+      }
+    } else {
+      if (cset_state.is_humongous()) {
+        log_info(gc, verify)("## inconsistent cset state " CSETSTATE_FORMAT " for non-humongous region %u", cset_state.value(), i);
+        _failures = true;
+        return true;
+      }
+      if (hr->in_collection_set() != cset_state.is_in_cset()) {
+        log_info(gc, verify)("## in CSet %d / cset state " CSETSTATE_FORMAT " inconsistency for region %u",
+                             hr->in_collection_set(), cset_state.value(), i);
+        _failures = true;
+        return true;
+      }
+      if (cset_state.is_in_cset()) {
+        if (hr->is_young() != (cset_state.is_young())) {
+          log_info(gc, verify)("## is_young %d / cset state " CSETSTATE_FORMAT " inconsistency for region %u",
+                               hr->is_young(), cset_state.value(), i);
+          _failures = true;
+          return true;
+        }
+        if (hr->is_old() != (cset_state.is_old())) {
+          log_info(gc, verify)("## is_old %d / cset state " CSETSTATE_FORMAT " inconsistency for region %u",
+                               hr->is_old(), cset_state.value(), i);
+          _failures = true;
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  bool failures() const { return _failures; }
+};
+
+bool G1HeapVerifier::check_cset_fast_test() {
+  G1CheckCSetFastTableClosure cl;
+  _g1h->_hrm.iterate(&cl);
+  return !cl.failures();
+}
+#endif // PRODUCT
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc/g1/g1HeapVerifier.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2016, 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_G1HEAPVERIFIER_HPP
+#define SHARE_VM_GC_G1_G1HEAPVERIFIER_HPP
+
+#include "gc/g1/heapRegionSet.hpp"
+#include "memory/allocation.hpp"
+#include "memory/universe.hpp"
+
+class G1CollectedHeap;
+
+class G1HeapVerifier : public CHeapObj<mtGC> {
+private:
+  G1CollectedHeap* _g1h;
+
+  // verify_region_sets() performs verification over the region
+  // lists. It will be compiled in the product code to be used when
+  // necessary (i.e., during heap verification).
+  void verify_region_sets();
+
+public:
+
+  G1HeapVerifier(G1CollectedHeap* heap) : _g1h(heap) { }
+
+  // Perform verification.
+
+  // vo == UsePrevMarking  -> use "prev" marking information,
+  // vo == UseNextMarking -> use "next" marking information
+  // vo == UseMarkWord    -> use the mark word in the object header
+  //
+  // NOTE: Only the "prev" marking information is guaranteed to be
+  // consistent most of the time, so most calls to this should use
+  // vo == UsePrevMarking.
+  // Currently, there is only one case where this is called with
+  // vo == UseNextMarking, which is to verify the "next" marking
+  // information at the end of remark.
+  // Currently there is only one place where this is called with
+  // vo == UseMarkWord, which is to verify the marking during a
+  // full GC.
+  void verify(VerifyOption vo);
+
+  // verify_region_sets_optional() is planted in the code for
+  // list verification in non-product builds (and it can be enabled in
+  // product builds by defining HEAP_REGION_SET_FORCE_VERIFY to be 1).
+#if HEAP_REGION_SET_FORCE_VERIFY
+  void verify_region_sets_optional() {
+    verify_region_sets();
+  }
+#else // HEAP_REGION_SET_FORCE_VERIFY
+  void verify_region_sets_optional() { }
+#endif // HEAP_REGION_SET_FORCE_VERIFY
+
+  void prepare_for_verify();
+  double verify(bool guard, const char* msg);
+  void verify_before_gc();
+  void verify_after_gc();
+
+#ifndef PRODUCT
+  // Make sure that the given bitmap has no marked objects in the
+  // range [from,limit). If it does, print an error message and return
+  // false. Otherwise, just return true. bitmap_name should be "prev"
+  // or "next".
+  bool verify_no_bits_over_tams(const char* bitmap_name, CMBitMapRO* bitmap,
+                                HeapWord* from, HeapWord* limit);
+
+  // Verify that the prev / next bitmap range [tams,end) for the given
+  // region has no marks. Return true if all is well, false if errors
+  // are detected.
+  bool verify_bitmaps(const char* caller, HeapRegion* hr);
+#endif // PRODUCT
+
+  // If G1VerifyBitmaps is set, verify that the marking bitmaps for
+  // the given region do not have any spurious marks. If errors are
+  // detected, print appropriate error messages and crash.
+  void check_bitmaps(const char* caller, HeapRegion* hr) PRODUCT_RETURN;
+
+  // If G1VerifyBitmaps is set, verify that the marking bitmaps do not
+  // have any spurious marks. If errors are detected, print
+  // appropriate error messages and crash.
+  void check_bitmaps(const char* caller) PRODUCT_RETURN;
+
+  // Do sanity check on the contents of the in-cset fast test table.
+  bool check_cset_fast_test() PRODUCT_RETURN_( return true; );
+
+  void verify_card_table_cleanup() PRODUCT_RETURN;
+
+  void verify_not_dirty_region(HeapRegion* hr) PRODUCT_RETURN;
+  void verify_dirty_region(HeapRegion* hr) PRODUCT_RETURN;
+  void verify_dirty_young_list(HeapRegion* head) PRODUCT_RETURN;
+  void verify_dirty_young_regions() PRODUCT_RETURN;
+};
+
+#endif // SHARE_VM_GC_G1_G1HEAPVERIFIER_HPP
--- a/src/share/vm/gc/g1/g1OopClosures.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/g1/g1OopClosures.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -206,9 +206,9 @@
   OopClosure* _c2;
 public:
   G1Mux2Closure(OopClosure *c1, OopClosure *c2);
-  template <class T> void do_oop_work(T* p);
-  virtual void do_oop(oop* p)        { do_oop_work(p); }
-  virtual void do_oop(narrowOop* p)  { do_oop_work(p); }
+  template <class T> inline void do_oop_work(T* p);
+  virtual inline void do_oop(oop* p);
+  virtual inline void do_oop(narrowOop* p);
 };
 
 // A closure that returns true if it is actually applied
@@ -219,9 +219,9 @@
 public:
   G1TriggerClosure();
   bool triggered() const { return _triggered; }
-  template <class T> void do_oop_work(T* p);
-  virtual void do_oop(oop* p)        { do_oop_work(p); }
-  virtual void do_oop(narrowOop* p)  { do_oop_work(p); }
+  template <class T> inline void do_oop_work(T* p);
+  virtual inline void do_oop(oop* p);
+  virtual inline void do_oop(narrowOop* p);
 };
 
 // A closure which uses a triggering closure to determine
@@ -232,9 +232,9 @@
   OopClosure* _oop_cl;
 public:
   G1InvokeIfNotTriggeredClosure(G1TriggerClosure* t, OopClosure* oc);
-  template <class T> void do_oop_work(T* p);
-  virtual void do_oop(oop* p)        { do_oop_work(p); }
-  virtual void do_oop(narrowOop* p)  { do_oop_work(p); }
+  template <class T> inline void do_oop_work(T* p);
+  virtual inline void do_oop(oop* p);
+  virtual inline void do_oop(narrowOop* p);
 };
 
 class G1UpdateRSOrPushRefOopClosure: public OopClosure {
@@ -263,9 +263,9 @@
     return result;
   }
 
-  template <class T> void do_oop_work(T* p);
-  virtual void do_oop(narrowOop* p) { do_oop_work(p); }
-  virtual void do_oop(oop* p)       { do_oop_work(p); }
+  template <class T> inline void do_oop_work(T* p);
+  virtual inline void do_oop(narrowOop* p);
+  virtual inline void do_oop(oop* p);
 };
 
 #endif // SHARE_VM_GC_G1_G1OOPCLOSURES_HPP
--- a/src/share/vm/gc/g1/g1OopClosures.inline.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/g1/g1OopClosures.inline.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, 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
@@ -141,12 +141,16 @@
   _c1->do_oop(p);
   _c2->do_oop(p);
 }
+void G1Mux2Closure::do_oop(oop* p)       { do_oop_work(p); }
+void G1Mux2Closure::do_oop(narrowOop* p) { do_oop_work(p); }
 
 template <class T>
 inline void G1TriggerClosure::do_oop_work(T* p) {
   // Record that this closure was actually applied (triggered).
   _triggered = true;
 }
+void G1TriggerClosure::do_oop(oop* p)       { do_oop_work(p); }
+void G1TriggerClosure::do_oop(narrowOop* p) { do_oop_work(p); }
 
 template <class T>
 inline void G1InvokeIfNotTriggeredClosure::do_oop_work(T* p) {
@@ -154,6 +158,8 @@
     _oop_cl->do_oop(p);
   }
 }
+void G1InvokeIfNotTriggeredClosure::do_oop(oop* p)       { do_oop_work(p); }
+void G1InvokeIfNotTriggeredClosure::do_oop(narrowOop* p) { do_oop_work(p); }
 
 template <class T>
 inline void G1UpdateRSOrPushRefOopClosure::do_oop_work(T* p) {
@@ -224,6 +230,8 @@
     to->rem_set()->add_reference(p, _worker_i);
   }
 }
+void G1UpdateRSOrPushRefOopClosure::do_oop(oop* p)       { do_oop_work(p); }
+void G1UpdateRSOrPushRefOopClosure::do_oop(narrowOop* p) { do_oop_work(p); }
 
 template <class T>
 void G1ParCopyHelper::do_klass_barrier(T* p, oop new_obj) {
--- a/src/share/vm/gc/g1/g1RemSet.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/g1/g1RemSet.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -34,6 +34,7 @@
 #include "gc/g1/g1HotCardCache.hpp"
 #include "gc/g1/g1OopClosures.inline.hpp"
 #include "gc/g1/g1RemSet.inline.hpp"
+#include "gc/g1/g1SATBCardTableModRefBS.inline.hpp"
 #include "gc/g1/heapRegion.inline.hpp"
 #include "gc/g1/heapRegionManager.inline.hpp"
 #include "gc/g1/heapRegionRemSet.hpp"
--- a/src/share/vm/gc/g1/g1SATBCardTableModRefBS.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/g1/g1SATBCardTableModRefBS.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,7 +24,7 @@
 
 #include "precompiled.hpp"
 #include "gc/g1/g1CollectedHeap.inline.hpp"
-#include "gc/g1/g1SATBCardTableModRefBS.hpp"
+#include "gc/g1/g1SATBCardTableModRefBS.inline.hpp"
 #include "gc/g1/heapRegion.hpp"
 #include "gc/g1/satbMarkQueue.hpp"
 #include "gc/shared/memset_with_concurrent_readers.hpp"
--- a/src/share/vm/gc/g1/g1SATBCardTableModRefBS.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/g1/g1SATBCardTableModRefBS.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, 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
@@ -58,20 +58,11 @@
 
   // 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));
-    }
-  }
+  template <class T> inline void inline_write_ref_field_pre(T* field, oop 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);
-  }
-  virtual void write_ref_field_pre_work(narrowOop* field, oop new_val) {
-    inline_write_ref_field_pre(field, new_val);
-  }
+  inline virtual void write_ref_field_pre_work(oop* field, oop new_val);
+  inline virtual void write_ref_field_pre_work(narrowOop* field, oop new_val);
   virtual void write_ref_field_pre_work(void* field, oop new_val) {
     guarantee(false, "Not needed");
   }
@@ -98,15 +89,7 @@
     return (val & (clean_card_mask_val() | claimed_card_val())) == claimed_card_val();
   }
 
-  void set_card_claimed(size_t card_index) {
-      jbyte val = _byte_map[card_index];
-      if (val == clean_card_val()) {
-        val = (jbyte)claimed_card_val();
-      } else {
-        val |= (jbyte)claimed_card_val();
-      }
-      _byte_map[card_index] = val;
-  }
+  inline void set_card_claimed(size_t card_index);
 
   void verify_g1_young_region(MemRegion mr) PRODUCT_RETURN;
   void g1_mark_as_young(const MemRegion& mr);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc/g1/g1SATBCardTableModRefBS.inline.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016, 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_G1SATBCARDTABLEMODREFBS_INLINE_HPP
+#define SHARE_VM_GC_G1_G1SATBCARDTABLEMODREFBS_INLINE_HPP
+
+#include "gc/g1/g1SATBCardTableModRefBS.hpp"
+#include "oops/oop.inline.hpp"
+
+// 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> void G1SATBCardTableModRefBS::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));
+  }
+}
+
+// These are the more general virtual versions.
+void G1SATBCardTableModRefBS::write_ref_field_pre_work(oop* field, oop new_val) {
+  inline_write_ref_field_pre(field, new_val);
+}
+void G1SATBCardTableModRefBS::write_ref_field_pre_work(narrowOop* field, oop new_val) {
+  inline_write_ref_field_pre(field, new_val);
+}
+
+void G1SATBCardTableModRefBS::set_card_claimed(size_t card_index) {
+  jbyte val = _byte_map[card_index];
+  if (val == clean_card_val()) {
+    val = (jbyte)claimed_card_val();
+  } else {
+    val |= (jbyte)claimed_card_val();
+  }
+  _byte_map[card_index] = val;
+}
+
+#endif // SHARE_VM_GC_G1_G1SATBCARDTABLEMODREFBS_INLINE_HPP
--- a/src/share/vm/gc/g1/heapRegion.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/g1/heapRegion.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -143,6 +143,7 @@
   // The cast to int is safe, given that we've bounded region_size by
   // MIN_REGION_SIZE and MAX_REGION_SIZE.
   GrainBytes = region_size;
+  log_info(gc, heap)("Heap region size: " SIZE_FORMAT "M", GrainBytes / M);
 
   guarantee(GrainWords == 0, "we should only set it once");
   GrainWords = GrainBytes >> LogHeapWordSize;
--- a/src/share/vm/gc/g1/heapRegionRemSet.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/g1/heapRegionRemSet.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, 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
@@ -110,7 +110,9 @@
 
 public:
 
-  HeapRegion* hr() const { return _hr; }
+  HeapRegion* hr() const {
+    return (HeapRegion*) OrderAccess::load_ptr_acquire(&_hr);
+  }
 
   jint occupied() const {
     // Overkill, but if we ever need it...
@@ -123,10 +125,12 @@
       set_next(NULL);
       set_prev(NULL);
     }
-    _hr = hr;
     _collision_list_next = NULL;
     _occupied = 0;
     _bm.clear();
+    // Make sure that the bitmap clearing above has been finished before publishing
+    // this PRT to concurrent threads.
+    OrderAccess::release_store_ptr(&_hr, hr);
   }
 
   void add_reference(OopOrNarrowOopStar from) {
@@ -357,7 +361,7 @@
   int from_card = (int)(uintptr_t(from) >> CardTableModRefBS::card_shift);
 
   if (G1FromCardCache::contains_or_replace(tid, cur_hrm_ind, from_card)) {
-    assert(contains_reference(from), "We just added it!");
+    assert(contains_reference(from), "We just found " PTR_FORMAT " in the FromCardCache", p2i(from));
     return;
   }
 
@@ -367,7 +371,7 @@
 
   // If the region is already coarsened, return.
   if (_coarse_map.at(from_hrm_ind)) {
-    assert(contains_reference(from), "We just added it!");
+    assert(contains_reference(from), "We just found " PTR_FORMAT " in the Coarse table", p2i(from));
     return;
   }
 
@@ -388,7 +392,7 @@
              "Must be in range.");
       if (G1HRRSUseSparseTable &&
           _sparse_table.add_card(from_hrm_ind, card_index)) {
-        assert(contains_reference_locked(from), "We just added it!");
+        assert(contains_reference_locked(from), "We just added " PTR_FORMAT " to the Sparse table", p2i(from));
         return;
       }
 
@@ -438,7 +442,7 @@
   assert(prt != NULL, "Inv");
 
   prt->add_reference(from);
-  assert(contains_reference(from), "We just added it!");
+  assert(contains_reference(from), "We just added " PTR_FORMAT " to the PRT", p2i(from));
 }
 
 PerRegionTable*
@@ -785,6 +789,9 @@
 
 void HeapRegionRemSet::add_strong_code_root(nmethod* nm) {
   assert(nm != NULL, "sanity");
+  assert((!CodeCache_lock->owned_by_self() || SafepointSynchronize::is_at_safepoint()),
+          "should call add_strong_code_root_locked instead. CodeCache_lock->owned_by_self(): %s, is_at_safepoint(): %s",
+          BOOL_TO_STR(CodeCache_lock->owned_by_self()), BOOL_TO_STR(SafepointSynchronize::is_at_safepoint()));
   // Optimistic unlocked contains-check
   if (!_code_roots.contains(nm)) {
     MutexLockerEx ml(&_m, Mutex::_no_safepoint_check_flag);
@@ -794,6 +801,12 @@
 
 void HeapRegionRemSet::add_strong_code_root_locked(nmethod* nm) {
   assert(nm != NULL, "sanity");
+  assert((CodeCache_lock->owned_by_self() ||
+         (SafepointSynchronize::is_at_safepoint() &&
+          (_m.owned_by_self() || Thread::current()->is_VM_thread()))),
+          "not safely locked. CodeCache_lock->owned_by_self(): %s, is_at_safepoint(): %s, _m.owned_by_self(): %s, Thread::current()->is_VM_thread(): %s",
+          BOOL_TO_STR(CodeCache_lock->owned_by_self()), BOOL_TO_STR(SafepointSynchronize::is_at_safepoint()),
+          BOOL_TO_STR(_m.owned_by_self()), BOOL_TO_STR(Thread::current()->is_VM_thread()));
   _code_roots.add(nm);
 }
 
--- a/src/share/vm/gc/parallel/asPSYoungGen.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/parallel/asPSYoungGen.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,7 @@
 #include "gc/parallel/asPSYoungGen.hpp"
 #include "gc/parallel/parallelScavengeHeap.hpp"
 #include "gc/parallel/psMarkSweepDecorator.hpp"
-#include "gc/parallel/psScavenge.hpp"
+#include "gc/parallel/psScavenge.inline.hpp"
 #include "gc/parallel/psYoungGen.hpp"
 #include "gc/shared/gcUtil.hpp"
 #include "gc/shared/spaceDecorator.hpp"
--- a/src/share/vm/gc/parallel/cardTableExtension.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/parallel/cardTableExtension.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
 #include "precompiled.hpp"
 #include "gc/parallel/cardTableExtension.hpp"
 #include "gc/parallel/gcTaskManager.hpp"
+#include "gc/parallel/objectStartArray.inline.hpp"
 #include "gc/parallel/parallelScavengeHeap.hpp"
 #include "gc/parallel/psPromotionManager.inline.hpp"
 #include "gc/parallel/psScavenge.hpp"
--- a/src/share/vm/gc/parallel/objectStartArray.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/parallel/objectStartArray.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
  */
 
 #include "precompiled.hpp"
-#include "gc/parallel/objectStartArray.hpp"
+#include "gc/parallel/objectStartArray.inline.hpp"
 #include "gc/shared/cardTableModRefBS.hpp"
 #include "memory/allocation.inline.hpp"
 #include "oops/oop.inline.hpp"
@@ -123,7 +123,6 @@
   memset(_blocks_region.start(), clean_block, _blocks_region.byte_size());
 }
 
-
 bool ObjectStartArray::object_starts_in_range(HeapWord* start_addr,
                                               HeapWord* end_addr) const {
   assert(start_addr <= end_addr,
--- a/src/share/vm/gc/parallel/objectStartArray.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/parallel/objectStartArray.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, 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
@@ -139,23 +139,7 @@
   // a given block. The blocks contain the offset of the last
   // object in that block. Scroll backwards by one, and the first
   // object hit should be at the beginning of the block
-  HeapWord* object_start(HeapWord* addr) const {
-    assert_covered_region_contains(addr);
-    jbyte* block = block_for_addr(addr);
-    HeapWord* scroll_forward = offset_addr_for_block(block--);
-    while (scroll_forward > addr) {
-      scroll_forward = offset_addr_for_block(block--);
-    }
-
-    HeapWord* next = scroll_forward;
-    while (next <= addr) {
-      scroll_forward = next;
-      next += oop(next)->size();
-    }
-    assert(scroll_forward <= addr, "wrong order for current and arg");
-    assert(addr <= next, "wrong order for arg and next");
-    return scroll_forward;
-  }
+  inline HeapWord* object_start(HeapWord* addr) const;
 
   bool is_block_allocated(HeapWord* addr) {
     assert_covered_region_contains(addr);
@@ -165,7 +149,6 @@
 
     return true;
   }
-#undef assert_covered_region_contains
 
   // Return true if an object starts in the range of heap addresses.
   // If an object starts at an address corresponding to
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc/parallel/objectStartArray.inline.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016, 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_PARALLEL_OBJECTSTARTARRAY_INLINE_HPP
+#define SHARE_VM_GC_PARALLEL_OBJECTSTARTARRAY_INLINE_HPP
+
+#include "gc/parallel/objectStartArray.hpp"
+
+// Optimized for finding the first object that crosses into
+// a given block. The blocks contain the offset of the last
+// object in that block. Scroll backwards by one, and the first
+// object hit should be at the beginning of the block
+HeapWord* ObjectStartArray::object_start(HeapWord* addr) const {
+  assert_covered_region_contains(addr);
+  jbyte* block = block_for_addr(addr);
+  HeapWord* scroll_forward = offset_addr_for_block(block--);
+  while (scroll_forward > addr) {
+    scroll_forward = offset_addr_for_block(block--);
+  }
+
+  HeapWord* next = scroll_forward;
+  while (next <= addr) {
+    scroll_forward = next;
+    next += oop(next)->size();
+  }
+  assert(scroll_forward <= addr, "wrong order for current and arg");
+  assert(addr <= next, "wrong order for arg and next");
+  return scroll_forward;
+}
+
+
+#endif // SHARE_VM_GC_PARALLEL_OBJECTSTARTARRAY_INLINE_HPP
--- a/src/share/vm/gc/parallel/parMarkBitMap.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/parallel/parMarkBitMap.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,7 +24,8 @@
 
 #include "precompiled.hpp"
 #include "gc/parallel/parMarkBitMap.hpp"
-#include "gc/parallel/psParallelCompact.hpp"
+#include "gc/parallel/psCompactionManager.inline.hpp"
+#include "gc/parallel/psParallelCompact.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/atomic.inline.hpp"
 #include "runtime/os.hpp"
@@ -96,7 +97,20 @@
   return false;
 }
 
-size_t ParMarkBitMap::live_words_in_range(HeapWord* beg_addr, oop end_obj) const
+inline bool
+ParMarkBitMap::is_live_words_in_range_in_cache(ParCompactionManager* cm, HeapWord* beg_addr) const {
+  return cm->last_query_begin() == beg_addr;
+}
+
+inline void
+ParMarkBitMap::update_live_words_in_range_cache(ParCompactionManager* cm, HeapWord* beg_addr, oop end_obj, size_t result) const {
+  cm->set_last_query_begin(beg_addr);
+  cm->set_last_query_object(end_obj);
+  cm->set_last_query_return(result);
+}
+
+size_t
+ParMarkBitMap::live_words_in_range_helper(HeapWord* beg_addr, oop end_obj) const
 {
   assert(beg_addr <= (HeapWord*)end_obj, "bad range");
   assert(is_marked(end_obj), "end_obj must be live");
@@ -117,6 +131,42 @@
   return bits_to_words(live_bits);
 }
 
+size_t
+ParMarkBitMap::live_words_in_range_use_cache(ParCompactionManager* cm, HeapWord* beg_addr, oop end_obj) const
+{
+  HeapWord* last_beg = cm->last_query_begin();
+  oop last_obj = cm->last_query_object();
+  size_t last_ret = cm->last_query_return();
+  if (end_obj > last_obj) {
+    last_ret = last_ret + live_words_in_range_helper((HeapWord*)last_obj, end_obj);
+    last_obj = end_obj;
+  } else if (end_obj < last_obj) {
+    // The cached value is for an object that is to the left (lower address) of the current
+    // end_obj. Calculate back from that cached value.
+    if (pointer_delta((HeapWord*)end_obj, (HeapWord*)beg_addr) > pointer_delta((HeapWord*)last_obj, (HeapWord*)end_obj)) {
+      last_ret = last_ret - live_words_in_range_helper((HeapWord*)end_obj, last_obj);
+    } else {
+      last_ret = live_words_in_range_helper(beg_addr, end_obj);
+    }
+    last_obj = end_obj;
+  }
+
+  update_live_words_in_range_cache(cm, last_beg, last_obj, last_ret);
+  return last_ret;
+}
+
+size_t
+ParMarkBitMap::live_words_in_range(ParCompactionManager* cm, HeapWord* beg_addr, oop end_obj) const
+{
+  // Try to reuse result from ParCompactionManager cache first.
+  if (is_live_words_in_range_in_cache(cm, beg_addr)) {
+    return live_words_in_range_use_cache(cm, beg_addr, end_obj);
+  }
+  size_t ret = live_words_in_range_helper(beg_addr, end_obj);
+  update_live_words_in_range_cache(cm, beg_addr, end_obj, ret);
+  return ret;
+}
+
 ParMarkBitMap::IterationStatus
 ParMarkBitMap::iterate(ParMarkBitMapClosure* live_closure,
                        idx_t range_beg, idx_t range_end) const
--- a/src/share/vm/gc/parallel/parMarkBitMap.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/parallel/parMarkBitMap.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,6 +31,7 @@
 
 class ParMarkBitMapClosure;
 class PSVirtualSpace;
+class ParCompactionManager;
 
 class ParMarkBitMap: public CHeapObj<mtGC>
 {
@@ -124,7 +125,7 @@
   // the range are included in the result. The end of the range must be a live object,
   // which is the case when updating pointers.  This allows a branch to be removed
   // from inside the loop.
-  size_t live_words_in_range(HeapWord* beg_addr, oop end_obj) const;
+  size_t live_words_in_range(ParCompactionManager* cm, HeapWord* beg_addr, oop end_obj) const;
 
   inline HeapWord* region_start() const;
   inline HeapWord* region_end() const;
@@ -167,6 +168,12 @@
 #endif  // #ifdef ASSERT
 
 private:
+  size_t live_words_in_range_helper(HeapWord* beg_addr, oop end_obj) const;
+
+  bool is_live_words_in_range_in_cache(ParCompactionManager* cm, HeapWord* beg_addr) const;
+  size_t live_words_in_range_use_cache(ParCompactionManager* cm, HeapWord* beg_addr, oop end_obj) const;
+  void update_live_words_in_range_cache(ParCompactionManager* cm, HeapWord* beg_addr, oop end_obj, size_t result) const;
+
   // Each bit in the bitmap represents one unit of 'object granularity.' Objects
   // are double-word aligned in 32-bit VMs, but not in 64-bit VMs, so the 32-bit
   // granularity is 2, 64-bit is 1.
--- a/src/share/vm/gc/parallel/parallelScavengeHeap.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/parallel/parallelScavengeHeap.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,10 +28,11 @@
 #include "gc/parallel/cardTableExtension.hpp"
 #include "gc/parallel/gcTaskManager.hpp"
 #include "gc/parallel/generationSizer.hpp"
+#include "gc/parallel/objectStartArray.inline.hpp"
 #include "gc/parallel/parallelScavengeHeap.inline.hpp"
 #include "gc/parallel/psAdaptiveSizePolicy.hpp"
 #include "gc/parallel/psMarkSweep.hpp"
-#include "gc/parallel/psParallelCompact.hpp"
+#include "gc/parallel/psParallelCompact.inline.hpp"
 #include "gc/parallel/psPromotionManager.hpp"
 #include "gc/parallel/psScavenge.hpp"
 #include "gc/parallel/vmPSOperations.hpp"
--- a/src/share/vm/gc/parallel/psCompactionManager.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/parallel/psCompactionManager.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -68,6 +68,8 @@
 
   marking_stack()->initialize();
   _objarray_stack.initialize();
+
+  reset_bitmap_query_cache();
 }
 
 ParCompactionManager::~ParCompactionManager() {
@@ -124,6 +126,13 @@
     "Not initialized?");
 }
 
+void ParCompactionManager::reset_all_bitmap_query_caches() {
+  uint parallel_gc_threads = PSParallelCompact::gc_task_manager()->workers();
+  for (uint i=0; i<=parallel_gc_threads; i++) {
+    _manager_array[i]->reset_bitmap_query_cache();
+  }
+}
+
 int ParCompactionManager::pop_recycled_stack_index() {
   assert(_recycled_bottom <= _recycled_top, "list is empty");
   // Get the next available index
--- a/src/share/vm/gc/parallel/psCompactionManager.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/parallel/psCompactionManager.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -109,6 +109,10 @@
 
   Action _action;
 
+  HeapWord* _last_query_beg;
+  oop _last_query_obj;
+  size_t _last_query_ret;
+
   static PSOldGen* old_gen()             { return _old_gen; }
   static ObjectStartArray* start_array() { return _start_array; }
   static OopTaskQueueSet* stack_array()  { return _stack_array; }
@@ -127,9 +131,26 @@
   // marking stack and overflow stack directly.
 
  public:
+  void reset_bitmap_query_cache() {
+    _last_query_beg = NULL;
+    _last_query_obj = NULL;
+    _last_query_ret = 0;
+  }
+
   Action action() { return _action; }
   void set_action(Action v) { _action = v; }
 
+  // Bitmap query support, cache last query and result
+  HeapWord* last_query_begin() { return _last_query_beg; }
+  oop last_query_object() { return _last_query_obj; }
+  size_t last_query_return() { return _last_query_ret; }
+
+  void set_last_query_begin(HeapWord *new_beg) { _last_query_beg = new_beg; }
+  void set_last_query_object(oop new_obj) { _last_query_obj = new_obj; }
+  void set_last_query_return(size_t new_ret) { _last_query_ret = new_ret; }
+
+  static void reset_all_bitmap_query_caches();
+
   RegionTaskQueue* region_stack()                { return _region_stack; }
   void set_region_stack(RegionTaskQueue* v)       { _region_stack = v; }
 
--- a/src/share/vm/gc/parallel/psCompactionManager.inline.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/parallel/psCompactionManager.inline.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2016, 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
@@ -144,7 +144,7 @@
 }
 
 inline void ParCompactionManager::update_contents(oop obj) {
-  obj->pc_update_contents();
+  obj->pc_update_contents(this);
 }
 
 #endif // SHARE_VM_GC_PARALLEL_PSCOMPACTIONMANAGER_INLINE_HPP
--- a/src/share/vm/gc/parallel/psMarkSweep.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/parallel/psMarkSweep.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, 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
@@ -99,7 +99,7 @@
     heap->collector_policy()->should_clear_all_soft_refs();
 
   uint count = maximum_heap_compaction ? 1 : MarkSweepAlwaysCompactCount;
-  UIntXFlagSetting flag_setting(MarkSweepAlwaysCompactCount, count);
+  UIntFlagSetting flag_setting(MarkSweepAlwaysCompactCount, count);
   PSMarkSweep::invoke_no_policy(clear_all_soft_refs || maximum_heap_compaction);
 }
 
--- a/src/share/vm/gc/parallel/psOldGen.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/parallel/psOldGen.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "gc/parallel/objectStartArray.inline.hpp"
 #include "gc/parallel/parallelScavengeHeap.hpp"
 #include "gc/parallel/psAdaptiveSizePolicy.hpp"
 #include "gc/parallel/psMarkSweepDecorator.hpp"
--- a/src/share/vm/gc/parallel/psParallelCompact.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/parallel/psParallelCompact.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -195,7 +195,7 @@
 };
 
 void PSParallelCompact::print_region_ranges() {
-  if (!develop_log_is_enabled(Trace, gc, compaction, phases)) {
+  if (!log_develop_is_enabled(Trace, gc, compaction, phases)) {
     return;
   }
   LogHandle(gc, compaction, phases) log;
@@ -265,7 +265,7 @@
 print_generic_summary_data(ParallelCompactData& summary_data,
                            SpaceInfo* space_info)
 {
-  if (!develop_log_is_enabled(Trace, gc, compaction, phases)) {
+  if (!log_develop_is_enabled(Trace, gc, compaction, phases)) {
     return;
   }
 
@@ -360,7 +360,7 @@
 void
 print_initial_summary_data(ParallelCompactData& summary_data,
                            SpaceInfo* space_info) {
-  if (!develop_log_is_enabled(Trace, gc, compaction, phases)) {
+  if (!log_develop_is_enabled(Trace, gc, compaction, phases)) {
     return;
   }
 
@@ -641,7 +641,7 @@
   *target_next = split_destination + partial_obj_size;
   HeapWord* const source_next = region_to_addr(split_region) + partial_obj_size;
 
-  if (develop_log_is_enabled(Trace, gc, compaction, phases)) {
+  if (log_develop_is_enabled(Trace, gc, compaction, phases)) {
     const char * split_type = partial_obj_size == 0 ? "easy" : "hard";
     log_develop_trace(gc, compaction, phases)("%s split:  src=" PTR_FORMAT " src_c=" SIZE_FORMAT " pos=" SIZE_FORMAT,
                                               split_type, p2i(source_next), split_region, partial_obj_size);
@@ -751,7 +751,7 @@
   return true;
 }
 
-HeapWord* ParallelCompactData::calc_new_pointer(HeapWord* addr) {
+HeapWord* ParallelCompactData::calc_new_pointer(HeapWord* addr, ParCompactionManager* cm) {
   assert(addr != NULL, "Should detect NULL oop earlier");
   assert(ParallelScavengeHeap::heap()->is_in(addr), "not in heap");
   assert(PSParallelCompact::mark_bitmap()->is_marked(addr), "not marked");
@@ -788,7 +788,7 @@
   const size_t block_offset = addr_to_block_ptr(addr)->offset();
 
   const ParMarkBitMap* bitmap = PSParallelCompact::mark_bitmap();
-  const size_t live = bitmap->live_words_in_range(search_start, oop(addr));
+  const size_t live = bitmap->live_words_in_range(cm, search_start, oop(addr));
   result += block_offset + live;
   DEBUG_ONLY(PSParallelCompact::check_new_location(addr, result));
   return result;
@@ -825,11 +825,9 @@
 
 bool PSParallelCompact::IsAliveClosure::do_object_b(oop p) { return mark_bitmap()->is_marked(p); }
 
-PSParallelCompact::AdjustPointerClosure PSParallelCompact::_adjust_pointer_closure;
-PSParallelCompact::AdjustKlassClosure PSParallelCompact::_adjust_klass_closure;
-
 void PSParallelCompact::AdjustKlassClosure::do_klass(Klass* klass) {
-  klass->oops_do(&PSParallelCompact::_adjust_pointer_closure);
+  PSParallelCompact::AdjustPointerClosure closure(_cm);
+  klass->oops_do(&closure);
 }
 
 void PSParallelCompact::post_initialize() {
@@ -977,6 +975,8 @@
 
   // Have worker threads release resources the next time they run a task.
   gc_task_manager()->release_all_resources();
+
+  ParCompactionManager::reset_all_bitmap_query_caches();
 }
 
 void PSParallelCompact::post_compact()
@@ -1535,7 +1535,7 @@
     }
   }
 
-  if (develop_log_is_enabled(Trace, gc, compaction, phases)) {
+  if (log_develop_is_enabled(Trace, gc, compaction, phases)) {
     const size_t region_size = ParallelCompactData::RegionSize;
     HeapWord* const dense_prefix_end = _space_info[id].dense_prefix();
     const size_t dp_region = _summary_data.addr_to_region_idx(dense_prefix_end);
@@ -1801,7 +1801,7 @@
 
     // adjust_roots() updates Universe::_intArrayKlassObj which is
     // needed by the compaction for filling holes in the dense prefix.
-    adjust_roots();
+    adjust_roots(vmthread_cm);
 
     compaction_start.update();
     compact();
@@ -2142,39 +2142,42 @@
 };
 static PSAlwaysTrueClosure always_true;
 
-void PSParallelCompact::adjust_roots() {
+void PSParallelCompact::adjust_roots(ParCompactionManager* cm) {
   // Adjust the pointers to reflect the new locations
   GCTraceTime(Trace, gc, phases) tm("Adjust Roots", &_gc_timer);
 
   // Need new claim bits when tracing through and adjusting pointers.
   ClassLoaderDataGraph::clear_claimed_marks();
 
+  PSParallelCompact::AdjustPointerClosure oop_closure(cm);
+  PSParallelCompact::AdjustKlassClosure klass_closure(cm);
+
   // General strong roots.
-  Universe::oops_do(adjust_pointer_closure());
-  JNIHandles::oops_do(adjust_pointer_closure());   // Global (strong) JNI handles
-  CLDToOopClosure adjust_from_cld(adjust_pointer_closure());
-  Threads::oops_do(adjust_pointer_closure(), &adjust_from_cld, NULL);
-  ObjectSynchronizer::oops_do(adjust_pointer_closure());
-  FlatProfiler::oops_do(adjust_pointer_closure());
-  Management::oops_do(adjust_pointer_closure());
-  JvmtiExport::oops_do(adjust_pointer_closure());
-  SystemDictionary::oops_do(adjust_pointer_closure());
-  ClassLoaderDataGraph::oops_do(adjust_pointer_closure(), adjust_klass_closure(), true);
+  Universe::oops_do(&oop_closure);
+  JNIHandles::oops_do(&oop_closure);   // Global (strong) JNI handles
+  CLDToOopClosure adjust_from_cld(&oop_closure);
+  Threads::oops_do(&oop_closure, &adjust_from_cld, NULL);
+  ObjectSynchronizer::oops_do(&oop_closure);
+  FlatProfiler::oops_do(&oop_closure);
+  Management::oops_do(&oop_closure);
+  JvmtiExport::oops_do(&oop_closure);
+  SystemDictionary::oops_do(&oop_closure);
+  ClassLoaderDataGraph::oops_do(&oop_closure, &klass_closure, true);
 
   // Now adjust pointers in remaining weak roots.  (All of which should
   // have been cleared if they pointed to non-surviving objects.)
   // Global (weak) JNI handles
-  JNIHandles::weak_oops_do(&always_true, adjust_pointer_closure());
-
-  CodeBlobToOopClosure adjust_from_blobs(adjust_pointer_closure(), CodeBlobToOopClosure::FixRelocations);
+  JNIHandles::weak_oops_do(&always_true, &oop_closure);
+
+  CodeBlobToOopClosure adjust_from_blobs(&oop_closure, CodeBlobToOopClosure::FixRelocations);
   CodeCache::blobs_do(&adjust_from_blobs);
-  StringTable::oops_do(adjust_pointer_closure());
-  ref_processor()->weak_oops_do(adjust_pointer_closure());
+  StringTable::oops_do(&oop_closure);
+  ref_processor()->weak_oops_do(&oop_closure);
   // Roots were visited so references into the young gen in roots
   // may have been scanned.  Process them also.
   // Should the reference processor have a span that excludes
   // young gen objects?
-  PSScavenge::reference_processor()->weak_oops_do(adjust_pointer_closure());
+  PSScavenge::reference_processor()->weak_oops_do(&oop_closure);
 }
 
 // Helper class to print 8 region numbers per line and then print the total at the end.
@@ -2187,7 +2190,7 @@
   bool _enabled;
   size_t _total_regions;
 public:
-  FillableRegionLogger() : _next_index(0), _total_regions(0), _enabled(develop_log_is_enabled(Trace, gc, compaction)) { }
+  FillableRegionLogger() : _next_index(0), _total_regions(0), _enabled(log_develop_is_enabled(Trace, gc, compaction)) { }
   ~FillableRegionLogger() {
     log.trace(SIZE_FORMAT " initially fillable regions", _total_regions);
   }
@@ -2378,7 +2381,7 @@
 // region.
 void PSParallelCompact::write_block_fill_histogram()
 {
-  if (!develop_log_is_enabled(Trace, gc, compaction)) {
+  if (!log_develop_is_enabled(Trace, gc, compaction)) {
     return;
   }
 
@@ -3062,18 +3065,20 @@
   update_state(words);
 }
 
-void InstanceKlass::oop_pc_update_pointers(oop obj) {
-  oop_oop_iterate_oop_maps<true>(obj, PSParallelCompact::adjust_pointer_closure());
+void InstanceKlass::oop_pc_update_pointers(oop obj, ParCompactionManager* cm) {
+  PSParallelCompact::AdjustPointerClosure closure(cm);
+  oop_oop_iterate_oop_maps<true>(obj, &closure);
 }
 
-void InstanceMirrorKlass::oop_pc_update_pointers(oop obj) {
-  InstanceKlass::oop_pc_update_pointers(obj);
-
-  oop_oop_iterate_statics<true>(obj, PSParallelCompact::adjust_pointer_closure());
+void InstanceMirrorKlass::oop_pc_update_pointers(oop obj, ParCompactionManager* cm) {
+  InstanceKlass::oop_pc_update_pointers(obj, cm);
+
+  PSParallelCompact::AdjustPointerClosure closure(cm);
+  oop_oop_iterate_statics<true>(obj, &closure);
 }
 
-void InstanceClassLoaderKlass::oop_pc_update_pointers(oop obj) {
-  InstanceKlass::oop_pc_update_pointers(obj);
+void InstanceClassLoaderKlass::oop_pc_update_pointers(oop obj, ParCompactionManager* cm) {
+  InstanceKlass::oop_pc_update_pointers(obj, cm);
 }
 
 #ifdef ASSERT
@@ -3092,33 +3097,34 @@
 #endif
 
 template <class T>
-static void oop_pc_update_pointers_specialized(oop obj) {
+static void oop_pc_update_pointers_specialized(oop obj, ParCompactionManager* cm) {
   T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
-  PSParallelCompact::adjust_pointer(referent_addr);
+  PSParallelCompact::adjust_pointer(referent_addr, cm);
   T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
-  PSParallelCompact::adjust_pointer(next_addr);
+  PSParallelCompact::adjust_pointer(next_addr, cm);
   T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
-  PSParallelCompact::adjust_pointer(discovered_addr);
+  PSParallelCompact::adjust_pointer(discovered_addr, cm);
   debug_only(trace_reference_gc("InstanceRefKlass::oop_update_ptrs", obj,
                                 referent_addr, next_addr, discovered_addr);)
 }
 
-void InstanceRefKlass::oop_pc_update_pointers(oop obj) {
-  InstanceKlass::oop_pc_update_pointers(obj);
+void InstanceRefKlass::oop_pc_update_pointers(oop obj, ParCompactionManager* cm) {
+  InstanceKlass::oop_pc_update_pointers(obj, cm);
 
   if (UseCompressedOops) {
-    oop_pc_update_pointers_specialized<narrowOop>(obj);
+    oop_pc_update_pointers_specialized<narrowOop>(obj, cm);
   } else {
-    oop_pc_update_pointers_specialized<oop>(obj);
+    oop_pc_update_pointers_specialized<oop>(obj, cm);
   }
 }
 
-void ObjArrayKlass::oop_pc_update_pointers(oop obj) {
+void ObjArrayKlass::oop_pc_update_pointers(oop obj, ParCompactionManager* cm) {
   assert(obj->is_objArray(), "obj must be obj array");
-  oop_oop_iterate_elements<true>(objArrayOop(obj), PSParallelCompact::adjust_pointer_closure());
+  PSParallelCompact::AdjustPointerClosure closure(cm);
+  oop_oop_iterate_elements<true>(objArrayOop(obj), &closure);
 }
 
-void TypeArrayKlass::oop_pc_update_pointers(oop obj) {
+void TypeArrayKlass::oop_pc_update_pointers(oop obj, ParCompactionManager* cm) {
   assert(obj->is_typeArray(),"must be a type array");
 }
 
@@ -3128,7 +3134,7 @@
   assert(bitmap()->obj_size(addr) == words, "bad size");
 
   _source = addr;
-  assert(PSParallelCompact::summary_data().calc_new_pointer(source()) ==
+  assert(PSParallelCompact::summary_data().calc_new_pointer(source(), compaction_manager()) ==
          destination(), "wrong destination");
 
   if (words > words_remaining()) {
@@ -3169,3 +3175,14 @@
   do_addr(addr);
   return ParMarkBitMap::incomplete;
 }
+
+ParMarkBitMapClosure::IterationStatus
+FillClosure::do_addr(HeapWord* addr, size_t size) {
+  CollectedHeap::fill_with_objects(addr, size);
+  HeapWord* const end = addr + size;
+  do {
+    _start_array->allocate_block(addr);
+    addr += oop(addr)->size();
+  } while (addr < end);
+  return ParMarkBitMap::incomplete;
+}
--- a/src/share/vm/gc/parallel/psParallelCompact.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/parallel/psParallelCompact.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -451,10 +451,10 @@
   HeapWord* partial_obj_end(size_t region_idx) const;
 
   // Return the location of the object after compaction.
-  HeapWord* calc_new_pointer(HeapWord* addr);
+  HeapWord* calc_new_pointer(HeapWord* addr, ParCompactionManager* cm);
 
-  HeapWord* calc_new_pointer(oop p) {
-    return calc_new_pointer((HeapWord*) p);
+  HeapWord* calc_new_pointer(oop p, ParCompactionManager* cm) {
+    return calc_new_pointer((HeapWord*) p, cm);
   }
 
 #ifdef  ASSERT
@@ -937,17 +937,29 @@
 
   class AdjustPointerClosure: public ExtendedOopClosure {
    public:
+    AdjustPointerClosure(ParCompactionManager* cm) {
+      assert(cm != NULL, "associate ParCompactionManage should not be NULL");
+      _cm = cm;
+    }
     template <typename T> void do_oop_nv(T* p);
     virtual void do_oop(oop* p);
     virtual void do_oop(narrowOop* p);
 
     // This closure provides its own oop verification code.
     debug_only(virtual bool should_verify_oops() { return false; })
+   private:
+    ParCompactionManager* _cm;
   };
 
   class AdjustKlassClosure : public KlassClosure {
    public:
+    AdjustKlassClosure(ParCompactionManager* cm) {
+      assert(cm != NULL, "associate ParCompactionManage should not be NULL");
+      _cm = cm;
+    }
     void do_klass(Klass* klass);
+   private:
+    ParCompactionManager* _cm;
   };
 
   friend class AdjustPointerClosure;
@@ -966,8 +978,6 @@
   static ParallelCompactData  _summary_data;
   static IsAliveClosure       _is_alive_closure;
   static SpaceInfo            _space_info[last_space_id];
-  static AdjustPointerClosure _adjust_pointer_closure;
-  static AdjustKlassClosure   _adjust_klass_closure;
 
   // Reference processing (used in ...follow_contents)
   static ReferenceProcessor*  _ref_processor;
@@ -1063,7 +1073,7 @@
   static void summary_phase(ParCompactionManager* cm, bool maximum_compaction);
 
   // Adjust addresses in roots.  Does not adjust addresses in heap.
-  static void adjust_roots();
+  static void adjust_roots(ParCompactionManager* cm);
 
   DEBUG_ONLY(static void write_block_fill_histogram();)
 
@@ -1109,10 +1119,6 @@
   static bool initialize();
 
   // Closure accessors
-  static PSParallelCompact::AdjustPointerClosure* adjust_pointer_closure() {
-    return &_adjust_pointer_closure;
-  }
-  static KlassClosure* adjust_klass_closure()      { return (KlassClosure*)&_adjust_klass_closure; }
   static BoolObjectClosure* is_alive_closure()     { return (BoolObjectClosure*)&_is_alive_closure; }
 
   // Public accessors
@@ -1127,7 +1133,7 @@
   static inline bool mark_obj(oop obj);
   static inline bool is_marked(oop obj);
 
-  template <class T> static inline void adjust_pointer(T* p);
+  template <class T> static inline void adjust_pointer(T* p, ParCompactionManager* cm);
 
   // Compaction support.
   // Return true if p is in the range [beg_addr, end_addr).
@@ -1242,16 +1248,6 @@
 #endif  // #ifdef ASSERT
 };
 
-inline bool PSParallelCompact::mark_obj(oop obj) {
-  const int obj_size = obj->size();
-  if (mark_bitmap()->mark_obj(obj, obj_size)) {
-    _summary_data.add_obj(obj, obj_size);
-    return true;
-  } else {
-    return false;
-  }
-}
-
 inline bool PSParallelCompact::is_marked(oop obj) {
   return mark_bitmap()->is_marked(obj);
 }
@@ -1386,9 +1382,8 @@
   inline void do_addr(HeapWord* addr);
 };
 
-class FillClosure: public ParMarkBitMapClosure
-{
-public:
+class FillClosure: public ParMarkBitMapClosure {
+ public:
   FillClosure(ParCompactionManager* cm, PSParallelCompact::SpaceId space_id) :
     ParMarkBitMapClosure(PSParallelCompact::mark_bitmap(), cm),
     _start_array(PSParallelCompact::start_array(space_id))
@@ -1397,17 +1392,9 @@
            "cannot use FillClosure in the young gen");
   }
 
-  virtual IterationStatus do_addr(HeapWord* addr, size_t size) {
-    CollectedHeap::fill_with_objects(addr, size);
-    HeapWord* const end = addr + size;
-    do {
-      _start_array->allocate_block(addr);
-      addr += oop(addr)->size();
-    } while (addr < end);
-    return ParMarkBitMap::incomplete;
-  }
+  virtual IterationStatus do_addr(HeapWord* addr, size_t size);
 
-private:
+ private:
   ObjectStartArray* const _start_array;
 };
 
--- a/src/share/vm/gc/parallel/psParallelCompact.inline.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/parallel/psParallelCompact.inline.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,14 +31,24 @@
 #include "oops/klass.hpp"
 #include "oops/oop.inline.hpp"
 
+inline bool PSParallelCompact::mark_obj(oop obj) {
+  const int obj_size = obj->size();
+  if (mark_bitmap()->mark_obj(obj, obj_size)) {
+    _summary_data.add_obj(obj, obj_size);
+    return true;
+  } else {
+    return false;
+  }
+}
+
 template <class T>
-inline void PSParallelCompact::adjust_pointer(T* p) {
+inline void PSParallelCompact::adjust_pointer(T* p, ParCompactionManager* cm) {
   T heap_oop = oopDesc::load_heap_oop(p);
   if (!oopDesc::is_null(heap_oop)) {
     oop obj     = oopDesc::decode_heap_oop_not_null(heap_oop);
     assert(ParallelScavengeHeap::heap()->is_in(obj), "should be in heap");
 
-    oop new_obj = (oop)summary_data().calc_new_pointer(obj);
+    oop new_obj = (oop)summary_data().calc_new_pointer(obj, cm);
     assert(new_obj != NULL,                    // is forwarding ptr?
            "should be forwarded");
     // Just always do the update unconditionally?
@@ -52,7 +62,7 @@
 
 template <typename T>
 void PSParallelCompact::AdjustPointerClosure::do_oop_nv(T* p) {
-  adjust_pointer(p);
+  adjust_pointer(p, _cm);
 }
 
 inline void PSParallelCompact::AdjustPointerClosure::do_oop(oop* p)       { do_oop_nv(p); }
--- a/src/share/vm/gc/parallel/psPromotionManager.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/parallel/psPromotionManager.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -130,7 +130,7 @@
 
 void
 PSPromotionManager::print_taskqueue_stats() {
-  if (!develop_log_is_enabled(Trace, gc, task, stats)) {
+  if (!log_develop_is_enabled(Trace, gc, task, stats)) {
     return;
   }
   LogHandle(gc, task, stats) log;
--- a/src/share/vm/gc/parallel/psPromotionManager.inline.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/parallel/psPromotionManager.inline.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -284,7 +284,7 @@
 
   // This code must come after the CAS test, or it will print incorrect
   // information.
-  if (develop_log_is_enabled(Trace, gc, scavenge) && o->is_forwarded()) {
+  if (log_develop_is_enabled(Trace, gc, scavenge) && o->is_forwarded()) {
     log_develop_trace(gc, scavenge)("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
                       "forwarding",
                       new_obj->klass()->internal_name(), p2i((void *)o), p2i((void *)new_obj), new_obj->size());
--- a/src/share/vm/gc/parallel/psScavenge.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/parallel/psScavenge.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,7 @@
 #include "gc/parallel/parallelScavengeHeap.hpp"
 #include "gc/parallel/psAdaptiveSizePolicy.hpp"
 #include "gc/parallel/psMarkSweep.hpp"
-#include "gc/parallel/psParallelCompact.hpp"
+#include "gc/parallel/psParallelCompact.inline.hpp"
 #include "gc/parallel/psScavenge.inline.hpp"
 #include "gc/parallel/psTasks.hpp"
 #include "gc/shared/collectorPolicy.hpp"
@@ -763,6 +763,15 @@
   return ParallelScavengeHeap::gc_task_manager();
 }
 
+// Adaptive size policy support.  When the young generation/old generation
+// boundary moves, _young_generation_boundary must be reset
+void PSScavenge::set_young_generation_boundary(HeapWord* v) {
+  _young_generation_boundary = v;
+  if (UseCompressedOops) {
+    _young_generation_boundary_compressed = (uintptr_t)oopDesc::encode_heap_oop((oop)v);
+  }
+}
+
 void PSScavenge::initialize() {
   // Arguments must have been parsed
 
--- a/src/share/vm/gc/parallel/psScavenge.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/parallel/psScavenge.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, 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
@@ -117,12 +117,7 @@
   }
   // Adaptive size policy support.  When the young generation/old generation
   // boundary moves, _young_generation_boundary must be reset
-  static void set_young_generation_boundary(HeapWord* v) {
-    _young_generation_boundary = v;
-    if (UseCompressedOops) {
-      _young_generation_boundary_compressed = (uintptr_t)oopDesc::encode_heap_oop((oop)v);
-    }
-  }
+  static void set_young_generation_boundary(HeapWord* v);
 
   // Called by parallelScavengeHeap to init the tenuring threshold
   static void initialize();
--- a/src/share/vm/gc/serial/defNewGeneration.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/serial/defNewGeneration.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "gc/serial/defNewGeneration.inline.hpp"
+#include "gc/shared/ageTable.inline.hpp"
 #include "gc/shared/cardTableRS.hpp"
 #include "gc/shared/collectorCounters.hpp"
 #include "gc/shared/gcHeapSummary.hpp"
--- a/src/share/vm/gc/shared/ageTable.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/shared/ageTable.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,15 +23,16 @@
  */
 
 #include "precompiled.hpp"
-#include "gc/shared/ageTable.hpp"
+#include "gc/shared/ageTable.inline.hpp"
 #include "gc/shared/collectedHeap.hpp"
 #include "gc/shared/collectorPolicy.hpp"
 #include "gc/shared/gcPolicyCounters.hpp"
 #include "memory/resourceArea.hpp"
 #include "logging/log.hpp"
+#include "oops/oop.inline.hpp"
 #include "utilities/copy.hpp"
 
-/* Copyright (c) 1992, 2015, Oracle and/or its affiliates, and Stanford University.
+/* Copyright (c) 1992, 2016, Oracle and/or its affiliates, and Stanford University.
    See the LICENSE file for license information. */
 
 AgeTable::AgeTable(bool global) {
--- a/src/share/vm/gc/shared/ageTable.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/shared/ageTable.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,7 +31,7 @@
 
 class GCPolicyCounters;
 
-/* Copyright (c) 1992, 2015, Oracle and/or its affiliates, and Stanford University.
+/* Copyright (c) 1992, 2016, Oracle and/or its affiliates, and Stanford University.
    See the LICENSE file for license information. */
 
 // Age table for adaptive feedback-mediated tenuring (scavenging)
@@ -56,9 +56,7 @@
   void clear();
 
   // add entry
-  void add(oop p, size_t oop_size) {
-    add(p->age(), oop_size);
-  }
+  inline void add(oop p, size_t oop_size);
 
   void add(uint age, size_t oop_size) {
     assert(age > 0 && age < table_size, "invalid age of object");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc/shared/ageTable.inline.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016, 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_SHARED_AGETABLE_INLINE_HPP
+#define SHARE_VM_GC_SHARED_AGETABLE_INLINE_HPP
+
+#include "gc/shared/ageTable.hpp"
+#include "oops/oop.inline.hpp"
+
+// add entry
+void AgeTable::add(oop p, size_t oop_size) {
+  add(p->age(), oop_size);
+}
+
+#endif // SHARE_VM_GC_SHARED_AGETABLE_INLINE_HPP
--- a/src/share/vm/gc/shared/collectedHeap.inline.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/shared/collectedHeap.inline.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,6 +30,7 @@
 #include "gc/shared/threadLocalAllocBuffer.inline.hpp"
 #include "memory/universe.hpp"
 #include "oops/arrayOop.hpp"
+#include "oops/oop.inline.hpp"
 #include "prims/jvmtiExport.hpp"
 #include "runtime/sharedRuntime.hpp"
 #include "runtime/thread.inline.hpp"
@@ -248,7 +249,7 @@
   assert(is_size_aligned(alignment_in_bytes, HeapWordSize),
          "Alignment size %u is incorrect.", alignment_in_bytes);
 
-  HeapWord* new_addr = (HeapWord*) align_pointer_up(addr, alignment_in_bytes);
+  HeapWord* new_addr = (HeapWord*) align_ptr_up(addr, alignment_in_bytes);
   size_t padding = pointer_delta(new_addr, addr);
 
   if (padding == 0) {
--- a/src/share/vm/gc/shared/collectorPolicy.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/shared/collectorPolicy.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, 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
@@ -774,7 +774,7 @@
   // free memory should be here, especially if they are expensive. If this
   // attempt fails, an OOM exception will be thrown.
   {
-    UIntXFlagSetting flag_change(MarkSweepAlwaysCompactCount, 1); // Make sure the heap is fully compacted
+    UIntFlagSetting flag_change(MarkSweepAlwaysCompactCount, 1); // Make sure the heap is fully compacted
 
     gch->do_collection(true,                      // full
                        true,                      // clear_all_soft_refs
--- a/src/share/vm/gc/shared/genOopClosures.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/shared/genOopClosures.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, 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
@@ -146,23 +146,15 @@
   HeapWord*   _boundary;
   ExtendedOopClosure* _cl;
  protected:
-  template <class T> inline void do_oop_work(T* p) {
-    T heap_oop = oopDesc::load_heap_oop(p);
-    if (!oopDesc::is_null(heap_oop)) {
-      oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
-      if ((HeapWord*)obj < _boundary) {
-        _cl->do_oop(p);
-      }
-    }
-  }
+  template <class T> inline void do_oop_work(T* p);
  public:
   FilteringClosure(HeapWord* boundary, ExtendedOopClosure* cl) :
     ExtendedOopClosure(cl->ref_processor()), _boundary(boundary),
     _cl(cl) {}
   virtual void do_oop(oop* p);
   virtual void do_oop(narrowOop* p);
-  inline void do_oop_nv(oop* p)       { FilteringClosure::do_oop_work(p); }
-  inline void do_oop_nv(narrowOop* p) { FilteringClosure::do_oop_work(p); }
+  inline void do_oop_nv(oop* p);
+  inline void do_oop_nv(narrowOop* p);
   virtual bool do_metadata()          { return do_metadata_nv(); }
   inline bool do_metadata_nv()        { assert(!_cl->do_metadata(), "assumption broken, must change to 'return _cl->do_metadata()'"); return false; }
 };
--- a/src/share/vm/gc/shared/genOopClosures.inline.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/shared/genOopClosures.inline.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, 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
@@ -124,6 +124,19 @@
 inline void FastScanClosure::do_oop_nv(oop* p)       { FastScanClosure::do_oop_work(p); }
 inline void FastScanClosure::do_oop_nv(narrowOop* p) { FastScanClosure::do_oop_work(p); }
 
+template <class T> void FilteringClosure::do_oop_work(T* p) {
+  T heap_oop = oopDesc::load_heap_oop(p);
+  if (!oopDesc::is_null(heap_oop)) {
+    oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+    if ((HeapWord*)obj < _boundary) {
+      _cl->do_oop(p);
+    }
+  }
+}
+
+void FilteringClosure::do_oop_nv(oop* p)       { FilteringClosure::do_oop_work(p); }
+void FilteringClosure::do_oop_nv(narrowOop* p) { FilteringClosure::do_oop_work(p); }
+
 // Note similarity to ScanClosure; the difference is that
 // the barrier set is taken care of outside this closure.
 template <class T> inline void ScanWeakRefClosure::do_oop_work(T* p) {
--- a/src/share/vm/gc/shared/referenceProcessor.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/shared/referenceProcessor.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -30,7 +30,7 @@
 #include "gc/shared/gcTimer.hpp"
 #include "gc/shared/gcTraceTime.inline.hpp"
 #include "gc/shared/referencePolicy.hpp"
-#include "gc/shared/referenceProcessor.hpp"
+#include "gc/shared/referenceProcessor.inline.hpp"
 #include "logging/log.hpp"
 #include "memory/allocation.hpp"
 #include "oops/oop.inline.hpp"
--- a/src/share/vm/gc/shared/referenceProcessor.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/shared/referenceProcessor.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -58,23 +58,13 @@
 class DiscoveredList {
 public:
   DiscoveredList() : _len(0), _compressed_head(0), _oop_head(NULL) { }
-  oop head() const     {
-     return UseCompressedOops ?  oopDesc::decode_heap_oop(_compressed_head) :
-                                _oop_head;
-  }
+  inline oop head() const;
   HeapWord* adr_head() {
     return UseCompressedOops ? (HeapWord*)&_compressed_head :
                                (HeapWord*)&_oop_head;
   }
-  void set_head(oop o) {
-    if (UseCompressedOops) {
-      // Must compress the head ptr.
-      _compressed_head = oopDesc::encode_heap_oop(o);
-    } else {
-      _oop_head = o;
-    }
-  }
-  bool   is_empty() const       { return head() == NULL; }
+  inline void set_head(oop o);
+  inline bool is_empty() const;
   size_t length()               { return _len; }
   void   set_length(size_t len) { _len = len;  }
   void   inc_length(size_t inc) { _len += inc; assert(_len > 0, "Error"); }
@@ -113,22 +103,7 @@
 public:
   inline DiscoveredListIterator(DiscoveredList&    refs_list,
                                 OopClosure*        keep_alive,
-                                BoolObjectClosure* is_alive):
-    _refs_list(refs_list),
-    _prev_next(refs_list.adr_head()),
-    _prev(NULL),
-    _ref(refs_list.head()),
-#ifdef ASSERT
-    _first_seen(refs_list.head()),
-#endif
-#ifndef PRODUCT
-    _processed(0),
-    _removed(0),
-#endif
-    _next(NULL),
-    _keep_alive(keep_alive),
-    _is_alive(is_alive)
-{ }
+                                BoolObjectClosure* is_alive);
 
   // End Of List.
   inline bool has_next() const { return _ref != NULL; }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc/shared/referenceProcessor.inline.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2016, 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_SHARED_REFERENCEPROCESSOR_INLINE_HPP
+#define SHARE_VM_GC_SHARED_REFERENCEPROCESSOR_INLINE_HPP
+
+#include "gc/shared/referenceProcessor.hpp"
+#include "oops/oop.inline.hpp"
+
+oop DiscoveredList::head() const {
+  return UseCompressedOops ?  oopDesc::decode_heap_oop(_compressed_head) :
+    _oop_head;
+}
+
+void DiscoveredList::set_head(oop o) {
+  if (UseCompressedOops) {
+    // Must compress the head ptr.
+    _compressed_head = oopDesc::encode_heap_oop(o);
+  } else {
+    _oop_head = o;
+  }
+}
+
+bool DiscoveredList::is_empty() const {
+ return head() == NULL;
+}
+
+DiscoveredListIterator::DiscoveredListIterator(DiscoveredList&    refs_list,
+                                               OopClosure*        keep_alive,
+                                               BoolObjectClosure* is_alive):
+  _refs_list(refs_list),
+  _prev_next(refs_list.adr_head()),
+  _prev(NULL),
+  _ref(refs_list.head()),
+#ifdef ASSERT
+  _first_seen(refs_list.head()),
+#endif
+#ifndef PRODUCT
+  _processed(0),
+  _removed(0),
+#endif
+  _next(NULL),
+  _keep_alive(keep_alive),
+  _is_alive(is_alive) {
+}
+
+#endif // SHARE_VM_GC_SHARED_REFERENCEPROCESSOR_INLINE_HPP
--- a/src/share/vm/gc/shared/space.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/shared/space.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -360,9 +360,7 @@
     return size;
   }
 
-  inline size_t obj_size(const HeapWord* addr) const {
-    return oop(addr)->size();
-  }
+  inline size_t obj_size(const HeapWord* addr) const;
 
 public:
   CompactibleSpace() :
@@ -508,9 +506,7 @@
     return true; // Always true, since scan_limit is top
   }
 
-  inline size_t scanned_block_size(const HeapWord* addr) const {
-    return oop(addr)->size();
-  }
+  inline size_t scanned_block_size(const HeapWord* addr) const;
 
  protected:
   HeapWord* _top;
--- a/src/share/vm/gc/shared/space.inline.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/gc/shared/space.inline.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -72,6 +72,10 @@
   return _offsets.block_start(p);
 }
 
+size_t CompactibleSpace::obj_size(const HeapWord* addr) const {
+  return oop(addr)->size();
+}
+
 template <class SpaceType>
 inline void CompactibleSpace::scan_and_forward(SpaceType* space, CompactPoint* cp) {
   // Compute the new addresses for the live objects and store it in the mark
@@ -331,4 +335,9 @@
     if (ZapUnusedHeapArea) space->mangle_unused_area();
   }
 }
+
+size_t ContiguousSpace::scanned_block_size(const HeapWord* addr) const {
+  return oop(addr)->size();
+}
+
 #endif // SHARE_VM_GC_SHARED_SPACE_INLINE_HPP
--- a/src/share/vm/interpreter/bytecodeTracer.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/interpreter/bytecodeTracer.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -264,7 +264,7 @@
     return true;
   }
   //climit = cache->length();  // %%% private!
-  size_t size = cache->size() * HeapWordSize;
+  size_t size = cache->size() * wordSize;
   size -= sizeof(ConstantPoolCache);
   size /= sizeof(ConstantPoolCacheEntry);
   climit = (int) size;
--- a/src/share/vm/interpreter/interpreterRuntime.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/interpreter/interpreterRuntime.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -763,7 +763,7 @@
   if (cp_cache_entry->is_resolved(bytecode)) return;
 
   if (bytecode == Bytecodes::_invokeinterface) {
-    if (develop_log_is_enabled(Trace, itables)) {
+    if (log_develop_is_enabled(Trace, itables)) {
       ResourceMark rm(thread);
       log_develop_trace(itables)("Resolving: klass: %s to method: %s",
                                  info.resolved_klass()->name()->as_C_string(),
--- a/src/share/vm/interpreter/linkResolver.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/interpreter/linkResolver.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -168,7 +168,7 @@
   } else if (!resolved_klass->is_interface()) {
     // A default or miranda method.  Compute the vtable index.
     ResourceMark rm;
-    klassVtable* vt = InstanceKlass::cast(resolved_klass)->vtable();
+    klassVtable* vt = resolved_klass->vtable();
     index = LinkResolver::vtable_index_of_interface_method(resolved_klass,
                            resolved_method);
     assert(index >= 0 , "we should have valid vtable index at this point");
@@ -818,7 +818,7 @@
     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   }
 
-  if (develop_log_is_enabled(Trace, itables)) {
+  if (log_develop_is_enabled(Trace, itables)) {
     trace_method_resolution("invokeinterface resolved method: caller-class",
                             link_info.current_klass(), resolved_klass,
                             resolved_method, true);
@@ -1066,7 +1066,7 @@
     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   }
 
-  if (develop_log_is_enabled(Trace, itables)) {
+  if (log_develop_is_enabled(Trace, itables)) {
     trace_method_resolution("invokespecial resolved method: caller-class:",
                             current_klass, resolved_klass, resolved_method, true);
   }
@@ -1137,7 +1137,7 @@
                                                sel_method->signature()));
   }
 
-  if (develop_log_is_enabled(Trace, itables)) {
+  if (log_develop_is_enabled(Trace, itables)) {
     trace_method_resolution("invokespecial selected method: resolved-class:",
                             resolved_klass, resolved_klass, sel_method, true);
   }
@@ -1190,7 +1190,7 @@
     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   }
 
-  if (develop_log_is_enabled(Trace, vtables)) {
+  if (log_develop_is_enabled(Trace, vtables)) {
     trace_method_resolution("invokevirtual resolved method: caller-class:",
                             current_klass, resolved_klass, resolved_method, false);
   }
@@ -1229,8 +1229,7 @@
                            resolved_method);
     assert(vtable_index >= 0 , "we should have valid vtable index at this point");
 
-    InstanceKlass* inst = InstanceKlass::cast(recv_klass());
-    selected_method = methodHandle(THREAD, inst->method_at_vtable(vtable_index));
+    selected_method = methodHandle(THREAD, recv_klass->method_at_vtable(vtable_index));
   } else {
     // at this point we are sure that resolved_method is virtual and not
     // a default or miranda method; therefore, it must have a valid vtable index.
@@ -1245,10 +1244,7 @@
       assert(resolved_method->can_be_statically_bound(), "cannot override this method");
       selected_method = resolved_method;
     } else {
-      // recv_klass might be an arrayKlassOop but all vtables start at
-      // the same place. The cast is to avoid virtual call and assertion.
-      InstanceKlass* inst = (InstanceKlass*)recv_klass();
-      selected_method = methodHandle(THREAD, inst->method_at_vtable(vtable_index));
+      selected_method = methodHandle(THREAD, recv_klass->method_at_vtable(vtable_index));
     }
   }
 
@@ -1270,7 +1266,7 @@
                                                       selected_method->signature()));
   }
 
-  if (develop_log_is_enabled(Trace, vtables)) {
+  if (log_develop_is_enabled(Trace, vtables)) {
     trace_method_resolution("invokevirtual selected method: receiver-class:",
                             recv_klass, resolved_klass, selected_method,
                             false, vtable_index);
@@ -1369,7 +1365,7 @@
                                                       sel_method->signature()));
   }
 
-  if (develop_log_is_enabled(Trace, itables)) {
+  if (log_develop_is_enabled(Trace, itables)) {
     trace_method_resolution("invokeinterface selected method: receiver-class",
                             recv_klass, resolved_klass, sel_method, true);
   }
--- a/src/share/vm/jvmci/jvmciCompilerToVM.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/jvmci/jvmciCompilerToVM.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -121,8 +121,8 @@
 extern uint64_t jvmciHotSpotVMAddressEntryArrayStride;
 }
 
-int CompilerToVM::Data::InstanceKlass_vtable_start_offset;
-int CompilerToVM::Data::InstanceKlass_vtable_length_offset;
+int CompilerToVM::Data::Klass_vtable_start_offset;
+int CompilerToVM::Data::Klass_vtable_length_offset;
 
 int CompilerToVM::Data::Method_extra_stack_entries;
 
@@ -153,8 +153,8 @@
 int CompilerToVM::Data::vm_page_size;
 
 void CompilerToVM::Data::initialize() {
-  InstanceKlass_vtable_start_offset = InstanceKlass::vtable_start_offset();
-  InstanceKlass_vtable_length_offset = InstanceKlass::vtable_length_offset() * HeapWordSize;
+  Klass_vtable_start_offset = in_bytes(Klass::vtable_start_offset());
+  Klass_vtable_length_offset = in_bytes(Klass::vtable_length_offset());
 
   Method_extra_stack_entries = Method::extra_stack_entries();
 
@@ -659,8 +659,7 @@
         vtable_index = LinkResolver::vtable_index_of_interface_method(holder_klass, resolved_method);
         assert(vtable_index >= 0 , "we should have valid vtable index at this point");
 
-        InstanceKlass* inst = InstanceKlass::cast(recv_klass);
-        selected_method = inst->method_at_vtable(vtable_index);
+        selected_method = recv_klass->method_at_vtable(vtable_index);
       } else {
         // at this point we are sure that resolved_method is virtual and not
         // a miranda method; therefore, it must have a valid vtable index.
@@ -675,10 +674,7 @@
           assert(resolved_method->can_be_statically_bound(), "cannot override this method");
           selected_method = resolved_method();
         } else {
-          // recv_klass might be an arrayKlassOop but all vtables start at
-          // the same place. The cast is to avoid virtual call and assertion.
-          InstanceKlass* inst = (InstanceKlass*)recv_klass;
-          selected_method = inst->method_at_vtable(vtable_index);
+          selected_method = recv_klass->method_at_vtable(vtable_index);
         }
       }
       oop result = CompilerToVM::get_jvmci_method(selected_method, CHECK_NULL);
--- a/src/share/vm/jvmci/jvmciCompilerToVM.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/jvmci/jvmciCompilerToVM.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,8 +34,8 @@
     friend class JVMCIVMStructs;
 
    private:
-    static int InstanceKlass_vtable_start_offset;
-    static int InstanceKlass_vtable_length_offset;
+    static int Klass_vtable_start_offset;
+    static int Klass_vtable_length_offset;
 
     static int Method_extra_stack_entries;
 
--- a/src/share/vm/jvmci/vmStructs_jvmci.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/jvmci/vmStructs_jvmci.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -45,8 +45,8 @@
 
 
 #define VM_STRUCTS(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field) \
-  static_field(CompilerToVM::Data,             InstanceKlass_vtable_start_offset,      int)                                          \
-  static_field(CompilerToVM::Data,             InstanceKlass_vtable_length_offset,     int)                                          \
+  static_field(CompilerToVM::Data,             Klass_vtable_start_offset,              int)                                          \
+  static_field(CompilerToVM::Data,             Klass_vtable_length_offset,             int)                                          \
                                                                                                                                      \
   static_field(CompilerToVM::Data,             Method_extra_stack_entries,             int)                                          \
                                                                                                                                      \
--- a/src/share/vm/logging/log.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/logging/log.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -36,52 +36,54 @@
   remove("loglengthoutput.txt");
 
   // Write long message to output file
-  LogConfiguration::parse_log_arguments("loglengthoutput.txt", "logging=trace",
-    NULL, NULL, NULL);
   ResourceMark rm;
-  outputStream* logstream = LogHandle(logging)::trace_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-");
+  LogHandle(logging) log;
+  bool success = LogConfiguration::parse_log_arguments("loglengthoutput.txt", "logging=trace",
+    NULL, NULL, log.error_stream());
+  assert(success, "test unable to configure logging");
+  log.trace("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-");
+  LogConfiguration::parse_log_arguments("loglengthoutput.txt", "all=off",
+    NULL, NULL, log.error_stream());
 
   // Look for end of message in output file
-  FILE* fp;
-  fp = fopen("loglengthoutput.txt", "r");
-  assert (fp, "File read error");
+  FILE* 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");
@@ -89,5 +91,12 @@
   fclose(fp);
   remove("loglengthoutput.txt");
 }
+
+void Test_configure_stdout() {
+  LogConfiguration::configure_stdout(LogLevel::Info, true, LOG_TAGS(logging));
+  assert(log_is_enabled(Info, logging), "configure_stdout did not enable requested logging");
+  assert(!log_is_enabled(Info, logging, gc), "configure_stdout enabled too much logging");
+  LogConfiguration::configure_stdout(LogLevel::Off, false, LOG_TAGS(logging));
+  assert(!log_is_enabled(Info, logging), "configure_stdout did not disable requested logging");
+}
 #endif // PRODUCT
-
--- a/src/share/vm/logging/log.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/logging/log.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -57,13 +57,13 @@
 #define log_develop_info(...)  (!log_is_enabled(Info, __VA_ARGS__))   ? (void)0 : Log<LOG_TAGS(__VA_ARGS__)>::write<LogLevel::Info>
 #define log_develop_debug(...) (!log_is_enabled(Debug, __VA_ARGS__)) ? (void)0 : Log<LOG_TAGS(__VA_ARGS__)>::write<LogLevel::Debug>
 #define log_develop_trace(...) (!log_is_enabled(Trace, __VA_ARGS__))  ? (void)0 : Log<LOG_TAGS(__VA_ARGS__)>::write<LogLevel::Trace>
-#define develop_log_is_enabled(level, ...)  log_is_enabled(level, __VA_ARGS__)
+#define log_develop_is_enabled(level, ...)  log_is_enabled(level, __VA_ARGS__)
 #else
 #define DUMMY_ARGUMENT_CONSUMER(...)
 #define log_develop_info(...)  DUMMY_ARGUMENT_CONSUMER
 #define log_develop_debug(...) DUMMY_ARGUMENT_CONSUMER
 #define log_develop_trace(...) DUMMY_ARGUMENT_CONSUMER
-#define develop_log_is_enabled(...)  false
+#define log_develop_is_enabled(...)  false
 #endif
 
 // Convenience macro to test if the logging is enabled on the specified level for given tags.
@@ -120,15 +120,17 @@
   ATTRIBUTE_PRINTF(1, 0)
   static void vwrite(const char* fmt, va_list args) {
     char buf[LogBufferSize];
+    va_list saved_args;         // For re-format on buf overflow.
+    va_copy(saved_args, args);
     size_t prefix_len = LogPrefix<T0, T1, T2, T3, T4>::prefix(buf, sizeof(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)) {
+    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);
+      ret = os::log_vsnprintf(newbuf + prefix_len, newbuf_len - prefix_len, fmt, saved_args);
       assert(ret >= 0, "Log message buffer issue");
       puts<Level>(newbuf);
       FREE_C_HEAP_ARRAY(char, newbuf);
--- a/src/share/vm/logging/logTag.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/logging/logTag.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -59,6 +59,7 @@
   LOG_TAG(marking) \
   LOG_TAG(metaspace) \
   LOG_TAG(monitorinflation) \
+  LOG_TAG(os) \
   LOG_TAG(phases) \
   LOG_TAG(plab) \
   LOG_TAG(promotion) \
--- a/src/share/vm/logging/logTagLevelExpression.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/logging/logTagLevelExpression.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -29,21 +29,8 @@
 
 const char* LogTagLevelExpression::DefaultExpressionString = "all";
 
-void LogTagLevelExpression::clear() {
-  _ntags = 0;
-  _ncombinations = 0;
-  for (size_t combination = 0; combination < MaxCombinations; combination++) {
-    _level[combination] = LogLevel::Invalid;
-    _allow_other_tags[combination] = false;
-    for (size_t tag = 0; tag < LogTag::MaxTags; tag++) {
-      _tags[combination][tag] = LogTag::__NO_TAG;
-    }
-  }
-}
-
 bool LogTagLevelExpression::parse(const char* str, outputStream* errstream) {
   bool success = true;
-  clear();
   if (str == NULL || strcmp(str, "") == 0) {
     str = DefaultExpressionString;
   }
--- a/src/share/vm/logging/logTagLevelExpression.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/logging/logTagLevelExpression.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -47,6 +47,11 @@
   bool          _allow_other_tags[MaxCombinations];
 
   void new_combination() {
+    // Make sure either all tags are set or the last tag is __NO_TAG
+    if (_ntags < LogTag::MaxTags) {
+      _tags[_ncombinations][_ntags] = LogTag::__NO_TAG;
+    }
+
     _ncombinations++;
     _ntags = 0;
   }
@@ -64,10 +69,13 @@
     _allow_other_tags[_ncombinations] = true;
   }
 
-  void clear();
-
  public:
   LogTagLevelExpression() : _ntags(0), _ncombinations(0) {
+    for (size_t combination = 0; combination < MaxCombinations; combination++) {
+      _level[combination] = LogLevel::Invalid;
+      _allow_other_tags[combination] = false;
+      _tags[combination][0] = LogTag::__NO_TAG;
+    }
   }
 
   bool parse(const char* str, outputStream* errstream = NULL);
--- a/src/share/vm/memory/heapInspection.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/memory/heapInspection.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, 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
@@ -40,6 +40,14 @@
 
 // HeapInspection
 
+int KlassSizeStats::count(oop x) {
+  return (HeapWordSize * (((x) != NULL) ? (x)->size() : 0));
+}
+
+int KlassSizeStats::count_array(objArrayOop x) {
+  return (HeapWordSize * (((x) != NULL) ? (x)->size() : 0));
+}
+
 inline KlassInfoEntry::~KlassInfoEntry() {
   if (_subclasses != NULL) {
     delete _subclasses;
--- a/src/share/vm/memory/heapInspection.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/memory/heapInspection.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, 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
@@ -154,13 +154,9 @@
 
   HEAP_INSPECTION_COLUMNS_DO(DECLARE_KLASS_SIZE_STATS_FIELD)
 
-  static int count(oop x) {
-    return (HeapWordSize * (((x) != NULL) ? (x)->size() : 0));
-  }
+  static int count(oop x);
 
-  static int count_array(objArrayOop x) {
-    return (HeapWordSize * (((x) != NULL) ? (x)->size() : 0));
-  }
+  static int count_array(objArrayOop x);
 
   template <class T> static int count(T* x) {
     return (HeapWordSize * ((x) ? (x)->size() : 0));
--- a/src/share/vm/memory/metaspace.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/memory/metaspace.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -1234,7 +1234,7 @@
 #ifdef ASSERT
   new_entry->mangle();
 #endif
-  if (develop_log_is_enabled(Trace, gc, metaspace)) {
+  if (log_is_enabled(Trace, gc, metaspace)) {
     LogHandle(gc, metaspace) log;
     VirtualSpaceNode* vsl = current_virtual_space();
     ResourceMark rm;
@@ -3051,7 +3051,7 @@
 
   initialize_class_space(metaspace_rs);
 
-  if (develop_log_is_enabled(Trace, gc, metaspace)) {
+  if (log_is_enabled(Trace, gc, metaspace)) {
     LogHandle(gc, metaspace) log;
     ResourceMark rm;
     print_compressed_class_space(log.trace_stream(), requested_addr);
@@ -3474,7 +3474,7 @@
     }
 
     // Zero initialize.
-    Copy::fill_to_aligned_words((HeapWord*)result, word_size, 0);
+    Copy::fill_to_words((HeapWord*)result, word_size, 0);
 
     return result;
   }
@@ -3513,7 +3513,7 @@
   }
 
   // Zero initialize.
-  Copy::fill_to_aligned_words((HeapWord*)result, word_size, 0);
+  Copy::fill_to_words((HeapWord*)result, word_size, 0);
 
   return result;
 }
@@ -3583,7 +3583,7 @@
 void Metaspace::record_allocation(void* ptr, MetaspaceObj::Type type, size_t word_size) {
   assert(DumpSharedSpaces, "sanity");
 
-  int byte_size = (int)word_size * HeapWordSize;
+  int byte_size = (int)word_size * wordSize;
   AllocRecord *rec = new AllocRecord((address)ptr, type, byte_size);
 
   if (_alloc_record_head == NULL) {
@@ -3623,7 +3623,7 @@
 
   for (AllocRecord *rec = _alloc_record_head; rec; rec = rec->_next) {
     if (rec->_ptr == ptr) {
-      assert(rec->_byte_size == (int)word_size * HeapWordSize, "sanity");
+      assert(rec->_byte_size == (int)word_size * wordSize, "sanity");
       rec->_type = MetaspaceObj::DeallocatedType;
       return;
     }
--- a/src/share/vm/memory/padded.inline.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/memory/padded.inline.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, 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
@@ -41,7 +41,7 @@
   void* chunk = AllocateHeap(length * sizeof(PaddedEnd<T, alignment>) + alignment, flags);
 
   // Make the initial alignment.
-  PaddedEnd<T>* aligned_padded_array = (PaddedEnd<T>*)align_pointer_up(chunk, alignment);
+  PaddedEnd<T>* aligned_padded_array = (PaddedEnd<T>*)align_ptr_up(chunk, alignment);
 
   // Call the default constructor for each element.
   for (uint i = 0; i < length; i++) {
@@ -65,7 +65,7 @@
   // Clear the allocated memory.
   memset(chunk, 0, total_size);
   // Align the chunk of memory.
-  T** result = (T**)align_pointer_up(chunk, alignment);
+  T** result = (T**)align_ptr_up(chunk, alignment);
   void* data_start = (void*)((uintptr_t)result + table_size);
 
   // Fill in the row table.
@@ -87,7 +87,7 @@
 
   memset(chunk, 0, length * sizeof(T) + alignment);
 
-  return (T*)align_pointer_up(chunk, alignment);
+  return (T*)align_ptr_up(chunk, alignment);
 }
 
 #endif // SHARE_VM_MEMORY_PADDED_INLINE_HPP
--- a/src/share/vm/memory/virtualspace.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/memory/virtualspace.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -502,7 +502,7 @@
 
       // Calc address range within we try to attach (range of possible start addresses).
       char* const highest_start = (char *)align_ptr_down((char *)UnscaledOopHeapMax - size, attach_point_alignment);
-      char* const lowest_start  = (char *)align_ptr_up  (        aligned_heap_base_min_address             , attach_point_alignment);
+      char* const lowest_start  = (char *)align_ptr_up(aligned_heap_base_min_address, attach_point_alignment);
       try_reserve_range(highest_start, lowest_start, attach_point_alignment,
                         aligned_heap_base_min_address, (char *)UnscaledOopHeapMax, size, alignment, large);
     }
--- a/src/share/vm/oops/arrayKlass.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/oops/arrayKlass.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -42,12 +42,8 @@
   // If this assert fails, see comments in base_create_array_klass.
   header_size = InstanceKlass::header_size();
   int vtable_len = Universe::base_vtable_size();
-#ifdef _LP64
-  int size = header_size + align_object_offset(vtable_len);
-#else
   int size = header_size + vtable_len;
-#endif
-  return align_object_size(size);
+  return align_metadata_size(size);
 }
 
 
@@ -85,10 +81,10 @@
 ArrayKlass::ArrayKlass(Symbol* name) :
   _dimension(1),
   _higher_dimension(NULL),
-  _lower_dimension(NULL),
-  // Arrays don't add any new methods, so their vtable is the same size as
-  // the vtable of klass Object.
-  _vtable_len(Universe::base_vtable_size()) {
+  _lower_dimension(NULL) {
+    // Arrays don't add any new methods, so their vtable is the same size as
+    // the vtable of klass Object.
+    set_vtable_length(Universe::base_vtable_size());
     set_name(name);
     set_super(Universe::is_bootstrapping() ? (Klass*)NULL : SystemDictionary::Object_klass());
     set_layout_helper(Klass::_lh_neutral_value);
@@ -121,19 +117,6 @@
          || k == SystemDictionary::Serializable_klass();
 }
 
-
-inline intptr_t* ArrayKlass::start_of_vtable() const {
-  // all vtables start at the same place, that's why we use InstanceKlass::header_size here
-  return ((intptr_t*)this) + InstanceKlass::header_size();
-}
-
-
-klassVtable* ArrayKlass::vtable() const {
-  KlassHandle kh(Thread::current(), this);
-  return new klassVtable(kh, start_of_vtable(), vtable_length() / vtableEntry::size());
-}
-
-
 objArrayOop ArrayKlass::allocate_arrayArray(int n, int length, TRAPS) {
   if (length < 0) {
     THROW_0(vmSymbols::java_lang_NegativeArraySizeException());
--- a/src/share/vm/oops/arrayKlass.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/oops/arrayKlass.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,7 +39,6 @@
   int      _dimension;         // This is n'th-dimensional array.
   Klass* volatile _higher_dimension;  // Refers the (n+1)'th-dimensional array (if present).
   Klass* volatile _lower_dimension;   // Refers the (n-1)'th-dimensional array (if present).
-  int      _vtable_len;        // size of vtable for this klass
 
  protected:
   // Constructors
@@ -99,7 +98,6 @@
   bool compute_is_subtype_of(Klass* k);
 
   // Sizing
-  static int header_size()                 { return sizeof(ArrayKlass)/HeapWordSize; }
   static int static_size(int header_size);
 
 #if INCLUDE_SERVICES
@@ -110,15 +108,6 @@
   }
 #endif
 
-  // Java vtable
-  klassVtable* vtable() const;             // return new klassVtable
-  int  vtable_length() const               { return _vtable_len; }
-  static int base_vtable_length()          { return Universe::base_vtable_size(); }
-  void set_vtable_length(int len)          { assert(len == base_vtable_length(), "bad length"); _vtable_len = len; }
- protected:
-  inline intptr_t* start_of_vtable() const;
-
- public:
   // Iterators
   void array_klasses_do(void f(Klass* k));
   void array_klasses_do(void f(Klass* k, TRAPS), TRAPS);
--- a/src/share/vm/oops/constMethod.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/oops/constMethod.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -144,7 +144,7 @@
 
   int extra_words = align_size_up(extra_bytes, BytesPerWord) / BytesPerWord;
   assert(extra_words == extra_bytes/BytesPerWord, "should already be aligned");
-  return align_object_size(header_size() + extra_words);
+  return align_metadata_size(header_size() + extra_words);
 }
 
 Method* ConstMethod::method() const {
@@ -492,6 +492,6 @@
       uncompressed_table_start = (u2*) m_end;
   }
   int gap = (intptr_t) uncompressed_table_start - (intptr_t) compressed_table_end;
-  int max_gap = align_object_size(1)*BytesPerWord;
+  int max_gap = align_metadata_size(1)*BytesPerWord;
   guarantee(gap >= 0 && gap < max_gap, "invalid method layout");
 }
--- a/src/share/vm/oops/constMethod.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/oops/constMethod.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -328,9 +328,7 @@
   }
 
   // Sizing
-  static int header_size() {
-    return sizeof(ConstMethod)/HeapWordSize;
-  }
+  static int header_size() { return sizeof(ConstMethod)/wordSize; }
 
   // Size needed
   static int size(int code_size, InlineTableSizes* sizes);
--- a/src/share/vm/oops/constantPool.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/oops/constantPool.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -723,8 +723,8 @@
   }
 
   // Sizing (in words)
-  static int header_size()             { return sizeof(ConstantPool)/HeapWordSize; }
-  static int size(int length)          { return align_object_size(header_size() + length); }
+  static int header_size()             { return sizeof(ConstantPool)/wordSize; }
+  static int size(int length)          { return align_metadata_size(header_size() + length); }
   int size() const                     { return size(length()); }
 #if INCLUDE_SERVICES
   void collect_statistics(KlassSizeStats *sz) const;
--- a/src/share/vm/oops/cpCache.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/oops/cpCache.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, 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
@@ -396,9 +396,7 @@
         int holder_index = cpool->uncached_klass_ref_index_at(constant_pool_index());
         if (cpool->tag_at(holder_index).is_klass()) {
           Klass* klass = cpool->resolved_klass_at(holder_index);
-          if (!klass->is_instance_klass())
-            klass = SystemDictionary::Object_klass();
-          return InstanceKlass::cast(klass)->method_at_vtable(f2_as_index());
+          return klass->method_at_vtable(f2_as_index());
         }
       }
       break;
--- a/src/share/vm/oops/cpCache.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/oops/cpCache.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, 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
@@ -364,7 +364,7 @@
                                                    return (TosState)((_flags >> tos_state_shift) & tos_state_mask); }
 
   // Code generation support
-  static WordSize size()                         { return in_WordSize(sizeof(ConstantPoolCacheEntry) / HeapWordSize); }
+  static WordSize size()                         { return in_WordSize(sizeof(ConstantPoolCacheEntry) / wordSize); }
   static ByteSize size_in_bytes()                { return in_ByteSize(sizeof(ConstantPoolCacheEntry)); }
   static ByteSize indices_offset()               { return byte_offset_of(ConstantPoolCacheEntry, _indices); }
   static ByteSize f1_offset()                    { return byte_offset_of(ConstantPoolCacheEntry, _f1); }
@@ -439,14 +439,14 @@
  private:
   void set_length(int length)                    { _length = length; }
 
-  static int header_size()                       { return sizeof(ConstantPoolCache) / HeapWordSize; }
-  static int size(int length)                    { return align_object_size(header_size() + length * in_words(ConstantPoolCacheEntry::size())); }
+  static int header_size()                       { return sizeof(ConstantPoolCache) / wordSize; }
+  static int size(int length)                    { return align_metadata_size(header_size() + length * in_words(ConstantPoolCacheEntry::size())); }
  public:
   int size() const                               { return size(length()); }
  private:
 
   // Helpers
-  ConstantPool**        constant_pool_addr()   { return &_constant_pool; }
+  ConstantPool**        constant_pool_addr()     { return &_constant_pool; }
   ConstantPoolCacheEntry* base() const           { return (ConstantPoolCacheEntry*)((address)this + in_bytes(base_offset())); }
 
   friend class constantPoolCacheKlass;
--- a/src/share/vm/oops/instanceClassLoaderKlass.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/oops/instanceClassLoaderKlass.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -55,7 +55,7 @@
   void oop_ps_push_contents(  oop obj, PSPromotionManager* pm);
   // Parallel Compact
   void oop_pc_follow_contents(oop obj, ParCompactionManager* cm);
-  void oop_pc_update_pointers(oop obj);
+  void oop_pc_update_pointers(oop obj, ParCompactionManager* cm);
 #endif
 
   // Oop fields (and metadata) iterators
--- a/src/share/vm/oops/instanceKlass.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/oops/instanceKlass.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -211,9 +211,9 @@
 InstanceKlass::InstanceKlass(const ClassFileParser& parser, unsigned kind) :
   _static_field_size(parser.static_field_size()),
   _nonstatic_oop_map_size(nonstatic_oop_map_size(parser.total_oop_map_count())),
-  _vtable_len(parser.vtable_size()),
   _itable_len(parser.itable_size()),
   _reference_type(parser.reference_type()) {
+    set_vtable_length(parser.vtable_size());
     set_kind(kind);
     set_access_flags(parser.access_flags());
     set_is_anonymous(parser.is_anonymous());
@@ -364,10 +364,6 @@
   return !is_initialized();
 }
 
-klassVtable* InstanceKlass::vtable() const {
-  return new klassVtable(this, start_of_vtable(), vtable_length() / vtableEntry::size());
-}
-
 klassItable* InstanceKlass::itable() const {
   return new klassItable(instanceKlassHandle(this));
 }
@@ -2667,6 +2663,10 @@
   }
 }
 
+static void print_vtable(vtableEntry* start, int len, outputStream* st) {
+  return print_vtable(reinterpret_cast<intptr_t*>(start), len, st);
+}
+
 void InstanceKlass::print_on(outputStream* st) const {
   assert(is_klass(), "must be klass");
   Klass::print_on(st);
@@ -2909,13 +2909,10 @@
 void InstanceKlass::collect_statistics(KlassSizeStats *sz) const {
   Klass::collect_statistics(sz);
 
-  sz->_inst_size  = HeapWordSize * size_helper();
-  sz->_vtab_bytes = HeapWordSize * align_object_offset(vtable_length());
-  sz->_itab_bytes = HeapWordSize * align_object_offset(itable_length());
-  sz->_nonstatic_oopmap_bytes = HeapWordSize *
-        ((is_interface() || is_anonymous()) ?
-         align_object_offset(nonstatic_oop_map_size()) :
-         nonstatic_oop_map_size());
+  sz->_inst_size  = wordSize * size_helper();
+  sz->_vtab_bytes = wordSize * vtable_length();
+  sz->_itab_bytes = wordSize * itable_length();
+  sz->_nonstatic_oopmap_bytes = wordSize * nonstatic_oop_map_size();
 
   int n = 0;
   n += (sz->_methods_array_bytes         = sz->count_array(methods()));
--- a/src/share/vm/oops/instanceKlass.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/oops/instanceKlass.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -94,10 +94,10 @@
   uint count() const         { return _count; }
   void set_count(uint count) { _count = count; }
 
-  // sizeof(OopMapBlock) in HeapWords.
+  // sizeof(OopMapBlock) in words.
   static const int size_in_words() {
-    return align_size_up(int(sizeof(OopMapBlock)), HeapWordSize) >>
-      LogHeapWordSize;
+    return align_size_up(int(sizeof(OopMapBlock)), wordSize) >>
+      LogBytesPerWord;
   }
 
  private:
@@ -178,6 +178,7 @@
   u2              _java_fields_count;    // The number of declared Java fields
   int             _nonstatic_oop_map_size;// size in words of nonstatic oop map blocks
 
+  int             _itable_len;           // length of Java itable (in words)
   // _is_marked_dependent can be set concurrently, thus cannot be part of the
   // _misc_flags.
   bool            _is_marked_dependent;  // used for marking during flushing and deoptimization
@@ -211,8 +212,6 @@
   u2              _minor_version;        // minor version number of class file
   u2              _major_version;        // major version number of class file
   Thread*         _init_thread;          // Pointer to current thread doing initialization (to handle recusive initialization)
-  int             _vtable_len;           // length of Java vtable (in words)
-  int             _itable_len;           // length of Java itable (in words)
   OopMapCache*    volatile _oop_map_cache;   // OopMapCache for all methods in the klass (allocated lazily)
   MemberNameTable* _member_names;        // Member names
   JNIid*          _jni_ids;              // First JNI identifier for static fields in this class
@@ -311,10 +310,6 @@
   int static_oop_field_count() const       { return (int)_static_oop_field_count; }
   void set_static_oop_field_count(u2 size) { _static_oop_field_count = size; }
 
-  // Java vtable
-  int  vtable_length() const               { return _vtable_len; }
-  void set_vtable_length(int len)          { _vtable_len = len; }
-
   // Java itable
   int  itable_length() const               { return _itable_len; }
   void set_itable_length(int len)          { _itable_len = len; }
@@ -927,19 +922,17 @@
   }
 
   // Sizing (in words)
-  static int header_size()            { return align_object_offset(sizeof(InstanceKlass)/HeapWordSize); }
+  static int header_size()            { return sizeof(InstanceKlass)/wordSize; }
 
   static int size(int vtable_length, int itable_length,
                   int nonstatic_oop_map_size,
                   bool is_interface, bool is_anonymous) {
-    return align_object_size(header_size() +
-           align_object_offset(vtable_length) +
-           align_object_offset(itable_length) +
-           ((is_interface || is_anonymous) ?
-             align_object_offset(nonstatic_oop_map_size) :
-             nonstatic_oop_map_size) +
-           (is_interface ? (int)sizeof(Klass*)/HeapWordSize : 0) +
-           (is_anonymous ? (int)sizeof(Klass*)/HeapWordSize : 0));
+    return align_metadata_size(header_size() +
+           vtable_length +
+           itable_length +
+           nonstatic_oop_map_size +
+           (is_interface ? (int)sizeof(Klass*)/wordSize : 0) +
+           (is_anonymous ? (int)sizeof(Klass*)/wordSize : 0));
   }
   int size() const                    { return size(vtable_length(),
                                                itable_length(),
@@ -951,19 +944,15 @@
   virtual void collect_statistics(KlassSizeStats *sz) const;
 #endif
 
-  static int vtable_start_offset()    { return header_size(); }
-  static int vtable_length_offset()   { return offset_of(InstanceKlass, _vtable_len) / HeapWordSize; }
+  intptr_t* start_of_itable()   const { return (intptr_t*)start_of_vtable() + vtable_length(); }
+  intptr_t* end_of_itable()     const { return start_of_itable() + itable_length(); }
 
-  intptr_t* start_of_vtable() const        { return ((intptr_t*)this) + vtable_start_offset(); }
-  intptr_t* start_of_itable() const        { return start_of_vtable() + align_object_offset(vtable_length()); }
   int  itable_offset_in_words() const { return start_of_itable() - (intptr_t*)this; }
 
-  intptr_t* end_of_itable() const          { return start_of_itable() + itable_length(); }
-
   address static_field_addr(int offset);
 
   OopMapBlock* start_of_nonstatic_oop_maps() const {
-    return (OopMapBlock*)(start_of_itable() + align_object_offset(itable_length()));
+    return (OopMapBlock*)(start_of_itable() + itable_length());
   }
 
   Klass** end_of_nonstatic_oop_maps() const {
@@ -1007,9 +996,7 @@
     return !layout_helper_needs_slow_path(layout_helper());
   }
 
-  // Java vtable/itable
-  klassVtable* vtable() const;        // return new klassVtable wrapper
-  inline Method* method_at_vtable(int index);
+  // Java itable
   klassItable* itable() const;        // return new klassItable wrapper
   Method* method_at_itable(Klass* holder, int index, TRAPS);
 
@@ -1052,7 +1039,7 @@
   void oop_ps_push_contents(  oop obj, PSPromotionManager* pm);
   // Parallel Compact
   void oop_pc_follow_contents(oop obj, ParCompactionManager* cm);
-  void oop_pc_update_pointers(oop obj);
+  void oop_pc_update_pointers(oop obj, ParCompactionManager* cm);
 #endif
 
   // Oop fields (and metadata) iterators
@@ -1259,17 +1246,6 @@
   void oop_verify_on(oop obj, outputStream* st);
 };
 
-inline Method* InstanceKlass::method_at_vtable(int index)  {
-#ifndef PRODUCT
-  assert(index >= 0, "valid vtable index");
-  if (DebugVtables) {
-    verify_vtable_index(index);
-  }
-#endif
-  vtableEntry* ve = (vtableEntry*)start_of_vtable();
-  return ve[index].method();
-}
-
 // for adding methods
 // UNSET_IDNUM return means no more ids available
 inline u2 InstanceKlass::next_method_idnum() {
--- a/src/share/vm/oops/instanceMirrorKlass.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/oops/instanceMirrorKlass.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -96,7 +96,7 @@
   void oop_ps_push_contents(  oop obj, PSPromotionManager* pm);
   // Parallel Compact
   void oop_pc_follow_contents(oop obj, ParCompactionManager* cm);
-  void oop_pc_update_pointers(oop obj);
+  void oop_pc_update_pointers(oop obj, ParCompactionManager* cm);
 #endif
 
   // Oop fields (and metadata) iterators
--- a/src/share/vm/oops/instanceRefKlass.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/oops/instanceRefKlass.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -65,7 +65,7 @@
   void oop_ps_push_contents(  oop obj, PSPromotionManager* pm);
   // Parallel Compact
   void oop_pc_follow_contents(oop obj, ParCompactionManager* cm);
-  void oop_pc_update_pointers(oop obj);
+  void oop_pc_update_pointers(oop obj, ParCompactionManager* cm);
 #endif
 
   // Oop fields (and metadata) iterators
--- a/src/share/vm/oops/klass.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/oops/klass.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -673,6 +673,28 @@
   guarantee(obj->klass()->is_klass(), "klass field is not a klass");
 }
 
+klassVtable* Klass::vtable() const {
+  return new klassVtable(this, start_of_vtable(), vtable_length() / vtableEntry::size());
+}
+
+vtableEntry* Klass::start_of_vtable() const {
+  return (vtableEntry*) ((address)this + in_bytes(vtable_start_offset()));
+}
+
+Method* Klass::method_at_vtable(int index)  {
+#ifndef PRODUCT
+  assert(index >= 0, "valid vtable index");
+  if (DebugVtables) {
+    verify_vtable_index(index);
+  }
+#endif
+  return start_of_vtable()[index].method();
+}
+
+ByteSize Klass::vtable_start_offset() {
+  return in_ByteSize(InstanceKlass::header_size() * wordSize);
+}
+
 #ifndef PRODUCT
 
 bool Klass::verify_vtable_index(int i) {
--- a/src/share/vm/oops/klass.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/oops/klass.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -57,6 +57,7 @@
 class PSPromotionManager;
 class KlassSizeStats;
 class fieldDescriptor;
+class vtableEntry;
 
 class Klass : public Metadata {
   friend class VMStructs;
@@ -131,13 +132,16 @@
   jint        _modifier_flags;  // Processed access flags, for use by Class.getModifiers.
   AccessFlags _access_flags;    // Access flags. The class/interface distinction is stored here.
 
+  TRACE_DEFINE_KLASS_TRACE_ID;
+
   // Biased locking implementation and statistics
   // (the 64-bit chunk goes first, to avoid some fragmentation)
   jlong    _last_biased_lock_bulk_revocation_time;
   markOop  _prototype_header;   // Used when biased locking is both enabled and disabled for this type
   jint     _biased_lock_revocation_count;
 
-  TRACE_DEFINE_KLASS_TRACE_ID;
+  // vtable length
+  int _vtable_len;
 
   // Remembered sets support for the oops in the klasses.
   jbyte _modified_oops;             // Card Table Equivalent (YC/CMS support)
@@ -352,13 +356,13 @@
       |    (log2_esize << _lh_log2_element_size_shift);
   }
   static jint instance_layout_helper(jint size, bool slow_path_flag) {
-    return (size << LogHeapWordSize)
+    return (size << LogBytesPerWord)
       |    (slow_path_flag ? _lh_instance_slow_path_bit : 0);
   }
   static int layout_helper_to_size_helper(jint lh) {
     assert(lh > (jint)_lh_neutral_value, "must be instance");
     // Note that the following expression discards _lh_instance_slow_path_bit.
-    return lh >> LogHeapWordSize;
+    return lh >> LogBytesPerWord;
   }
   // Out-of-line version computes everything based on the etype:
   static jint array_layout_helper(BasicType etype);
@@ -374,8 +378,8 @@
 #endif
 
   // vtables
-  virtual klassVtable* vtable() const = 0;
-  virtual int vtable_length() const = 0;
+  klassVtable* vtable() const;
+  int vtable_length() const { return _vtable_len; }
 
   // subclass check
   bool is_subclass_of(const Klass* k) const;
@@ -438,7 +442,17 @@
   virtual Klass* array_klass_impl(bool or_null, int rank, TRAPS);
   virtual Klass* array_klass_impl(bool or_null, TRAPS);
 
+  void set_vtable_length(int len) { _vtable_len= len; }
+
+  vtableEntry* start_of_vtable() const;
  public:
+  Method* method_at_vtable(int index);
+
+  static ByteSize vtable_start_offset();
+  static ByteSize vtable_length_offset() {
+    return byte_offset_of(Klass, _vtable_len);
+  }
+
   // CDS support - remove and restore oops from metadata. Oops are not shared.
   virtual void remove_unshareable_info();
   virtual void restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS);
@@ -579,7 +593,7 @@
   virtual void oop_ps_push_contents(  oop obj, PSPromotionManager* pm)   = 0;
   // Parallel Compact
   virtual void oop_pc_follow_contents(oop obj, ParCompactionManager* cm) = 0;
-  virtual void oop_pc_update_pointers(oop obj) = 0;
+  virtual void oop_pc_update_pointers(oop obj, ParCompactionManager* cm) = 0;
 #endif
 
   // Iterators specialized to particular subtypes
--- a/src/share/vm/oops/klassVtable.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/oops/klassVtable.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -135,7 +135,7 @@
     superVtable->verify(tty, true);
 #endif
     superVtable->copy_vtable_to(table());
-    if (develop_log_is_enabled(Trace, vtables)) {
+    if (log_develop_is_enabled(Trace, vtables)) {
       ResourceMark rm;
       log_develop_trace(vtables)("copy vtable from %s to %s size %d",
                                  super->internal_name(), klass()->internal_name(),
@@ -272,7 +272,7 @@
       assert(super_method->name() == name && super_method->signature() == signature, "vtable entry name/sig mismatch");
 #endif
       if (supersuperklass->is_override(super_method, target_loader, target_classname, THREAD)) {
-        if (develop_log_is_enabled(Trace, vtables)) {
+        if (log_develop_is_enabled(Trace, vtables)) {
           ResourceMark rm(THREAD);
           outputStream* logst = LogHandle(vtables)::trace_stream();
           char* sig = target_method()->name_and_sig_as_C_string();
@@ -303,7 +303,7 @@
                         KlassHandle target_klass, Method* super_method,
                         Thread* thread) {
 #ifndef PRODUCT
-  if (develop_log_is_enabled(Trace, vtables)) {
+  if (log_develop_is_enabled(Trace, vtables)) {
     ResourceMark rm(thread);
     outputStream* logst = LogHandle(vtables)::trace_stream();
     char* sig = target_method()->name_and_sig_as_C_string();
@@ -491,7 +491,7 @@
 }
 
 void klassVtable::put_method_at(Method* m, int index) {
-  if (develop_log_is_enabled(Trace, vtables)) {
+  if (log_develop_is_enabled(Trace, vtables)) {
     ResourceMark rm;
     outputStream* logst = LogHandle(vtables)::trace_stream();
     const char* sig = (m != NULL) ? m->name_and_sig_as_C_string() : "<NULL>";
@@ -818,7 +818,7 @@
   get_mirandas(&mirandas, NULL, ik()->super(), ik()->methods(),
                ik()->default_methods(), ik()->local_interfaces());
   for (int i = 0; i < mirandas.length(); i++) {
-    if (develop_log_is_enabled(Trace, vtables)) {
+    if (log_develop_is_enabled(Trace, vtables)) {
       Method* meth = mirandas.at(i);
       ResourceMark rm(Thread::current());
       outputStream* logst = LogHandle(vtables)::trace_stream();
@@ -1043,7 +1043,7 @@
     if (interface_method_needs_itable_index(m)) {
       assert(!m->is_final_method(), "no final interface methods");
       // If m is already assigned a vtable index, do not disturb it.
-      if (develop_log_is_enabled(Trace, itables)) {
+      if (log_develop_is_enabled(Trace, itables)) {
         ResourceMark rm;
         outputStream* logst = LogHandle(itables)::trace_stream();
         assert(m != NULL, "methods can never be null");
@@ -1158,7 +1158,7 @@
       int ime_num = m->itable_index();
       assert(ime_num < ime_count, "oob");
       itableOffsetEntry::method_entry(_klass(), method_table_offset)[ime_num].initialize(target());
-      if (develop_log_is_enabled(Trace, itables)) {
+      if (log_develop_is_enabled(Trace, itables)) {
         ResourceMark rm(THREAD);
         if (target() != NULL) {
           outputStream* logst = LogHandle(itables)::trace_stream();
@@ -1331,7 +1331,7 @@
   int itable_size = calc_itable_size(cic.nof_interfaces() + 1, cic.nof_methods());
 
   // Statistics
-  update_stats(itable_size * HeapWordSize);
+  update_stats(itable_size * wordSize);
 
   return itable_size;
 }
--- a/src/share/vm/oops/klassVtable.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/oops/klassVtable.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -170,9 +170,9 @@
 
  public:
   // size in words
-  static int size() {
-    return sizeof(vtableEntry) / sizeof(HeapWord);
-  }
+  static int size()          { return sizeof(vtableEntry) / wordSize; }
+  static int size_in_bytes() { return sizeof(vtableEntry); }
+
   static int method_offset_in_bytes() { return offset_of(vtableEntry, _method); }
   Method* method() const    { return _method; }
 
@@ -223,7 +223,7 @@
   void initialize(Klass* interf, int offset) { _interface = interf; _offset = offset; }
 
   // Static size and offset accessors
-  static int size()                       { return sizeof(itableOffsetEntry) / HeapWordSize; }    // size in words
+  static int size()                       { return sizeof(itableOffsetEntry) / wordSize; }    // size in words
   static int interface_offset_in_bytes()  { return offset_of(itableOffsetEntry, _interface); }
   static int offset_offset_in_bytes()     { return offset_of(itableOffsetEntry, _offset); }
 
@@ -243,7 +243,7 @@
   void initialize(Method* method);
 
   // Static size and offset accessors
-  static int size()                         { return sizeof(itableMethodEntry) / HeapWordSize; }  // size in words
+  static int size()                         { return sizeof(itableMethodEntry) / wordSize; }  // size in words
   static int method_offset_in_bytes()       { return offset_of(itableMethodEntry, _method); }
 
   friend class klassItable;
--- a/src/share/vm/oops/markOop.inline.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/oops/markOop.inline.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2016, 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,7 @@
 
 #include "oops/klass.hpp"
 #include "oops/markOop.hpp"
+#include "oops/oop.inline.hpp"
 #include "runtime/globals.hpp"
 
 // Should this header be preserved during GC (when biased locking is enabled)?
--- a/src/share/vm/oops/metadata.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/oops/metadata.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -58,13 +58,13 @@
     if (this == NULL)
       st->print("NULL");
     else
-      print_on(tty);
+      print_on(st);
   }
   void print_value_on_maybe_null(outputStream* st) const {
     if (this == NULL)
       st->print("NULL");
     else
-      print_value_on(tty);
+      print_value_on(st);
   }
 
   virtual void print_on(outputStream* st) const;       // First level print
--- a/src/share/vm/oops/method.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/oops/method.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -295,7 +295,7 @@
   // If native, then include pointers for native_function and signature_handler
   int extra_bytes = (is_native) ? 2*sizeof(address*) : 0;
   int extra_words = align_size_up(extra_bytes, BytesPerWord) / BytesPerWord;
-  return align_object_size(header_size() + extra_words);
+  return align_metadata_size(header_size() + extra_words);
 }
 
 
--- a/src/share/vm/oops/method.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/oops/method.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -622,7 +622,7 @@
   bool has_compiled_code() const                 { return code() != NULL; }
 
   // sizing
-  static int header_size()                       { return sizeof(Method)/HeapWordSize; }
+  static int header_size()                       { return sizeof(Method)/wordSize; }
   static int size(bool is_native);
   int size() const                               { return method_size(); }
 #if INCLUDE_SERVICES
--- a/src/share/vm/oops/methodData.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/oops/methodData.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -934,7 +934,7 @@
 int MethodData::compute_allocation_size_in_words(const methodHandle& method) {
   int byte_size = compute_allocation_size_in_bytes(method);
   int word_size = align_size_up(byte_size, BytesPerWord) / BytesPerWord;
-  return align_object_size(word_size);
+  return align_metadata_size(word_size);
 }
 
 // Initialize an individual data segment.  Returns the size of
--- a/src/share/vm/oops/methodData.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/oops/methodData.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -2334,7 +2334,7 @@
 
   // My size
   int size_in_bytes() const { return _size; }
-  int size() const    { return align_object_size(align_size_up(_size, BytesPerWord)/BytesPerWord); }
+  int size() const    { return align_metadata_size(align_size_up(_size, BytesPerWord)/BytesPerWord); }
 #if INCLUDE_SERVICES
   void collect_statistics(KlassSizeStats *sz) const;
 #endif
--- a/src/share/vm/oops/objArrayKlass.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/oops/objArrayKlass.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -101,7 +101,7 @@
   }
 
   // Sizing
-  static int header_size()                { return sizeof(ObjArrayKlass)/HeapWordSize; }
+  static int header_size()                { return sizeof(ObjArrayKlass)/wordSize; }
   int size() const                        { return ArrayKlass::static_size(header_size()); }
 
   // Initialization (virtual from Klass)
@@ -116,7 +116,7 @@
   void oop_ps_push_contents(  oop obj, PSPromotionManager* pm);
   // Parallel Compact
   void oop_pc_follow_contents(oop obj, ParCompactionManager* cm);
-  void oop_pc_update_pointers(oop obj);
+  void oop_pc_update_pointers(oop obj, ParCompactionManager* cm);
 #endif
 
   // Oop fields (and metadata) iterators
--- a/src/share/vm/oops/objArrayOop.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/oops/objArrayOop.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -81,7 +81,7 @@
   // Accessing
   oop obj_at(int index) const;
 
-  void /*inline*/ obj_at_put(int index, oop value);
+  void inline obj_at_put(int index, oop value);
 
   oop atomic_compare_exchange_oop(int index, oop exchange_value, oop compare_value);
 
--- a/src/share/vm/oops/objArrayOop.inline.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/oops/objArrayOop.inline.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -39,7 +39,7 @@
   }
 }
 
-inline void objArrayOopDesc::obj_at_put(int index, oop value) {
+void objArrayOopDesc::obj_at_put(int index, oop value) {
   if (UseCompressedOops) {
     oop_store(obj_at_addr<narrowOop>(index), value);
   } else {
--- a/src/share/vm/oops/oop.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/oops/oop.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -82,16 +82,16 @@
   // objects during a GC) -- requires a valid klass pointer
   inline void init_mark();
 
-  /*inline*/ Klass* klass() const;
+  inline Klass* klass() const;
   inline Klass* klass_or_null() const volatile;
   inline Klass** klass_addr();
   inline narrowKlass* compressed_klass_addr();
 
-  /*inline*/ void set_klass(Klass* k);
+  inline void set_klass(Klass* k);
 
   // For klass field compression
   inline int klass_gap() const;
-  /*inline*/ void set_klass_gap(int z);
+  inline void set_klass_gap(int z);
   // For when the klass pointer is being used as a linked list "next" field.
   inline void set_klass_to_list_ptr(oop k);
   inline oop list_ptr_from_klass();
@@ -103,7 +103,7 @@
   inline bool is_a(Klass* k) const;
 
   // Returns the actual oop size of the object
-  /*inline*/ int size();
+  inline int size();
 
   // Sometimes (for complicated concurrency-related reasons), it is useful
   // to be able to figure out the size of an object knowing its klass.
@@ -111,7 +111,7 @@
 
   // type test operations (inlined in oop.inline.hpp)
   inline bool is_instance()            const;
-  /*inline*/ bool is_array()               const;
+  inline bool is_array()               const;
   inline bool is_objArray()            const;
   inline bool is_typeArray()           const;
 
@@ -149,15 +149,15 @@
   // These are overloaded for oop and narrowOop as are the other functions
   // below so that they can be called in template functions.
   static inline oop decode_heap_oop_not_null(oop v) { return v; }
-  static /*inline*/ oop decode_heap_oop_not_null(narrowOop v);
+  static inline oop decode_heap_oop_not_null(narrowOop v);
   static inline oop decode_heap_oop(oop v) { return v; }
-  static /*inline*/ oop decode_heap_oop(narrowOop v);
+  static inline oop decode_heap_oop(narrowOop v);
 
   // Encode an oop pointer to a narrow oop. The or_null versions accept
   // null oop pointer, others do not in order to eliminate the
   // null checking branches.
   static inline narrowOop encode_heap_oop_not_null(oop v);
-  static /*inline*/ narrowOop encode_heap_oop(oop v);
+  static inline narrowOop encode_heap_oop(oop v);
 
   // Load an oop out of the Java heap as is without decoding.
   // Called by GC to check for null before decoding.
@@ -284,8 +284,8 @@
   inline bool has_bias_pattern() const;
 
   // asserts
-  /*inline*/ bool is_oop(bool ignore_mark_word = false) const;
-  /*inline*/ bool is_oop_or_null(bool ignore_mark_word = false) const;
+  inline bool is_oop(bool ignore_mark_word = false) const;
+  inline bool is_oop_or_null(bool ignore_mark_word = false) const;
 #ifndef PRODUCT
   inline bool is_unlocked_oop() const;
 #endif
@@ -312,7 +312,7 @@
   inline oop forwardee() const;
 
   // Age of object during scavenge
-  /*inline*/ uint age() const;
+  inline uint age() const;
   inline void incr_age();
 
   // mark-sweep support
@@ -330,8 +330,8 @@
   inline int  ms_adjust_pointers();
 #if INCLUDE_ALL_GCS
   // Parallel Compact
-  inline void pc_follow_contents(ParCompactionManager* pc);
-  inline void pc_update_contents();
+  inline void pc_follow_contents(ParCompactionManager* cm);
+  inline void pc_update_contents(ParCompactionManager* cm);
   // Parallel Scavenge
   inline void ps_push_contents(PSPromotionManager* pm);
 #endif
--- a/src/share/vm/oops/oop.inline.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/oops/oop.inline.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -100,7 +100,7 @@
   set_mark(markOopDesc::prototype_for_object(this));
 }
 
-inline Klass* oopDesc::klass() const {
+Klass* oopDesc::klass() const {
   if (UseCompressedClassPointers) {
     return Klass::decode_klass_not_null(_metadata._compressed_klass);
   } else {
@@ -129,7 +129,7 @@
   return &_metadata._compressed_klass;
 }
 
-inline void oopDesc::set_klass(Klass* k) {
+void oopDesc::set_klass(Klass* k) {
   // since klasses are promoted no store check is needed
   assert(Universe::is_bootstrapping() || k != NULL, "must be a real Klass*");
   assert(Universe::is_bootstrapping() || k->is_klass(), "not a Klass*");
@@ -144,7 +144,7 @@
   return *(int*)(((intptr_t)this) + klass_gap_offset_in_bytes());
 }
 
-inline void oopDesc::set_klass_gap(int v) {
+void oopDesc::set_klass_gap(int v) {
   if (UseCompressedClassPointers) {
     *(int*)(((intptr_t)this) + klass_gap_offset_in_bytes()) = v;
   }
@@ -174,7 +174,7 @@
   return klass()->is_subtype_of(k);
 }
 
-inline int oopDesc::size()  {
+int oopDesc::size()  {
   return size_given_klass(klass());
 }
 
@@ -264,7 +264,7 @@
 }
 
 bool oopDesc::is_instance()  const { return klass()->is_instance_klass();  }
-inline bool oopDesc::is_array()     const { return klass()->is_array_klass();     }
+bool oopDesc::is_array()     const { return klass()->is_array_klass();     }
 bool oopDesc::is_objArray()  const { return klass()->is_objArray_klass();  }
 bool oopDesc::is_typeArray() const { return klass()->is_typeArray_klass(); }
 
@@ -298,7 +298,7 @@
   return cast_from_oop<intptr_t>(obj) % MinObjAlignmentInBytes == 0;
 }
 
-inline oop oopDesc::decode_heap_oop_not_null(narrowOop v) {
+oop oopDesc::decode_heap_oop_not_null(narrowOop v) {
   assert(!is_null(v), "narrow oop value can never be zero");
   address base = Universe::narrow_oop_base();
   int    shift = Universe::narrow_oop_shift();
@@ -307,7 +307,7 @@
   return result;
 }
 
-inline oop oopDesc::decode_heap_oop(narrowOop v) {
+oop oopDesc::decode_heap_oop(narrowOop v) {
   return is_null(v) ? (oop)NULL : decode_heap_oop_not_null(v);
 }
 
@@ -325,7 +325,7 @@
   return (narrowOop)result;
 }
 
-inline narrowOop oopDesc::encode_heap_oop(oop v) {
+narrowOop oopDesc::encode_heap_oop(oop v) {
   return (is_null(v)) ? (narrowOop)0 : encode_heap_oop_not_null(v);
 }
 
@@ -516,7 +516,7 @@
 }
 
 // used only for asserts
-inline bool oopDesc::is_oop(bool ignore_mark_word) const {
+bool oopDesc::is_oop(bool ignore_mark_word) const {
   oop obj = (oop) this;
   if (!check_obj_alignment(obj)) return false;
   if (!Universe::heap()->is_in_reserved(obj)) return false;
@@ -538,7 +538,7 @@
 
 
 // used only for asserts
-inline bool oopDesc::is_oop_or_null(bool ignore_mark_word) const {
+bool oopDesc::is_oop_or_null(bool ignore_mark_word) const {
   return this == NULL ? true : is_oop(ignore_mark_word);
 }
 
@@ -620,7 +620,7 @@
 }
 
 // The following method needs to be MT safe.
-inline uint oopDesc::age() const {
+uint oopDesc::age() const {
   assert(!is_forwarded(), "Attempt to read age from forwarded mark");
   if (has_displaced_mark()) {
     return displaced_mark()->age();
@@ -650,11 +650,11 @@
   klass()->oop_pc_follow_contents(this, cm);
 }
 
-void oopDesc::pc_update_contents() {
+void oopDesc::pc_update_contents(ParCompactionManager* cm) {
   Klass* k = klass();
   if (!k->is_typeArray_klass()) {
     // It might contain oops beyond the header, so take the virtual call.
-    k->oop_pc_update_pointers(this);
+    k->oop_pc_update_pointers(this, cm);
   }
   // Else skip it.  The TypeArrayKlass in the header never needs scavenging.
 }
--- a/src/share/vm/oops/symbol.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/oops/symbol.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -42,20 +42,19 @@
 }
 
 void* Symbol::operator new(size_t sz, int len, TRAPS) throw() {
-  int alloc_size = size(len)*HeapWordSize;
+  int alloc_size = size(len)*wordSize;
   address res = (address) AllocateHeap(alloc_size, mtSymbol);
   return res;
 }
 
 void* Symbol::operator new(size_t sz, int len, Arena* arena, TRAPS) throw() {
-  int alloc_size = size(len)*HeapWordSize;
-  address res = (address)arena->Amalloc(alloc_size);
+  int alloc_size = size(len)*wordSize;
+  address res = (address)arena->Amalloc_4(alloc_size);
   return res;
 }
 
 void* Symbol::operator new(size_t sz, int len, ClassLoaderData* loader_data, TRAPS) throw() {
   address res;
-  int alloc_size = size(len)*HeapWordSize;
   res = (address) Metaspace::allocate(loader_data, size(len), true,
                                       MetaspaceObj::SymbolType, CHECK_NULL);
   return res;
--- a/src/share/vm/oops/symbol.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/oops/symbol.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -125,8 +125,8 @@
   };
 
   static int size(int length) {
-    size_t sz = heap_word_size(sizeof(Symbol) + (length > 2 ? length - 2 : 0));
-    return align_object_size(sz);
+    // minimum number of natural words needed to hold these bits (no non-heap version)
+    return (int)heap_word_size(sizeof(Symbol) + (length > 2 ? length - 2 : 0));
   }
 
   void byte_at_put(int index, int value) {
--- a/src/share/vm/oops/typeArrayKlass.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/oops/typeArrayKlass.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -81,7 +81,7 @@
   void oop_ps_push_contents(  oop obj, PSPromotionManager* pm);
   // Parallel Compact
   void oop_pc_follow_contents(oop obj, ParCompactionManager* cm);
-  void oop_pc_update_pointers(oop obj);
+  void oop_pc_update_pointers(oop obj, ParCompactionManager* cm);
 #endif
 
   // Oop iterators. Since there are no oops in TypeArrayKlasses,
@@ -133,7 +133,7 @@
   static const char* external_name(BasicType type);
 
   // Sizing
-  static int header_size()  { return sizeof(TypeArrayKlass)/HeapWordSize; }
+  static int header_size()  { return sizeof(TypeArrayKlass)/wordSize; }
   int size() const          { return ArrayKlass::static_size(header_size()); }
 
   // Initialization (virtual from Klass)
--- a/src/share/vm/opto/library_call.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/opto/library_call.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -3822,8 +3822,8 @@
   assert(vtable_index >= 0 || vtable_index == Method::nonvirtual_vtable_index,
          "bad index %d", vtable_index);
   // Get the Method* out of the appropriate vtable entry.
-  int entry_offset  = (InstanceKlass::vtable_start_offset() +
-                     vtable_index*vtableEntry::size()) * wordSize +
+  int entry_offset  = in_bytes(Klass::vtable_start_offset()) +
+                     vtable_index*vtableEntry::size_in_bytes() +
                      vtableEntry::method_offset_in_bytes();
   Node* entry_addr  = basic_plus_adr(obj_klass, entry_offset);
   Node* target_call = make_load(NULL, entry_addr, TypePtr::NOTNULL, T_ADDRESS, MemNode::unordered);
--- a/src/share/vm/prims/jni.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/prims/jni.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1131,11 +1131,7 @@
       assert(m->valid_vtable_index(), "no valid vtable index");
       int vtbl_index = m->vtable_index();
       if (vtbl_index != Method::nonvirtual_vtable_index) {
-        Klass* k = h_recv->klass();
-        // k might be an arrayKlassOop but all vtables start at
-        // the same place. The cast is to avoid virtual call and assertion.
-        InstanceKlass *ik = (InstanceKlass*)k;
-        selected_method = ik->method_at_vtable(vtbl_index);
+        selected_method = h_recv->klass()->method_at_vtable(vtbl_index);
       } else {
         // final method
         selected_method = m;
--- a/src/share/vm/runtime/arguments.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/runtime/arguments.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -83,6 +83,7 @@
 int    Arguments::_num_jvm_args                 = 0;
 char*  Arguments::_java_command                 = NULL;
 SystemProperty* Arguments::_system_properties   = NULL;
+const char*  Arguments::_gc_log_filename        = NULL;
 bool   Arguments::_has_profile                  = false;
 size_t Arguments::_conservative_max_heap_alignment = 0;
 size_t Arguments::_min_heap_size                = 0;
@@ -3090,6 +3091,10 @@
     // -Xnoagent
     } else if (match_option(option, "-Xnoagent")) {
       // For compatibility with classic. HotSpot refuses to load the old style agent.dll.
+    } else if (match_option(option, "-Xloggc:", &tail)) {
+      // Deprecated flag to redirect GC output to a file. -Xloggc:<filename>
+      log_warning(gc)("-Xloggc is deprecated. Will use -Xlog:gc:%s instead.", tail);
+      _gc_log_filename = os::strdup_check_oom(tail);
     } else if (match_option(option, "-Xlog", &tail)) {
       bool ret = false;
       if (strcmp(tail, ":help") == 0) {
@@ -3999,6 +4004,24 @@
   }
 }
 
+bool Arguments::handle_deprecated_print_gc_flags() {
+  if (PrintGC) {
+    log_warning(gc)("-XX:+PrintGC is deprecated. Will use -Xlog:gc instead.");
+  }
+  if (PrintGCDetails) {
+    log_warning(gc)("-XX:+PrintGCDetails is deprecated. Will use -Xlog:gc* instead.");
+  }
+
+  if (_gc_log_filename != NULL) {
+    // -Xloggc was used to specify a filename
+    const char* gc_conf = PrintGCDetails ? "gc*" : "gc";
+    return  LogConfiguration::parse_log_arguments(_gc_log_filename, gc_conf, NULL, NULL, NULL);
+  } else if (PrintGC || PrintGCDetails) {
+    LogConfiguration::configure_stdout(LogLevel::Info, !PrintGCDetails, LOG_TAGS(gc));
+  }
+  return true;
+}
+
 // Parse entry point called from JNI_CreateJavaVM
 
 jint Arguments::parse(const JavaVMInitArgs* initial_cmd_args) {
@@ -4147,6 +4170,10 @@
     ScavengeRootsInCode = 1;
   }
 
+  if (!handle_deprecated_print_gc_flags()) {
+    return JNI_EINVAL;
+  }
+
   // Set object alignment values.
   set_object_alignment();
 
--- a/src/share/vm/runtime/arguments.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/runtime/arguments.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -294,6 +294,7 @@
 
   // Option flags
   static bool   _has_profile;
+  static const char*  _gc_log_filename;
   // Value of the conservative maximum heap alignment needed
   static size_t  _conservative_max_heap_alignment;
 
@@ -400,6 +401,8 @@
   static jint match_special_option_and_act(const JavaVMInitArgs* args,
                                            ScopedVMInitArgs* args_out);
 
+  static bool handle_deprecated_print_gc_flags();
+
   static jint parse_vm_init_args(const JavaVMInitArgs *java_tool_options_args,
                                  const JavaVMInitArgs *java_options_args,
                                  const JavaVMInitArgs *cmd_line_args);
--- a/src/share/vm/runtime/globals.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/runtime/globals.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -2388,6 +2388,14 @@
           "will sleep while yielding before giving up and resuming GC")     \
           range(0, max_juint)                                               \
                                                                             \
+  product(bool, PrintGC, false,                                             \
+          "Print message at garbage collection. "                           \
+          "Deprecated, use -Xlog:gc instead.")                              \
+                                                                            \
+  product(bool, PrintGCDetails, false,                                      \
+          "Print more details at garbage collection. "                      \
+          "Deprecated, use -Xlog:gc* instead.")                             \
+                                                                            \
   develop(intx, ConcGCYieldTimeout, 0,                                      \
           "If non-zero, assert that GC threads yield within this "          \
           "number of milliseconds")                                         \
@@ -3249,7 +3257,7 @@
                                                                             \
   product(size_t, MinTLABSize, 2*K,                                         \
           "Minimum allowed TLAB size (in bytes)")                           \
-          range(1, max_uintx)                                               \
+          range(1, max_uintx/2)                                             \
           constraint(MinTLABSizeConstraintFunc,AfterMemoryInit)             \
                                                                             \
   product(size_t, TLABSize, 0,                                              \
@@ -3392,10 +3400,10 @@
           "also has a smaller default value; see arguments.cpp.")           \
           range(0, 100)                                                     \
                                                                             \
-  product(uintx, MarkSweepAlwaysCompactCount,     4,                        \
+  product(uint, MarkSweepAlwaysCompactCount,     4,                         \
           "How often should we fully compact the heap (ignoring the dead "  \
           "space parameters)")                                              \
-          range(1, max_uintx)                                               \
+          range(1, max_juint)                                               \
                                                                             \
   develop(uintx, GCExpandToAllocateDelayMillis, 0,                          \
           "Delay between expansion and allocation (in milliseconds)")       \
--- a/src/share/vm/runtime/reflection.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/runtime/reflection.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -939,10 +939,7 @@
         int index = reflected_method->vtable_index();
         method = reflected_method;
         if (index != Method::nonvirtual_vtable_index) {
-          // target_klass might be an arrayKlassOop but all vtables start at
-          // the same place. The cast is to avoid virtual call and assertion.
-          InstanceKlass* inst = (InstanceKlass*)target_klass();
-          method = methodHandle(THREAD, inst->method_at_vtable(index));
+          method = methodHandle(THREAD, target_klass->method_at_vtable(index));
         }
         if (!method.is_null()) {
           // Check for abstract methods as well
--- a/src/share/vm/runtime/vmStructs.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/runtime/vmStructs.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -298,7 +298,6 @@
   nonstatic_field(ArrayKlass,                  _dimension,                                    int)                                   \
   volatile_nonstatic_field(ArrayKlass,         _higher_dimension,                             Klass*)                                \
   volatile_nonstatic_field(ArrayKlass,         _lower_dimension,                              Klass*)                                \
-  nonstatic_field(ArrayKlass,                  _vtable_len,                                   int)                                   \
   nonstatic_field(CompiledICHolder,            _holder_method,                                Method*)                               \
   nonstatic_field(CompiledICHolder,            _holder_klass,                                 Klass*)                                \
   nonstatic_field(ConstantPool,                _tags,                                         Array<u1>*)                            \
@@ -332,7 +331,6 @@
   nonstatic_field(InstanceKlass,               _major_version,                                u2)                                    \
   nonstatic_field(InstanceKlass,               _init_state,                                   u1)                                    \
   nonstatic_field(InstanceKlass,               _init_thread,                                  Thread*)                               \
-  nonstatic_field(InstanceKlass,               _vtable_len,                                   int)                                   \
   nonstatic_field(InstanceKlass,               _itable_len,                                   int)                                   \
   nonstatic_field(InstanceKlass,               _reference_type,                               u1)                                    \
   volatile_nonstatic_field(InstanceKlass,      _oop_map_cache,                                OopMapCache*)                          \
@@ -358,6 +356,7 @@
   nonstatic_field(Klass,                       _access_flags,                                 AccessFlags)                           \
   nonstatic_field(Klass,                       _prototype_header,                             markOop)                               \
   nonstatic_field(Klass,                       _next_sibling,                                 Klass*)                                \
+  nonstatic_field(Klass,                       _vtable_len,                                   int)                                \
   nonstatic_field(vtableEntry,                 _method,                                       Method*)                               \
   nonstatic_field(MethodData,                  _size,                                         int)                                   \
   nonstatic_field(MethodData,                  _method,                                       Method*)                               \
--- a/src/share/vm/shark/sharkTopLevelBlock.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/shark/sharkTopLevelBlock.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2008, 2009, 2010 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -1143,8 +1143,8 @@
     builder()->CreateArrayAddress(
       klass,
       SharkType::Method_type(),
-      vtableEntry::size() * wordSize,
-      in_ByteSize(InstanceKlass::vtable_start_offset() * wordSize),
+      vtableEntry::size_in_bytes(),
+      Klass::vtable_start_offset(),
       LLVMValue::intptr_constant(vtable_index)),
     "callee");
 }
@@ -1166,12 +1166,12 @@
   Value *vtable_start = builder()->CreateAdd(
     builder()->CreatePtrToInt(object_klass, SharkType::intptr_type()),
     LLVMValue::intptr_constant(
-      InstanceKlass::vtable_start_offset() * HeapWordSize),
+      in_bytes(Klass::vtable_start_offset())),
     "vtable_start");
 
   Value *vtable_length = builder()->CreateValueOfStructEntry(
     object_klass,
-    in_ByteSize(InstanceKlass::vtable_length_offset() * HeapWordSize),
+    Klass::vtable_length_offset(),
     SharkType::jint_type(),
     "vtable_length");
   vtable_length =
@@ -1182,7 +1182,7 @@
     vtable_start,
     builder()->CreateShl(
       vtable_length,
-      LLVMValue::intptr_constant(exact_log2(vtableEntry::size() * wordSize))),
+      LLVMValue::intptr_constant(exact_log2(vtableEntry::size_in_bytes()))),
     needs_aligning ? "" : "itable_start");
   if (needs_aligning) {
     itable_start = builder()->CreateAnd(
--- a/src/share/vm/utilities/debug.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/utilities/debug.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -461,7 +461,7 @@
 extern "C" void dump_vtable(address p) {
   Command c("dump_vtable");
   Klass* k = (Klass*)p;
-  InstanceKlass::cast(k)->vtable()->print();
+  k->vtable()->print();
 }
 
 
--- a/src/share/vm/utilities/globalDefinitions.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/utilities/globalDefinitions.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -85,6 +85,8 @@
   assert( 1 == sizeof( u1),        "wrong size for basic type");
   assert( 2 == sizeof( u2),        "wrong size for basic type");
   assert( 4 == sizeof( u4),        "wrong size for basic type");
+  assert(wordSize == BytesPerWord, "should be the same since they're used interchangeably");
+  assert(wordSize == HeapWordSize, "should be the same since they're also used interchangeably");
 
   int num_type_chars = 0;
   for (int i = 0; i < 99; i++) {
--- a/src/share/vm/utilities/globalDefinitions.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/utilities/globalDefinitions.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -157,7 +157,6 @@
 // Analogous opaque struct for metadata allocated from
 // metaspaces.
 class MetaWord {
-  friend class VMStructs;
  private:
   char* i;
 };
@@ -486,7 +485,7 @@
 
 #define is_size_aligned_(size, alignment) ((size) == (align_size_up_(size, alignment)))
 
-inline void* align_ptr_up(void* ptr, size_t alignment) {
+inline void* align_ptr_up(const void* ptr, size_t alignment) {
   return (void*)align_size_up((intptr_t)ptr, (intptr_t)alignment);
 }
 
@@ -494,10 +493,15 @@
   return (void*)align_size_down((intptr_t)ptr, (intptr_t)alignment);
 }
 
-// Align objects by rounding up their size, in HeapWord units.
+// Align metaspace objects by rounding up to natural word boundary
 
-#define align_object_size_(size) align_size_up_(size, MinObjAlignment)
+inline intptr_t align_metadata_size(intptr_t size) {
+  return align_size_up(size, 1);
+}
 
+// Align objects in the Java Heap by rounding up their size, in HeapWord units.
+// Since the size is given in words this is somewhat of a nop, but
+// distinguishes it from align_object_size.
 inline intptr_t align_object_size(intptr_t size) {
   return align_size_up(size, MinObjAlignment);
 }
@@ -512,10 +516,6 @@
   return align_size_up(offset, HeapWordsPerLong);
 }
 
-inline void* align_pointer_up(const void* addr, size_t size) {
-  return (void*) align_size_up_((uintptr_t)addr, size);
-}
-
 // Align down with a lower bound. If the aligning results in 0, return 'alignment'.
 
 inline size_t align_size_down_bounded(size_t size, size_t alignment) {
--- a/src/share/vm/utilities/growableArray.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/utilities/growableArray.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -169,7 +169,9 @@
     : GenericGrowableArray(initial_size, 0, C_heap, F) {
     _data = (E*)raw_allocate(sizeof(E));
 // Needed for Visual Studio 2012 and older
+#ifdef _MSC_VER
 #pragma warning(suppress: 4345)
+#endif
     for (int i = 0; i < _max; i++) ::new ((void*)&_data[i]) E();
   }
 
@@ -422,7 +424,9 @@
     int i = 0;
     for (     ; i < _len; i++) ::new ((void*)&newData[i]) E(_data[i]);
 // Needed for Visual Studio 2012 and older
+#ifdef _MSC_VER
 #pragma warning(suppress: 4345)
+#endif
     for (     ; i < _max; i++) ::new ((void*)&newData[i]) E();
     for (i = 0; i < old_max; i++) _data[i].~E();
     if (on_C_heap() && _data != NULL) {
--- a/src/share/vm/utilities/internalVMTests.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/utilities/internalVMTests.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -53,6 +53,7 @@
 void TestResourcehash_test();
 void TestChunkedList_test();
 void Test_log_length();
+void Test_configure_stdout();
 void Test_TempNewSymbol();
 void GlobalDefinitions_test();
 void GCTimer_test();
@@ -110,6 +111,7 @@
   run_unit_test(TestChunkedList_test());
   run_unit_test(JSON_test());
   run_unit_test(Test_log_length());
+  run_unit_test(Test_configure_stdout());
   run_unit_test(DirectivesParser_test());
   run_unit_test(Test_TempNewSymbol());
 #if INCLUDE_VM_STRUCTS
--- a/src/share/vm/utilities/ostream.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/utilities/ostream.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -44,6 +44,8 @@
   _newlines    = 0;
   _precount    = 0;
   _indentation = 0;
+  _scratch     = NULL;
+  _scratch_len = 0;
 }
 
 outputStream::outputStream(int width, bool has_time_stamps) {
@@ -52,6 +54,8 @@
   _newlines    = 0;
   _precount    = 0;
   _indentation = 0;
+  _scratch     = NULL;
+  _scratch_len = 0;
   if (has_time_stamps)  _stamp.update();
 }
 
@@ -119,38 +123,47 @@
   return result;
 }
 
+void outputStream::do_vsnprintf_and_write_with_automatic_buffer(const char* format, va_list ap, bool add_cr) {
+  char buffer[O_BUFLEN];
+  size_t len;
+  const char* str = do_vsnprintf(buffer, sizeof(buffer), format, ap, add_cr, len);
+  write(str, len);
+}
+
+void outputStream::do_vsnprintf_and_write_with_scratch_buffer(const char* format, va_list ap, bool add_cr) {
+  size_t len;
+  const char* str = do_vsnprintf(_scratch, _scratch_len, format, ap, add_cr, len);
+  write(str, len);
+}
+
+void outputStream::do_vsnprintf_and_write(const char* format, va_list ap, bool add_cr) {
+  if (_scratch) {
+    do_vsnprintf_and_write_with_scratch_buffer(format, ap, add_cr);
+  } else {
+    do_vsnprintf_and_write_with_automatic_buffer(format, ap, add_cr);
+  }
+}
+
 void outputStream::print(const char* format, ...) {
-  char buffer[O_BUFLEN];
   va_list ap;
   va_start(ap, format);
-  size_t len;
-  const char* str = do_vsnprintf(buffer, O_BUFLEN, format, ap, false, len);
-  write(str, len);
+  do_vsnprintf_and_write(format, ap, false);
   va_end(ap);
 }
 
 void outputStream::print_cr(const char* format, ...) {
-  char buffer[O_BUFLEN];
   va_list ap;
   va_start(ap, format);
-  size_t len;
-  const char* str = do_vsnprintf(buffer, O_BUFLEN, format, ap, true, len);
-  write(str, len);
+  do_vsnprintf_and_write(format, ap, true);
   va_end(ap);
 }
 
 void outputStream::vprint(const char *format, va_list argptr) {
-  char buffer[O_BUFLEN];
-  size_t len;
-  const char* str = do_vsnprintf(buffer, O_BUFLEN, format, argptr, false, len);
-  write(str, len);
+  do_vsnprintf_and_write(format, argptr, false);
 }
 
 void outputStream::vprint_cr(const char* format, va_list argptr) {
-  char buffer[O_BUFLEN];
-  size_t len;
-  const char* str = do_vsnprintf(buffer, O_BUFLEN, format, argptr, true, len);
-  write(str, len);
+  do_vsnprintf_and_write(format, argptr, true);
 }
 
 void outputStream::fill_to(int col) {
@@ -958,53 +971,6 @@
   }
 }
 
-staticBufferStream::staticBufferStream(char* buffer, size_t buflen,
-                                       outputStream *outer_stream) {
-  _buffer = buffer;
-  _buflen = buflen;
-  _outer_stream = outer_stream;
-  // compile task prints time stamp relative to VM start
-  _stamp.update_to(1);
-}
-
-void staticBufferStream::write(const char* c, size_t len) {
-  _outer_stream->print_raw(c, (int)len);
-}
-
-void staticBufferStream::flush() {
-  _outer_stream->flush();
-}
-
-void staticBufferStream::print(const char* format, ...) {
-  va_list ap;
-  va_start(ap, format);
-  size_t len;
-  const char* str = do_vsnprintf(_buffer, _buflen, format, ap, false, len);
-  write(str, len);
-  va_end(ap);
-}
-
-void staticBufferStream::print_cr(const char* format, ...) {
-  va_list ap;
-  va_start(ap, format);
-  size_t len;
-  const char* str = do_vsnprintf(_buffer, _buflen, format, ap, true, len);
-  write(str, len);
-  va_end(ap);
-}
-
-void staticBufferStream::vprint(const char *format, va_list argptr) {
-  size_t len;
-  const char* str = do_vsnprintf(_buffer, _buflen, format, argptr, false, len);
-  write(str, len);
-}
-
-void staticBufferStream::vprint_cr(const char* format, va_list argptr) {
-  size_t len;
-  const char* str = do_vsnprintf(_buffer, _buflen, format, argptr, true, len);
-  write(str, len);
-}
-
 bufferedStream::bufferedStream(size_t initial_size, size_t bufmax) : outputStream() {
   buffer_length = initial_size;
   buffer        = NEW_C_HEAP_ARRAY(char, buffer_length, mtInternal);
@@ -1133,7 +1099,7 @@
 void logStream::write(const char* s, size_t len) {
   if (len > 0 && s[len - 1] == '\n') {
     _current_line.write(s, len - 1);
-    _log_func(_current_line.as_string());
+    _log_func("%s", _current_line.as_string());
     _current_line.reset();
   } else {
     _current_line.write(s, len);
--- a/src/share/vm/utilities/ostream.hpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/utilities/ostream.hpp	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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,7 @@
 
 #include "memory/allocation.hpp"
 #include "runtime/timer.hpp"
+#include "utilities/globalDefinitions.hpp"
 
 class GCId;
 DEBUG_ONLY(class ResourceMark;)
@@ -49,6 +50,8 @@
    int _newlines;    // number of '\n' output so far
    julong _precount; // number of chars output, less _position
    TimeStamp _stamp; // for time stamps
+   char* _scratch;   // internal scratch buffer for printf
+   size_t _scratch_len; // size of internal scratch buffer
 
    void update_position(const char* s, size_t len);
    static const char* do_vsnprintf(char* buffer, size_t buflen,
@@ -56,6 +59,13 @@
                                    bool add_cr,
                                    size_t& result_len)  ATTRIBUTE_PRINTF(3, 0);
 
+   // calls do_vsnprintf and writes output to stream; uses an on-stack buffer.
+   void do_vsnprintf_and_write_with_automatic_buffer(const char* format, va_list ap, bool add_cr) ATTRIBUTE_PRINTF(2, 0);
+   // calls do_vsnprintf and writes output to stream; uses the user-provided buffer;
+   void do_vsnprintf_and_write_with_scratch_buffer(const char* format, va_list ap, bool add_cr) ATTRIBUTE_PRINTF(2, 0);
+   // calls do_vsnprintf, then writes output to stream.
+   void do_vsnprintf_and_write(const char* format, va_list ap, bool add_cr) ATTRIBUTE_PRINTF(2, 0);
+
  public:
    // creation
    outputStream(int width = 80);
@@ -119,6 +129,10 @@
    virtual void rotate_log(bool force, outputStream* out = NULL) {} // GC log rotation
    virtual ~outputStream() {}   // close properly on deletion
 
+   // Caller may specify their own scratch buffer to use for printing; otherwise,
+   // an automatic buffer on the stack (with O_BUFLEN len) is used.
+   void set_scratch_buffer(char* p, size_t len) { _scratch = p; _scratch_len = len; }
+
    void dec_cr() { dec(); cr(); }
    void inc_cr() { inc(); cr(); }
 };
@@ -236,7 +250,7 @@
 class logStream : public outputStream {
 private:
   stringStream _current_line;
-  void (*_log_func)(const char* fmt, ...);
+  void (*_log_func)(const char* fmt, ...) ATTRIBUTE_PRINTF(1, 2);
 public:
   void write(const char* s, size_t len);
   logStream(void (*log_func)(const char* fmt, ...)) : _log_func(log_func) {}
@@ -250,26 +264,6 @@
 void ostream_exit();
 void ostream_abort();
 
-// staticBufferStream uses a user-supplied buffer for all formatting.
-// Used for safe formatting during fatal error handling.  Not MT safe.
-// Do not share the stream between multiple threads.
-class staticBufferStream : public outputStream {
- private:
-  char* _buffer;
-  size_t _buflen;
-  outputStream* _outer_stream;
- public:
-  staticBufferStream(char* buffer, size_t buflen,
-                     outputStream *outer_stream);
-  ~staticBufferStream() {};
-  virtual void write(const char* c, size_t len);
-  void flush();
-  void print(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
-  void print_cr(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
-  void vprint(const char *format, va_list argptr) ATTRIBUTE_PRINTF(2, 0);
-  void vprint_cr(const char* format, va_list argptr) ATTRIBUTE_PRINTF(2, 0);
-};
-
 // In the non-fixed buffer case an underlying buffer will be created and
 // managed in C heap. Not MT-safe.
 class bufferedStream : public outputStream {
--- a/src/share/vm/utilities/vmError.cpp	Thu Jan 28 16:30:37 2016 -0800
+++ b/src/share/vm/utilities/vmError.cpp	Wed Feb 03 01:35:25 2016 +0100
@@ -987,10 +987,12 @@
 volatile intptr_t VMError::first_error_tid = -1;
 
 // An error could happen before tty is initialized or after it has been
-// destroyed. Here we use a very simple unbuffered fdStream for printing.
-// Only out.print_raw() and out.print_raw_cr() should be used, as other
-// printing methods need to allocate large buffer on stack. To format a
-// string, use jio_snprintf() with a static buffer or use staticBufferStream.
+// destroyed.
+// Please note: to prevent large stack allocations, the log- and
+// output-stream use a global scratch buffer for format printing.
+// (see VmError::report_and_die(). Access to those streams is synchronized
+// in  VmError::report_and_die() - there is only one reporting thread at
+// any given time.
 fdStream VMError::out(defaultStream::output_fd());
 fdStream VMError::log; // error log used by VMError::report_and_die()
 
@@ -1100,6 +1102,8 @@
 {
   // Don't allocate large buffer on stack
   static char buffer[O_BUFLEN];
+  out.set_scratch_buffer(buffer, sizeof(buffer));
+  log.set_scratch_buffer(buffer, sizeof(buffer));
 
   // How many errors occurred in error handler when reporting first_error.
   static int recursive_error_count;
@@ -1186,8 +1190,7 @@
 
   // print to screen
   if (!out_done) {
-    staticBufferStream sbs(buffer, sizeof(buffer), &out);
-    report(&sbs, false);
+    report(&out, false);
 
     out_done = true;
 
@@ -1215,8 +1218,7 @@
       }
     }
 
-    staticBufferStream sbs(buffer, O_BUFLEN, &log);
-    report(&sbs, true);
+    report(&log, true);
     _current_step = 0;
     _current_step_info = "";
 
--- a/test/gc/g1/TestG1TraceEagerReclaimHumongousObjects.java	Thu Jan 28 16:30:37 2016 -0800
+++ b/test/gc/g1/TestG1TraceEagerReclaimHumongousObjects.java	Wed Feb 03 01:35:25 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -38,34 +38,6 @@
 
 public class TestG1TraceEagerReclaimHumongousObjects {
   public static void main(String[] args) throws Exception {
-    testGCLogs();
-    testHumongousObjectGCLogs();
-  }
-
-  private static void testGCLogs() throws Exception {
-
-    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
-                                               "-Xms128M",
-                                               "-Xmx128M",
-                                               "-Xmn16M",
-                                               "-XX:G1HeapRegionSize=1M",
-                                               "-Xlog:gc+phases=trace",
-                                               "-XX:+UnlockExperimentalVMOptions",
-                                               GCTest.class.getName());
-
-    OutputAnalyzer output = new OutputAnalyzer(pb.start());
-
-    // As G1EagerReclaimHumongousObjects is set(default), below logs should be displayed.
-    // And GCTest doesn't have humongous objects, so values should be zero.
-    output.shouldContain("Humongous Reclaim");
-    output.shouldContain("Humongous Total: 0");
-    output.shouldContain("Humongous Candidate: 0");
-    output.shouldContain("Humongous Reclaimed: 0");
-
-    output.shouldHaveExitValue(0);
-  }
-
-  private static void testHumongousObjectGCLogs() throws Exception {
     ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
                                                "-Xms128M",
                                                "-Xmx128M",
@@ -90,19 +62,6 @@
     output.shouldHaveExitValue(0);
   }
 
-  static class GCTest {
-    private static byte[] garbage;
-
-    public static void main(String [] args) {
-      System.out.println("Creating garbage");
-      // create 128MB of garbage. This should result in at least one GC
-      for (int i = 0; i < 1024; i++) {
-        garbage = new byte[128 * 1024];
-      }
-      System.out.println("Done");
-    }
-  }
-
   static class GCWithHumongousObjectTest {
 
     public static final int M = 1024*1024;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/gc/g1/plab/TestPLABPromotion.java	Wed Feb 03 01:35:25 2016 +0100
@@ -0,0 +1,327 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /*
+ * @test TestPLABPromotion
+ * @bug 8141278
+ * @summary Test PLAB promotion
+ * @requires vm.gc=="G1" | vm.gc=="null"
+ * @library /testlibrary /../../test/lib /
+ * @modules java.management
+ * @build ClassFileInstaller
+ *        sun.hotspot.WhiteBox
+ *        gc.g1.plab.lib.MemoryConsumer
+ *        gc.g1.plab.lib.LogParser
+ *        gc.g1.plab.lib.AppPLABPromotion
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main gc.g1.plab.TestPLABPromotion
+ */
+package gc.g1.plab;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Arrays;
+import java.io.PrintStream;
+
+import gc.g1.plab.lib.AppPLABPromotion;
+import gc.g1.plab.lib.LogParser;
+import gc.g1.plab.lib.PLABUtils;
+
+import jdk.test.lib.OutputAnalyzer;
+import jdk.test.lib.ProcessTools;
+import jdk.test.lib.Platform;
+
+/**
+ * Test checks PLAB promotion of different size objects.
+ */
+public class TestPLABPromotion {
+
+    // GC ID with survivor PLAB statistics
+    private final static long GC_ID_SURVIVOR_STATS = 1l;
+    // GC ID with old PLAB statistics
+    private final static long GC_ID_OLD_STATS = 2l;
+
+    // Threshold to determine whether the correct amount of objects were promoted.
+    // This is only an approximate threshold for these checks.
+    private final static long MEM_CONSUMPTION_THRESHOLD = 256l * 1024l;
+
+    private static final int PLAB_SIZE_SMALL = 1024;
+    private static final int PLAB_SIZE_MEDIUM = 4096;
+    private static final int PLAB_SIZE_HIGH = 65536;
+    private static final int OBJECT_SIZE_SMALL = 10;
+    private static final int OBJECT_SIZE_MEDIUM = 100;
+    private static final int OBJECT_SIZE_HIGH = 1000;
+    private static final int GC_NUM_SMALL = 1;
+    private static final int GC_NUM_MEDIUM = 3;
+    private static final int GC_NUM_HIGH = 7;
+    private static final int WASTE_PCT_SMALL = 10;
+    private static final int WASTE_PCT_MEDIUM = 20;
+    private static final int WASTE_PCT_HIGH = 30;
+    private static final int YOUNG_SIZE_LOW = 16;
+    private static final int YOUNG_SIZE_HIGH = 64;
+    private static final boolean PLAB_FIXED = true;
+    private static final boolean PLAB_DYNAMIC = false;
+
+    private final static TestCase[] TEST_CASES = {
+        // Test cases for unreachable object, PLAB size is fixed
+        new TestCase(WASTE_PCT_SMALL, PLAB_SIZE_SMALL, OBJECT_SIZE_MEDIUM, GC_NUM_SMALL, YOUNG_SIZE_LOW, PLAB_FIXED, false, false),
+        new TestCase(WASTE_PCT_HIGH, PLAB_SIZE_MEDIUM, OBJECT_SIZE_SMALL, GC_NUM_HIGH, YOUNG_SIZE_HIGH, PLAB_FIXED, false, false),
+        // Test cases for reachable objects, PLAB size is fixed
+        new TestCase(WASTE_PCT_SMALL, PLAB_SIZE_SMALL, OBJECT_SIZE_SMALL, GC_NUM_HIGH, YOUNG_SIZE_HIGH, PLAB_FIXED, true, true),
+        new TestCase(WASTE_PCT_SMALL, PLAB_SIZE_MEDIUM, OBJECT_SIZE_MEDIUM, GC_NUM_SMALL, YOUNG_SIZE_LOW, PLAB_FIXED, true, true),
+        new TestCase(WASTE_PCT_SMALL, PLAB_SIZE_SMALL, OBJECT_SIZE_HIGH, GC_NUM_MEDIUM, YOUNG_SIZE_LOW, PLAB_FIXED, true, false),
+        new TestCase(WASTE_PCT_MEDIUM, PLAB_SIZE_HIGH, OBJECT_SIZE_SMALL, GC_NUM_HIGH, YOUNG_SIZE_HIGH, PLAB_FIXED, true, true),
+        new TestCase(WASTE_PCT_MEDIUM, PLAB_SIZE_SMALL, OBJECT_SIZE_MEDIUM, GC_NUM_SMALL, YOUNG_SIZE_LOW, PLAB_FIXED, true, true),
+        new TestCase(WASTE_PCT_MEDIUM, PLAB_SIZE_MEDIUM, OBJECT_SIZE_HIGH, GC_NUM_MEDIUM, YOUNG_SIZE_LOW, PLAB_FIXED, true, true),
+        new TestCase(WASTE_PCT_HIGH, PLAB_SIZE_SMALL, OBJECT_SIZE_SMALL, GC_NUM_HIGH, YOUNG_SIZE_HIGH, PLAB_FIXED, true, true),
+        new TestCase(WASTE_PCT_HIGH, PLAB_SIZE_HIGH, OBJECT_SIZE_MEDIUM, GC_NUM_SMALL, YOUNG_SIZE_LOW, PLAB_FIXED, true, true),
+        new TestCase(WASTE_PCT_HIGH, PLAB_SIZE_SMALL, OBJECT_SIZE_HIGH, GC_NUM_MEDIUM, YOUNG_SIZE_HIGH, PLAB_FIXED, true, false),
+        // Test cases for unreachable object, PLAB size is not fixed
+        new TestCase(WASTE_PCT_MEDIUM, PLAB_SIZE_MEDIUM, OBJECT_SIZE_SMALL, GC_NUM_HIGH, YOUNG_SIZE_LOW, PLAB_DYNAMIC, false, false),
+        // Test cases for reachable objects, PLAB size is not fixed
+        new TestCase(WASTE_PCT_SMALL, PLAB_SIZE_HIGH, OBJECT_SIZE_SMALL, GC_NUM_HIGH, YOUNG_SIZE_HIGH, PLAB_DYNAMIC, true, true),
+        new TestCase(WASTE_PCT_MEDIUM, PLAB_SIZE_MEDIUM, OBJECT_SIZE_SMALL, GC_NUM_SMALL, YOUNG_SIZE_LOW, PLAB_DYNAMIC, true, true),
+        new TestCase(WASTE_PCT_SMALL, PLAB_SIZE_MEDIUM, OBJECT_SIZE_HIGH, GC_NUM_HIGH, YOUNG_SIZE_HIGH, PLAB_DYNAMIC, true, false),
+        new TestCase(WASTE_PCT_MEDIUM, PLAB_SIZE_SMALL, OBJECT_SIZE_MEDIUM, GC_NUM_MEDIUM, YOUNG_SIZE_LOW, PLAB_DYNAMIC, true, true),
+        new TestCase(WASTE_PCT_HIGH, PLAB_SIZE_HIGH, OBJECT_SIZE_MEDIUM, GC_NUM_SMALL, YOUNG_SIZE_HIGH, PLAB_DYNAMIC, true, true),
+        new TestCase(WASTE_PCT_HIGH, PLAB_SIZE_HIGH, OBJECT_SIZE_SMALL, GC_NUM_HIGH, YOUNG_SIZE_LOW, PLAB_DYNAMIC, true, true)
+    };
+
+    public static void main(String[] args) throws Throwable {
+
+        for (TestCase testCase : TEST_CASES) {
+            // What we going to check.
+            testCase.print(System.out);
+            List<String> options = PLABUtils.prepareOptions(testCase.toOptions());
+            options.add(AppPLABPromotion.class.getName());
+            OutputAnalyzer out = ProcessTools.executeTestJvm(options.toArray(new String[options.size()]));
+            if (out.getExitValue() != 0) {
+                System.out.println(out.getOutput());
+                throw new RuntimeException("Expect exit code 0.");
+            }
+            checkResults(out.getOutput(), testCase);
+        }
+    }
+
+    private static void checkResults(String output, TestCase testCase) {
+        long plabAllocatedSurvivor;
+        long directAllocatedSurvivor;
+        long plabAllocatedOld;
+        long directAllocatedOld;
+        long memAllocated = testCase.getMemToFill();
+        long wordSize = Platform.is32bit() ? 4l : 8l;
+        LogParser logParser = new LogParser(output);
+
+        Map<String, Long> survivorStats = getPlabStats(logParser, LogParser.ReportType.SURVIVOR_STATS, GC_ID_SURVIVOR_STATS);
+        Map<String, Long> oldStats = getPlabStats(logParser, LogParser.ReportType.OLD_STATS, GC_ID_OLD_STATS);
+
+        plabAllocatedSurvivor = wordSize * survivorStats.get("used");
+        directAllocatedSurvivor = wordSize * survivorStats.get("direct_allocated");
+        plabAllocatedOld = wordSize * oldStats.get("used");
+        directAllocatedOld = wordSize * oldStats.get("direct_allocated");
+
+        System.out.printf("Survivor PLAB allocated:%17d Direct allocated: %17d Mem consumed:%17d%n", plabAllocatedSurvivor, directAllocatedSurvivor, memAllocated);
+        System.out.printf("Old      PLAB allocated:%17d Direct allocated: %17d Mem consumed:%17d%n", plabAllocatedOld, directAllocatedOld, memAllocated);
+
+        // Unreachable objects case
+        if (testCase.isDeadObjectCase()) {
+            // No dead objects should be promoted
+            if (plabAllocatedSurvivor > MEM_CONSUMPTION_THRESHOLD || directAllocatedSurvivor > MEM_CONSUMPTION_THRESHOLD) {
+                System.out.println(output);
+                throw new RuntimeException("Unreachable objects should not be allocated using PLAB or direct allocated to Survivor");
+            }
+            if (plabAllocatedOld > MEM_CONSUMPTION_THRESHOLD || directAllocatedOld > MEM_CONSUMPTION_THRESHOLD) {
+                System.out.println(output);
+                throw new RuntimeException("Unreachable objects should not be allocated using PLAB or direct allocated to Old");
+            }
+        } else {
+            // Live objects case
+            if (testCase.isPromotedByPLAB()) {
+                // All live small objects should be promoted using PLAB
+                if (Math.abs(plabAllocatedSurvivor - memAllocated) > MEM_CONSUMPTION_THRESHOLD) {
+                    System.out.println(output);
+                    throw new RuntimeException("Expect that Survivor PLAB allocation are similar to all mem consumed");
+                }
+                if (Math.abs(plabAllocatedOld - memAllocated) > MEM_CONSUMPTION_THRESHOLD) {
+                    System.out.println(output);
+                    throw new RuntimeException("Expect that Old PLAB allocation are similar to all mem consumed");
+                }
+            } else {
+                // All big objects should be directly allocated
+                if (Math.abs(directAllocatedSurvivor - memAllocated) > MEM_CONSUMPTION_THRESHOLD) {
+                    System.out.println(output);
+                    throw new RuntimeException("Test fails. Expect that Survivor direct allocation are similar to all mem consumed");
+                }
+                if (Math.abs(directAllocatedOld - memAllocated) > MEM_CONSUMPTION_THRESHOLD) {
+                    System.out.println(output);
+                    throw new RuntimeException("Test fails. Expect that Old direct allocation are similar to all mem consumed");
+                }
+            }
+
+            // All promoted objects size should be similar to all consumed memory
+            if (Math.abs(plabAllocatedSurvivor + directAllocatedSurvivor - memAllocated) > MEM_CONSUMPTION_THRESHOLD) {
+                System.out.println(output);
+                throw new RuntimeException("Test fails. Expect that Survivor gen total allocation are similar to all mem consumed");
+            }
+            if (Math.abs(plabAllocatedOld + directAllocatedOld - memAllocated) > MEM_CONSUMPTION_THRESHOLD) {
+                System.out.println(output);
+                throw new RuntimeException("Test fails. Expect that Old gen total allocation are similar to all mem consumed");
+            }
+        }
+        System.out.println("Test passed!");
+    }
+
+    private static Map<String, Long> getPlabStats(LogParser logParser, LogParser.ReportType type, long gc_id) {
+
+        Map<String, Long> survivorStats = logParser.getEntries()
+                .get(gc_id)
+                .get(type);
+        return survivorStats;
+    }
+
+    /**
+     * Description of one test case.
+     */
+    private static class TestCase {
+
+        private final int wastePct;
+        private final int plabSize;
+        private final int chunkSize;
+        private final int parGCThreads;
+        private final int edenSize;
+        private final boolean plabIsFixed;
+        private final boolean objectsAreReachable;
+        private final boolean promotedByPLAB;
+
+        /**
+         * @param wastePct
+         * ParallelGCBufferWastePct
+         * @param plabSize
+         * -XX:OldPLABSize and -XX:YoungPLABSize
+         * @param chunkSize
+         * requested object size for memory consumption
+         * @param parGCThreads
+         * -XX:ParallelGCThreads
+         * @param edenSize
+         * NewSize and MaxNewSize
+         * @param plabIsFixed
+         * Use dynamic PLAB or fixed size PLAB
+         * @param objectsAreReachable
+         * true - allocate live objects
+         * false - allocate unreachable objects
+         * @param promotedByPLAB
+         * true - we expect to see PLAB allocation during promotion
+         * false - objects will be directly allocated during promotion
+         */
+        public TestCase(int wastePct,
+                int plabSize,
+                int chunkSize,
+                int parGCThreads,
+                int edenSize,
+                boolean plabIsFixed,
+                boolean objectsAreReachable,
+                boolean promotedByPLAB
+        ) {
+            if (wastePct == 0 || plabSize == 0 || chunkSize == 0 || parGCThreads == 0 || edenSize == 0) {
+                throw new IllegalArgumentException("Parameters should not be 0");
+            }
+            this.wastePct = wastePct;
+            this.plabSize = plabSize;
+            this.chunkSize = chunkSize;
+            this.parGCThreads = parGCThreads;
+            this.edenSize = edenSize;
+            this.plabIsFixed = plabIsFixed;
+            this.objectsAreReachable = objectsAreReachable;
+            this.promotedByPLAB = promotedByPLAB;
+        }
+
+        /**
+         * Convert current TestCase to List of options.
+         * Assume test will fill half of existed eden.
+         *
+         * @return
+         * List of options
+         */
+        public List<String> toOptions() {
+            return Arrays.asList("-XX:ParallelGCThreads=" + parGCThreads,
+                    "-XX:ParallelGCBufferWastePct=" + wastePct,
+                    "-XX:OldPLABSize=" + plabSize,
+                    "-XX:YoungPLABSize=" + plabSize,
+                    "-XX:" + (plabIsFixed ? "-" : "+") + "ResizePLAB",
+                    "-Dchunk.size=" + chunkSize,
+                    "-Dreachable=" + objectsAreReachable,
+                    "-XX:NewSize=" + edenSize + "m",
+                    "-XX:MaxNewSize=" + edenSize + "m",
+                    "-Dmem.to.fill=" + getMemToFill()
+            );
+        }
+
+        /**
+         * Print details about test case.
+         */
+        public void print(PrintStream out) {
+            boolean expectPLABAllocation = promotedByPLAB && objectsAreReachable;
+            boolean expectDirectAllocation = (!promotedByPLAB) && objectsAreReachable;
+
+            out.println("Test case details:");
+            out.println("  Young gen size : " + edenSize + "M");
+            out.println("  Predefined PLAB size : " + plabSize);
+            out.println("  Parallel GC buffer waste pct : " + wastePct);
+            out.println("  Chunk size : " + chunkSize);
+            out.println("  Parallel GC threads : " + parGCThreads);
+            out.println("  Objects are created : " + (objectsAreReachable ? "reachable" : "unreachable"));
+            out.println("  PLAB size is fixed: " + (plabIsFixed ? "yes" : "no"));
+            out.println("Test expectations:");
+            out.println("  PLAB allocation : " + (expectPLABAllocation ? "expected" : "unexpected"));
+            out.println("  Direct allocation : " + (expectDirectAllocation ? "expected" : "unexpected"));
+        }
+
+        /**
+         * @return
+         * true if we expect PLAB allocation
+         * false if no
+         */
+        public boolean isPromotedByPLAB() {
+            return promotedByPLAB;
+        }
+
+        /**
+         * @return
+         * true if it is test case for unreachable objects
+         * false for live objects
+         */
+        public boolean isDeadObjectCase() {
+            return !objectsAreReachable;
+        }
+
+        /**
+         * Returns amount of memory to fill
+         *
+         * @return amount of memory
+         */
+        public long getMemToFill() {
+            return (long) (edenSize) * 1024l * 1024l / 2;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/gc/g1/plab/TestPLABResize.java	Wed Feb 03 01:35:25 2016 +0100
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /*
+ * @test TestPLABResize
+ * @bug 8141278
+ * @summary Test for PLAB resizing
+ * @requires vm.gc=="G1" | vm.gc=="null"
+ * @library /testlibrary /../../test/lib /
+ * @modules java.management
+ * @build ClassFileInstaller
+ *        sun.hotspot.WhiteBox
+ *        gc.g1.plab.lib.LogParser
+ *        gc.g1.plab.lib.MemoryConsumer
+ *        gc.g1.plab.lib.PLABUtils
+ *        gc.g1.plab.lib.AppPLABResize
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main gc.g1.plab.TestPLABResize
+ */
+package gc.g1.plab;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.io.PrintStream;
+
+import gc.g1.plab.lib.LogParser;
+import gc.g1.plab.lib.PLABUtils;
+import gc.g1.plab.lib.AppPLABResize;
+
+import jdk.test.lib.OutputAnalyzer;
+import jdk.test.lib.ProcessTools;
+
+/**
+ * Test for PLAB resizing.
+ */
+public class TestPLABResize {
+
+    private static final int OBJECT_SIZE_SMALL = 10;
+    private static final int OBJECT_SIZE_MEDIUM = 70;
+    private static final int OBJECT_SIZE_HIGH = 150;
+    private static final int GC_NUM_SMALL = 1;
+    private static final int GC_NUM_MEDIUM = 3;
+    private static final int GC_NUM_HIGH = 7;
+    private static final int WASTE_PCT_SMALL = 10;
+    private static final int WASTE_PCT_MEDIUM = 20;
+    private static final int WASTE_PCT_HIGH = 30;
+
+    private static final int ITERATIONS_SMALL = 3;
+    private static final int ITERATIONS_MEDIUM = 5;
+    private static final int ITERATIONS_HIGH = 8;
+
+    private final static TestCase[] TEST_CASES = {
+        new TestCase(WASTE_PCT_SMALL, OBJECT_SIZE_SMALL, GC_NUM_SMALL, ITERATIONS_MEDIUM),
+        new TestCase(WASTE_PCT_SMALL, OBJECT_SIZE_MEDIUM, GC_NUM_HIGH, ITERATIONS_SMALL),
+        new TestCase(WASTE_PCT_SMALL, OBJECT_SIZE_HIGH, GC_NUM_MEDIUM, ITERATIONS_HIGH),
+        new TestCase(WASTE_PCT_MEDIUM, OBJECT_SIZE_SMALL, GC_NUM_HIGH, ITERATIONS_MEDIUM),
+        new TestCase(WASTE_PCT_MEDIUM, OBJECT_SIZE_MEDIUM, GC_NUM_SMALL, ITERATIONS_SMALL),
+        new TestCase(WASTE_PCT_MEDIUM, OBJECT_SIZE_HIGH, GC_NUM_MEDIUM, ITERATIONS_HIGH),
+        new TestCase(WASTE_PCT_HIGH, OBJECT_SIZE_SMALL, GC_NUM_HIGH, ITERATIONS_MEDIUM),
+        new TestCase(WASTE_PCT_HIGH, OBJECT_SIZE_MEDIUM, GC_NUM_SMALL, ITERATIONS_SMALL),
+        new TestCase(WASTE_PCT_HIGH, OBJECT_SIZE_HIGH, GC_NUM_MEDIUM, ITERATIONS_HIGH)
+    };
+
+    public static void main(String[] args) throws Throwable {
+        for (TestCase testCase : TEST_CASES) {
+            testCase.print(System.out);
+            List<String> options = PLABUtils.prepareOptions(testCase.toOptions());
+            options.add(AppPLABResize.class.getName());
+            OutputAnalyzer out = ProcessTools.executeTestJvm(options.toArray(new String[options.size()]));
+            if (out.getExitValue() != 0) {
+                System.out.println(out.getOutput());
+                throw new RuntimeException("Exit code is not 0");
+            }
+            checkResults(out.getOutput(), testCase);
+        }
+    }
+
+    /**
+     * Checks testing results.
+     * Expected results - desired PLAB size is decreased and increased during promotion to Survivor.
+     *
+     * @param output - VM output
+     * @param testCase
+     */
+    private static void checkResults(String output, TestCase testCase) {
+        final LogParser log = new LogParser(output);
+        final Map<Long, Map<LogParser.ReportType, Map<String, Long>>> entries = log.getEntries();
+
+        final ArrayList<Long> plabSizes = entries.entrySet()
+                .stream()
+                .map(item -> {
+                    return item.getValue()
+                            .get(LogParser.ReportType.SURVIVOR_STATS)
+                            .get("desired_plab_sz");
+                })
+                .collect(Collectors.toCollection(ArrayList::new));
+
+        // Check that desired plab size was changed during iterations.
+        // It should decrease during first half of iterations
+        // and increase after.
+        List<Long> decreasedPlabs = plabSizes.subList(testCase.getIterations(), testCase.getIterations() * 2);
+        List<Long> increasedPlabs = plabSizes.subList(testCase.getIterations() * 2, testCase.getIterations() * 3);
+
+        Long prev = decreasedPlabs.get(0);
+        for (int index = 1; index < decreasedPlabs.size(); ++index) {
+            Long current = decreasedPlabs.get(index);
+            if (prev < current) {
+                System.out.println(output);
+                throw new RuntimeException("Test failed! Expect that previous PLAB size should be greater than current. Prev.size: " + prev + " Current size:" + current);
+            }
+            prev = current;
+        }
+
+        prev = increasedPlabs.get(0);
+        for (int index = 1; index < increasedPlabs.size(); ++index) {
+            Long current = increasedPlabs.get(index);
+            if (prev > current) {
+                System.out.println(output);
+                throw new RuntimeException("Test failed! Expect that previous PLAB size should be less than current. Prev.size: " + prev + " Current size:" + current);
+            }
+            prev = current;
+        }
+
+        System.out.println("Test passed!");
+    }
+
+    /**
+     * Description of one test case.
+     */
+    private static class TestCase {
+
+        private final int wastePct;
+        private final int chunkSize;
+        private final int parGCThreads;
+        private final int iterations;
+
+        /**
+         * @param wastePct
+         * ParallelGCBufferWastePct
+         * @param chunkSize
+         * requested object size for memory consumption
+         * @param parGCThreads
+         * -XX:ParallelGCThreads
+         * @param iterations
+         *
+         */
+        public TestCase(int wastePct,
+                int chunkSize,
+                int parGCThreads,
+                int iterations
+        ) {
+            if (wastePct == 0 || chunkSize == 0 || parGCThreads == 0 || iterations == 0) {
+                throw new IllegalArgumentException("Parameters should not be 0");
+            }
+            this.wastePct = wastePct;
+
+            this.chunkSize = chunkSize;
+            this.parGCThreads = parGCThreads;
+            this.iterations = iterations;
+        }
+
+        /**
+         * Convert current TestCase to List of options.
+         *
+         * @return
+         * List of options
+         */
+        public List<String> toOptions() {
+            return Arrays.asList("-XX:ParallelGCThreads=" + parGCThreads,
+                    "-XX:ParallelGCBufferWastePct=" + wastePct,
+                    "-XX:+ResizePLAB",
+                    "-Dthreads=" + parGCThreads,
+                    "-Dchunk.size=" + chunkSize,
+                    "-Diterations=" + iterations,
+                    "-XX:NewSize=16m",
+                    "-XX:MaxNewSize=16m"
+            );
+        }
+
+        /**
+         * Print details about test case.
+         */
+        public void print(PrintStream out) {
+            out.println("Test case details:");
+            out.println("  Parallel GC buffer waste pct : " + wastePct);
+            out.println("  Chunk size : " + chunkSize);
+            out.println("  Parallel GC threads : " + parGCThreads);
+            out.println("  Iterations: " + iterations);
+        }
+
+        /**
+         * @return iterations
+         */
+        public int getIterations() {
+            return iterations;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/gc/g1/plab/lib/AppPLABPromotion.java	Wed Feb 03 01:35:25 2016 +0100
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package gc.g1.plab.lib;
+
+import sun.hotspot.WhiteBox;
+
+/**
+ * This application is part of PLAB promotion test.
+ * The application fills a part of young gen with a number of small objects.
+ * Then it calls young GC twice to promote objects from eden to survivor, and from survivor to old.
+ * The test which running the application is responsible to set up test parameters
+ * and VM flags including flags turning GC logging on. The test will then check the produced log.
+ */
+final public class AppPLABPromotion {
+
+    private final static WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
+
+    /**
+     * AppPLABPromotion is used for testing PLAB promotion.
+     * Expects the following properties to be set:
+     * - chunk.size - size of one object (byte array)
+     * - mem.to.fill - amount of memory to be consumed
+     * - reachable - memory should be consumed by live or dead objects
+     *
+     * @param args
+     */
+    public static void main(String[] args) {
+        long chunkSize = Long.getLong("chunk.size");
+        long memToFill = Long.getLong("mem.to.fill");
+        boolean reachable = Boolean.getBoolean("reachable");
+        if (chunkSize == 0) {
+            throw new IllegalArgumentException("Chunk size must be not 0");
+        }
+        if (memToFill <= 0) {
+            throw new IllegalArgumentException("mem.to.fill property should be above 0");
+        }
+        // Fill requested amount of memory
+        allocate(reachable, memToFill, chunkSize);
+        // Promote all allocated objects from Eden to Survivor
+        WHITE_BOX.youngGC();
+        // Promote all allocated objects from Survivor to Old
+        WHITE_BOX.youngGC();
+    }
+
+    /**
+     *
+     * @param reachable - should allocate reachable object
+     * @param memSize - Memory to fill
+     * @param chunkSize - requested bytes per objects.
+     * Actual size of bytes per object will be greater
+     */
+    private static void allocate(boolean reachable, long memSize, long chunkSize) {
+        long realSize = WHITE_BOX.getObjectSize(new byte[(int) chunkSize]);
+        int items = (int) ((memSize - 1) / (realSize)) + 1;
+        MemoryConsumer storage;
+        if (reachable) {
+            storage = new MemoryConsumer(items, (int) chunkSize);
+        } else {
+            storage = new MemoryConsumer(1, (int) chunkSize);
+        }
+        // Make all young gen available.
+        WHITE_BOX.fullGC();
+        storage.consume(items * chunkSize);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/gc/g1/plab/lib/AppPLABResize.java	Wed Feb 03 01:35:25 2016 +0100
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package gc.g1.plab.lib;
+
+import jdk.test.lib.Platform;
+import sun.hotspot.WhiteBox;
+
+/**
+ * This application is part of PLAB Resize test.
+ * The application allocates objects in 3 iterations:
+ * 1. Objects of fixed size
+ * 2. Objects of decreasing size
+ * 3. Objects of increasing size
+ * The application doesn't have any assumptions about expected behavior.
+ * It's supposed to be executed by a test which should set up test parameters (object sizes, number of allocations, etc)
+ * and VM flags including flags turning GC logging on. The test will then check the produced log.
+ *
+ * Expects the following properties to be set:
+ * - iterations - amount of iteration per cycle.
+ * - chunk.size - size of objects to be allocated
+ * - threads - number of gc threads (-XX:ParallelGCThreads) to calculate PLAB sizes.
+ */
+final public class AppPLABResize {
+
+    // Memory to be promoted by PLAB for one thread.
+    private static final long MEM_ALLOC_WORDS = 32768;
+    // Defined by properties.
+    private static final int ITERATIONS = Integer.getInteger("iterations");
+    private static final long CHUNK = Long.getLong("chunk.size");
+    private static final int GC_THREADS = Integer.getInteger("threads");
+
+    private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
+
+    /**
+     * Main method for AppPLABResizing. Application expect for next properties:
+     * iterations, chunk.size and threads.
+     *
+     * @param args
+     */
+    public static void main(String[] args) {
+
+        if (ITERATIONS == 0 || CHUNK == 0 || GC_THREADS == 0) {
+            throw new IllegalArgumentException("Properties should be set");
+        }
+
+        long wordSize = Platform.is32bit() ? 4l : 8l;
+        // PLAB size is shared between threads.
+        long initialMemorySize = wordSize * GC_THREADS * MEM_ALLOC_WORDS;
+
+        // Expect changing memory to half during all iterations.
+        long memChangeStep = initialMemorySize / 2 / ITERATIONS;
+
+        WHITE_BOX.fullGC();
+
+        // Warm the PLAB. Fill memory ITERATIONS times without changing memory size.
+        iterateAllocation(initialMemorySize, 0);
+        // Fill memory ITERATIONS times.
+        // Initial size is initialMemorySize and step is -memChangeStep
+        iterateAllocation(initialMemorySize, -memChangeStep);
+        // Fill memory ITERATIONS times.
+        // Initial size is memoryAfterChanging, step is memChangeStep.
+        // Memory size at start should be greater then last size on previous step.
+        // Last size on previous step is initialMemorySize - memChangeStep*(ITERATIONS - 1)
+        long memoryAfterChanging = initialMemorySize - memChangeStep * (ITERATIONS - 2);
+        iterateAllocation(memoryAfterChanging, memChangeStep);
+    }
+
+    private static void iterateAllocation(long memoryToFill, long change) {
+        int items;
+        if (change > 0) {
+            items = (int) ((memoryToFill + change * ITERATIONS) / CHUNK) + 1;
+        } else {
+            items = (int) (memoryToFill / CHUNK) + 1;
+        }
+
+        long currentMemToFill = memoryToFill;
+        for (int iteration = 0; iteration < ITERATIONS; ++iteration) {
+            MemoryConsumer storage = new MemoryConsumer(items, (int) CHUNK);
+            storage.consume(currentMemToFill);
+            // Promote all objects to survivor
+            WHITE_BOX.youngGC();
+            storage.clear();
+            currentMemToFill += change;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/gc/g1/plab/lib/LogParser.java	Wed Feb 03 01:35:25 2016 +0100
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package gc.g1.plab.lib;
+
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Scanner;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * LogParser class parses VM output to get PLAB and ConsumptionStats values.
+ *
+ * Typical GC log with PLAB statistics (options - -Xlog:gc=debug,gc+plab=debug) looks like:
+ *
+ * [2,244s][info   ][gc     ] GC(30) Concurrent Mark abort
+ * [2,245s][debug  ][gc,plab] GC(33)  (allocated = 1 wasted = 0 unused = 0 used = 1 undo_waste = 0 region_end_waste = 0 regions filled = 0 direct_allocated = 0 failure_used = 0 failure_waste = 0)  (plab_sz = 0 desired_plab_sz = 258)
+ * [2,245s][debug  ][gc,plab] GC(33)  (allocated = 1 wasted = 0 unused = 0 used = 1 undo_waste = 0 region_end_waste = 0 regions filled = 0 direct_allocated = 0 failure_used = 0 failure_waste = 0)  (plab_sz = 0 desired_plab_sz = 258)
+ * [2,245s][info