Merge
authorctornqvi
Mon, 27 Apr 2015 14:41:49 +0200
changeset 30287 b39d2cec5056
parent 30286 7e076dc01291 (current diff)
parent 30284 909da3c92522 (diff)
child 30288 476c276de939
Merge
hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp
hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp
hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.inline.hpp
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java	Mon Apr 27 14:41:49 2015 +0200
@@ -259,8 +259,7 @@
      saProps = new Properties();
      URL url = null;
      try {
-       url = VM.class.getClassLoader().getResource("sa.properties");
-       saProps.load(new BufferedInputStream(url.openStream()));
+       saProps.load(VM.class.getResourceAsStream("/sa.properties"));
      } catch (Exception e) {
        System.err.println("Unable to load properties  " +
                                   (url == null ? "null" : url.toString()) +
--- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp	Mon Apr 27 14:41:49 2015 +0200
@@ -3695,23 +3695,11 @@
     if (satb_log_enqueue_with_frame == 0) {
       generate_satb_log_enqueue(with_frame);
       assert(satb_log_enqueue_with_frame != 0, "postcondition.");
-      if (G1SATBPrintStubs) {
-        tty->print_cr("Generated with-frame satb enqueue:");
-        Disassembler::decode((u_char*)satb_log_enqueue_with_frame,
-                             satb_log_enqueue_with_frame_end,
-                             tty);
-      }
     }
   } else {
     if (satb_log_enqueue_frameless == 0) {
       generate_satb_log_enqueue(with_frame);
       assert(satb_log_enqueue_frameless != 0, "postcondition.");
-      if (G1SATBPrintStubs) {
-        tty->print_cr("Generated frameless satb enqueue:");
-        Disassembler::decode((u_char*)satb_log_enqueue_frameless,
-                             satb_log_enqueue_frameless_end,
-                             tty);
-      }
     }
   }
 }
@@ -3904,12 +3892,6 @@
   if (dirty_card_log_enqueue == 0) {
     generate_dirty_card_log_enqueue(byte_map_base);
     assert(dirty_card_log_enqueue != 0, "postcondition.");
-    if (G1SATBPrintStubs) {
-      tty->print_cr("Generated dirty_card enqueue:");
-      Disassembler::decode((u_char*)dirty_card_log_enqueue,
-                           dirty_card_log_enqueue_end,
-                           tty);
-    }
   }
 }
 
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp	Mon Apr 27 14:41:49 2015 +0200
@@ -1181,8 +1181,6 @@
   // Accessors
   static oop              target(         oop site);
   static void         set_target(         oop site, oop target);
-
-  static volatile oop     target_volatile(oop site);
   static void         set_target_volatile(oop site, oop target);
 
   // Testers
--- a/hotspot/src/share/vm/classfile/javaClasses.inline.hpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.inline.hpp	Mon Apr 27 14:41:49 2015 +0200
@@ -29,10 +29,6 @@
 #include "oops/oop.inline.hpp"
 #include "oops/oopsHierarchy.hpp"
 
-inline volatile oop java_lang_invoke_CallSite::target_volatile(oop site) {
-  return oop((oopDesc *)(site->obj_field_volatile(_target_offset)));
-}
-
 inline void java_lang_invoke_CallSite::set_target_volatile(oop site, oop target) {
   site->obj_field_put_volatile(_target_offset, target);
 }
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Mon Apr 27 14:41:49 2015 +0200
@@ -943,13 +943,6 @@
 
   _has_aborted = false;
 
-#ifndef PRODUCT
-  if (G1PrintReachableAtInitialMark) {
-    print_reachable("at-cycle-start",
-                    VerifyOption_G1UsePrevMarking, true /* all */);
-  }
-#endif
-
   // Initialize marking structures. This has to be done in a STW phase.
   reset();
 
@@ -2684,166 +2677,6 @@
   print_stats();
 }
 
-#ifndef PRODUCT
-
-class PrintReachableOopClosure: public OopClosure {
-private:
-  G1CollectedHeap* _g1h;
-  outputStream*    _out;
-  VerifyOption     _vo;
-  bool             _all;
-
-public:
-  PrintReachableOopClosure(outputStream* out,
-                           VerifyOption  vo,
-                           bool          all) :
-    _g1h(G1CollectedHeap::heap()),
-    _out(out), _vo(vo), _all(all) { }
-
-  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);
-    const char* str = NULL;
-    const char* str2 = "";
-
-    if (obj == NULL) {
-      str = "";
-    } else if (!_g1h->is_in_g1_reserved(obj)) {
-      str = " O";
-    } else {
-      HeapRegion* hr  = _g1h->heap_region_containing(obj);
-      bool over_tams = _g1h->allocated_since_marking(obj, hr, _vo);
-      bool marked = _g1h->is_marked(obj, _vo);
-
-      if (over_tams) {
-        str = " >";
-        if (marked) {
-          str2 = " AND MARKED";
-        }
-      } else if (marked) {
-        str = " M";
-      } else {
-        str = " NOT";
-      }
-    }
-
-    _out->print_cr("  "PTR_FORMAT": "PTR_FORMAT"%s%s",
-                   p2i(p), p2i((void*) obj), str, str2);
-  }
-};
-
-class PrintReachableObjectClosure : public ObjectClosure {
-private:
-  G1CollectedHeap* _g1h;
-  outputStream*    _out;
-  VerifyOption     _vo;
-  bool             _all;
-  HeapRegion*      _hr;
-
-public:
-  PrintReachableObjectClosure(outputStream* out,
-                              VerifyOption  vo,
-                              bool          all,
-                              HeapRegion*   hr) :
-    _g1h(G1CollectedHeap::heap()),
-    _out(out), _vo(vo), _all(all), _hr(hr) { }
-
-  void do_object(oop o) {
-    bool over_tams = _g1h->allocated_since_marking(o, _hr, _vo);
-    bool marked = _g1h->is_marked(o, _vo);
-    bool print_it = _all || over_tams || marked;
-
-    if (print_it) {
-      _out->print_cr(" "PTR_FORMAT"%s",
-                     p2i((void *)o), (over_tams) ? " >" : (marked) ? " M" : "");
-      PrintReachableOopClosure oopCl(_out, _vo, _all);
-      o->oop_iterate_no_header(&oopCl);
-    }
-  }
-};
-
-class PrintReachableRegionClosure : public HeapRegionClosure {
-private:
-  G1CollectedHeap* _g1h;
-  outputStream*    _out;
-  VerifyOption     _vo;
-  bool             _all;
-
-public:
-  bool doHeapRegion(HeapRegion* hr) {
-    HeapWord* b = hr->bottom();
-    HeapWord* e = hr->end();
-    HeapWord* t = hr->top();
-    HeapWord* p = _g1h->top_at_mark_start(hr, _vo);
-    _out->print_cr("** ["PTR_FORMAT", "PTR_FORMAT"] top: "PTR_FORMAT" "
-                   "TAMS: " PTR_FORMAT, p2i(b), p2i(e), p2i(t), p2i(p));
-    _out->cr();
-
-    HeapWord* from = b;
-    HeapWord* to   = t;
-
-    if (to > from) {
-      _out->print_cr("Objects in [" PTR_FORMAT ", " PTR_FORMAT "]", p2i(from), p2i(to));
-      _out->cr();
-      PrintReachableObjectClosure ocl(_out, _vo, _all, hr);
-      hr->object_iterate_mem_careful(MemRegion(from, to), &ocl);
-      _out->cr();
-    }
-
-    return false;
-  }
-
-  PrintReachableRegionClosure(outputStream* out,
-                              VerifyOption  vo,
-                              bool          all) :
-    _g1h(G1CollectedHeap::heap()), _out(out), _vo(vo), _all(all) { }
-};
-
-void ConcurrentMark::print_reachable(const char* str,
-                                     VerifyOption vo,
-                                     bool all) {
-  gclog_or_tty->cr();
-  gclog_or_tty->print_cr("== Doing heap dump... ");
-
-  if (G1PrintReachableBaseFile == NULL) {
-    gclog_or_tty->print_cr("  #### error: no base file defined");
-    return;
-  }
-
-  if (strlen(G1PrintReachableBaseFile) + 1 + strlen(str) >
-      (JVM_MAXPATHLEN - 1)) {
-    gclog_or_tty->print_cr("  #### error: file name too long");
-    return;
-  }
-
-  char file_name[JVM_MAXPATHLEN];
-  sprintf(file_name, "%s.%s", G1PrintReachableBaseFile, str);
-  gclog_or_tty->print_cr("  dumping to file %s", file_name);
-
-  fileStream fout(file_name);
-  if (!fout.is_open()) {
-    gclog_or_tty->print_cr("  #### error: could not open file");
-    return;
-  }
-
-  outputStream* out = &fout;
-  out->print_cr("-- USING %s", _g1h->top_at_mark_start_str(vo));
-  out->cr();
-
-  out->print_cr("--- ITERATING OVER REGIONS");
-  out->cr();
-  PrintReachableRegionClosure rcl(out, vo, all);
-  _g1h->heap_region_iterate(&rcl);
-  out->cr();
-
-  gclog_or_tty->print_cr("  done");
-  gclog_or_tty->flush();
-}
-
-#endif // PRODUCT
-
 void ConcurrentMark::clearRangePrevBitmap(MemRegion mr) {
   // Note we are overriding the read-only view of the prev map here, via
   // the cast.
@@ -2960,9 +2793,7 @@
 #ifndef PRODUCT
 enum VerifyNoCSetOopsPhase {
   VerifyNoCSetOopsStack,
-  VerifyNoCSetOopsQueues,
-  VerifyNoCSetOopsSATBCompleted,
-  VerifyNoCSetOopsSATBThread
+  VerifyNoCSetOopsQueues
 };
 
 class VerifyNoCSetOopsClosure : public OopClosure, public ObjectClosure  {
@@ -2975,8 +2806,6 @@
     switch (_phase) {
     case VerifyNoCSetOopsStack:         return "Stack";
     case VerifyNoCSetOopsQueues:        return "Queue";
-    case VerifyNoCSetOopsSATBCompleted: return "Completed SATB Buffers";
-    case VerifyNoCSetOopsSATBThread:    return "Thread SATB Buffers";
     default:                            ShouldNotReachHere();
     }
     return NULL;
@@ -3003,7 +2832,7 @@
 
   virtual void do_oop(narrowOop* p) {
     // We should not come across narrow oops while scanning marking
-    // stacks and SATB buffers.
+    // stacks
     ShouldNotReachHere();
   }
 
@@ -3012,10 +2841,7 @@
   }
 };
 
-void ConcurrentMark::verify_no_cset_oops(bool verify_stacks,
-                                         bool verify_enqueued_buffers,
-                                         bool verify_thread_buffers,
-                                         bool verify_fingers) {
+void ConcurrentMark::verify_no_cset_oops() {
   assert(SafepointSynchronize::is_at_safepoint(), "should be at a safepoint");
   if (!G1CollectedHeap::heap()->mark_in_progress()) {
     return;
@@ -3023,65 +2849,47 @@
 
   VerifyNoCSetOopsClosure cl;
 
-  if (verify_stacks) {
-    // Verify entries on the global mark stack
-    cl.set_phase(VerifyNoCSetOopsStack);
-    _markStack.oops_do(&cl);
-
-    // Verify entries on the task queues
-    for (uint i = 0; i < _max_worker_id; i += 1) {
-      cl.set_phase(VerifyNoCSetOopsQueues, i);
-      CMTaskQueue* queue = _task_queues->queue(i);
-      queue->oops_do(&cl);
-    }
-  }
-
-  SATBMarkQueueSet& satb_qs = JavaThread::satb_mark_queue_set();
-
-  // Verify entries on the enqueued SATB buffers
-  if (verify_enqueued_buffers) {
-    cl.set_phase(VerifyNoCSetOopsSATBCompleted);
-    satb_qs.iterate_completed_buffers_read_only(&cl);
-  }
-
-  // Verify entries on the per-thread SATB buffers
-  if (verify_thread_buffers) {
-    cl.set_phase(VerifyNoCSetOopsSATBThread);
-    satb_qs.iterate_thread_buffers_read_only(&cl);
+  // Verify entries on the global mark stack
+  cl.set_phase(VerifyNoCSetOopsStack);
+  _markStack.oops_do(&cl);
+
+  // Verify entries on the task queues
+  for (uint i = 0; i < _max_worker_id; i += 1) {
+    cl.set_phase(VerifyNoCSetOopsQueues, i);
+    CMTaskQueue* queue = _task_queues->queue(i);
+    queue->oops_do(&cl);
   }
 
-  if (verify_fingers) {
-    // Verify the global finger
-    HeapWord* global_finger = finger();
-    if (global_finger != NULL && global_finger < _heap_end) {
-      // The global finger always points to a heap region boundary. We
-      // use heap_region_containing_raw() to get the containing region
-      // given that the global finger could be pointing to a free region
-      // which subsequently becomes continues humongous. If that
-      // happens, heap_region_containing() will return the bottom of the
-      // corresponding starts humongous region and the check below will
-      // not hold any more.
-      // Since we always iterate over all regions, we might get a NULL HeapRegion
-      // here.
-      HeapRegion* global_hr = _g1h->heap_region_containing_raw(global_finger);
-      guarantee(global_hr == NULL || global_finger == global_hr->bottom(),
-                err_msg("global finger: "PTR_FORMAT" region: "HR_FORMAT,
-                        p2i(global_finger), HR_FORMAT_PARAMS(global_hr)));
-    }
-
-    // Verify the task fingers
-    assert(parallel_marking_threads() <= _max_worker_id, "sanity");
-    for (int i = 0; i < (int) parallel_marking_threads(); i += 1) {
-      CMTask* task = _tasks[i];
-      HeapWord* task_finger = task->finger();
-      if (task_finger != NULL && task_finger < _heap_end) {
-        // See above note on the global finger verification.
-        HeapRegion* task_hr = _g1h->heap_region_containing_raw(task_finger);
-        guarantee(task_hr == NULL || task_finger == task_hr->bottom() ||
-                  !task_hr->in_collection_set(),
-                  err_msg("task finger: "PTR_FORMAT" region: "HR_FORMAT,
-                          p2i(task_finger), HR_FORMAT_PARAMS(task_hr)));
-      }
+  // Verify the global finger
+  HeapWord* global_finger = finger();
+  if (global_finger != NULL && global_finger < _heap_end) {
+    // The global finger always points to a heap region boundary. We
+    // use heap_region_containing_raw() to get the containing region
+    // given that the global finger could be pointing to a free region
+    // which subsequently becomes continues humongous. If that
+    // happens, heap_region_containing() will return the bottom of the
+    // corresponding starts humongous region and the check below will
+    // not hold any more.
+    // Since we always iterate over all regions, we might get a NULL HeapRegion
+    // here.
+    HeapRegion* global_hr = _g1h->heap_region_containing_raw(global_finger);
+    guarantee(global_hr == NULL || global_finger == global_hr->bottom(),
+              err_msg("global finger: "PTR_FORMAT" region: "HR_FORMAT,
+                      p2i(global_finger), HR_FORMAT_PARAMS(global_hr)));
+  }
+
+  // Verify the task fingers
+  assert(parallel_marking_threads() <= _max_worker_id, "sanity");
+  for (int i = 0; i < (int) parallel_marking_threads(); i += 1) {
+    CMTask* task = _tasks[i];
+    HeapWord* task_finger = task->finger();
+    if (task_finger != NULL && task_finger < _heap_end) {
+      // See above note on the global finger verification.
+      HeapRegion* task_hr = _g1h->heap_region_containing_raw(task_finger);
+      guarantee(task_hr == NULL || task_finger == task_hr->bottom() ||
+                !task_hr->in_collection_set(),
+                err_msg("task finger: "PTR_FORMAT" region: "HR_FORMAT,
+                        p2i(task_finger), HR_FORMAT_PARAMS(task_hr)));
     }
   }
 }
@@ -3887,12 +3695,11 @@
 
   CMObjectClosure oc(this);
   SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
-  satb_mq_set.set_closure(_worker_id, &oc);
 
   // This keeps claiming and applying the closure to completed buffers
   // until we run out of buffers or we need to abort.
   while (!has_aborted() &&
-         satb_mq_set.apply_closure_to_completed_buffer(_worker_id)) {
+         satb_mq_set.apply_closure_to_completed_buffer(&oc)) {
     if (_cm->verbose_medium()) {
       gclog_or_tty->print_cr("[%u] processed an SATB buffer", _worker_id);
     }
@@ -3906,8 +3713,6 @@
          concurrent() ||
          satb_mq_set.completed_buffers_num() == 0, "invariant");
 
-  satb_mq_set.set_closure(_worker_id, NULL);
-
   // again, this was a potentially expensive operation, decrease the
   // limits to get the regular clock call early
   decrease_limits();
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Mon Apr 27 14:41:49 2015 +0200
@@ -785,14 +785,9 @@
   }
 
   // Verify that there are no CSet oops on the stacks (taskqueues /
-  // global mark stack), enqueued SATB buffers, per-thread SATB
-  // buffers, and fingers (global / per-task). The boolean parameters
-  // decide which of the above data structures to verify. If marking
-  // is not in progress, it's a no-op.
-  void verify_no_cset_oops(bool verify_stacks,
-                           bool verify_enqueued_buffers,
-                           bool verify_thread_buffers,
-                           bool verify_fingers) PRODUCT_RETURN;
+  // global mark stack) and fingers (global / per-task).
+  // 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");
--- a/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.cpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.cpp	Mon Apr 27 14:41:49 2015 +0200
@@ -110,15 +110,15 @@
   _retained_old_gc_alloc_region = NULL;
 }
 
-G1ParGCAllocBuffer::G1ParGCAllocBuffer(size_t gclab_word_size) :
-  ParGCAllocBuffer(gclab_word_size), _retired(true) { }
+G1PLAB::G1PLAB(size_t gclab_word_size) :
+  PLAB(gclab_word_size), _retired(true) { }
 
 HeapWord* G1ParGCAllocator::allocate_direct_or_new_plab(InCSetState dest,
                                                         size_t word_sz,
                                                         AllocationContext_t context) {
   size_t gclab_word_size = _g1h->desired_plab_sz(dest);
   if (word_sz * 100 < gclab_word_size * ParallelGCBufferWastePct) {
-    G1ParGCAllocBuffer* alloc_buf = alloc_buffer(dest, context);
+    G1PLAB* alloc_buf = alloc_buffer(dest, context);
     add_to_alloc_buffer_waste(alloc_buf->words_remaining());
     alloc_buf->retire();
 
@@ -151,7 +151,7 @@
 
 void G1DefaultParGCAllocator::retire_alloc_buffers() {
   for (uint state = 0; state < InCSetState::Num; state++) {
-    G1ParGCAllocBuffer* const buf = _alloc_buffers[state];
+    G1PLAB* const buf = _alloc_buffers[state];
     if (buf != NULL) {
       add_to_alloc_buffer_waste(buf->words_remaining());
       buf->flush_and_retire_stats(_g1h->alloc_buffer_stats(state));
--- a/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.hpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.hpp	Mon Apr 27 14:41:49 2015 +0200
@@ -28,7 +28,7 @@
 #include "gc_implementation/g1/g1AllocationContext.hpp"
 #include "gc_implementation/g1/g1AllocRegion.hpp"
 #include "gc_implementation/g1/g1InCSetState.hpp"
-#include "gc_implementation/shared/parGCAllocBuffer.hpp"
+#include "gc_implementation/shared/plab.hpp"
 #include "gc_interface/collectedHeap.hpp"
 
 class EvacuationInfo;
@@ -147,18 +147,18 @@
   }
 };
 
-class G1ParGCAllocBuffer: public ParGCAllocBuffer {
+class G1PLAB: public PLAB {
 private:
   bool _retired;
 
 public:
-  G1ParGCAllocBuffer(size_t gclab_word_size);
-  virtual ~G1ParGCAllocBuffer() {
+  G1PLAB(size_t gclab_word_size);
+  virtual ~G1PLAB() {
     guarantee(_retired, "Allocation buffer has not been retired");
   }
 
   virtual void set_buf(HeapWord* buf) {
-    ParGCAllocBuffer::set_buf(buf);
+    PLAB::set_buf(buf);
     _retired = false;
   }
 
@@ -166,7 +166,12 @@
     if (_retired) {
       return;
     }
-    ParGCAllocBuffer::retire();
+    PLAB::retire();
+    _retired = true;
+  }
+
+  virtual void flush_and_retire_stats(PLABStats* stats) {
+    PLAB::flush_and_retire_stats(stats);
     _retired = true;
   }
 };
@@ -190,7 +195,7 @@
   void add_to_undo_waste(size_t waste)         { _undo_waste += waste; }
 
   virtual void retire_alloc_buffers() = 0;
-  virtual G1ParGCAllocBuffer* alloc_buffer(InCSetState dest, AllocationContext_t context) = 0;
+  virtual G1PLAB* alloc_buffer(InCSetState dest, AllocationContext_t context) = 0;
 
   // Calculate the survivor space object alignment in bytes. Returns that or 0 if
   // there are no restrictions on survivor alignment.
@@ -211,6 +216,7 @@
     _g1h(g1h), _survivor_alignment_bytes(calc_survivor_alignment_bytes()),
     _alloc_buffer_waste(0), _undo_waste(0) {
   }
+  virtual ~G1ParGCAllocator() { }
 
   static G1ParGCAllocator* create_allocator(G1CollectedHeap* g1h);
 
@@ -229,7 +235,7 @@
   HeapWord* plab_allocate(InCSetState dest,
                           size_t word_sz,
                           AllocationContext_t context) {
-    G1ParGCAllocBuffer* buffer = alloc_buffer(dest, context);
+    G1PLAB* buffer = alloc_buffer(dest, context);
     if (_survivor_alignment_bytes == 0) {
       return buffer->allocate(word_sz);
     } else {
@@ -259,14 +265,14 @@
 };
 
 class G1DefaultParGCAllocator : public G1ParGCAllocator {
-  G1ParGCAllocBuffer  _surviving_alloc_buffer;
-  G1ParGCAllocBuffer  _tenured_alloc_buffer;
-  G1ParGCAllocBuffer* _alloc_buffers[InCSetState::Num];
+  G1PLAB  _surviving_alloc_buffer;
+  G1PLAB  _tenured_alloc_buffer;
+  G1PLAB* _alloc_buffers[InCSetState::Num];
 
 public:
   G1DefaultParGCAllocator(G1CollectedHeap* g1h);
 
-  virtual G1ParGCAllocBuffer* alloc_buffer(InCSetState dest, AllocationContext_t context) {
+  virtual G1PLAB* alloc_buffer(InCSetState dest, AllocationContext_t context) {
     assert(dest.is_valid(),
            err_msg("Allocation buffer index out-of-bounds: " CSETSTATE_FORMAT, dest.value()));
     assert(_alloc_buffers[dest.value()] != NULL,
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Mon Apr 27 14:41:49 2015 +0200
@@ -22,11 +22,6 @@
  *
  */
 
-#if !defined(__clang_major__) && defined(__GNUC__)
-// FIXME, formats have issues.  Disable this macro definition, compile, and study warnings for more information.
-#define ATTRIBUTE_PRINTF(x,y)
-#endif
-
 #include "precompiled.hpp"
 #include "classfile/metadataOnStackMark.hpp"
 #include "classfile/stringTable.hpp"
@@ -201,7 +196,7 @@
     if (!curr->is_young()) {
       gclog_or_tty->print_cr("### YOUNG REGION "PTR_FORMAT"-"PTR_FORMAT" "
                              "incorrectly tagged (y: %d, surv: %d)",
-                             curr->bottom(), curr->end(),
+                             p2i(curr->bottom()), p2i(curr->end()),
                              curr->is_young(), curr->is_survivor());
       ret = false;
     }
@@ -330,8 +325,8 @@
     while (curr != NULL) {
       gclog_or_tty->print_cr("  "HR_FORMAT", P: "PTR_FORMAT ", N: "PTR_FORMAT", age: %4d",
                              HR_FORMAT_PARAMS(curr),
-                             curr->prev_top_at_mark_start(),
-                             curr->next_top_at_mark_start(),
+                             p2i(curr->prev_top_at_mark_start()),
+                             p2i(curr->next_top_at_mark_start()),
                              curr->age_in_surv_rate_group_cond());
       curr = curr->get_next_young_region();
     }
@@ -410,10 +405,6 @@
   return !hr->is_humongous();
 }
 
-// Private class members.
-
-G1CollectedHeap* G1CollectedHeap::_g1h;
-
 // Private methods.
 
 HeapRegion*
@@ -1769,14 +1760,12 @@
   _gc_tracer_stw(new (ResourceObj::C_HEAP, mtGC) G1NewTracer()),
   _gc_tracer_cm(new (ResourceObj::C_HEAP, mtGC) G1OldTracer()) {
 
-  _g1h = this;
-
   _workers = new FlexibleWorkGang("GC Thread", ParallelGCThreads,
                           /* are_GC_task_threads */true,
                           /* are_ConcurrentGC_threads */false);
   _workers->initialize_workers();
 
-  _allocator = G1Allocator::create_allocator(_g1h);
+  _allocator = G1Allocator::create_allocator(this);
   _humongous_object_threshold_in_words = HeapRegion::GrainWords / 2;
 
   int n_queues = MAX2((int)ParallelGCThreads, 1);
@@ -1939,8 +1928,6 @@
 
   _bot_shared = new G1BlockOffsetSharedArray(reserved_region(), bot_storage);
 
-  _g1h = this;
-
   {
     HeapWord* start = _hrm.reserved().start();
     HeapWord* end = _hrm.reserved().end();
@@ -2760,9 +2747,9 @@
       oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
       if (_g1h->is_obj_dead_cond(obj, _vo)) {
         gclog_or_tty->print_cr("Root location "PTR_FORMAT" "
-                              "points to dead obj "PTR_FORMAT, p, (void*) obj);
+                               "points to dead obj "PTR_FORMAT, p2i(p), p2i(obj));
         if (_vo == VerifyOption_G1UseMarkWord) {
-          gclog_or_tty->print_cr("  Mark word: "PTR_FORMAT, (void*)(obj->mark()));
+          gclog_or_tty->print_cr("  Mark word: "INTPTR_FORMAT, (intptr_t)obj->mark());
         }
         obj->print_on(gclog_or_tty);
         _failures = true;
@@ -2810,9 +2797,9 @@
       // contains the nmethod
       if (!hrrs->strong_code_roots_list_contains(_nm)) {
         gclog_or_tty->print_cr("Code root location "PTR_FORMAT" "
-                              "from nmethod "PTR_FORMAT" not in strong "
-                              "code roots for region ["PTR_FORMAT","PTR_FORMAT")",
-                              p, _nm, hr->bottom(), hr->end());
+                               "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;
       }
     }
@@ -2868,7 +2855,7 @@
     _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(), err_msg("Klass " PTR_FORMAT ", has young refs but is not dirty.", k));
+      guarantee(k->has_modified_oops(), err_msg("Klass " PTR_FORMAT ", has young refs but is not dirty.", p2i(k)));
     }
   }
 };
@@ -2929,35 +2916,6 @@
   size_t live_bytes() { return _live_bytes; }
 };
 
-class PrintObjsInRegionClosure : public ObjectClosure {
-  HeapRegion *_hr;
-  G1CollectedHeap *_g1;
-public:
-  PrintObjsInRegionClosure(HeapRegion *hr) : _hr(hr) {
-    _g1 = G1CollectedHeap::heap();
-  };
-
-  void do_object(oop o) {
-    if (o != NULL) {
-      HeapWord *start = (HeapWord *) o;
-      size_t word_sz = o->size();
-      gclog_or_tty->print("\nPrinting obj "PTR_FORMAT" of size " SIZE_FORMAT
-                          " isMarkedPrev %d isMarkedNext %d isAllocSince %d\n",
-                          (void*) o, word_sz,
-                          _g1->isMarkedPrev(o),
-                          _g1->isMarkedNext(o),
-                          _hr->obj_allocated_since_prev_marking(o));
-      HeapWord *end = start + word_sz;
-      HeapWord *cur;
-      int *val;
-      for (cur = start; cur < end; cur++) {
-        val = (int *) cur;
-        gclog_or_tty->print("\t "PTR_FORMAT":%d\n", val, *val);
-      }
-    }
-  }
-};
-
 class VerifyRegionClosure: public HeapRegionClosure {
 private:
   bool             _par;
@@ -2990,7 +2948,7 @@
             gclog_or_tty->print_cr("["PTR_FORMAT","PTR_FORMAT"] "
                                    "max_live_bytes "SIZE_FORMAT" "
                                    "< calculated "SIZE_FORMAT,
-                                   r->bottom(), r->end(),
+                                   p2i(r->bottom()), p2i(r->end()),
                                    r->max_live_bytes(),
                                  not_dead_yet_cl.live_bytes());
             _failures = true;
@@ -3109,12 +3067,6 @@
       // print_extended_on() instead of print_on().
       print_extended_on(gclog_or_tty);
       gclog_or_tty->cr();
-#ifndef PRODUCT
-      if (VerifyDuringGC && G1VerifyDuringGCPrintReachable) {
-        concurrent_mark()->print_reachable("at-verification-failure",
-                                           vo, false /* all */);
-      }
-#endif
       gclog_or_tty->flush();
     }
     guarantee(!failures, "there should not have been any failures");
@@ -3194,10 +3146,10 @@
   st->print(" %-20s", "garbage-first heap");
   st->print(" total " SIZE_FORMAT "K, used " SIZE_FORMAT "K",
             capacity()/K, used_unlocked()/K);
-  st->print(" [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " INTPTR_FORMAT ")",
-            _hrm.reserved().start(),
-            _hrm.reserved().start() + _hrm.length() + HeapRegion::GrainWords,
-            _hrm.reserved().end());
+  st->print(" [" PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT ")",
+            p2i(_hrm.reserved().start()),
+            p2i(_hrm.reserved().start() + _hrm.length() + HeapRegion::GrainWords),
+            p2i(_hrm.reserved().end()));
   st->cr();
   st->print("  region size " SIZE_FORMAT "K, ", HeapRegion::GrainBytes / K);
   uint young_regions = _young_list->length();
@@ -3320,9 +3272,10 @@
 #endif // PRODUCT
 
 G1CollectedHeap* G1CollectedHeap::heap() {
-  assert(_g1h != NULL, "Uninitialized access to G1CollectedHeap::heap()");
-  assert(_g1h->kind() == CollectedHeap::G1CollectedHeap, "Not a G1 heap");
-  return _g1h;
+  CollectedHeap* heap = Universe::heap();
+  assert(heap != NULL, "Uninitialized access to G1CollectedHeap::heap()");
+  assert(heap->kind() == CollectedHeap::G1CollectedHeap, "Not a G1CollectedHeap");
+  return (G1CollectedHeap*)heap;
 }
 
 void G1CollectedHeap::gc_prologue(bool full /* Ignored */) {
@@ -3853,14 +3806,9 @@
         assert(check_cset_fast_test(), "Inconsistency in the InCSetState table.");
 
         _cm->note_start_of_gc();
-        // We should not verify the per-thread SATB buffers given that
-        // we have not filtered them yet (we'll do so during the
-        // GC). We also call this after finalize_cset() to
+        // We call this after finalize_cset() to
         // ensure that the CSet has been finalized.
-        _cm->verify_no_cset_oops(true  /* verify_stacks */,
-                                 true  /* verify_enqueued_buffers */,
-                                 false /* verify_thread_buffers */,
-                                 true  /* verify_fingers */);
+        _cm->verify_no_cset_oops();
 
         if (_hr_printer.is_active()) {
           HeapRegion* hr = g1_policy()->collection_set();
@@ -3883,16 +3831,6 @@
         // Actually do the work...
         evacuate_collection_set(evacuation_info);
 
-        // We do this to mainly verify the per-thread SATB buffers
-        // (which have been filtered by now) since we didn't verify
-        // them earlier. No point in re-checking the stacks / enqueued
-        // buffers given that the CSet has not changed since last time
-        // we checked.
-        _cm->verify_no_cset_oops(false /* verify_stacks */,
-                                 false /* verify_enqueued_buffers */,
-                                 true  /* verify_thread_buffers */,
-                                 true  /* verify_fingers */);
-
         free_collection_set(g1_policy()->collection_set(), evacuation_info);
 
         eagerly_reclaim_humongous_regions();
@@ -3975,10 +3913,7 @@
 
         // We redo the verification but now wrt to the new CSet which
         // has just got initialized after the previous CSet was freed.
-        _cm->verify_no_cset_oops(true  /* verify_stacks */,
-                                 true  /* verify_enqueued_buffers */,
-                                 true  /* verify_thread_buffers */,
-                                 true  /* verify_fingers */);
+        _cm->verify_no_cset_oops();
         _cm->note_end_of_gc();
 
         // This timing is only used by the ergonomics to handle our pause target.
@@ -4137,7 +4072,7 @@
                                                oop old) {
   assert(obj_in_cs(old),
          err_msg("obj: "PTR_FORMAT" should still be in the CSet",
-                 (HeapWord*) old));
+                 p2i(old)));
   markOop m = old->mark();
   oop forward_ptr = old->forward_to_atomic(old);
   if (forward_ptr == NULL) {
@@ -4172,7 +4107,7 @@
     assert(old == forward_ptr || !obj_in_cs(forward_ptr),
            err_msg("obj: "PTR_FORMAT" forwarded to: "PTR_FORMAT" "
                    "should not be in the CSet",
-                   (HeapWord*) old, (HeapWord*) forward_ptr));
+                   p2i(old), p2i(forward_ptr)));
     return forward_ptr;
   }
 }
@@ -4877,7 +4812,7 @@
 void G1CollectedHeap::unlink_string_and_symbol_table(BoolObjectClosure* is_alive,
                                                      bool process_strings, bool process_symbols) {
   {
-    uint n_workers = _g1h->workers()->active_workers();
+    uint n_workers = workers()->active_workers();
     G1StringSymbolTableUnlinkTask g1_unlink_task(is_alive, process_strings, process_symbols);
     set_par_threads(n_workers);
     workers()->run_task(&g1_unlink_task);
@@ -4909,7 +4844,7 @@
 void G1CollectedHeap::redirty_logged_cards() {
   double redirty_logged_cards_start = os::elapsedTime();
 
-  uint n_workers = _g1h->workers()->active_workers();
+  uint n_workers = workers()->active_workers();
 
   G1RedirtyLoggedCardsTask redirty_task(&dirty_card_queue_set());
   dirty_card_queue_set().reset_for_par_iteration();
@@ -5022,8 +4957,7 @@
         _par_scan_state->push_on_queue(p);
       } else {
         assert(!Metaspace::contains((const void*)p),
-               err_msg("Unexpectedly found a pointer from metadata: "
-                              PTR_FORMAT, p));
+               err_msg("Unexpectedly found a pointer from metadata: " PTR_FORMAT, p2i(p)));
         _copy_non_heap_obj_cl->do_oop(p);
       }
     }
@@ -5342,7 +5276,7 @@
 
   OopClosure*                    copy_non_heap_cl = &only_copy_non_heap_cl;
 
-  if (_g1h->g1_policy()->during_initial_mark_pause()) {
+  if (g1_policy()->during_initial_mark_pause()) {
     // We also need to mark copied objects.
     copy_non_heap_cl = &copy_mark_non_heap_cl;
   }
@@ -5688,14 +5622,14 @@
 bool G1CollectedHeap::verify_no_bits_over_tams(const char* bitmap_name, CMBitMapRO* bitmap,
                                                HeapWord* tams, HeapWord* end) {
   guarantee(tams <= end,
-            err_msg("tams: "PTR_FORMAT" end: "PTR_FORMAT, tams, end));
+            err_msg("tams: "PTR_FORMAT" end: "PTR_FORMAT, p2i(tams), p2i(end)));
   HeapWord* result = bitmap->getNextMarkedWordAddress(tams, end);
   if (result < end) {
     gclog_or_tty->cr();
     gclog_or_tty->print_cr("## wrong marked address on %s bitmap: "PTR_FORMAT,
-                           bitmap_name, result);
+                           bitmap_name, p2i(result));
     gclog_or_tty->print_cr("## %s tams: "PTR_FORMAT" end: "PTR_FORMAT,
-                           bitmap_name, tams, end);
+                           bitmap_name, p2i(tams), p2i(end));
     return false;
   }
   return true;
@@ -6019,10 +5953,10 @@
         !r->rem_set()->is_empty()) {
 
       if (G1TraceEagerReclaimHumongousObjects) {
-        gclog_or_tty->print_cr("Live humongous region %u size "SIZE_FORMAT" start "PTR_FORMAT" length "UINT32_FORMAT" with remset "SIZE_FORMAT" code roots "SIZE_FORMAT" is marked %d reclaim candidate %d type array %d",
+        gclog_or_tty->print_cr("Live humongous region %u size "SIZE_FORMAT" start "PTR_FORMAT" length %u with remset "SIZE_FORMAT" code roots "SIZE_FORMAT" is marked %d reclaim candidate %d type array %d",
                                region_idx,
-                               obj->size()*HeapWordSize,
-                               r->bottom(),
+                               (size_t)obj->size() * HeapWordSize,
+                               p2i(r->bottom()),
                                r->region_num(),
                                r->rem_set()->occupied(),
                                r->rem_set()->strong_code_roots_list_length(),
@@ -6038,13 +5972,13 @@
     guarantee(obj->is_typeArray(),
               err_msg("Only eagerly reclaiming type arrays is supported, but the object "
                       PTR_FORMAT " is not.",
-                      r->bottom()));
+                      p2i(r->bottom())));
 
     if (G1TraceEagerReclaimHumongousObjects) {
-      gclog_or_tty->print_cr("Dead humongous region %u size "SIZE_FORMAT" start "PTR_FORMAT" length "UINT32_FORMAT" with remset "SIZE_FORMAT" code roots "SIZE_FORMAT" is marked %d reclaim candidate %d type array %d",
+      gclog_or_tty->print_cr("Dead humongous region %u size "SIZE_FORMAT" start "PTR_FORMAT" length %u with remset "SIZE_FORMAT" code roots "SIZE_FORMAT" is marked %d reclaim candidate %d type array %d",
                              region_idx,
-                             obj->size()*HeapWordSize,
-                             r->bottom(),
+                             (size_t)obj->size() * HeapWordSize,
+                             p2i(r->bottom()),
                              r->region_num(),
                              r->rem_set()->occupied(),
                              r->rem_set()->strong_code_roots_list_length(),
@@ -6097,12 +6031,12 @@
   HeapRegionSetCount empty_set;
   remove_from_old_sets(empty_set, cl.humongous_free_count());
 
-  G1HRPrinter* hr_printer = _g1h->hr_printer();
-  if (hr_printer->is_active()) {
+  G1HRPrinter* hrp = hr_printer();
+  if (hrp->is_active()) {
     FreeRegionListIterator iter(&local_cleanup_list);
     while (iter.more_available()) {
       HeapRegion* hr = iter.get_next();
-      hr_printer->cleanup(hr);
+      hrp->cleanup(hr);
     }
   }
 
@@ -6196,7 +6130,7 @@
   bool doHeapRegion(HeapRegion* r) {
     if (r->is_young()) {
       gclog_or_tty->print_cr("Region ["PTR_FORMAT", "PTR_FORMAT") tagged as young",
-                             r->bottom(), r->end());
+                             p2i(r->bottom()), p2i(r->end()));
       _success = false;
     }
     return false;
@@ -6546,7 +6480,7 @@
       assert(!hr->is_continues_humongous(),
              err_msg("trying to add code root "PTR_FORMAT" in continuation of humongous region "HR_FORMAT
                      " starting at "HR_FORMAT,
-                     _nm, HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region())));
+                     p2i(_nm), HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region())));
 
       // HeapRegion::add_strong_code_root_locked() avoids adding duplicate entries.
       hr->add_strong_code_root_locked(_nm);
@@ -6573,7 +6507,7 @@
       assert(!hr->is_continues_humongous(),
              err_msg("trying to remove code root "PTR_FORMAT" in continuation of humongous region "HR_FORMAT
                      " starting at "HR_FORMAT,
-                     _nm, HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region())));
+                     p2i(_nm), HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region())));
 
       hr->remove_strong_code_root(_nm);
     }
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Mon Apr 27 14:41:49 2015 +0200
@@ -39,7 +39,6 @@
 #include "gc_implementation/g1/heapRegionManager.hpp"
 #include "gc_implementation/g1/heapRegionSet.hpp"
 #include "gc_implementation/shared/hSpaceCounters.hpp"
-#include "gc_implementation/shared/parGCAllocBuffer.hpp"
 #include "gc_interface/collectedHeap.hpp"
 #include "memory/barrierSet.hpp"
 #include "memory/memRegion.hpp"
@@ -202,9 +201,6 @@
   friend class G1CheckCSetFastTableClosure;
 
 private:
-  // The one and only G1CollectedHeap, so static functions can find it.
-  static G1CollectedHeap* _g1h;
-
   FlexibleWorkGang* _workers;
 
   static size_t _humongous_object_threshold_in_words;
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Mon Apr 27 14:41:49 2015 +0200
@@ -22,11 +22,6 @@
  *
  */
 
-#ifndef __clang_major__
-// FIXME, formats have issues.  Disable this macro definition, compile, and study warnings for more information.
-#define ATTRIBUTE_PRINTF(x,y)
-#endif
-
 #include "precompiled.hpp"
 #include "gc_implementation/g1/concurrentG1Refine.hpp"
 #include "gc_implementation/g1/concurrentMark.hpp"
@@ -302,7 +297,7 @@
   if (reserve_perc > 50) {
     reserve_perc = 50;
     warning("G1ReservePercent is set to a value that is too large, "
-            "it's been updated to %u", reserve_perc);
+            "it's been updated to " UINTX_FORMAT, reserve_perc);
   }
   _reserve_factor = (double) reserve_perc / 100.0;
   // This will be set when the heap is expanded
@@ -1800,7 +1795,7 @@
     assert(csr->in_collection_set(), "bad CS");
     st->print_cr("  "HR_FORMAT", P: "PTR_FORMAT "N: "PTR_FORMAT", age: %4d",
                  HR_FORMAT_PARAMS(csr),
-                 csr->prev_top_at_mark_start(), csr->next_top_at_mark_start(),
+                 p2i(csr->prev_top_at_mark_start()), p2i(csr->next_top_at_mark_start()),
                  csr->age_in_surv_rate_group_cond());
     csr = next;
   }
@@ -2166,7 +2161,7 @@
 void TraceYoungGenTimeData::print_summary_sd(const char* str,
                                              const NumberSeq* seq) const {
   print_summary(str, seq);
-  gclog_or_tty->print_cr("%+45s = %5d, std dev = %8.2lf ms, max = %8.2lf ms)",
+  gclog_or_tty->print_cr("%45s = %5d, std dev = %8.2lf ms, max = %8.2lf ms)",
                 "(num", seq->num(), seq->sd(), seq->maximum());
 }
 
--- a/hotspot/src/share/vm/gc_implementation/g1/g1ErgoVerbose.hpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1ErgoVerbose.hpp	Mon Apr 27 14:41:49 2015 +0200
@@ -160,40 +160,43 @@
   } while (0)
 
 
-#define ergo_verbose(_tag_, _action_)                                   \
-  ergo_verbose_common(_tag_, _action_, "", 0, 0, 0, 0, 0, 0)
-
-#define ergo_verbose0(_tag_, _action_, _extra_format_)                  \
-  ergo_verbose_common(_tag_, _action_, _extra_format_, 0, 0, 0, 0, 0, 0)
-
-#define ergo_verbose1(_tag_, _action_, _extra_format_,                  \
-                      _arg0_)                                           \
-  ergo_verbose_common(_tag_, _action_, _extra_format_,                  \
-                      _arg0_, 0, 0, 0, 0, 0)
-
-#define ergo_verbose2(_tag_, _action_, _extra_format_,                  \
-                      _arg0_, _arg1_)                                   \
-  ergo_verbose_common(_tag_, _action_, _extra_format_,                  \
-                      _arg0_, _arg1_, 0, 0, 0, 0)
-
-#define ergo_verbose3(_tag_, _action_, _extra_format_,                  \
-                      _arg0_, _arg1_, _arg2_)                           \
-  ergo_verbose_common(_tag_, _action_, _extra_format_,                  \
-                      _arg0_, _arg1_, _arg2_, 0, 0, 0)
-
-#define ergo_verbose4(_tag_, _action_, _extra_format_,                  \
-                      _arg0_, _arg1_, _arg2_, _arg3_)                   \
-  ergo_verbose_common(_tag_, _action_, _extra_format_,                  \
-                      _arg0_, _arg1_, _arg2_, _arg3_, 0, 0)
-
-#define ergo_verbose5(_tag_, _action_, _extra_format_,                  \
-                      _arg0_, _arg1_, _arg2_, _arg3_, _arg4_)           \
-  ergo_verbose_common(_tag_, _action_, _extra_format_,                  \
-                      _arg0_, _arg1_, _arg2_, _arg3_, _arg4_, 0)
-
 #define ergo_verbose6(_tag_, _action_, _extra_format_,                  \
                       _arg0_, _arg1_, _arg2_, _arg3_, _arg4_, _arg5_)   \
   ergo_verbose_common(_tag_, _action_, _extra_format_,                  \
                       _arg0_, _arg1_, _arg2_, _arg3_, _arg4_, _arg5_)
 
+#define ergo_verbose5(_tag_, _action_, _extra_format_,                  \
+                      _arg0_, _arg1_, _arg2_, _arg3_, _arg4_)           \
+  ergo_verbose6(_tag_, _action_, _extra_format_ "%s",                   \
+                _arg0_, _arg1_, _arg2_, _arg3_, _arg4_, "")
+
+#define ergo_verbose4(_tag_, _action_, _extra_format_,                  \
+                      _arg0_, _arg1_, _arg2_, _arg3_)                   \
+  ergo_verbose5(_tag_, _action_, _extra_format_ "%s",                   \
+                _arg0_, _arg1_, _arg2_, _arg3_, "")
+
+#define ergo_verbose3(_tag_, _action_, _extra_format_,                  \
+                      _arg0_, _arg1_, _arg2_)                           \
+  ergo_verbose4(_tag_, _action_, _extra_format_ "%s",                   \
+                _arg0_, _arg1_, _arg2_, "")
+
+#define ergo_verbose2(_tag_, _action_, _extra_format_,                  \
+                      _arg0_, _arg1_)                                   \
+  ergo_verbose3(_tag_, _action_, _extra_format_ "%s",                   \
+                _arg0_, _arg1_, "")
+
+#define ergo_verbose1(_tag_, _action_, _extra_format_,                  \
+                      _arg0_)                                           \
+  ergo_verbose2(_tag_, _action_, _extra_format_ "%s",                   \
+                _arg0_, "")
+
+
+#define ergo_verbose0(_tag_, _action_, _extra_format_)                  \
+  ergo_verbose1(_tag_, _action_, _extra_format_ "%s",                   \
+                "")
+
+#define ergo_verbose(_tag_, _action_)                                   \
+  ergo_verbose0(_tag_, _action_, "")
+
+
 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1ERGOVERBOSE_HPP
--- a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp	Mon Apr 27 14:41:49 2015 +0200
@@ -119,7 +119,6 @@
                                     bool clear_all_softrefs) {
   // Recursively traverse all live objects and mark them
   GCTraceTime tm("phase 1", G1Log::fine() && Verbose, true, gc_timer(), gc_tracer()->gc_id());
-  GenMarkSweep::trace(" 1");
 
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
 
@@ -199,7 +198,6 @@
   // tracking expects us to do so. See comment under phase4.
 
   GCTraceTime tm("phase 2", G1Log::fine() && Verbose, true, gc_timer(), gc_tracer()->gc_id());
-  GenMarkSweep::trace("2");
 
   prepare_compaction();
 }
@@ -233,7 +231,6 @@
 
   // Adjust the pointers to reflect the new locations
   GCTraceTime tm("phase 3", G1Log::fine() && Verbose, true, gc_timer(), gc_tracer()->gc_id());
-  GenMarkSweep::trace("3");
 
   // Need cleared claim bits for the roots processing
   ClassLoaderDataGraph::clear_claimed_marks();
@@ -295,7 +292,6 @@
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
 
   GCTraceTime tm("phase 4", G1Log::fine() && Verbose, true, gc_timer(), gc_tracer()->gc_id());
-  GenMarkSweep::trace("4");
 
   G1SpaceCompactClosure blk;
   g1h->heap_region_iterate(&blk);
--- a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp	Mon Apr 27 14:41:49 2015 +0200
@@ -41,15 +41,6 @@
   develop(intx, G1MarkingVerboseLevel, 0,                                   \
           "Level (0-4) of verboseness of the marking code")                 \
                                                                             \
-  develop(bool, G1PrintReachableAtInitialMark, false,                       \
-          "Reachable object dump at the initial mark pause")                \
-                                                                            \
-  develop(bool, G1VerifyDuringGCPrintReachable, false,                      \
-          "If conc mark verification fails, dump reachable objects")        \
-                                                                            \
-  develop(ccstr, G1PrintReachableBaseFile, NULL,                            \
-          "The base file name for the reachable object dumps")              \
-                                                                            \
   develop(bool, G1TraceMarkStackOverflow, false,                            \
           "If true, extra debugging code for CM restart for ovflw.")        \
                                                                             \
@@ -99,9 +90,6 @@
           "the buffer will be enqueued for processing. A value of 0 "       \
           "specifies that mutator threads should not do such filtering.")   \
                                                                             \
-  develop(bool, G1SATBPrintStubs, false,                                    \
-          "If true, print generated stubs for the SATB barrier")            \
-                                                                            \
   experimental(intx, G1ExpandByPercentOfAvailable, 20,                      \
           "When expanding, % of uncommitted space to claim.")               \
                                                                             \
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp	Mon Apr 27 14:41:49 2015 +0200
@@ -44,6 +44,7 @@
 // The solution is to remove this method from the definition
 // of a Space.
 
+class G1CollectedHeap;
 class HeapRegionRemSet;
 class HeapRegionRemSetIterator;
 class HeapRegion;
--- a/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp	Mon Apr 27 14:41:49 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,30 +33,67 @@
 #include "runtime/vmThread.hpp"
 
 void ObjPtrQueue::flush() {
-  // The buffer might contain refs into the CSet. We have to filter it
-  // first before we flush it, otherwise we might end up with an
-  // enqueued buffer with refs into the CSet which breaks our invariants.
+  // Filter now to possibly save work later.  If filtering empties the
+  // buffer then flush_impl can deallocate the buffer.
   filter();
   flush_impl();
 }
 
-// This method removes entries from an SATB buffer that will not be
-// useful to the concurrent marking threads. An entry is removed if it
-// satisfies one of the following conditions:
+// Return true if a SATB buffer entry refers to an object that
+// requires marking.
+//
+// The entry must point into the G1 heap.  In particular, it must not
+// be a NULL pointer.  NULL pointers are pre-filtered and never
+// inserted into a SATB buffer.
+//
+// An entry that is below the NTAMS pointer for the containing heap
+// region requires marking. Such an entry must point to a valid object.
+//
+// An entry that is at least the NTAMS pointer for the containing heap
+// region might be any of the following, none of which should be marked.
+//
+// * A reference to an object allocated since marking started.
+//   According to SATB, such objects are implicitly kept live and do
+//   not need to be dealt with via SATB buffer processing.
+//
+// * A reference to a young generation object. Young objects are
+//   handled separately and are not marked by concurrent marking.
+//
+// * A stale reference to a young generation object. If a young
+//   generation object reference is recorded and not filtered out
+//   before being moved by a young collection, the reference becomes
+//   stale.
 //
-// * it points to an object outside the G1 heap (G1's concurrent
-//     marking only visits objects inside the G1 heap),
-// * it points to an object that has been allocated since marking
-//     started (according to SATB those objects do not need to be
-//     visited during marking), or
-// * it points to an object that has already been marked (no need to
-//     process it again).
+// * A stale reference to an eagerly reclaimed humongous object.  If a
+//   humongous object is recorded and then reclaimed, the reference
+//   becomes stale.
 //
-// The rest of the entries will be retained and are compacted towards
-// the top of the buffer. Note that, because we do not allow old
-// regions in the CSet during marking, all objects on the CSet regions
-// are young (eden or survivors) and therefore implicitly live. So any
-// references into the CSet will be removed during filtering.
+// The stale reference cases are implicitly handled by the NTAMS
+// comparison. Because of the possibility of stale references, buffer
+// processing must be somewhat circumspect and not assume entries
+// in an unfiltered buffer refer to valid objects.
+
+inline bool requires_marking(const void* entry, G1CollectedHeap* heap) {
+  // Includes rejection of NULL pointers.
+  assert(heap->is_in_reserved(entry),
+         err_msg("Non-heap pointer in SATB buffer: " PTR_FORMAT, p2i(entry)));
+
+  HeapRegion* region = heap->heap_region_containing_raw(entry);
+  assert(region != NULL, err_msg("No region for " PTR_FORMAT, p2i(entry)));
+  if (entry >= region->next_top_at_mark_start()) {
+    return false;
+  }
+
+  assert(((oop)entry)->is_oop(true /* ignore mark word */),
+         err_msg("Invalid oop in SATB buffer: " PTR_FORMAT, p2i(entry)));
+
+  return true;
+}
+
+// This method removes entries from a SATB buffer that will not be
+// useful to the concurrent marking threads.  Entries are retained if
+// they require marking and are not already marked. Retained entries
+// are compacted toward the top of the buffer.
 
 void ObjPtrQueue::filter() {
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
@@ -78,26 +115,25 @@
     assert(i > 0, "we should have at least one more entry to process");
     i -= oopSize;
     debug_only(entries += 1;)
-    oop* p = (oop*) &buf[byte_index_to_index((int) i)];
-    oop obj = *p;
+    void** p = &buf[byte_index_to_index((int) i)];
+    void* entry = *p;
     // NULL the entry so that unused parts of the buffer contain NULLs
     // at the end. If we are going to retain it we will copy it to its
     // final place. If we have retained all entries we have visited so
     // far, we'll just end up copying it to the same place.
     *p = NULL;
 
-    bool retain = g1h->is_obj_ill(obj);
-    if (retain) {
+    if (requires_marking(entry, g1h) && !g1h->isMarkedNext((oop)entry)) {
       assert(new_index > 0, "we should not have already filled up the buffer");
       new_index -= oopSize;
       assert(new_index >= i,
              "new_index should never be below i, as we always compact 'up'");
-      oop* new_p = (oop*) &buf[byte_index_to_index((int) new_index)];
+      void** new_p = &buf[byte_index_to_index((int) new_index)];
       assert(new_p >= p, "the destination location should never be below "
              "the source as we always compact 'up'");
       assert(*new_p == NULL,
              "we should have already cleared the destination location");
-      *new_p = obj;
+      *new_p = entry;
       debug_only(retained += 1;)
     }
   }
@@ -144,12 +180,6 @@
   return should_enqueue;
 }
 
-void ObjPtrQueue::apply_closure(ObjectClosure* cl) {
-  if (_buf != NULL) {
-    apply_closure_to_buffer(cl, _buf, _index, _sz);
-  }
-}
-
 void ObjPtrQueue::apply_closure_and_empty(ObjectClosure* cl) {
   if (_buf != NULL) {
     apply_closure_to_buffer(cl, _buf, _index, _sz);
@@ -184,23 +214,12 @@
 }
 #endif // PRODUCT
 
-#ifdef ASSERT
-void ObjPtrQueue::verify_oops_in_buffer() {
-  if (_buf == NULL) return;
-  for (size_t i = _index; i < _sz; i += oopSize) {
-    oop obj = (oop)_buf[byte_index_to_index((int)i)];
-    assert(obj != NULL && obj->is_oop(true /* ignore mark word */),
-           "Not an oop");
-  }
-}
-#endif
-
 #ifdef _MSC_VER // the use of 'this' below gets a warning, make it go away
 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list
 #endif // _MSC_VER
 
 SATBMarkQueueSet::SATBMarkQueueSet() :
-  PtrQueueSet(), _closures(NULL),
+  PtrQueueSet(),
   _shared_satb_queue(this, true /*perm*/) { }
 
 void SATBMarkQueueSet::initialize(Monitor* cbl_mon, Mutex* fl_lock,
@@ -208,11 +227,9 @@
                                   Mutex* lock) {
   PtrQueueSet::initialize(cbl_mon, fl_lock, process_completed_threshold, -1);
   _shared_satb_queue.set_lock(lock);
-  _closures = NEW_C_HEAP_ARRAY(ObjectClosure*, ParallelGCThreads, mtGC);
 }
 
 void SATBMarkQueueSet::handle_zero_index_for_thread(JavaThread* t) {
-  DEBUG_ONLY(t->satb_mark_queue().verify_oops_in_buffer();)
   t->satb_mark_queue().handle_zero_index();
 }
 
@@ -272,13 +289,7 @@
   shared_satb_queue()->filter();
 }
 
-void SATBMarkQueueSet::set_closure(uint worker, ObjectClosure* closure) {
-  assert(_closures != NULL, "Precondition");
-  assert(worker < ParallelGCThreads, "Worker index must be in range [0...ParallelGCThreads)");
-  _closures[worker] = closure;
-}
-
-bool SATBMarkQueueSet::apply_closure_to_completed_buffer(uint worker) {
+bool SATBMarkQueueSet::apply_closure_to_completed_buffer(ObjectClosure* cl) {
   BufferNode* nd = NULL;
   {
     MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
@@ -290,7 +301,6 @@
       if (_n_completed_buffers == 0) _process_completed = false;
     }
   }
-  ObjectClosure* cl = _closures[worker];
   if (nd != NULL) {
     void **buf = BufferNode::make_buffer_from_node(nd);
     ObjPtrQueue::apply_closure_to_buffer(cl, buf, 0, _sz);
@@ -301,28 +311,6 @@
   }
 }
 
-void SATBMarkQueueSet::iterate_completed_buffers_read_only(ObjectClosure* cl) {
-  assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
-  assert(cl != NULL, "pre-condition");
-
-  BufferNode* nd = _completed_buffers_head;
-  while (nd != NULL) {
-    void** buf = BufferNode::make_buffer_from_node(nd);
-    ObjPtrQueue::apply_closure_to_buffer(cl, buf, 0, _sz);
-    nd = nd->next();
-  }
-}
-
-void SATBMarkQueueSet::iterate_thread_buffers_read_only(ObjectClosure* cl) {
-  assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
-  assert(cl != NULL, "pre-condition");
-
-  for (JavaThread* t = Threads::first(); t; t = t->next()) {
-    t->satb_mark_queue().apply_closure(cl);
-  }
-  shared_satb_queue()->apply_closure(cl);
-}
-
 #ifndef PRODUCT
 // Helpful for debugging
 
--- a/hotspot/src/share/vm/gc_implementation/g1/satbQueue.hpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/satbQueue.hpp	Mon Apr 27 14:41:49 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,9 +41,6 @@
   // Filter out unwanted entries from the buffer.
   void filter();
 
-  // Apply the closure to all elements.
-  void apply_closure(ObjectClosure* cl);
-
   // Apply the closure to all elements and empty the buffer;
   void apply_closure_and_empty(ObjectClosure* cl);
 
@@ -72,13 +69,9 @@
   void print(const char* name);
   static void print(const char* name, void** buf, size_t index, size_t sz);
 #endif // PRODUCT
-
-  void verify_oops_in_buffer() NOT_DEBUG_RETURN;
 };
 
 class SATBMarkQueueSet: public PtrQueueSet {
-  ObjectClosure** _closures;  // One per ParGCThread.
-
   ObjPtrQueue _shared_satb_queue;
 
 #ifdef ASSERT
@@ -104,22 +97,10 @@
   // Filter all the currently-active SATB buffers.
   void filter_thread_buffers();
 
-  // Register closure for the given worker thread. The "apply_closure_to_completed_buffer"
-  // method will apply this closure to a completed buffer, and "iterate_closure_all_threads"
-  // applies it to partially-filled buffers (the latter should only be done
-  // with the world stopped).
-  void set_closure(uint worker, ObjectClosure* closure);
-
   // If there exists some completed buffer, pop it, then apply the
-  // registered closure to all its elements, and return true.  If no
+  // closure to all its elements, and return true.  If no
   // completed buffers exist, return false.
-  bool apply_closure_to_completed_buffer(uint worker);
-
-  // Apply the given closure on enqueued and currently-active buffers
-  // respectively. Both methods are read-only, i.e., they do not
-  // modify any of the buffers.
-  void iterate_completed_buffers_read_only(ObjectClosure* cl);
-  void iterate_thread_buffers_read_only(ObjectClosure* cl);
+  bool apply_closure_to_completed_buffer(ObjectClosure* closure);
 
 #ifndef PRODUCT
   // Helpful for debugging
--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Mon Apr 27 14:41:49 2015 +0200
@@ -34,7 +34,7 @@
 #include "gc_implementation/shared/gcTimer.hpp"
 #include "gc_implementation/shared/gcTrace.hpp"
 #include "gc_implementation/shared/gcTraceTime.hpp"
-#include "gc_implementation/shared/parGCAllocBuffer.inline.hpp"
+#include "gc_implementation/shared/plab.inline.hpp"
 #include "gc_implementation/shared/spaceDecorator.hpp"
 #include "memory/defNewGeneration.inline.hpp"
 #include "memory/genCollectedHeap.hpp"
@@ -226,7 +226,7 @@
   // buffer.
   HeapWord* obj = NULL;
   if (!_to_space_full) {
-    ParGCAllocBuffer* const plab = to_space_alloc_buffer();
+    PLAB* const plab = to_space_alloc_buffer();
     Space*            const sp   = to_space();
     if (word_sz * 100 <
         ParallelGCBufferWastePct * plab->word_sz()) {
@@ -236,7 +236,7 @@
       HeapWord* buf_space = sp->par_allocate(buf_size);
       if (buf_space == NULL) {
         const size_t min_bytes =
-          ParGCAllocBuffer::min_size() << LogHeapWordSize;
+          PLAB::min_size() << LogHeapWordSize;
         size_t free_bytes = sp->free();
         while(buf_space == NULL && free_bytes >= min_bytes) {
           buf_size = free_bytes >> LogHeapWordSize;
@@ -252,7 +252,7 @@
         record_survivor_plab(buf_space, buf_size);
         obj = plab->allocate_aligned(word_sz, SurvivorAlignmentInBytes);
         // Note that we cannot compare buf_size < word_sz below
-        // because of AlignmentReserve (see ParGCAllocBuffer::allocate()).
+        // because of AlignmentReserve (see PLAB::allocate()).
         assert(obj != NULL || plab->words_remaining() < word_sz,
                "Else should have been able to allocate");
         // It's conceivable that we may be able to use the
--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp	Mon Apr 27 14:41:49 2015 +0200
@@ -27,7 +27,7 @@
 
 #include "gc_implementation/parNew/parOopClosures.hpp"
 #include "gc_implementation/shared/gcTrace.hpp"
-#include "gc_implementation/shared/parGCAllocBuffer.hpp"
+#include "gc_implementation/shared/plab.hpp"
 #include "gc_implementation/shared/copyFailedInfo.hpp"
 #include "memory/defNewGeneration.hpp"
 #include "memory/padded.hpp"
@@ -65,7 +65,7 @@
   ObjToScanQueue *_work_queue;
   Stack<oop, mtGC>* const _overflow_stack;
 
-  ParGCAllocBuffer _to_space_alloc_buffer;
+  PLAB _to_space_alloc_buffer;
 
   ParScanWithoutBarrierClosure         _to_space_closure; // scan_without_gc_barrier
   ParScanWithBarrierClosure            _old_gen_closure; // scan_with_gc_barrier
@@ -140,7 +140,7 @@
 
   ObjToScanQueue* work_queue() { return _work_queue; }
 
-  ParGCAllocBuffer* to_space_alloc_buffer() {
+  PLAB* to_space_alloc_buffer() {
     return &_to_space_alloc_buffer;
   }
 
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp	Mon Apr 27 14:41:49 2015 +0200
@@ -49,30 +49,19 @@
 PSOldGen*    ParallelScavengeHeap::_old_gen = NULL;
 PSAdaptiveSizePolicy* ParallelScavengeHeap::_size_policy = NULL;
 PSGCAdaptivePolicyCounters* ParallelScavengeHeap::_gc_policy_counters = NULL;
-ParallelScavengeHeap* ParallelScavengeHeap::_psh = NULL;
 GCTaskManager* ParallelScavengeHeap::_gc_task_manager = NULL;
 
 jint ParallelScavengeHeap::initialize() {
   CollectedHeap::pre_initialize();
 
-  // Initialize collector policy
-  _collector_policy = new GenerationSizer();
-  _collector_policy->initialize_all();
-
   const size_t heap_size = _collector_policy->max_heap_byte_size();
 
   ReservedSpace heap_rs = Universe::reserve_heap(heap_size, _collector_policy->heap_alignment());
-  MemTracker::record_virtual_memory_type((address)heap_rs.base(), mtJavaHeap);
 
   os::trace_page_sizes("ps main", _collector_policy->min_heap_byte_size(),
                        heap_size, generation_alignment(),
                        heap_rs.base(),
                        heap_rs.size());
-  if (!heap_rs.is_reserved()) {
-    vm_shutdown_during_initialization(
-      "Could not reserve enough space for object heap");
-    return JNI_ENOMEM;
-  }
 
   initialize_reserved_region((HeapWord*)heap_rs.base(), (HeapWord*)(heap_rs.base() + heap_rs.size()));
 
@@ -89,7 +78,6 @@
   double max_gc_pause_sec = ((double) MaxGCPauseMillis)/1000.0;
   double max_gc_minor_pause_sec = ((double) MaxGCMinorPauseMillis)/1000.0;
 
-  _psh = this;
   _gens = new AdjoiningGenerations(heap_rs, _collector_policy, generation_alignment());
 
   _old_gen = _gens->old_gen();
@@ -634,9 +622,10 @@
 }
 
 ParallelScavengeHeap* ParallelScavengeHeap::heap() {
-  assert(_psh != NULL, "Uninitialized access to ParallelScavengeHeap::heap()");
-  assert(_psh->kind() == CollectedHeap::ParallelScavengeHeap, "not a parallel scavenge heap");
-  return _psh;
+  CollectedHeap* heap = Universe::heap();
+  assert(heap != NULL, "Uninitialized access to ParallelScavengeHeap::heap()");
+  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Not a ParallelScavengeHeap");
+  return (ParallelScavengeHeap*)heap;
 }
 
 // Before delegating the resize to the young generation,
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp	Mon Apr 27 14:41:49 2015 +0200
@@ -53,8 +53,6 @@
   static PSAdaptiveSizePolicy*       _size_policy;
   static PSGCAdaptivePolicyCounters* _gc_policy_counters;
 
-  static ParallelScavengeHeap* _psh;
-
   GenerationSizer* _collector_policy;
 
   // Collection of generations that are adjacent in the
@@ -76,7 +74,8 @@
   HeapWord* mem_allocate_old_gen(size_t size);
 
  public:
-  ParallelScavengeHeap() : CollectedHeap(), _death_march_count(0) { }
+  ParallelScavengeHeap(GenerationSizer* policy) :
+    CollectedHeap(), _collector_policy(policy), _death_march_count(0) { }
 
   // For use by VM operations
   enum CollectionType {
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Mon Apr 27 14:41:49 2015 +0200
@@ -510,7 +510,6 @@
 void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
   // Recursively traverse all live objects and mark them
   GCTraceTime tm("phase 1", PrintGCDetails && Verbose, true, _gc_timer, _gc_tracer->gc_id());
-  trace(" 1");
 
   ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
 
@@ -570,7 +569,6 @@
 
 void PSMarkSweep::mark_sweep_phase2() {
   GCTraceTime tm("phase 2", PrintGCDetails && Verbose, true, _gc_timer, _gc_tracer->gc_id());
-  trace("2");
 
   // Now all live objects are marked, compute the new object addresses.
 
@@ -598,7 +596,6 @@
 void PSMarkSweep::mark_sweep_phase3() {
   // Adjust the pointers to reflect the new locations
   GCTraceTime tm("phase 3", PrintGCDetails && Verbose, true, _gc_timer, _gc_tracer->gc_id());
-  trace("3");
 
   ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   PSYoungGen* young_gen = heap->young_gen();
@@ -639,7 +636,6 @@
 void PSMarkSweep::mark_sweep_phase4() {
   EventMark m("4 compact heap");
   GCTraceTime tm("phase 4", PrintGCDetails && Verbose, true, _gc_timer, _gc_tracer->gc_id());
-  trace("4");
 
   // All pointers are now adjusted, move objects accordingly
 
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.hpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.hpp	Mon Apr 27 14:41:49 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -60,11 +60,29 @@
   // Used when initializing the _name field.
   static inline const char* select_name();
 
+#ifdef ASSERT
+  void assert_block_in_covered_region(MemRegion new_memregion) {
+    // Explictly capture current covered_region in a local
+    MemRegion covered_region = this->start_array()->covered_region();
+    assert(covered_region.contains(new_memregion),
+           err_msg("new region is not in covered_region [ "PTR_FORMAT", "PTR_FORMAT" ], "
+                   "new region [ "PTR_FORMAT", "PTR_FORMAT" ], "
+                   "object space [ "PTR_FORMAT", "PTR_FORMAT" ]",
+                   p2i(covered_region.start()),
+                   p2i(covered_region.end()),
+                   p2i(new_memregion.start()),
+                   p2i(new_memregion.end()),
+                   p2i(this->object_space()->used_region().start()),
+                   p2i(this->object_space()->used_region().end())));
+  }
+#endif
+
   HeapWord* allocate_noexpand(size_t word_size) {
     // We assume the heap lock is held here.
     assert_locked_or_safepoint(Heap_lock);
     HeapWord* res = object_space()->allocate(word_size);
     if (res != NULL) {
+      DEBUG_ONLY(assert_block_in_covered_region(MemRegion(res, word_size)));
       _start_array.allocate_block(res);
     }
     return res;
@@ -77,6 +95,7 @@
     assert(SafepointSynchronize::is_at_safepoint(), "Must only be called at safepoint");
     HeapWord* res = object_space()->cas_allocate(word_size);
     if (res != NULL) {
+      DEBUG_ONLY(assert_block_in_covered_region(MemRegion(res, word_size)));
       _start_array.allocate_block(res);
     }
     return res;
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.cpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.cpp	Mon Apr 27 14:41:49 2015 +0200
@@ -26,7 +26,6 @@
 #include "gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp"
 #include "gc_implementation/parallelScavenge/psMarkSweep.hpp"
 #include "gc_implementation/parallelScavenge/psScavenge.hpp"
-#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
 #include "gc_implementation/parallelScavenge/vmPSOperations.hpp"
 #include "memory/gcLocker.inline.hpp"
 #include "utilities/dtrace.hpp"
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmStructs_parallelgc.hpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmStructs_parallelgc.hpp	Mon Apr 27 14:41:49 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -61,7 +61,6 @@
                                                                                                                                      \
      static_field(ParallelScavengeHeap,        _young_gen,                                    PSYoungGen*)                           \
      static_field(ParallelScavengeHeap,        _old_gen,                                      PSOldGen*)                             \
-     static_field(ParallelScavengeHeap,        _psh,                                          ParallelScavengeHeap*)                 \
                                                                                                                                      \
 
 #define VM_TYPES_PARALLELGC(declare_type,                                 \
--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp	Mon Apr 27 14:41:49 2015 +0200
@@ -338,15 +338,6 @@
   MarkSweep::_gc_tracer = new (ResourceObj::C_HEAP, mtGC) SerialOldTracer();
 }
 
-#ifndef PRODUCT
-
-void MarkSweep::trace(const char* msg) {
-  if (TraceMarkSweep)
-    gclog_or_tty->print("%s", msg);
-}
-
-#endif
-
 int InstanceKlass::oop_ms_adjust_pointers(oop obj) {
   int size = size_helper();
   oop_oop_iterate_oop_maps<true>(obj, &MarkSweep::adjust_pointer_closure);
--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp	Mon Apr 27 14:41:49 2015 +0200
@@ -131,9 +131,6 @@
   // Non public closures
   static KeepAliveClosure keep_alive;
 
-  // Debugging
-  static void trace(const char* msg) PRODUCT_RETURN;
-
  public:
   // Public closures
   static IsAliveClosure       is_alive;
--- a/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp	Thu Apr 23 12:47:23 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,134 +0,0 @@
-/*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "gc_implementation/shared/parGCAllocBuffer.hpp"
-#include "memory/threadLocalAllocBuffer.hpp"
-#include "oops/arrayOop.hpp"
-#include "oops/oop.inline.hpp"
-
-size_t ParGCAllocBuffer::min_size() {
-  // Make sure that we return something that is larger than AlignmentReserve
-  return align_object_size(MAX2(MinTLABSize / HeapWordSize, (uintx)oopDesc::header_size())) + AlignmentReserve;
-}
-
-size_t ParGCAllocBuffer::max_size() {
-  return ThreadLocalAllocBuffer::max_size();
-}
-
-ParGCAllocBuffer::ParGCAllocBuffer(size_t desired_plab_sz_) :
-  _word_sz(desired_plab_sz_), _bottom(NULL), _top(NULL),
-  _end(NULL), _hard_end(NULL), _allocated(0), _wasted(0)
-{
-  // ArrayOopDesc::header_size depends on command line initialization.
-  AlignmentReserve = oopDesc::header_size() > MinObjAlignment ? align_object_size(arrayOopDesc::header_size(T_INT)) : 0;
-  assert(min_size() > AlignmentReserve,
-         err_msg("Minimum PLAB size " SIZE_FORMAT" must be larger than alignment reserve " SIZE_FORMAT" "
-                 "to be able to contain objects", min_size(), AlignmentReserve));
-}
-
-// If the minimum object size is greater than MinObjAlignment, we can
-// end up with a shard at the end of the buffer that's smaller than
-// the smallest object.  We can't allow that because the buffer must
-// look like it's full of objects when we retire it, so we make
-// sure we have enough space for a filler int array object.
-size_t ParGCAllocBuffer::AlignmentReserve;
-
-void ParGCAllocBuffer::flush_and_retire_stats(PLABStats* stats) {
-  // Retire the last allocation buffer.
-  size_t unused = retire_internal();
-
-  // Now flush the statistics.
-  stats->add_allocated(_allocated);
-  stats->add_wasted(_wasted);
-  stats->add_unused(unused);
-
-  // Since we have flushed the stats we need to clear  the _allocated and _wasted
-  // fields in case somebody retains an instance of this over GCs. Not doing so
-  // will artifically inflate the values in the statistics.
-  _allocated = 0;
-  _wasted = 0;
-}
-
-void ParGCAllocBuffer::retire() {
-  _wasted += retire_internal();
-}
-
-size_t ParGCAllocBuffer::retire_internal() {
-  size_t result = 0;
-  if (_top < _hard_end) {
-    CollectedHeap::fill_with_object(_top, _hard_end);
-    result += invalidate();
-  }
-  return result;
-}
-
-// Compute desired plab size and latch result for later
-// use. This should be called once at the end of parallel
-// scavenge; it clears the sensor accumulators.
-void PLABStats::adjust_desired_plab_sz(uint no_of_gc_workers) {
-  assert(ResizePLAB, "Not set");
-
-  assert(is_object_aligned(max_size()) && min_size() <= max_size(),
-         "PLAB clipping computation may be incorrect");
-
-  if (_allocated == 0) {
-    assert(_unused == 0,
-           err_msg("Inconsistency in PLAB stats: "
-                   "_allocated: "SIZE_FORMAT", "
-                   "_wasted: "SIZE_FORMAT", "
-                   "_unused: "SIZE_FORMAT,
-                   _allocated, _wasted, _unused));
-
-    _allocated = 1;
-  }
-  double wasted_frac    = (double)_unused / (double)_allocated;
-  size_t target_refills = (size_t)((wasted_frac * TargetSurvivorRatio) / TargetPLABWastePct);
-  if (target_refills == 0) {
-    target_refills = 1;
-  }
-  size_t used = _allocated - _wasted - _unused;
-  size_t recent_plab_sz = used / (target_refills * no_of_gc_workers);
-  // Take historical weighted average
-  _filter.sample(recent_plab_sz);
-  // Clip from above and below, and align to object boundary
-  size_t new_plab_sz = MAX2(min_size(), (size_t)_filter.average());
-  new_plab_sz = MIN2(max_size(), new_plab_sz);
-  new_plab_sz = align_object_size(new_plab_sz);
-  // Latch the result
-  if (PrintPLAB) {
-    gclog_or_tty->print(" (plab_sz = " SIZE_FORMAT" desired_plab_sz = " SIZE_FORMAT") ", recent_plab_sz, new_plab_sz);
-  }
-  _desired_plab_sz = new_plab_sz;
-
-  reset();
-}
-
-#ifndef PRODUCT
-void ParGCAllocBuffer::print() {
-  gclog_or_tty->print_cr("parGCAllocBuffer: _bottom: " PTR_FORMAT "  _top: " PTR_FORMAT
-    "  _end: " PTR_FORMAT "  _hard_end: " PTR_FORMAT ")",
-    p2i(_bottom), p2i(_top), p2i(_end), p2i(_hard_end));
-}
-#endif // !PRODUCT
--- a/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp	Thu Apr 23 12:47:23 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,197 +0,0 @@
-/*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARGCALLOCBUFFER_HPP
-#define SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARGCALLOCBUFFER_HPP
-
-#include "gc_implementation/shared/gcUtil.hpp"
-#include "memory/allocation.hpp"
-#include "runtime/atomic.hpp"
-#include "utilities/globalDefinitions.hpp"
-
-// Forward declarations.
-class PLABStats;
-
-// A per-thread allocation buffer used during GC.
-class ParGCAllocBuffer: public CHeapObj<mtGC> {
-protected:
-  char      head[32];
-  size_t    _word_sz;          // In HeapWord units
-  HeapWord* _bottom;
-  HeapWord* _top;
-  HeapWord* _end;           // Last allocatable address + 1
-  HeapWord* _hard_end;      // _end + AlignmentReserve
-  // In support of ergonomic sizing of PLAB's
-  size_t    _allocated;     // in HeapWord units
-  size_t    _wasted;        // in HeapWord units
-  char      tail[32];
-  static size_t AlignmentReserve;
-
-  // Force future allocations to fail and queries for contains()
-  // to return false. Returns the amount of unused space in this PLAB.
-  size_t invalidate() {
-    _end    = _hard_end;
-    size_t remaining = pointer_delta(_end, _top);  // Calculate remaining space.
-    _top    = _end;      // Force future allocations to fail.
-    _bottom = _end;      // Force future contains() queries to return false.
-    return remaining;
-  }
-
-  // Fill in remaining space with a dummy object and invalidate the PLAB. Returns
-  // the amount of remaining space.
-  size_t retire_internal();
-
-public:
-  // Initializes the buffer to be empty, but with the given "word_sz".
-  // Must get initialized with "set_buf" for an allocation to succeed.
-  ParGCAllocBuffer(size_t word_sz);
-  virtual ~ParGCAllocBuffer() {}
-
-  // Minimum PLAB size.
-  static size_t min_size();
-  // Maximum PLAB size.
-  static size_t max_size();
-
-  // If an allocation of the given "word_sz" can be satisfied within the
-  // buffer, do the allocation, returning a pointer to the start of the
-  // allocated block.  If the allocation request cannot be satisfied,
-  // return NULL.
-  HeapWord* allocate(size_t word_sz) {
-    HeapWord* res = _top;
-    if (pointer_delta(_end, _top) >= word_sz) {
-      _top = _top + word_sz;
-      return res;
-    } else {
-      return NULL;
-    }
-  }
-
-  // Allocate the object aligned to "alignment_in_bytes".
-  HeapWord* allocate_aligned(size_t word_sz, unsigned short alignment_in_bytes);
-
-  // Undo the last allocation in the buffer, which is required to be of the
-  // "obj" of the given "word_sz".
-  void undo_allocation(HeapWord* obj, size_t word_sz) {
-    assert(pointer_delta(_top, _bottom) >= word_sz, "Bad undo");
-    assert(pointer_delta(_top, obj)     == word_sz, "Bad undo");
-    _top = obj;
-  }
-
-  // The total (word) size of the buffer, including both allocated and
-  // unallocated space.
-  size_t word_sz() { return _word_sz; }
-
-  // Should only be done if we are about to reset with a new buffer of the
-  // given size.
-  void set_word_size(size_t new_word_sz) {
-    assert(new_word_sz > AlignmentReserve, "Too small");
-    _word_sz = new_word_sz;
-  }
-
-  // The number of words of unallocated space remaining in the buffer.
-  size_t words_remaining() {
-    assert(_end >= _top, "Negative buffer");
-    return pointer_delta(_end, _top, HeapWordSize);
-  }
-
-  bool contains(void* addr) {
-    return (void*)_bottom <= addr && addr < (void*)_hard_end;
-  }
-
-  // Sets the space of the buffer to be [buf, space+word_sz()).
-  virtual void set_buf(HeapWord* buf) {
-    _bottom   = buf;
-    _top      = _bottom;
-    _hard_end = _bottom + word_sz();
-    _end      = _hard_end - AlignmentReserve;
-    assert(_end >= _top, "Negative buffer");
-    // In support of ergonomic sizing
-    _allocated += word_sz();
-  }
-
-  // Flush allocation statistics into the given PLABStats supporting ergonomic
-  // sizing of PLAB's and retire the current buffer. To be called at the end of
-  // GC.
-  void flush_and_retire_stats(PLABStats* stats);
-
-  // Fills in the unallocated portion of the buffer with a garbage object and updates
-  // statistics. To be called during GC.
-  virtual void retire();
-
-  void print() PRODUCT_RETURN;
-};
-
-// PLAB book-keeping.
-class PLABStats VALUE_OBJ_CLASS_SPEC {
-  size_t _allocated;      // Total allocated
-  size_t _wasted;         // of which wasted (internal fragmentation)
-  size_t _unused;         // Unused in last buffer
-  size_t _desired_plab_sz;// Output of filter (below), suitably trimmed and quantized
-  AdaptiveWeightedAverage
-         _filter;         // Integrator with decay
-
-  void reset() {
-    _allocated = 0;
-    _wasted    = 0;
-    _unused    = 0;
-  }
- public:
-  PLABStats(size_t desired_plab_sz_, unsigned wt) :
-    _allocated(0),
-    _wasted(0),
-    _unused(0),
-    _desired_plab_sz(desired_plab_sz_),
-    _filter(wt)
-  { }
-
-  static const size_t min_size() {
-    return ParGCAllocBuffer::min_size();
-  }
-
-  static const size_t max_size() {
-    return ParGCAllocBuffer::max_size();
-  }
-
-  size_t desired_plab_sz() {
-    return _desired_plab_sz;
-  }
-
-  // Updates the current desired PLAB size. Computes the new desired PLAB size,
-  // updates _desired_plab_sz and clears sensor accumulators.
-  void adjust_desired_plab_sz(uint no_of_gc_workers);
-
-  void add_allocated(size_t v) {
-    Atomic::add_ptr(v, &_allocated);
-  }
-
-  void add_unused(size_t v) {
-    Atomic::add_ptr(v, &_unused);
-  }
-
-  void add_wasted(size_t v) {
-    Atomic::add_ptr(v, &_wasted);
-  }
-};
-
-#endif // SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARGCALLOCBUFFER_HPP
--- a/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.inline.hpp	Thu Apr 23 12:47:23 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_PARGCALLOCBUFFER_INLINE_HPP
-#define SHARE_VM_GC_IMPLEMENTATION_SHARED_PARGCALLOCBUFFER_INLINE_HPP
-
-#include "gc_implementation/shared/parGCAllocBuffer.hpp"
-#include "gc_interface/collectedHeap.inline.hpp"
-
-HeapWord* ParGCAllocBuffer::allocate_aligned(size_t word_sz, unsigned short alignment_in_bytes) {
-
-  HeapWord* res = CollectedHeap::align_allocation_or_fail(_top, _end, alignment_in_bytes);
-  if (res == NULL) {
-    return NULL;
-  }
-
-  // Set _top so that allocate(), which expects _top to be correctly set,
-  // can be used below.
-  _top = res;
-  return allocate(word_sz);
-}
-
-#endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_PARGCALLOCBUFFER_INLINE_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc_implementation/shared/plab.cpp	Mon Apr 27 14:41:49 2015 +0200
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc_implementation/shared/plab.hpp"
+#include "memory/threadLocalAllocBuffer.hpp"
+#include "oops/arrayOop.hpp"
+#include "oops/oop.inline.hpp"
+
+size_t PLAB::min_size() {
+  // Make sure that we return something that is larger than AlignmentReserve
+  return align_object_size(MAX2(MinTLABSize / HeapWordSize, (uintx)oopDesc::header_size())) + AlignmentReserve;
+}
+
+size_t PLAB::max_size() {
+  return ThreadLocalAllocBuffer::max_size();
+}
+
+PLAB::PLAB(size_t desired_plab_sz_) :
+  _word_sz(desired_plab_sz_), _bottom(NULL), _top(NULL),
+  _end(NULL), _hard_end(NULL), _allocated(0), _wasted(0)
+{
+  // ArrayOopDesc::header_size depends on command line initialization.
+  AlignmentReserve = oopDesc::header_size() > MinObjAlignment ? align_object_size(arrayOopDesc::header_size(T_INT)) : 0;
+  assert(min_size() > AlignmentReserve,
+         err_msg("Minimum PLAB size " SIZE_FORMAT" must be larger than alignment reserve " SIZE_FORMAT" "
+                 "to be able to contain objects", min_size(), AlignmentReserve));
+}
+
+// If the minimum object size is greater than MinObjAlignment, we can
+// end up with a shard at the end of the buffer that's smaller than
+// the smallest object.  We can't allow that because the buffer must
+// look like it's full of objects when we retire it, so we make
+// sure we have enough space for a filler int array object.
+size_t PLAB::AlignmentReserve;
+
+void PLAB::flush_and_retire_stats(PLABStats* stats) {
+  // Retire the last allocation buffer.
+  size_t unused = retire_internal();
+
+  // Now flush the statistics.
+  stats->add_allocated(_allocated);
+  stats->add_wasted(_wasted);
+  stats->add_unused(unused);
+
+  // Since we have flushed the stats we need to clear  the _allocated and _wasted
+  // fields in case somebody retains an instance of this over GCs. Not doing so
+  // will artifically inflate the values in the statistics.
+  _allocated = 0;
+  _wasted = 0;
+}
+
+void PLAB::retire() {
+  _wasted += retire_internal();
+}
+
+size_t PLAB::retire_internal() {
+  size_t result = 0;
+  if (_top < _hard_end) {
+    CollectedHeap::fill_with_object(_top, _hard_end);
+    result += invalidate();
+  }
+  return result;
+}
+
+// Compute desired plab size and latch result for later
+// use. This should be called once at the end of parallel
+// scavenge; it clears the sensor accumulators.
+void PLABStats::adjust_desired_plab_sz(uint no_of_gc_workers) {
+  assert(ResizePLAB, "Not set");
+
+  assert(is_object_aligned(max_size()) && min_size() <= max_size(),
+         "PLAB clipping computation may be incorrect");
+
+  if (_allocated == 0) {
+    assert(_unused == 0,
+           err_msg("Inconsistency in PLAB stats: "
+                   "_allocated: "SIZE_FORMAT", "
+                   "_wasted: "SIZE_FORMAT", "
+                   "_unused: "SIZE_FORMAT,
+                   _allocated, _wasted, _unused));
+
+    _allocated = 1;
+  }
+  double wasted_frac    = (double)_unused / (double)_allocated;
+  size_t target_refills = (size_t)((wasted_frac * TargetSurvivorRatio) / TargetPLABWastePct);
+  if (target_refills == 0) {
+    target_refills = 1;
+  }
+  size_t used = _allocated - _wasted - _unused;
+  size_t recent_plab_sz = used / (target_refills * no_of_gc_workers);
+  // Take historical weighted average
+  _filter.sample(recent_plab_sz);
+  // Clip from above and below, and align to object boundary
+  size_t new_plab_sz = MAX2(min_size(), (size_t)_filter.average());
+  new_plab_sz = MIN2(max_size(), new_plab_sz);
+  new_plab_sz = align_object_size(new_plab_sz);
+  // Latch the result
+  if (PrintPLAB) {
+    gclog_or_tty->print(" (plab_sz = " SIZE_FORMAT" desired_plab_sz = " SIZE_FORMAT") ", recent_plab_sz, new_plab_sz);
+  }
+  _desired_plab_sz = new_plab_sz;
+
+  reset();
+}
+
+#ifndef PRODUCT
+void PLAB::print() {
+  gclog_or_tty->print_cr("PLAB: _bottom: " PTR_FORMAT "  _top: " PTR_FORMAT
+    "  _end: " PTR_FORMAT "  _hard_end: " PTR_FORMAT ")",
+    p2i(_bottom), p2i(_top), p2i(_end), p2i(_hard_end));
+}
+#endif // !PRODUCT
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc_implementation/shared/plab.hpp	Mon Apr 27 14:41:49 2015 +0200
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_PLAB_HPP
+#define SHARE_VM_GC_IMPLEMENTATION_SHARED_PLAB_HPP
+
+#include "gc_implementation/shared/gcUtil.hpp"
+#include "memory/allocation.hpp"
+#include "runtime/atomic.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+// Forward declarations.
+class PLABStats;
+
+// A per-thread allocation buffer used during GC.
+class PLAB: public CHeapObj<mtGC> {
+protected:
+  char      head[32];
+  size_t    _word_sz;          // In HeapWord units
+  HeapWord* _bottom;
+  HeapWord* _top;
+  HeapWord* _end;           // Last allocatable address + 1
+  HeapWord* _hard_end;      // _end + AlignmentReserve
+  // In support of ergonomic sizing of PLAB's
+  size_t    _allocated;     // in HeapWord units
+  size_t    _wasted;        // in HeapWord units
+  char      tail[32];
+  static size_t AlignmentReserve;
+
+  // Force future allocations to fail and queries for contains()
+  // to return false. Returns the amount of unused space in this PLAB.
+  size_t invalidate() {
+    _end    = _hard_end;
+    size_t remaining = pointer_delta(_end, _top);  // Calculate remaining space.
+    _top    = _end;      // Force future allocations to fail.
+    _bottom = _end;      // Force future contains() queries to return false.
+    return remaining;
+  }
+
+  // Fill in remaining space with a dummy object and invalidate the PLAB. Returns
+  // the amount of remaining space.
+  size_t retire_internal();
+
+public:
+  // Initializes the buffer to be empty, but with the given "word_sz".
+  // Must get initialized with "set_buf" for an allocation to succeed.
+  PLAB(size_t word_sz);
+  virtual ~PLAB() {}
+
+  // Minimum PLAB size.
+  static size_t min_size();
+  // Maximum PLAB size.
+  static size_t max_size();
+
+  // If an allocation of the given "word_sz" can be satisfied within the
+  // buffer, do the allocation, returning a pointer to the start of the
+  // allocated block.  If the allocation request cannot be satisfied,
+  // return NULL.
+  HeapWord* allocate(size_t word_sz) {
+    HeapWord* res = _top;
+    if (pointer_delta(_end, _top) >= word_sz) {
+      _top = _top + word_sz;
+      return res;
+    } else {
+      return NULL;
+    }
+  }
+
+  // Allocate the object aligned to "alignment_in_bytes".
+  HeapWord* allocate_aligned(size_t word_sz, unsigned short alignment_in_bytes);
+
+  // Undo the last allocation in the buffer, which is required to be of the
+  // "obj" of the given "word_sz".
+  void undo_allocation(HeapWord* obj, size_t word_sz) {
+    assert(pointer_delta(_top, _bottom) >= word_sz, "Bad undo");
+    assert(pointer_delta(_top, obj)     == word_sz, "Bad undo");
+    _top = obj;
+  }
+
+  // The total (word) size of the buffer, including both allocated and
+  // unallocated space.
+  size_t word_sz() { return _word_sz; }
+
+  // Should only be done if we are about to reset with a new buffer of the
+  // given size.
+  void set_word_size(size_t new_word_sz) {
+    assert(new_word_sz > AlignmentReserve, "Too small");
+    _word_sz = new_word_sz;
+  }
+
+  // The number of words of unallocated space remaining in the buffer.
+  size_t words_remaining() {
+    assert(_end >= _top, "Negative buffer");
+    return pointer_delta(_end, _top, HeapWordSize);
+  }
+
+  bool contains(void* addr) {
+    return (void*)_bottom <= addr && addr < (void*)_hard_end;
+  }
+
+  // Sets the space of the buffer to be [buf, space+word_sz()).
+  virtual void set_buf(HeapWord* buf) {
+    _bottom   = buf;
+    _top      = _bottom;
+    _hard_end = _bottom + word_sz();
+    _end      = _hard_end - AlignmentReserve;
+    assert(_end >= _top, "Negative buffer");
+    // In support of ergonomic sizing
+    _allocated += word_sz();
+  }
+
+  // Flush allocation statistics into the given PLABStats supporting ergonomic
+  // sizing of PLAB's and retire the current buffer. To be called at the end of
+  // GC.
+  virtual void flush_and_retire_stats(PLABStats* stats);
+
+  // Fills in the unallocated portion of the buffer with a garbage object and updates
+  // statistics. To be called during GC.
+  virtual void retire();
+
+  void print() PRODUCT_RETURN;
+};
+
+// PLAB book-keeping.
+class PLABStats VALUE_OBJ_CLASS_SPEC {
+  size_t _allocated;      // Total allocated
+  size_t _wasted;         // of which wasted (internal fragmentation)
+  size_t _unused;         // Unused in last buffer
+  size_t _desired_plab_sz;// Output of filter (below), suitably trimmed and quantized
+  AdaptiveWeightedAverage
+         _filter;         // Integrator with decay
+
+  void reset() {
+    _allocated = 0;
+    _wasted    = 0;
+    _unused    = 0;
+  }
+ public:
+  PLABStats(size_t desired_plab_sz_, unsigned wt) :
+    _allocated(0),
+    _wasted(0),
+    _unused(0),
+    _desired_plab_sz(desired_plab_sz_),
+    _filter(wt)
+  { }
+
+  static const size_t min_size() {
+    return PLAB::min_size();
+  }
+
+  static const size_t max_size() {
+    return PLAB::max_size();
+  }
+
+  size_t desired_plab_sz() {
+    return _desired_plab_sz;
+  }
+
+  // Updates the current desired PLAB size. Computes the new desired PLAB size,
+  // updates _desired_plab_sz and clears sensor accumulators.
+  void adjust_desired_plab_sz(uint no_of_gc_workers);
+
+  void add_allocated(size_t v) {
+    Atomic::add_ptr(v, &_allocated);
+  }
+
+  void add_unused(size_t v) {
+    Atomic::add_ptr(v, &_unused);
+  }
+
+  void add_wasted(size_t v) {
+    Atomic::add_ptr(v, &_wasted);
+  }
+};
+
+#endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_PLAB_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc_implementation/shared/plab.inline.hpp	Mon Apr 27 14:41:49 2015 +0200
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_PLAB_INLINE_HPP
+#define SHARE_VM_GC_IMPLEMENTATION_SHARED_PLAB_INLINE_HPP
+
+#include "gc_implementation/shared/plab.hpp"
+#include "gc_interface/collectedHeap.inline.hpp"
+
+HeapWord* PLAB::allocate_aligned(size_t word_sz, unsigned short alignment_in_bytes) {
+
+  HeapWord* res = CollectedHeap::align_allocation_or_fail(_top, _end, alignment_in_bytes);
+  if (res == NULL) {
+    return NULL;
+  }
+
+  // Set _top so that allocate(), which expects _top to be correctly set,
+  // can be used below.
+  _top = res;
+  return allocate(word_sz);
+}
+
+#endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_PLAB_INLINE_HPP
--- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp	Mon Apr 27 14:41:49 2015 +0200
@@ -59,7 +59,6 @@
 #include "gc_implementation/concurrentMarkSweep/vmCMSOperations.hpp"
 #endif // INCLUDE_ALL_GCS
 
-GenCollectedHeap* GenCollectedHeap::_gch;
 NOT_PRODUCT(size_t GenCollectedHeap::_skip_header_HeapWords = 0;)
 
 // The set of potentially parallel tasks in root scanning.
@@ -127,8 +126,6 @@
   _rem_set = collector_policy()->create_rem_set(reserved_region());
   set_barrier_set(rem_set()->bs());
 
-  _gch = this;
-
   ReservedSpace young_rs = heap_rs.first_part(gen_policy()->young_gen_spec()->max_size(), false, false);
   _young_gen = gen_policy()->young_gen_spec()->init(young_rs, 0, rem_set());
   heap_rs = heap_rs.last_part(gen_policy()->young_gen_spec()->max_size());
@@ -1103,9 +1100,10 @@
 }
 
 GenCollectedHeap* GenCollectedHeap::heap() {
-  assert(_gch != NULL, "Uninitialized access to GenCollectedHeap::heap()");
-  assert(_gch->kind() == CollectedHeap::GenCollectedHeap, "not a generational heap");
-  return _gch;
+  CollectedHeap* heap = Universe::heap();
+  assert(heap != NULL, "Uninitialized access to GenCollectedHeap::heap()");
+  assert(heap->kind() == CollectedHeap::GenCollectedHeap, "Not a GenCollectedHeap");
+  return (GenCollectedHeap*)heap;
 }
 
 void GenCollectedHeap::prepare_for_compaction() {
--- a/hotspot/src/share/vm/memory/genCollectedHeap.hpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/memory/genCollectedHeap.hpp	Mon Apr 27 14:41:49 2015 +0200
@@ -54,11 +54,7 @@
 public:
   friend class VM_PopulateDumpSharedSpace;
 
- protected:
-  // Fields:
-  static GenCollectedHeap* _gch;
-
- private:
+private:
   Generation* _young_gen;
   Generation* _old_gen;
 
@@ -277,11 +273,6 @@
   // only and may need to be re-examined in case other
   // kinds of collectors are implemented in the future.
   virtual bool can_elide_initializing_store_barrier(oop new_obj) {
-    // We wanted to assert that:-
-    // assert(UseSerialGC || UseConcMarkSweepGC,
-    //       "Check can_elide_initializing_store_barrier() for this collector");
-    // but unfortunately the flag UseSerialGC need not necessarily always
-    // be set when DefNew+Tenured are being used.
     return is_in_young(new_obj);
   }
 
--- a/hotspot/src/share/vm/memory/genMarkSweep.cpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/memory/genMarkSweep.cpp	Mon Apr 27 14:41:49 2015 +0200
@@ -187,7 +187,6 @@
                                      bool clear_all_softrefs) {
   // Recursively traverse all live objects and mark them
   GCTraceTime tm("phase 1", PrintGC && Verbose, true, _gc_timer, _gc_tracer->gc_id());
-  trace(" 1");
 
   GenCollectedHeap* gch = GenCollectedHeap::heap();
 
@@ -258,7 +257,6 @@
   GenCollectedHeap* gch = GenCollectedHeap::heap();
 
   GCTraceTime tm("phase 2", PrintGC && Verbose, true, _gc_timer, _gc_tracer->gc_id());
-  trace("2");
 
   gch->prepare_for_compaction();
 }
@@ -275,7 +273,6 @@
 
   // Adjust the pointers to reflect the new locations
   GCTraceTime tm("phase 3", PrintGC && Verbose, true, _gc_timer, _gc_tracer->gc_id());
-  trace("3");
 
   // Need new claim bits for the pointer adjustment tracing.
   ClassLoaderDataGraph::clear_claimed_marks();
@@ -325,7 +322,6 @@
   GenCollectedHeap* gch = GenCollectedHeap::heap();
 
   GCTraceTime tm("phase 4", PrintGC && Verbose, true, _gc_timer, _gc_tracer->gc_id());
-  trace("4");
 
   GenCompactClosure blk;
   gch->generation_iterate(&blk, true);
--- a/hotspot/src/share/vm/memory/universe.cpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/memory/universe.cpp	Mon Apr 27 14:41:49 2015 +0200
@@ -687,6 +687,15 @@
   return JNI_OK;
 }
 
+template <class Heap, class Policy>
+jint Universe::create_heap() {
+  assert(_collectedHeap == NULL, "Heap already created");
+  Policy* policy = new Policy();
+  policy->initialize_all();
+  _collectedHeap = new Heap(policy);
+  return _collectedHeap->initialize();
+}
+
 // Choose the heap base address and oop encoding mode
 // when compressed oops are used:
 // Unscaled  - Use 32-bits oops without encoding when
@@ -696,50 +705,35 @@
 // HeapBased - Use compressed oops with heap base + encoding.
 
 jint Universe::initialize_heap() {
-
-  if (UseParallelGC) {
-#if INCLUDE_ALL_GCS
-    Universe::_collectedHeap = new ParallelScavengeHeap();
-#else  // INCLUDE_ALL_GCS
-    fatal("UseParallelGC not supported in this VM.");
-#endif // INCLUDE_ALL_GCS
-
-  } else if (UseG1GC) {
-#if INCLUDE_ALL_GCS
-    G1CollectorPolicyExt* g1p = new G1CollectorPolicyExt();
-    g1p->initialize_all();
-    G1CollectedHeap* g1h = new G1CollectedHeap(g1p);
-    Universe::_collectedHeap = g1h;
-#else  // INCLUDE_ALL_GCS
-    fatal("UseG1GC not supported in java kernel vm.");
-#endif // INCLUDE_ALL_GCS
+  jint status = JNI_ERR;
 
+#if !INCLUDE_ALL_GCS
+  if (UseParallelGC) {
+    fatal("UseParallelGC not supported in this VM.");
+  } else if (UseG1GC) {
+    fatal("UseG1GC not supported in this VM.");
+  } else if (UseConcMarkSweepGC) {
+    fatal("UseConcMarkSweepGC not supported in this VM.");
+#else
+  if (UseParallelGC) {
+    status = Universe::create_heap<ParallelScavengeHeap, GenerationSizer>();
+  } else if (UseG1GC) {
+    status = Universe::create_heap<G1CollectedHeap, G1CollectorPolicyExt>();
+  } else if (UseConcMarkSweepGC) {
+    status = Universe::create_heap<GenCollectedHeap, ConcurrentMarkSweepPolicy>();
+#endif
+  } else if (UseSerialGC) {
+    status = Universe::create_heap<GenCollectedHeap, MarkSweepPolicy>();
   } else {
-    GenCollectorPolicy *gc_policy;
+    ShouldNotReachHere();
+  }
 
-    if (UseSerialGC) {
-      gc_policy = new MarkSweepPolicy();
-    } else if (UseConcMarkSweepGC) {
-#if INCLUDE_ALL_GCS
-      gc_policy = new ConcurrentMarkSweepPolicy();
-#else  // INCLUDE_ALL_GCS
-      fatal("UseConcMarkSweepGC not supported in this VM.");
-#endif // INCLUDE_ALL_GCS
-    } else { // default old generation
-      gc_policy = new MarkSweepPolicy();
-    }
-    gc_policy->initialize_all();
-
-    Universe::_collectedHeap = new GenCollectedHeap(gc_policy);
+  if (status != JNI_OK) {
+    return status;
   }
 
   ThreadLocalAllocBuffer::set_max_size(Universe::heap()->max_tlab_size());
 
-  jint status = Universe::heap()->initialize();
-  if (status != JNI_OK) {
-    return status;
-  }
-
 #ifdef _LP64
   if (UseCompressedOops) {
     // Subtract a page because something can get allocated at heap base.
@@ -1063,7 +1057,7 @@
 
   MemoryService::add_metaspace_memory_pools();
 
-  MemoryService::set_universe_heap(Universe::_collectedHeap);
+  MemoryService::set_universe_heap(Universe::heap());
 #if INCLUDE_CDS
   SharedClassUtil::initialize(CHECK_false);
 #endif
--- a/hotspot/src/share/vm/memory/universe.hpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/memory/universe.hpp	Mon Apr 27 14:41:49 2015 +0200
@@ -214,6 +214,7 @@
   static size_t _heap_capacity_at_last_gc;
   static size_t _heap_used_at_last_gc;
 
+  template <class Heap, class Policy> static jint create_heap();
   static jint initialize_heap();
   static void initialize_basic_type_mirrors(TRAPS);
   static void fixup_mirrors(TRAPS);
--- a/hotspot/src/share/vm/oops/oop.hpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/oops/oop.hpp	Mon Apr 27 14:41:49 2015 +0200
@@ -201,7 +201,6 @@
 
   // Access to fields in a instanceOop through these methods.
   oop obj_field(int offset) const;
-  volatile oop obj_field_volatile(int offset) const;
   void obj_field_put(int offset, oop value);
   void obj_field_put_raw(int offset, oop value);
   void obj_field_put_volatile(int offset, oop value);
--- a/hotspot/src/share/vm/oops/oop.inline.hpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/oops/oop.inline.hpp	Mon Apr 27 14:41:49 2015 +0200
@@ -284,11 +284,6 @@
     load_decode_heap_oop(obj_field_addr<narrowOop>(offset)) :
     load_decode_heap_oop(obj_field_addr<oop>(offset));
 }
-inline volatile oop oopDesc::obj_field_volatile(int offset) const {
-  volatile oop value = obj_field(offset);
-  OrderAccess::acquire();
-  return value;
-}
 inline void oopDesc::obj_field_put(int offset, oop value) {
   UseCompressedOops ? oop_store(obj_field_addr<narrowOop>(offset), value) :
                       oop_store(obj_field_addr<oop>(offset),       value);
--- a/hotspot/src/share/vm/precompiled/precompiled.hpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/precompiled/precompiled.hpp	Mon Apr 27 14:41:49 2015 +0200
@@ -315,7 +315,7 @@
 # include "gc_implementation/parallelScavenge/psYoungGen.hpp"
 # include "gc_implementation/shared/gcAdaptivePolicyCounters.hpp"
 # include "gc_implementation/shared/gcPolicyCounters.hpp"
-# include "gc_implementation/shared/parGCAllocBuffer.hpp"
+# include "gc_implementation/shared/plab.hpp"
 #endif // INCLUDE_ALL_GCS
 
 #endif // !DONT_USE_PRECOMPILED_HEADER
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Mon Apr 27 14:41:49 2015 +0200
@@ -1560,12 +1560,15 @@
     } else {
       FLAG_SET_ERGO(bool, UseParallelGC, true);
     }
+  } else {
+    FLAG_SET_ERGO(bool, UseSerialGC, true);
   }
 }
 
 void Arguments::select_gc() {
   if (!gc_selected()) {
     select_gc_ergonomically();
+    guarantee(gc_selected(), "No GC selected");
   }
 }
 
@@ -2091,10 +2094,8 @@
   }
 
   if (UseParNewGC && !UseConcMarkSweepGC) {
-    // !UseConcMarkSweepGC means that we are using serial old gc. Unfortunately we don't
-    // set up UseSerialGC properly, so that can't be used in the check here.
     jio_fprintf(defaultStream::error_stream(),
-        "It is not possible to combine the ParNew young collector with the Serial old collector.\n");
+        "It is not possible to combine the ParNew young collector with any collector other than CMS.\n");
     return false;
   }
 
--- a/hotspot/src/share/vm/runtime/globals.hpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/runtime/globals.hpp	Mon Apr 27 14:41:49 2015 +0200
@@ -1954,7 +1954,7 @@
           "collection")                                                     \
                                                                             \
   develop(uintx, PromotionFailureALotCount, 1000,                           \
-          "Number of promotion failures occurring at ParGCAllocBuffer "     \
+          "Number of promotion failures occurring at PLAB "     \
           "refill attempts (ParNew) or promotion attempts "                 \
           "(other young collectors)")                                       \
                                                                             \
@@ -2284,9 +2284,6 @@
           "If non-zero, assert that GC threads yield within this "          \
           "number of milliseconds")                                         \
                                                                             \
-  notproduct(bool, TraceMarkSweep, false,                                   \
-          "Trace mark sweep")                                               \
-                                                                            \
   product(bool, PrintReferenceGC, false,                                    \
           "Print times spent handling reference objects during GC "         \
           "(enabled only when PrintGCDetails)")                             \
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp	Mon Apr 27 14:41:49 2015 +0200
@@ -555,7 +555,6 @@
   nonstatic_field(GenerationSpec,              _init_size,                                    size_t)                                \
   nonstatic_field(GenerationSpec,              _max_size,                                     size_t)                                \
                                                                                                                                      \
-    static_field(GenCollectedHeap,             _gch,                                          GenCollectedHeap*)                     \
   nonstatic_field(GenCollectedHeap,            _young_gen,                                    Generation*)                           \
   nonstatic_field(GenCollectedHeap,            _old_gen,                                      Generation*)                           \
                                                                                                                                      \
--- a/hotspot/test/Makefile	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/test/Makefile	Mon Apr 27 14:41:49 2015 +0200
@@ -346,6 +346,34 @@
 
 ################################################################
 
+# basicvmtest (make sure various basic java options work)
+
+# Set up the directory in which the jvm directories live (client/, server/, etc.)
+ifeq ($(PLATFORM),windows)
+JVMS_DIR := $(PRODUCT_HOME)/bin
+else ifeq ($(PLATFORM),bsd)
+JVMS_DIR := $(PRODUCT_HOME)/lib
+else
+# The jvms live in the architecture directory (amd64, sparcv9,
+# etc.). By using a wildcard there's no need to figure out the exact
+# name of that directory.
+JVMS_DIR := $(PRODUCT_HOME)/lib/*
+endif
+
+# Use the existance of a directory as a sign that jvm variant is available
+CANDIDATE_JVM_VARIANTS := client minimal server
+JVM_VARIANTS := $(strip $(foreach x,$(CANDIDATE_JVM_VARIANTS),$(if $(wildcard $(JVMS_DIR)/$(x)),$(x))))
+
+hotspot_basicvmtest:
+	for variant in $(JVM_VARIANTS);                                           \
+	do                                                                        \
+	    $(MAKE) JAVA_ARGS="$(JAVA_ARGS) -$$variant" hotspot_$${variant}test;  \
+	done
+
+PHONY_LIST += hotspot_basicvmtest
+
+################################################################
+
 # clienttest (make sure various basic java client options work)
 
 hotspot_clienttest clienttest: sanitytest
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/arguments/TestSelectDefaultGC.java	Mon Apr 27 14:41:49 2015 +0200
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test TestSelectDefaultGC
+ * @summary Test selection of GC when no GC option is specified
+ * @bug 8068582
+ * @key gc
+ * @library /testlibrary
+ * @modules java.base/sun.misc
+ *          java.management
+ * @run driver TestSelectDefaultGC
+ */
+
+import com.oracle.java.testlibrary.*;
+import java.util.regex.*;
+
+public class TestSelectDefaultGC {
+    public static boolean versionStringContains(OutputAnalyzer output, String pattern) {
+        Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(output.getStderr());
+        return matcher.find();
+    }
+
+    public static void assertVMOption(OutputAnalyzer output, String option, boolean value) {
+        output.shouldMatch(" " + option + " .*=.* " + value + " ");
+    }
+
+    public static void main(String[] args) throws Exception {
+        // Start VM without specifying GC
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+PrintFlagsFinal", "-version");
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        output.shouldHaveExitValue(0);
+
+        boolean isServerVM = versionStringContains(output, "Server VM");
+
+        // Verify GC selection
+        assertVMOption(output, "UseParallelGC",      isServerVM);
+        assertVMOption(output, "UseParallelOldGC",   isServerVM);
+        assertVMOption(output, "UseSerialGC",        !isServerVM);
+        assertVMOption(output, "UseConcMarkSweepGC", false);
+        assertVMOption(output, "UseG1GC",            false);
+        assertVMOption(output, "UseParNewGC",        false);
+    }
+}
--- a/hotspot/test/gc/startup_warnings/TestParNewSerialOld.java	Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/test/gc/startup_warnings/TestParNewSerialOld.java	Mon Apr 27 14:41:49 2015 +0200
@@ -40,7 +40,7 @@
   public static void main(String args[]) throws Exception {
     ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseParNewGC", "-version");
     OutputAnalyzer output = new OutputAnalyzer(pb.start());
-    output.shouldContain("It is not possible to combine the ParNew young collector with the Serial old collector.");
+    output.shouldContain("It is not possible to combine the ParNew young collector with any collector other than CMS.");
     output.shouldContain("Error");
     output.shouldHaveExitValue(1);
   }