Merge
authorjwilhelm
Thu, 05 Mar 2015 17:27:16 +0100
changeset 29332 c2364e06aa8d
parent 29331 b788134d664a (diff)
parent 29322 1f646019dc45 (current diff)
child 29361 ae2aef8d8ab9
Merge
hotspot/src/share/vm/runtime/thread.cpp
hotspot/src/share/vm/runtime/thread.hpp
--- a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2012, 2014 SAP AG. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -2204,7 +2204,8 @@
 
 // Write the card table byte if needed.
 void MacroAssembler::card_write_barrier_post(Register Rstore_addr, Register Rnew_val, Register Rtmp) {
-  CardTableModRefBS* bs = (CardTableModRefBS*) Universe::heap()->barrier_set();
+  CardTableModRefBS* bs =
+    barrier_set_cast<CardTableModRefBS>(Universe::heap()->barrier_set());
   assert(bs->kind() == BarrierSet::CardTableModRef ||
          bs->kind() == BarrierSet::CardTableExtension, "wrong barrier");
 #ifdef ASSERT
@@ -2310,9 +2311,8 @@
   Label& filtered = (filtered_ext != NULL) ? *filtered_ext : filtered_int;
   assert_different_registers(Rstore_addr, Rnew_val, Rtmp1, Rtmp2);
 
-  G1SATBCardTableModRefBS* bs = (G1SATBCardTableModRefBS*) Universe::heap()->barrier_set();
-  assert(bs->kind() == BarrierSet::G1SATBCT ||
-         bs->kind() == BarrierSet::G1SATBCTLogging, "wrong barrier");
+  G1SATBCardTableLoggingModRefBS* bs =
+    barrier_set_cast<G1SATBCardTableLoggingModRefBS>(Universe::heap()->barrier_set());
 
   // Does store cross heap regions?
   if (G1RSBarrierRegionFilter) {
--- a/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -694,7 +694,7 @@
             __ release();
           }
 
-          CardTableModRefBS* const ct = (CardTableModRefBS*)bs;
+          CardTableModRefBS* const ct = barrier_set_cast<CardTableModRefBS>(bs);
           assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
           assert_different_registers(addr, count, tmp);
 
--- a/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -916,7 +916,7 @@
         Register cardtable = G5;
         Register tmp  = G1_scratch;
         Register tmp2 = G3_scratch;
-        jbyte* byte_map_base = ((CardTableModRefBS*)bs)->byte_map_base;
+        jbyte* byte_map_base = barrier_set_cast<CardTableModRefBS>(bs)->byte_map_base;
 
         Label not_already_dirty, restart, refill, young_card;
 
--- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -3858,9 +3858,8 @@
 
   if (new_val == G0) return;
 
-  G1SATBCardTableModRefBS* bs = (G1SATBCardTableModRefBS*) Universe::heap()->barrier_set();
-  assert(bs->kind() == BarrierSet::G1SATBCT ||
-         bs->kind() == BarrierSet::G1SATBCTLogging, "wrong barrier");
+  G1SATBCardTableLoggingModRefBS* bs =
+    barrier_set_cast<G1SATBCardTableLoggingModRefBS>(Universe::heap()->barrier_set());
 
   if (G1RSBarrierRegionFilter) {
     xor3(store_addr, new_val, tmp);
@@ -3904,7 +3903,8 @@
 void MacroAssembler::card_write_barrier_post(Register store_addr, Register new_val, Register tmp) {
   // If we're writing constant NULL, we can skip the write barrier.
   if (new_val == G0) return;
-  CardTableModRefBS* bs = (CardTableModRefBS*) Universe::heap()->barrier_set();
+  CardTableModRefBS* bs =
+    barrier_set_cast<CardTableModRefBS>(Universe::heap()->barrier_set());
   assert(bs->kind() == BarrierSet::CardTableModRef ||
          bs->kind() == BarrierSet::CardTableExtension, "wrong barrier");
   card_table_write(bs->byte_map_base, tmp, store_addr);
--- a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1019,7 +1019,7 @@
       case BarrierSet::CardTableModRef:
       case BarrierSet::CardTableExtension:
         {
-          CardTableModRefBS* ct = (CardTableModRefBS*)bs;
+          CardTableModRefBS* ct = barrier_set_cast<CardTableModRefBS>(bs);
           assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
           assert_different_registers(addr, count, tmp);
 
--- a/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1718,8 +1718,8 @@
         // arg0: store_address
         Address store_addr(rbp, 2*BytesPerWord);
 
-        BarrierSet* bs = Universe::heap()->barrier_set();
-        CardTableModRefBS* ct = (CardTableModRefBS*)bs;
+        CardTableModRefBS* ct =
+          barrier_set_cast<CardTableModRefBS>(Universe::heap()->barrier_set());
         assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
 
         Label done;
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -4204,8 +4204,8 @@
   Address buffer(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
                                        PtrQueue::byte_offset_of_buf()));
 
-  BarrierSet* bs = Universe::heap()->barrier_set();
-  CardTableModRefBS* ct = (CardTableModRefBS*)bs;
+  CardTableModRefBS* ct =
+    barrier_set_cast<CardTableModRefBS>(Universe::heap()->barrier_set());
   assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
 
   Label done;
@@ -4305,7 +4305,7 @@
 void MacroAssembler::store_check_part_2(Register obj) {
   BarrierSet* bs = Universe::heap()->barrier_set();
   assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind");
-  CardTableModRefBS* ct = (CardTableModRefBS*)bs;
+  CardTableModRefBS* ct = barrier_set_cast<CardTableModRefBS>(bs);
   assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
 
   // The calculation for byte_map_base is as follows:
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -752,7 +752,7 @@
       case BarrierSet::CardTableModRef:
       case BarrierSet::CardTableExtension:
         {
-          CardTableModRefBS* ct = (CardTableModRefBS*)bs;
+          CardTableModRefBS* ct = barrier_set_cast<CardTableModRefBS>(bs);
           assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
 
           Label L_loop;
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1272,7 +1272,7 @@
       case BarrierSet::CardTableModRef:
       case BarrierSet::CardTableExtension:
         {
-          CardTableModRefBS* ct = (CardTableModRefBS*)bs;
+          CardTableModRefBS* ct = barrier_set_cast<CardTableModRefBS>(bs);
           assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
 
           Label L_loop;
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -1582,9 +1582,9 @@
 ////////////////////////////////////////////////////////////////////////
 
 void LIRGenerator::CardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val) {
-
-  assert(sizeof(*((CardTableModRefBS*)_bs)->byte_map_base) == sizeof(jbyte), "adjust this code");
-  LIR_Const* card_table_base = new LIR_Const(((CardTableModRefBS*)_bs)->byte_map_base);
+  CardTableModRefBS* ct = barrier_set_cast<CardTableModRefBS>(_bs);
+  assert(sizeof(*(ct->byte_map_base)) == sizeof(jbyte), "adjust this code");
+  LIR_Const* card_table_base = new LIR_Const(ct->byte_map_base);
   if (addr->is_address()) {
     LIR_Address* address = addr->as_address_ptr();
     // ptr cannot be an object because we use this barrier for array card marks
@@ -1609,7 +1609,6 @@
     __ move(new LIR_Address(FrameMap::Rthread_opr, in_bytes(JavaThread::card_table_base_offset()), T_ADDRESS), tmp);
   }
 
-  CardTableModRefBS* ct = (CardTableModRefBS*)_bs;
   LIR_Address *card_addr = new LIR_Address(tmp, addr, (LIR_Address::Scale) -CardTableModRefBS::card_shift, 0, T_BYTE);
   if(((int)ct->byte_map_base & 0xff) == 0) {
     __ move(tmp, card_addr);
--- a/hotspot/src/share/vm/compiler/disassembler.cpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/share/vm/compiler/disassembler.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -340,8 +340,8 @@
     }
 
     BarrierSet* bs = Universe::heap()->barrier_set();
-    if (bs->kind() == BarrierSet::CardTableModRef &&
-        adr == (address)((CardTableModRefBS*)(bs))->byte_map_base) {
+    if (bs->is_a(BarrierSet::CardTableModRef) &&
+        adr == (address)(barrier_set_cast<CardTableModRefBS>(bs)->byte_map_base)) {
       st->print("word_map_base");
       if (WizardMode) st->print(" " INTPTR_FORMAT, (intptr_t)adr);
       return;
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -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
@@ -97,9 +97,7 @@
 void ConcurrentMarkSweepThread::run() {
   assert(this == cmst(), "just checking");
 
-  this->record_stack_base_and_size();
-  this->initialize_thread_local_storage();
-  this->set_active_handles(JNIHandleBlock::allocate_block());
+  initialize_in_thread();
   // From this time Thread::current() should be working.
   assert(this == Thread::current(), "just checking");
   if (BindCMSThreadToCPU && !os::bind_to_processor(CPUForCMSThread)) {
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -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
@@ -1440,7 +1440,7 @@
   CMCountDataClosureBase(G1CollectedHeap* g1h,
                          BitMap* region_bm, BitMap* card_bm):
     _g1h(g1h), _cm(g1h->concurrent_mark()),
-    _ct_bs((CardTableModRefBS*) (g1h->barrier_set())),
+    _ct_bs(barrier_set_cast<CardTableModRefBS>(g1h->barrier_set())),
     _region_bm(region_bm), _card_bm(card_bm) { }
 };
 
@@ -3111,7 +3111,7 @@
                               BitMap* cm_card_bm,
                               uint max_worker_id) :
     _g1h(g1h), _cm(g1h->concurrent_mark()),
-    _ct_bs((CardTableModRefBS*) (g1h->barrier_set())),
+    _ct_bs(barrier_set_cast<CardTableModRefBS>(g1h->barrier_set())),
     _cm_card_bm(cm_card_bm), _max_worker_id(max_worker_id) { }
 
   bool doHeapRegion(HeapRegion* hr) {
--- a/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.cpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -120,7 +120,7 @@
   if (word_sz * 100 < gclab_word_size * ParallelGCBufferWastePct) {
     G1ParGCAllocBuffer* alloc_buf = alloc_buffer(dest, context);
     add_to_alloc_buffer_waste(alloc_buf->words_remaining());
-    alloc_buf->retire(false /* end_of_gc */, false /* retain */);
+    alloc_buf->retire();
 
     HeapWord* buf = _g1h->par_allocate_during_gc(dest, gclab_word_size, context);
     if (buf == NULL) {
@@ -154,9 +154,7 @@
     G1ParGCAllocBuffer* const buf = _alloc_buffers[state];
     if (buf != NULL) {
       add_to_alloc_buffer_waste(buf->words_remaining());
-      buf->flush_stats_and_retire(_g1h->alloc_buffer_stats(state),
-                                  true /* end_of_gc */,
-                                  false /* retain */);
+      buf->flush_and_retire_stats(_g1h->alloc_buffer_stats(state));
     }
   }
 }
--- a/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.hpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.hpp	Thu Mar 05 17:27:16 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -159,11 +159,11 @@
     _retired = false;
   }
 
-  virtual void retire(bool end_of_gc, bool retain) {
+  virtual void retire() {
     if (_retired) {
       return;
     }
-    ParGCAllocBuffer::retire(end_of_gc, retain);
+    ParGCAllocBuffer::retire();
     _retired = true;
   }
 };
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Thu Mar 05 17:27:16 2015 +0100
@@ -1274,7 +1274,7 @@
   virtual bool is_in_closed_subset(const void* p) const;
 
   G1SATBCardTableLoggingModRefBS* g1_barrier_set() {
-    return (G1SATBCardTableLoggingModRefBS*) barrier_set();
+    return barrier_set_cast<G1SATBCardTableLoggingModRefBS>(barrier_set());
   }
 
   // This resets the card table to all zeros.  It is used after
--- a/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -33,8 +33,11 @@
 #include "runtime/orderAccess.inline.hpp"
 #include "runtime/thread.inline.hpp"
 
-G1SATBCardTableModRefBS::G1SATBCardTableModRefBS(MemRegion whole_heap, BarrierSet::Name kind) :
-  CardTableModRefBS(whole_heap, kind) { }
+G1SATBCardTableModRefBS::G1SATBCardTableModRefBS(
+  MemRegion whole_heap,
+  const BarrierSet::FakeRtti& fake_rtti) :
+  CardTableModRefBS(whole_heap, fake_rtti.add_tag(BarrierSet::G1SATBCT))
+{ }
 
 void G1SATBCardTableModRefBS::enqueue(oop pre_val) {
   // Nulls should have been already filtered.
@@ -130,7 +133,7 @@
 
 G1SATBCardTableLoggingModRefBS::
 G1SATBCardTableLoggingModRefBS(MemRegion whole_heap) :
-  G1SATBCardTableModRefBS(whole_heap, BarrierSet::G1SATBCTLogging),
+  G1SATBCardTableModRefBS(whole_heap, BarrierSet::FakeRtti(G1SATBCTLogging)),
   _dcqs(JavaThread::dirty_card_queue_set()),
   _listener()
 {
@@ -203,7 +206,7 @@
   if (new_val == NULL) return;
   // Otherwise, log it.
   G1SATBCardTableLoggingModRefBS* g1_bs =
-    (G1SATBCardTableLoggingModRefBS*)Universe::heap()->barrier_set();
+    barrier_set_cast<G1SATBCardTableLoggingModRefBS>(Universe::heap()->barrier_set());
   g1_bs->write_ref_field_work(field, new_val);
 }
 
--- a/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp	Thu Mar 05 17:27:16 2015 +0100
@@ -43,7 +43,7 @@
     g1_young_gen = CT_MR_BS_last_reserved << 1
   };
 
-  G1SATBCardTableModRefBS(MemRegion whole_heap, BarrierSet::Name kind);
+  G1SATBCardTableModRefBS(MemRegion whole_heap, const BarrierSet::FakeRtti& fake_rtti);
   ~G1SATBCardTableModRefBS() { }
 
 public:
@@ -53,10 +53,6 @@
   // pre-marking object graph.
   static void enqueue(oop pre_val);
 
-  bool is_a(BarrierSet::Name bsn) {
-    return bsn == BarrierSet::G1SATBCT || CardTableModRefBS::is_a(bsn);
-  }
-
   virtual bool has_write_ref_pre_barrier() { return true; }
 
   // This notes that we don't need to access any BarrierSet data
@@ -128,6 +124,11 @@
   }
 };
 
+template<>
+struct BarrierSet::GetName<G1SATBCardTableModRefBS> {
+  static const BarrierSet::Name value = BarrierSet::G1SATBCT;
+};
+
 class G1SATBCardTableLoggingModRefBSChangedListener : public G1MappingChangedListener {
  private:
   G1SATBCardTableLoggingModRefBS* _card_table;
@@ -159,11 +160,6 @@
 
   virtual void resize_covered_region(MemRegion new_region) { ShouldNotReachHere(); }
 
-  bool is_a(BarrierSet::Name bsn) {
-    return bsn == BarrierSet::G1SATBCTLogging ||
-      G1SATBCardTableModRefBS::is_a(bsn);
-  }
-
   void write_ref_field_work(void* field, oop new_val, bool release = false);
 
   // Can be called from static contexts.
@@ -177,4 +173,9 @@
   void write_ref_array_work(MemRegion mr) { invalidate(mr); }
 };
 
+template<>
+struct BarrierSet::GetName<G1SATBCardTableLoggingModRefBS> {
+  static const BarrierSet::Name value = BarrierSet::G1SATBCTLogging;
+};
+
 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1SATBCARDTABLEMODREFBS_HPP
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -193,7 +193,7 @@
   HeapRegionRemSet* hrrs = rem_set();
   hrrs->clear();
   CardTableModRefBS* ct_bs =
-                   (CardTableModRefBS*)G1CollectedHeap::heap()->barrier_set();
+    barrier_set_cast<CardTableModRefBS>(G1CollectedHeap::heap()->barrier_set());
   ct_bs->clear(MemRegion(bottom(), end()));
 }
 
@@ -643,13 +643,9 @@
   // _vo == UseNextMarking -> use "next" marking information,
   // _vo == UseMarkWord    -> use mark word from object header.
   VerifyLiveClosure(G1CollectedHeap* g1h, VerifyOption vo) :
-    _g1h(g1h), _bs(NULL), _containing_obj(NULL),
-    _failures(false), _n_failures(0), _vo(vo)
-  {
-    BarrierSet* bs = _g1h->barrier_set();
-    if (bs->is_a(BarrierSet::CardTableModRef))
-      _bs = (CardTableModRefBS*)bs;
-  }
+    _g1h(g1h), _bs(barrier_set_cast<CardTableModRefBS>(g1h->barrier_set())),
+    _containing_obj(NULL), _failures(false), _n_failures(0), _vo(vo)
+  { }
 
   void set_containing_obj(oop obj) {
     _containing_obj = obj;
--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -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
@@ -232,7 +232,7 @@
     if (word_sz * 100 <
         ParallelGCBufferWastePct * plab->word_sz()) {
       // Is small enough; abandon this buffer and start a new one.
-      plab->retire(false, false);
+      plab->retire();
       size_t buf_size = plab->word_sz();
       HeapWord* buf_space = sp->par_allocate(buf_size);
       if (buf_space == NULL) {
@@ -463,10 +463,7 @@
 
     // Flush stats related to To-space PLAB activity and
     // retire the last buffer.
-    par_scan_state.to_space_alloc_buffer()->
-      flush_stats_and_retire(_gen.plab_stats(),
-                             true /* end_of_gc */,
-                             false /* retain */);
+    par_scan_state.to_space_alloc_buffer()->flush_and_retire_stats(_gen.plab_stats());
 
     // Every thread has its own age table.  We need to merge
     // them all into one.
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -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
@@ -81,7 +81,7 @@
     assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
 
     _young_gen = heap->young_gen();
-    _card_table = (CardTableExtension*)heap->barrier_set();
+    _card_table = barrier_set_cast<CardTableExtension>(heap->barrier_set());
     // No point in asserting barrier set type here. Need to make CardTableExtension
     // a unique barrier set type.
   }
@@ -341,7 +341,9 @@
 
   PSOldGen* old_gen = heap->old_gen();
 
-  CheckForPreciseMarks check(heap->young_gen(), (CardTableExtension*)heap->barrier_set());
+  CheckForPreciseMarks check(
+    heap->young_gen(),
+    barrier_set_cast<CardTableExtension>(heap->barrier_set()));
 
   old_gen->oop_iterate_no_header(&check);
 
@@ -349,8 +351,8 @@
 }
 
 void CardTableExtension::verify_all_young_refs_precise_helper(MemRegion mr) {
-  CardTableExtension* card_table = (CardTableExtension*)Universe::heap()->barrier_set();
-  // FIX ME ASSERT HERE
+  CardTableExtension* card_table =
+    barrier_set_cast<CardTableExtension>(Universe::heap()->barrier_set());
 
   jbyte* bot = card_table->byte_for(mr.start());
   jbyte* top = card_table->byte_for(mr.end());
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.hpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.hpp	Thu Mar 05 17:27:16 2015 +0100
@@ -54,10 +54,16 @@
   };
 
   CardTableExtension(MemRegion whole_heap) :
-    CardTableModRefBS(whole_heap, BarrierSet::CardTableModRef) { }
-
-  // Too risky for the 4/10/02 putback
-  // BarrierSet::Name kind() { return BarrierSet::CardTableExtension; }
+    CardTableModRefBS(
+      whole_heap,
+      // Concrete tag should be BarrierSet::CardTableExtension.
+      // That will presently break things in a bunch of places though.
+      // The concrete tag is used as a dispatch key in many places, and
+      // CardTableExtension does not correctly dispatch in some of those
+      // uses. This will be addressed as part of a reorganization of the
+      // BarrierSet hierarchy.
+      BarrierSet::FakeRtti(BarrierSet::CardTableModRef, 0).add_tag(BarrierSet::CardTableExtension))
+    { }
 
   // Scavenge support
   void scavenge_contents_parallel(ObjectStartArray* start_array,
@@ -110,4 +116,9 @@
 #endif // ASSERT
 };
 
+template<>
+struct BarrierSet::GetName<CardTableExtension> {
+  static const BarrierSet::Name value = BarrierSet::CardTableExtension;
+};
+
 #endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_CARDTABLEEXTENSION_HPP
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.cpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -1,6 +1,6 @@
 
 /*
- * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -98,6 +98,7 @@
   // Set up the thread for stack overflow support
   this->record_stack_base_and_size();
   this->initialize_thread_local_storage();
+  this->initialize_named_thread();
   // Bind yourself to your processor.
   if (processor_id() != GCTaskManager::sentinel_worker()) {
     if (TraceGCTaskThread) {
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -1,6 +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
@@ -233,15 +232,12 @@
                       young_gen->to_space()->is_empty();
     young_gen_empty = eden_empty && survivors_empty;
 
-    BarrierSet* bs = heap->barrier_set();
-    if (bs->is_a(BarrierSet::ModRef)) {
-      ModRefBarrierSet* modBS = (ModRefBarrierSet*)bs;
-      MemRegion old_mr = heap->old_gen()->reserved();
-      if (young_gen_empty) {
-        modBS->clear(MemRegion(old_mr.start(), old_mr.end()));
-      } else {
-        modBS->invalidate(MemRegion(old_mr.start(), old_mr.end()));
-      }
+    ModRefBarrierSet* modBS = barrier_set_cast<ModRefBarrierSet>(heap->barrier_set());
+    MemRegion old_mr = heap->old_gen()->reserved();
+    if (young_gen_empty) {
+      modBS->clear(MemRegion(old_mr.start(), old_mr.end()));
+    } else {
+      modBS->invalidate(MemRegion(old_mr.start(), old_mr.end()));
     }
 
     // Delete metaspaces for unloaded class loaders and clean up loader_data graph
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -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
@@ -111,8 +111,8 @@
 
   Universe::heap()->barrier_set()->resize_covered_region(cmr);
 
-  CardTableModRefBS* _ct = (CardTableModRefBS*)Universe::heap()->barrier_set();
-  assert (_ct->kind() == BarrierSet::CardTableModRef, "Sanity");
+  CardTableModRefBS* _ct =
+    barrier_set_cast<CardTableModRefBS>(Universe::heap()->barrier_set());
 
   // Verify that the start and end of this generation is the start of a card.
   // If this wasn't true, a single card could span more than one generation,
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -1050,16 +1050,12 @@
   bool young_gen_empty = eden_empty && from_space->is_empty() &&
     to_space->is_empty();
 
-  BarrierSet* bs = heap->barrier_set();
-  if (bs->is_a(BarrierSet::ModRef)) {
-    ModRefBarrierSet* modBS = (ModRefBarrierSet*)bs;
-    MemRegion old_mr = heap->old_gen()->reserved();
-
-    if (young_gen_empty) {
-      modBS->clear(MemRegion(old_mr.start(), old_mr.end()));
-    } else {
-      modBS->invalidate(MemRegion(old_mr.start(), old_mr.end()));
-    }
+  ModRefBarrierSet* modBS = barrier_set_cast<ModRefBarrierSet>(heap->barrier_set());
+  MemRegion old_mr = heap->old_gen()->reserved();
+  if (young_gen_empty) {
+    modBS->clear(MemRegion(old_mr.start(), old_mr.end()));
+  } else {
+    modBS->invalidate(MemRegion(old_mr.start(), old_mr.end()));
   }
 
   // Delete metaspaces for unloaded class loaders and clean up loader_data graph
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -1,6 +1,5 @@
-
 /*
- * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -866,9 +865,7 @@
                            NULL);                      // header provides liveness info
 
   // Cache the cardtable
-  BarrierSet* bs = Universe::heap()->barrier_set();
-  assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind");
-  _card_table = (CardTableExtension*)bs;
+  _card_table = barrier_set_cast<CardTableExtension>(heap->barrier_set());
 
   _counters = new CollectorCounters("PSScavenge", 0);
 }
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -183,8 +183,8 @@
     PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(which);
 
     assert(Universe::heap()->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
-    CardTableExtension* card_table = (CardTableExtension *)Universe::heap()->barrier_set();
-    // FIX ME! Assert that card_table is the type we believe it to be.
+    CardTableExtension* card_table =
+      barrier_set_cast<CardTableExtension>(Universe::heap()->barrier_set());
 
     card_table->scavenge_contents_parallel(_gen->start_array(),
                                            _gen->object_space(),
--- a/hotspot/src/share/vm/gc_implementation/shared/concurrentGCThread.cpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/shared/concurrentGCThread.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -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
@@ -56,6 +56,7 @@
 void ConcurrentGCThread::initialize_in_thread() {
   this->record_stack_base_and_size();
   this->initialize_thread_local_storage();
+  this->initialize_named_thread();
   this->set_active_handles(JNIHandleBlock::allocate_block());
   // From this time Thread::current() should be working.
   assert(this == Thread::current(), "just checking");
--- a/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -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
@@ -24,27 +24,30 @@
 
 #include "precompiled.hpp"
 #include "gc_implementation/shared/parGCAllocBuffer.hpp"
-#include "memory/sharedHeap.hpp"
+#include "memory/threadLocalAllocBuffer.hpp"
 #include "oops/arrayOop.hpp"
 #include "oops/oop.inline.hpp"
-#include "utilities/globalDefinitions.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
+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),
-  _retained(false), _retained_filler(),
-  _allocated(0), _wasted(0)
+  _end(NULL), _hard_end(NULL), _allocated(0), _wasted(0)
 {
-  assert (min_size() > AlignmentReserve, "Inconsistency!");
-  // arrayOopDesc::header_size depends on command line initialization.
-  FillerHeaderSize = align_object_size(arrayOopDesc::header_size(T_INT));
-  AlignmentReserve = oopDesc::header_size() > MinObjAlignment ? FillerHeaderSize : 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));
 }
 
-size_t ParGCAllocBuffer::FillerHeaderSize;
-
 // 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
@@ -52,39 +55,33 @@
 // sure we have enough space for a filler int array object.
 size_t ParGCAllocBuffer::AlignmentReserve;
 
-void ParGCAllocBuffer::retire(bool end_of_gc, bool retain) {
-  assert(!retain || end_of_gc, "Can only retain at GC end.");
-  if (_retained) {
-    // If the buffer had been retained shorten the previous filler object.
-    assert(_retained_filler.end() <= _top, "INVARIANT");
-    CollectedHeap::fill_with_object(_retained_filler);
-    // Wasted space book-keeping, otherwise (normally) done in invalidate()
-    _wasted += _retained_filler.word_size();
-    _retained = false;
-  }
-  assert(!end_of_gc || !_retained, "At this point, end_of_gc ==> !_retained.");
+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);
-    if (!retain) {
-      invalidate();
-    } else {
-      // Is there wasted space we'd like to retain for the next GC?
-      if (pointer_delta(_end, _top) > FillerHeaderSize) {
-        _retained = true;
-        _retained_filler = MemRegion(_top, FillerHeaderSize);
-        _top = _top + FillerHeaderSize;
-      } else {
-        invalidate();
-      }
-    }
+    result += invalidate();
   }
-}
-
-void ParGCAllocBuffer::flush_stats(PLABStats* stats) {
-  assert(ResizePLAB, "Wasted work");
-  stats->add_allocated(_allocated);
-  stats->add_wasted(_wasted);
-  stats->add_unused(pointer_delta(_end, _top));
+  return result;
 }
 
 // Compute desired plab size and latch result for later
@@ -101,44 +98,37 @@
            err_msg("Inconsistency in PLAB stats: "
                    "_allocated: "SIZE_FORMAT", "
                    "_wasted: "SIZE_FORMAT", "
-                   "_unused: "SIZE_FORMAT", "
-                   "_used  : "SIZE_FORMAT,
-                   _allocated, _wasted, _unused, _used));
+                   "_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);
+  double wasted_frac    = (double)_unused / (double)_allocated;
+  size_t target_refills = (size_t)((wasted_frac * TargetSurvivorRatio) / TargetPLABWastePct);
   if (target_refills == 0) {
     target_refills = 1;
   }
-  _used = _allocated - _wasted - _unused;
-  size_t plab_sz = _used/(target_refills*no_of_gc_workers);
-  if (PrintPLAB) gclog_or_tty->print(" (plab_sz = " SIZE_FORMAT " ", plab_sz);
+  size_t used = _allocated - _wasted - _unused;
+  size_t recent_plab_sz = used / (target_refills * no_of_gc_workers);
   // Take historical weighted average
-  _filter.sample(plab_sz);
+  _filter.sample(recent_plab_sz);
   // Clip from above and below, and align to object boundary
-  plab_sz = MAX2(min_size(), (size_t)_filter.average());
-  plab_sz = MIN2(max_size(), plab_sz);
-  plab_sz = align_object_size(plab_sz);
+  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(" desired_plab_sz = " SIZE_FORMAT ") ", plab_sz);
-  _desired_plab_sz = plab_sz;
-  // Now clear the accumulators for next round:
-  // note this needs to be fixed in the case where we
-  // are retaining across scavenges. FIX ME !!! XXX
-  _allocated = 0;
-  _wasted    = 0;
-  _unused    = 0;
+  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("parGCAllocBuffer: _bottom: " PTR_FORMAT "  _top: " PTR_FORMAT
-             "  _end: " PTR_FORMAT "  _hard_end: " PTR_FORMAT " _retained: %c"
-             " _retained_filler: [" PTR_FORMAT "," PTR_FORMAT ")\n",
-             _bottom, _top, _end, _hard_end,
-             "FT"[_retained], _retained_filler.start(), _retained_filler.end());
+  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	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp	Thu Mar 05 17:27:16 2015 +0100
@@ -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
@@ -24,37 +24,43 @@
 
 #ifndef SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARGCALLOCBUFFER_HPP
 #define SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARGCALLOCBUFFER_HPP
-#include "gc_interface/collectedHeap.hpp"
+
+#include "gc_implementation/shared/gcUtil.hpp"
 #include "memory/allocation.hpp"
-#include "memory/blockOffsetTable.hpp"
-#include "memory/threadLocalAllocBuffer.hpp"
+#include "runtime/atomic.hpp"
 #include "utilities/globalDefinitions.hpp"
 
-// Forward decl.
-
+// 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
+  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
-  bool      _retained;  // whether we hold a _retained_filler
-  MemRegion _retained_filler;
+  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 FillerHeaderSize;
+  char      tail[32];
   static size_t AlignmentReserve;
 
-  // Flush the stats supporting ergonomic sizing of PLAB's
-  // Should not be called directly
-  void flush_stats(PLABStats* stats);
+  // 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".
@@ -62,14 +68,10 @@
   ParGCAllocBuffer(size_t word_sz);
   virtual ~ParGCAllocBuffer() {}
 
-  static const size_t 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;
-  }
-
-  static const size_t max_size() {
-    return ThreadLocalAllocBuffer::max_size();
-  }
+  // 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
@@ -128,62 +130,37 @@
     _allocated += word_sz();
   }
 
-  // Flush the stats supporting ergonomic sizing of PLAB's
-  // and retire the current buffer.
-  void flush_stats_and_retire(PLABStats* stats, bool end_of_gc, bool retain) {
-    // We flush the stats first in order to get a reading of
-    // unused space in the last buffer.
-    if (ResizePLAB) {
-      flush_stats(stats);
+  // 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);
 
-      // Since we have flushed the stats we need to clear
-      // the _allocated and _wasted fields. Not doing so
-      // will artifically inflate the values in the stats
-      // to which we add them.
-      // The next time we flush these values, we will add
-      // what we have just flushed in addition to the size
-      // of the buffers allocated between now and then.
-      _allocated = 0;
-      _wasted = 0;
-    }
-    // Retire the last allocation buffer.
-    retire(end_of_gc, retain);
-  }
-
-  // Force future allocations to fail and queries for contains()
-  // to return false
-  void invalidate() {
-    assert(!_retained, "Shouldn't retain an invalidated buffer.");
-    _end    = _hard_end;
-    _wasted += pointer_delta(_end, _top);  // unused  space
-    _top    = _end;      // force future allocations to fail
-    _bottom = _end;      // force future contains() queries to return false
-  }
-
-  // Fills in the unallocated portion of the buffer with a garbage object.
-  // If "end_of_gc" is TRUE, is after the last use in the GC.  IF "retain"
-  // is true, attempt to re-use the unused portion in the next GC.
-  virtual void retire(bool end_of_gc, bool retain);
+  // 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 stats book-keeping
+// PLAB book-keeping.
 class PLABStats VALUE_OBJ_CLASS_SPEC {
-  size_t _allocated;      // total allocated
+  size_t _allocated;      // Total allocated
   size_t _wasted;         // of which wasted (internal fragmentation)
   size_t _unused;         // Unused in last buffer
-  size_t _used;           // derived = allocated - wasted - unused
-  size_t _desired_plab_sz;// output of filter (below), suitably trimmed and quantized
+  size_t _desired_plab_sz;// Output of filter (below), suitably trimmed and quantized
   AdaptiveWeightedAverage
-         _filter;         // integrator with decay
+         _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),
-    _used(0),
     _desired_plab_sz(desired_plab_sz_),
     _filter(wt)
   { }
@@ -200,9 +177,9 @@
     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);
-                                 // filter computation, latches output to
-                                 // _desired_plab_sz, clears sensor accumulators
 
   void add_allocated(size_t v) {
     Atomic::add_ptr(v, &_allocated);
--- a/hotspot/src/share/vm/memory/barrierSet.hpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/share/vm/memory/barrierSet.hpp	Thu Mar 05 17:27:16 2015 +0100
@@ -27,6 +27,7 @@
 
 #include "memory/memRegion.hpp"
 #include "oops/oopsHierarchy.hpp"
+#include "utilities/fakeRttiSupport.hpp"
 
 // This class provides the interface between a barrier implementation and
 // the rest of the system.
@@ -34,18 +35,57 @@
 class BarrierSet: public CHeapObj<mtGC> {
   friend class VMStructs;
 public:
-  enum Name {
-    ModRef,
-    CardTableModRef,
-    CardTableExtension,
-    G1SATBCT,
-    G1SATBCTLogging
+  // Fake RTTI support.  For a derived class T to participate
+  // - T must have a corresponding Name entry.
+  // - GetName<T> must be specialized to return the corresponding Name
+  //   entry.
+  // - If T is a base class, the constructor must have a FakeRtti
+  //   parameter and pass it up to its base class, with the tag set
+  //   augmented with the corresponding Name entry.
+  // - If T is a concrete class, the constructor must create a
+  //   FakeRtti object whose tag set includes the corresponding Name
+  //   entry, and pass it up to its base class.
+
+  enum Name {                   // associated class
+    ModRef,                     // ModRefBarrierSet
+    CardTableModRef,            // CardTableModRefBS
+    CardTableForRS,             // CardTableModRefBSForCTRS
+    CardTableExtension,         // CardTableExtension
+    G1SATBCT,                   // G1SATBCardTableModRefBS
+    G1SATBCTLogging             // G1SATBCardTableLoggingModRefBS
   };
 
+protected:
+  typedef FakeRttiSupport<BarrierSet, Name> FakeRtti;
+
+private:
+  FakeRtti _fake_rtti;
+
+  // Metafunction mapping a class derived from BarrierSet to the
+  // corresponding Name enum tag.
+  template<typename T> struct GetName;
+
+  // Downcast argument to a derived barrier set type.
+  // The cast is checked in a debug build.
+  // T must have a specialization for BarrierSet::GetName<T>.
+  template<typename T> friend T* barrier_set_cast(BarrierSet* bs);
+
+public:
+  // Note: This is not presently the Name corresponding to the
+  // concrete class of this object.
+  BarrierSet::Name kind() const { return _fake_rtti.concrete_tag(); }
+
+  // Test whether this object is of the type corresponding to bsn.
+  bool is_a(BarrierSet::Name bsn) const { return _fake_rtti.has_tag(bsn); }
+
+  // End of fake RTTI support.
+
+public:
   enum Flags {
     None                = 0,
     TargetUninitialized = 1
   };
+
 protected:
   // Some barrier sets create tables whose elements correspond to parts of
   // the heap; the CardTableModRefBS is an example.  Such barrier sets will
@@ -53,17 +93,12 @@
   // "covering" parts of the heap that are committed. At most one covered
   // region per generation is needed.
   static const int _max_covered_regions = 2;
-  Name _kind;
 
-  BarrierSet(Name kind) : _kind(kind) { }
+  BarrierSet(const FakeRtti& fake_rtti) : _fake_rtti(fake_rtti) { }
   ~BarrierSet() { }
 
 public:
 
-  // To get around prohibition on RTTI.
-  BarrierSet::Name kind() { return _kind; }
-  virtual bool is_a(BarrierSet::Name bsn) = 0;
-
   // These operations indicate what kind of barriers the BarrierSet has.
   virtual bool has_read_ref_barrier() = 0;
   virtual bool has_read_prim_barrier() = 0;
@@ -177,4 +212,10 @@
   virtual void print_on(outputStream* st) const = 0;
 };
 
+template<typename T>
+inline T* barrier_set_cast(BarrierSet* bs) {
+  assert(bs->is_a(BarrierSet::GetName<T>::value), "wrong type of barrier set");
+  return static_cast<T*>(bs);
+}
+
 #endif // SHARE_VM_MEMORY_BARRIERSET_HPP
--- a/hotspot/src/share/vm/memory/barrierSet.inline.hpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/share/vm/memory/barrierSet.inline.hpp	Thu Mar 05 17:27:16 2015 +0100
@@ -34,7 +34,7 @@
 
 template <class T> void BarrierSet::write_ref_field_pre(T* field, oop new_val) {
   if (kind() == CardTableModRef) {
-    ((CardTableModRefBS*)this)->inline_write_ref_field_pre(field, new_val);
+    barrier_set_cast<CardTableModRefBS>(this)->inline_write_ref_field_pre(field, new_val);
   } else {
     write_ref_field_pre_work(field, new_val);
   }
@@ -42,7 +42,7 @@
 
 void BarrierSet::write_ref_field(void* field, oop new_val, bool release) {
   if (kind() == CardTableModRef) {
-    ((CardTableModRefBS*)this)->inline_write_ref_field(field, new_val, release);
+    barrier_set_cast<CardTableModRefBS>(this)->inline_write_ref_field(field, new_val, release);
   } else {
     write_ref_field_work(field, new_val, release);
   }
@@ -78,7 +78,7 @@
 
 inline void BarrierSet::write_region(MemRegion mr) {
   if (kind() == CardTableModRef) {
-    ((CardTableModRefBS*)this)->inline_write_region(mr);
+    barrier_set_cast<CardTableModRefBS>(this)->inline_write_region(mr);
   } else {
     write_region_work(mr);
   }
--- a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -53,8 +53,10 @@
   return align_size_up(_guard_index + 1, MAX2(_page_size, granularity));
 }
 
-CardTableModRefBS::CardTableModRefBS(MemRegion whole_heap, BarrierSet::Name kind) :
-  ModRefBarrierSet(kind),
+CardTableModRefBS::CardTableModRefBS(
+  MemRegion whole_heap,
+  const BarrierSet::FakeRtti& fake_rtti) :
+  ModRefBarrierSet(fake_rtti.add_tag(BarrierSet::CardTableModRef)),
   _whole_heap(whole_heap),
   _guard_index(0),
   _guard_region(),
--- a/hotspot/src/share/vm/memory/cardTableModRefBS.hpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/share/vm/memory/cardTableModRefBS.hpp	Thu Mar 05 17:27:16 2015 +0100
@@ -279,11 +279,6 @@
   static int precleaned_card_val() { return precleaned_card; }
   static int deferred_card_val()   { return deferred_card; }
 
-  // For RTTI simulation.
-  bool is_a(BarrierSet::Name bsn) {
-    return bsn == BarrierSet::CardTableModRef || ModRefBarrierSet::is_a(bsn);
-  }
-
   virtual void initialize();
 
   // *** Barrier set functions.
@@ -292,7 +287,7 @@
 
 protected:
 
-  CardTableModRefBS(MemRegion whole_heap, BarrierSet::Name kind);
+  CardTableModRefBS(MemRegion whole_heap, const BarrierSet::FakeRtti& fake_rtti);
   ~CardTableModRefBS();
 
   // Record a reference update. Note that these versions are precise!
@@ -462,6 +457,11 @@
   void verify_dirty_region(MemRegion mr) PRODUCT_RETURN;
 };
 
+template<>
+struct BarrierSet::GetName<CardTableModRefBS> {
+  static const BarrierSet::Name value = BarrierSet::CardTableModRef;
+};
+
 class CardTableRS;
 
 // A specialization for the CardTableRS gen rem set.
@@ -472,10 +472,24 @@
   bool card_may_have_been_dirty(jbyte cv);
 public:
   CardTableModRefBSForCTRS(MemRegion whole_heap) :
-    CardTableModRefBS(whole_heap, BarrierSet::CardTableModRef) {}
+    CardTableModRefBS(
+      whole_heap,
+      // Concrete tag should be BarrierSet::CardTableForRS.
+      // That will presently break things in a bunch of places though.
+      // The concrete tag is used as a dispatch key in many places, and
+      // CardTableForRS does not correctly dispatch in some of those
+      // uses. This will be addressed as part of a reorganization of the
+      // BarrierSet hierarchy.
+      BarrierSet::FakeRtti(BarrierSet::CardTableModRef, 0).add_tag(BarrierSet::CardTableForRS))
+    {}
 
   void set_CTRS(CardTableRS* rs) { _rs = rs; }
 };
 
+template<>
+struct BarrierSet::GetName<CardTableModRefBSForCTRS> {
+  static const BarrierSet::Name value = BarrierSet::CardTableForRS;
+};
+
 
 #endif // SHARE_VM_MEMORY_CARDTABLEMODREFBS_HPP
--- a/hotspot/src/share/vm/memory/modRefBarrierSet.hpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/share/vm/memory/modRefBarrierSet.hpp	Thu Mar 05 17:27:16 2015 +0100
@@ -37,10 +37,6 @@
 class ModRefBarrierSet: public BarrierSet {
 public:
 
-  bool is_a(BarrierSet::Name bsn) {
-    return bsn == BarrierSet::ModRef;
-  }
-
   // Barriers only on ref writes.
   bool has_read_ref_barrier() { return false; }
   bool has_read_prim_barrier() { return false; }
@@ -60,7 +56,8 @@
 
 protected:
 
-  ModRefBarrierSet(BarrierSet::Name kind) : BarrierSet(kind) { }
+  ModRefBarrierSet(const BarrierSet::FakeRtti& fake_rtti)
+    : BarrierSet(fake_rtti.add_tag(BarrierSet::ModRef)) { }
   ~ModRefBarrierSet() { }
 
   virtual void write_ref_field_work(void* field, oop new_val, bool release = false) = 0;
@@ -100,4 +97,9 @@
   virtual void clear(MemRegion mr) = 0;
 };
 
+template<>
+struct BarrierSet::GetName<ModRefBarrierSet> {
+  static const BarrierSet::Name value = BarrierSet::ModRef;
+};
+
 #endif // SHARE_VM_MEMORY_MODREFBARRIERSET_HPP
--- a/hotspot/src/share/vm/opto/graphKit.cpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/share/vm/opto/graphKit.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -3759,7 +3759,8 @@
 
 Node* GraphKit::byte_map_base_node() {
   // Get base of card map
-  CardTableModRefBS* ct = (CardTableModRefBS*)(Universe::heap()->barrier_set());
+  CardTableModRefBS* ct =
+    barrier_set_cast<CardTableModRefBS>(Universe::heap()->barrier_set());
   assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust users of this code");
   if (ct->byte_map_base != NULL) {
     return makecon(TypeRawPtr::make((address)ct->byte_map_base));
--- a/hotspot/src/share/vm/runtime/thread.cpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/share/vm/runtime/thread.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -1161,6 +1161,10 @@
   va_end(ap);
 }
 
+void NamedThread::initialize_named_thread() {
+  set_native_thread_name(name());
+}
+
 void NamedThread::print_on(outputStream* st) const {
   st->print("\"%s\" ", name());
   Thread::print_on(st);
--- a/hotspot/src/share/vm/runtime/thread.hpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/share/vm/runtime/thread.hpp	Thu Mar 05 17:27:16 2015 +0100
@@ -667,6 +667,7 @@
   ~NamedThread();
   // May only be called once per thread.
   void set_name(const char* format, ...)  ATTRIBUTE_PRINTF(2, 3);
+  void initialize_named_thread();
   virtual bool is_Named_thread() const { return true; }
   virtual char* name() const { return _name == NULL ? (char*)"Unknown Thread" : _name; }
   JavaThread *processed_thread() { return _processed_thread; }
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -481,7 +481,6 @@
                                                                                                                                      \
   unchecked_nonstatic_field(ageTable,          sizes,                                         sizeof(ageTable::sizes))               \
                                                                                                                                      \
-  nonstatic_field(BarrierSet,                  _kind,                                         BarrierSet::Name)                      \
   nonstatic_field(BlockOffsetTable,            _bottom,                                       HeapWord*)                             \
   nonstatic_field(BlockOffsetTable,            _end,                                          HeapWord*)                             \
                                                                                                                                      \
--- a/hotspot/src/share/vm/runtime/vmThread.cpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/share/vm/runtime/vmThread.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -243,7 +243,7 @@
   assert(this == vm_thread(), "check");
 
   this->initialize_thread_local_storage();
-  this->set_native_thread_name(this->name());
+  this->initialize_named_thread();
   this->record_stack_base_and_size();
   // Notify_lock wait checks on active_handles() to rewait in
   // case of spurious wakeup, it should wait on the last
--- a/hotspot/src/share/vm/shark/sharkBuilder.cpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/share/vm/shark/sharkBuilder.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2008, 2009, 2010 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -446,7 +446,7 @@
     CreateIntToPtr(
       CreateAdd(
         LLVMValue::intptr_constant(
-          (intptr_t) ((CardTableModRefBS *) bs)->byte_map_base),
+          (intptr_t) (barrier_set_cast<CardTableModRefBS>(bs)->byte_map_base)),
         CreateLShr(
           CreatePtrToInt(field, SharkType::intptr_type()),
           LLVMValue::intptr_constant(CardTableModRefBS::card_shift))),
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/utilities/fakeRttiSupport.hpp	Thu Mar 05 17:27:16 2015 +0100
@@ -0,0 +1,100 @@
+/*
+ * 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.
+ *
+ */
+
+#ifndef SHARE_VM_UTILITIES_FAKERTTISUPPORT_HPP
+#define SHARE_VM_UTILITIES_FAKERTTISUPPORT_HPP
+
+#include "utilities/globalDefinitions.hpp"
+#include "utilities/debug.hpp"
+
+// Provides support for checked downcasts in a hierarchy of classes.
+// The base class provides a member of this type, specialized on that
+// base class and an associated tag type.  Tags are small non-negative
+// integer values uniquely associated with distinct classes in the
+// hierarchy.  A tag type is often an enum type.
+//
+// The concrete class specifies the concrete tag.
+//
+// The tag set specifies the set of classes in the derivation
+// sequence.  Classes in the derivation sequence add their associated
+// tag during construction.  Given the tag associated with a class, an
+// object is an instance of that class if the tag is included in the
+// object's set of recorded tags.
+//
+// A tag T is present in a tag set if the T'th bit of the tag set is
+// one.
+//
+// Note: The representation of a tag set being uintx sets an upper
+// bound on the size of a class hierarchy this utility can be used
+// with.
+template<typename T, typename TagType>
+class FakeRttiSupport VALUE_OBJ_CLASS_SPEC {
+public:
+  // Construct with the indicated concrete tag, and include the
+  // concrete tag in the associated tag set.
+  explicit FakeRttiSupport(TagType concrete_tag) :
+    _tag_set(tag_bit(concrete_tag)), _concrete_tag(concrete_tag) { }
+
+  // Construct with the indicated concrete tag and tag set.
+  // Note: This constructor is public only to allow clients to set up
+  // "unusual" (or perhaps buggy) fake RTTI configurations.
+  FakeRttiSupport(TagType concrete_tag, uintx tag_set) :
+    _tag_set(tag_set), _concrete_tag(validate_tag(concrete_tag)) { }
+
+  // Get the concrete tag.
+  TagType concrete_tag() const { return _concrete_tag; }
+
+  // Test whether tag is in the tag set.
+  bool has_tag(TagType tag) const {
+    return (_tag_set & tag_bit(tag)) != 0;
+  }
+
+  // Return a new support object which is the same as this, except tag
+  // has been added to the tag set.  The tag must not already be
+  // present in the tag set.
+  FakeRttiSupport add_tag(TagType tag) const {
+    uintx tbit = tag_bit(tag);
+    assert((_tag_set & tbit) == 0,
+           err_msg("Tag " UINTX_FORMAT " is already present in tag set: " UINTX_FORMAT,
+                   (uintx)tag, _tag_set));
+    return FakeRttiSupport(_concrete_tag, _tag_set | tbit);
+  }
+
+private:
+  uintx _tag_set;
+  TagType _concrete_tag;
+
+  static uintx tag_bit(TagType tag) {
+    return ((uintx)1) << validate_tag(tag);
+  }
+
+  static TagType validate_tag(uintx tag) {
+    // Type of tag is not TagType to dodge useless MacOSX compiler warning.
+    assert(tag < (sizeof(uintx) * BitsPerByte),
+           err_msg("Tag " UINTX_FORMAT " is too large", tag));
+    return static_cast<TagType>(tag);
+  }
+};
+
+#endif // include guard
--- a/hotspot/src/share/vm/utilities/workgroup.cpp	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/src/share/vm/utilities/workgroup.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -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
@@ -247,6 +247,7 @@
 void GangWorker::initialize() {
   this->initialize_thread_local_storage();
   this->record_stack_base_and_size();
+  this->initialize_named_thread();
   assert(_gang != NULL, "No gang to run in");
   os::set_priority(this, NearMaxPriority);
   if (TraceWorkGang) {
--- a/hotspot/test/gc/TestSmallHeap.java	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/test/gc/TestSmallHeap.java	Thu Mar 05 17:27:16 2015 +0100
@@ -26,6 +26,7 @@
  * @bug 8067438
  * @requires vm.gc=="null"
  * @requires (vm.opt.AggressiveOpts=="null") | (vm.opt.AggressiveOpts=="false")
+ * @requires vm.compMode != "Xcomp"
  * @summary Verify that starting the VM with a small heap works
  * @library /testlibrary /../../test/lib
  * @build TestSmallHeap
--- a/hotspot/test/gc/TestSoftReferencesBehaviorOnOOME.java	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/test/gc/TestSoftReferencesBehaviorOnOOME.java	Thu Mar 05 17:27:16 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -26,6 +26,7 @@
  * @key gc
  * @summary Tests that all SoftReferences has been cleared at time of OOM.
  * @library /testlibrary
+ * @ignore 8073669
  * @build TestSoftReferencesBehaviorOnOOME
  * @run main/othervm -Xmx128m TestSoftReferencesBehaviorOnOOME 512 2k
  * @run main/othervm -Xmx128m TestSoftReferencesBehaviorOnOOME 128k 256k
--- a/hotspot/test/serviceability/dcmd/gc/RunGCTest.java	Tue Mar 03 20:17:07 2015 +0100
+++ b/hotspot/test/serviceability/dcmd/gc/RunGCTest.java	Thu Mar 05 17:27:16 2015 +0100
@@ -39,7 +39,7 @@
  * @library /testlibrary
  * @build com.oracle.java.testlibrary.*
  * @build com.oracle.java.testlibrary.dcmd.*
- * @run testng/othervm -XX:+PrintGCDetails -Xloggc:RunGC.gclog RunGCTest
+ * @run testng/othervm -XX:+PrintGCDetails -Xloggc:RunGC.gclog -XX:-ExplicitGCInvokesConcurrent RunGCTest
  */
 public class RunGCTest {
     public void run(CommandExecutor executor) {