8069016: Add BarrierSet downcast support

Add FakeRttiSupport utility and use to provide barrier_set_cast.

Reviewed-by: jmasa, sangheki
This commit is contained in:
Kim Barrett 2015-02-27 19:52:48 -05:00
parent 1426bc9dc1
commit 40d3986051
32 changed files with 289 additions and 131 deletions

View file

@ -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 @@ void MacroAssembler::serialize_memory(Register thread, Register tmp1, Register t
// 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 @@ void MacroAssembler::g1_write_barrier_post(Register Rstore_addr, Register Rnew_v
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) {

View file

@ -694,7 +694,7 @@ class StubGenerator: public StubCodeGenerator {
__ 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);

View file

@ -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 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
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;

View file

@ -3858,9 +3858,8 @@ void MacroAssembler::g1_write_barrier_post(Register store_addr, Register new_val
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::g1_write_barrier_post(Register store_addr, Register new_val
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);

View file

@ -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 @@ class StubGenerator: public StubCodeGenerator {
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);

View file

@ -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 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
// 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;

View file

@ -4204,8 +4204,8 @@ void MacroAssembler::g1_write_barrier_post(Register store_addr,
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_1(Register obj) {
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:

View file

@ -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 @@ class StubGenerator: public StubCodeGenerator {
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;

View file

@ -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 @@ class StubGenerator: public StubCodeGenerator {
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;

View file

@ -1582,9 +1582,9 @@ void LIRGenerator::G1SATBCardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_Opr
////////////////////////////////////////////////////////////////////////
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 @@ void LIRGenerator::CardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_OprDesc*
__ 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);

View file

@ -340,8 +340,8 @@ void decode_env::print_address(address adr) {
}
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;

View file

@ -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 @@ public:
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 @@ class AggregateCountDataHRClosure: public HeapRegionClosure {
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) {

View file

@ -1274,7 +1274,7 @@ public:
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

View file

@ -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 @@ void G1SATBCardTableLoggingModRefBSChangedListener::on_commit(uint start_idx, si
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 @@ G1SATBCardTableLoggingModRefBS::write_ref_field_static(void* field,
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);
}

View file

@ -43,7 +43,7 @@ protected:
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 @@ public:
// 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 @@ public:
}
};
template<>
struct BarrierSet::GetName<G1SATBCardTableModRefBS> {
static const BarrierSet::Name value = BarrierSet::G1SATBCT;
};
class G1SATBCardTableLoggingModRefBSChangedListener : public G1MappingChangedListener {
private:
G1SATBCardTableLoggingModRefBS* _card_table;
@ -159,11 +160,6 @@ class G1SATBCardTableLoggingModRefBS: public G1SATBCardTableModRefBS {
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 @@ class G1SATBCardTableLoggingModRefBS: public G1SATBCardTableModRefBS {
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

View file

@ -193,7 +193,7 @@ void HeapRegion::par_clear() {
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 @@ public:
// _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;

View file

@ -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 @@ class CheckForUnmarkedObjects : public ObjectClosure {
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 @@ void CardTableExtension::verify_all_young_refs_precise() {
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() {
}
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());

View file

@ -54,10 +54,16 @@ class CardTableExtension : public CardTableModRefBS {
};
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 @@ class CardTableExtension : public CardTableModRefBS {
#endif // ASSERT
};
template<>
struct BarrierSet::GetName<CardTableExtension> {
static const BarrierSet::Name value = BarrierSet::CardTableExtension;
};
#endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_CARDTABLEEXTENSION_HPP

View file

@ -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,16 +232,13 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
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;
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
ClassLoaderDataGraph::purge();

View file

@ -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 @@ void PSOldGen::initialize_work(const char* perf_data_name, int level) {
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,

View file

@ -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,17 +1050,13 @@ void PSParallelCompact::post_compact()
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;
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
ClassLoaderDataGraph::purge();

View file

@ -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 @@ void PSScavenge::initialize() {
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);
}

View file

@ -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 @@ void OldToYoungRootsTask::do_it(GCTaskManager* manager, uint which) {
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(),

View file

@ -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 @@ protected:
// "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;

View file

@ -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 @@ template <class T> void BarrierSet::write_ref_field_pre(T* field, oop new_val) {
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 @@ void BarrierSet::write_ref_array(HeapWord* start, size_t count) {
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);
}

View file

@ -53,8 +53,10 @@ size_t CardTableModRefBS::compute_byte_map_size()
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(),

View file

@ -279,11 +279,6 @@ public:
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 @@ public:
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 @@ public:
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 @@ protected:
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

View file

@ -37,10 +37,6 @@ class Generation;
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 @@ public:
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 @@ public:
virtual void clear(MemRegion mr) = 0;
};
template<>
struct BarrierSet::GetName<ModRefBarrierSet> {
static const BarrierSet::Name value = BarrierSet::ModRef;
};
#endif // SHARE_VM_MEMORY_MODREFBARRIERSET_HPP

View file

@ -3759,7 +3759,8 @@ void GraphKit::final_sync(IdealKit& ideal) {
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));

View file

@ -481,7 +481,6 @@ typedef CompactHashtable<Symbol*, char> SymbolCompactHashTable;
\
unchecked_nonstatic_field(ageTable, sizes, sizeof(ageTable::sizes)) \
\
nonstatic_field(BarrierSet, _kind, BarrierSet::Name) \
nonstatic_field(BlockOffsetTable, _bottom, HeapWord*) \
nonstatic_field(BlockOffsetTable, _end, HeapWord*) \
\

View file

@ -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 @@ void SharkBuilder::CreateUpdateBarrierSet(BarrierSet* bs, Value* field) {
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))),

View file

@ -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