8069016: Add BarrierSet downcast support
Summary: Add FakeRttiSupport utility and use to provide barrier_set_cast.
Reviewed-by: jmasa, sangheki
--- a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp Thu Feb 26 21:00:03 2015 +0100
+++ b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp Fri Feb 27 19:52:48 2015 -0500
@@ -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 Thu Feb 26 21:00:03 2015 +0100
+++ b/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp Fri Feb 27 19:52:48 2015 -0500
@@ -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 Thu Feb 26 21:00:03 2015 +0100
+++ b/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp Fri Feb 27 19:52:48 2015 -0500
@@ -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 Thu Feb 26 21:00:03 2015 +0100
+++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp Fri Feb 27 19:52:48 2015 -0500
@@ -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 Thu Feb 26 21:00:03 2015 +0100
+++ b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp Fri Feb 27 19:52:48 2015 -0500
@@ -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 Thu Feb 26 21:00:03 2015 +0100
+++ b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp Fri Feb 27 19:52:48 2015 -0500
@@ -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 Thu Feb 26 21:00:03 2015 +0100
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp Fri Feb 27 19:52:48 2015 -0500
@@ -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 Thu Feb 26 21:00:03 2015 +0100
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp Fri Feb 27 19:52:48 2015 -0500
@@ -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 Thu Feb 26 21:00:03 2015 +0100
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Fri Feb 27 19:52:48 2015 -0500
@@ -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 Thu Feb 26 21:00:03 2015 +0100
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Fri Feb 27 19:52:48 2015 -0500
@@ -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 Thu Feb 26 21:00:03 2015 +0100
+++ b/hotspot/src/share/vm/compiler/disassembler.cpp Fri Feb 27 19:52:48 2015 -0500
@@ -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/g1/concurrentMark.cpp Thu Feb 26 21:00:03 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Fri Feb 27 19:52:48 2015 -0500
@@ -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/g1CollectedHeap.hpp Thu Feb 26 21:00:03 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Fri Feb 27 19:52:48 2015 -0500
@@ -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 Thu Feb 26 21:00:03 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp Fri Feb 27 19:52:48 2015 -0500
@@ -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 Thu Feb 26 21:00:03 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp Fri Feb 27 19:52:48 2015 -0500
@@ -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 Thu Feb 26 21:00:03 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Fri Feb 27 19:52:48 2015 -0500
@@ -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/parallelScavenge/cardTableExtension.cpp Thu Feb 26 21:00:03 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp Fri Feb 27 19:52:48 2015 -0500
@@ -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 Thu Feb 26 21:00:03 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.hpp Fri Feb 27 19:52:48 2015 -0500
@@ -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/psMarkSweep.cpp Thu Feb 26 21:00:03 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Fri Feb 27 19:52:48 2015 -0500
@@ -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 Thu Feb 26 21:00:03 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp Fri Feb 27 19:52:48 2015 -0500
@@ -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 Thu Feb 26 21:00:03 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Fri Feb 27 19:52:48 2015 -0500
@@ -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 Thu Feb 26 21:00:03 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Fri Feb 27 19:52:48 2015 -0500
@@ -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 Thu Feb 26 21:00:03 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp Fri Feb 27 19:52:48 2015 -0500
@@ -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/memory/barrierSet.hpp Thu Feb 26 21:00:03 2015 +0100
+++ b/hotspot/src/share/vm/memory/barrierSet.hpp Fri Feb 27 19:52:48 2015 -0500
@@ -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,61 @@
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) {
+ assert(bs->is_a(BarrierSet::GetName<T>::value), "wrong type of barrier set");
+ return static_cast<T*>(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 +97,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;
--- a/hotspot/src/share/vm/memory/barrierSet.inline.hpp Thu Feb 26 21:00:03 2015 +0100
+++ b/hotspot/src/share/vm/memory/barrierSet.inline.hpp Fri Feb 27 19:52:48 2015 -0500
@@ -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 Thu Feb 26 21:00:03 2015 +0100
+++ b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp Fri Feb 27 19:52:48 2015 -0500
@@ -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 Thu Feb 26 21:00:03 2015 +0100
+++ b/hotspot/src/share/vm/memory/cardTableModRefBS.hpp Fri Feb 27 19:52:48 2015 -0500
@@ -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 Thu Feb 26 21:00:03 2015 +0100
+++ b/hotspot/src/share/vm/memory/modRefBarrierSet.hpp Fri Feb 27 19:52:48 2015 -0500
@@ -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 Thu Feb 26 21:00:03 2015 +0100
+++ b/hotspot/src/share/vm/opto/graphKit.cpp Fri Feb 27 19:52:48 2015 -0500
@@ -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/vmStructs.cpp Thu Feb 26 21:00:03 2015 +0100
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Fri Feb 27 19:52:48 2015 -0500
@@ -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/shark/sharkBuilder.cpp Thu Feb 26 21:00:03 2015 +0100
+++ b/hotspot/src/share/vm/shark/sharkBuilder.cpp Fri Feb 27 19:52:48 2015 -0500
@@ -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 Fri Feb 27 19:52:48 2015 -0500
@@ -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