# HG changeset patch # User kbarrett # Date 1424118816 18000 # Mon Feb 16 15:33:36 2015 -0500 # Node ID 752f1657cf268e205c7e698fb8dc4f2e631779d8 # Parent d8ded1e4465b2c3f026097a36c62d1c5bb125fcb [mq]: bcast diff --git a/src/cpu/ppc/vm/macroAssembler_ppc.cpp b/src/cpu/ppc/vm/macroAssembler_ppc.cpp --- a/src/cpu/ppc/vm/macroAssembler_ppc.cpp +++ b/src/cpu/ppc/vm/macroAssembler_ppc.cpp @@ -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(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(Universe::heap()->barrier_set()); // Does store cross heap regions? if (G1RSBarrierRegionFilter) { diff --git a/src/cpu/ppc/vm/stubGenerator_ppc.cpp b/src/cpu/ppc/vm/stubGenerator_ppc.cpp --- a/src/cpu/ppc/vm/stubGenerator_ppc.cpp +++ b/src/cpu/ppc/vm/stubGenerator_ppc.cpp @@ -694,7 +694,7 @@ __ release(); } - CardTableModRefBS* const ct = (CardTableModRefBS*)bs; + CardTableModRefBS* const ct = barrier_set_cast(bs); assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code"); assert_different_registers(addr, count, tmp); diff --git a/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp b/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp --- a/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp +++ b/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp @@ -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(bs)->byte_map_base; Label not_already_dirty, restart, refill, young_card; diff --git a/src/cpu/sparc/vm/macroAssembler_sparc.cpp b/src/cpu/sparc/vm/macroAssembler_sparc.cpp --- a/src/cpu/sparc/vm/macroAssembler_sparc.cpp +++ b/src/cpu/sparc/vm/macroAssembler_sparc.cpp @@ -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 @@ -3868,9 +3868,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(Universe::heap()->barrier_set()); if (G1RSBarrierRegionFilter) { xor3(store_addr, new_val, tmp); @@ -3914,7 +3913,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(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); diff --git a/src/cpu/sparc/vm/stubGenerator_sparc.cpp b/src/cpu/sparc/vm/stubGenerator_sparc.cpp --- a/src/cpu/sparc/vm/stubGenerator_sparc.cpp +++ b/src/cpu/sparc/vm/stubGenerator_sparc.cpp @@ -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(bs); assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code"); assert_different_registers(addr, count, tmp); diff --git a/src/cpu/x86/vm/c1_Runtime1_x86.cpp b/src/cpu/x86/vm/c1_Runtime1_x86.cpp --- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp +++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp @@ -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(Universe::heap()->barrier_set()); assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code"); Label done; diff --git a/src/cpu/x86/vm/macroAssembler_x86.cpp b/src/cpu/x86/vm/macroAssembler_x86.cpp --- a/src/cpu/x86/vm/macroAssembler_x86.cpp +++ b/src/cpu/x86/vm/macroAssembler_x86.cpp @@ -4235,8 +4235,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(Universe::heap()->barrier_set()); assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code"); Label done; @@ -4336,7 +4336,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(bs); assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code"); // The calculation for byte_map_base is as follows: diff --git a/src/cpu/x86/vm/stubGenerator_x86_32.cpp b/src/cpu/x86/vm/stubGenerator_x86_32.cpp --- a/src/cpu/x86/vm/stubGenerator_x86_32.cpp +++ b/src/cpu/x86/vm/stubGenerator_x86_32.cpp @@ -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(bs); assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code"); Label L_loop; diff --git a/src/cpu/x86/vm/stubGenerator_x86_64.cpp b/src/cpu/x86/vm/stubGenerator_x86_64.cpp --- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp +++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp @@ -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(bs); assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code"); Label L_loop; diff --git a/src/share/vm/c1/c1_LIRGenerator.cpp b/src/share/vm/c1/c1_LIRGenerator.cpp --- a/src/share/vm/c1/c1_LIRGenerator.cpp +++ b/src/share/vm/c1/c1_LIRGenerator.cpp @@ -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(_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); diff --git a/src/share/vm/compiler/disassembler.cpp b/src/share/vm/compiler/disassembler.cpp --- a/src/share/vm/compiler/disassembler.cpp +++ b/src/share/vm/compiler/disassembler.cpp @@ -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(bs)->byte_map_base)) { st->print("word_map_base"); if (WizardMode) st->print(" " INTPTR_FORMAT, (intptr_t)adr); return; diff --git a/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/src/share/vm/gc_implementation/g1/concurrentMark.cpp --- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp +++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp @@ -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(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(g1h->barrier_set())), _cm_card_bm(cm_card_bm), _max_worker_id(max_worker_id) { } bool doHeapRegion(HeapRegion* hr) { diff --git a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp @@ -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(barrier_set()); } // This resets the card table to all zeros. It is used after diff --git a/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp b/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp --- a/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp +++ b/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp @@ -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(Universe::heap()->barrier_set()); g1_bs->write_ref_field_work(field, new_val); } diff --git a/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp b/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp --- a/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp +++ b/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp @@ -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 { + 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 { + static const BarrierSet::Name value = BarrierSet::G1SATBCTLogging; +}; + #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1SATBCARDTABLEMODREFBS_HPP diff --git a/src/share/vm/gc_implementation/g1/heapRegion.cpp b/src/share/vm/gc_implementation/g1/heapRegion.cpp --- a/src/share/vm/gc_implementation/g1/heapRegion.cpp +++ b/src/share/vm/gc_implementation/g1/heapRegion.cpp @@ -193,7 +193,7 @@ HeapRegionRemSet* hrrs = rem_set(); hrrs->clear(); CardTableModRefBS* ct_bs = - (CardTableModRefBS*)G1CollectedHeap::heap()->barrier_set(); + barrier_set_cast(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(g1h->barrier_set())), + _containing_obj(NULL), _failures(false), _n_failures(0), _vo(vo) + { } void set_containing_obj(oop obj) { _containing_obj = obj; diff --git a/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp b/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp --- a/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp +++ b/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp @@ -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 @@ -79,7 +79,7 @@ assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); _young_gen = heap->young_gen(); - _card_table = (CardTableExtension*)heap->barrier_set(); + _card_table = barrier_set_cast(heap->barrier_set()); // No point in asserting barrier set type here. Need to make CardTableExtension // a unique barrier set type. } @@ -339,7 +339,9 @@ PSOldGen* old_gen = heap->old_gen(); - CheckForPreciseMarks check(heap->young_gen(), (CardTableExtension*)heap->barrier_set()); + CheckForPreciseMarks check( + heap->young_gen(), + barrier_set_cast(heap->barrier_set())); old_gen->oop_iterate_no_header(&check); @@ -347,8 +349,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(Universe::heap()->barrier_set()); jbyte* bot = card_table->byte_for(mr.start()); jbyte* top = card_table->byte_for(mr.end()); diff --git a/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.hpp b/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.hpp --- a/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.hpp +++ b/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.hpp @@ -54,10 +54,12 @@ }; 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. + BarrierSet::FakeRtti(BarrierSet::CardTableModRef, 0).add_tag(BarrierSet::CardTableExtension)) + { } // Scavenge support void scavenge_contents_parallel(ObjectStartArray* start_array, @@ -110,4 +112,9 @@ #endif // ASSERT }; +template<> +struct BarrierSet::GetName { + static const BarrierSet::Name value = BarrierSet::CardTableExtension; +}; + #endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_CARDTABLEEXTENSION_HPP diff --git a/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp b/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp --- a/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp +++ b/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp @@ -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(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 diff --git a/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp b/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp --- a/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp +++ b/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp @@ -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(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, diff --git a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp --- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp +++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp @@ -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(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 diff --git a/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp b/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp --- a/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp +++ b/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp @@ -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(heap->barrier_set()); _counters = new CollectorCounters("PSScavenge", 0); } diff --git a/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp b/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp --- a/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp +++ b/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp @@ -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(Universe::heap()->barrier_set()); card_table->scavenge_contents_parallel(_gen->start_array(), _gen->object_space(), diff --git a/src/share/vm/memory/barrierSet.hpp b/src/share/vm/memory/barrierSet.hpp --- a/src/share/vm/memory/barrierSet.hpp +++ b/src/share/vm/memory/barrierSet.hpp @@ -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 { 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 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 FakeRtti; + +private: + FakeRtti _fake_rtti; + + // Metafunction mapping a class derived from BarrierSet to the + // corresponding Name enum tag. + template 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. + template + friend T* barrier_set_cast(BarrierSet* bs) { + assert(bs->is_a(BarrierSet::GetName::value), "wrong type of barrier set"); + return static_cast(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; diff --git a/src/share/vm/memory/barrierSet.inline.hpp b/src/share/vm/memory/barrierSet.inline.hpp --- a/src/share/vm/memory/barrierSet.inline.hpp +++ b/src/share/vm/memory/barrierSet.inline.hpp @@ -34,7 +34,7 @@ template 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(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(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(this)->inline_write_region(mr); } else { write_region_work(mr); } diff --git a/src/share/vm/memory/cardTableModRefBS.cpp b/src/share/vm/memory/cardTableModRefBS.cpp --- a/src/share/vm/memory/cardTableModRefBS.cpp +++ b/src/share/vm/memory/cardTableModRefBS.cpp @@ -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(), diff --git a/src/share/vm/memory/cardTableModRefBS.hpp b/src/share/vm/memory/cardTableModRefBS.hpp --- a/src/share/vm/memory/cardTableModRefBS.hpp +++ b/src/share/vm/memory/cardTableModRefBS.hpp @@ -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 { + static const BarrierSet::Name value = BarrierSet::CardTableModRef; +}; + class CardTableRS; // A specialization for the CardTableRS gen rem set. @@ -472,10 +472,20 @@ 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. + BarrierSet::FakeRtti(BarrierSet::CardTableModRef, 0).add_tag(BarrierSet::CardTableForRS)) + {} void set_CTRS(CardTableRS* rs) { _rs = rs; } }; +template<> +struct BarrierSet::GetName { + static const BarrierSet::Name value = BarrierSet::CardTableForRS; +}; + #endif // SHARE_VM_MEMORY_CARDTABLEMODREFBS_HPP diff --git a/src/share/vm/memory/modRefBarrierSet.hpp b/src/share/vm/memory/modRefBarrierSet.hpp --- a/src/share/vm/memory/modRefBarrierSet.hpp +++ b/src/share/vm/memory/modRefBarrierSet.hpp @@ -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 { + static const BarrierSet::Name value = BarrierSet::ModRef; +}; + #endif // SHARE_VM_MEMORY_MODREFBARRIERSET_HPP diff --git a/src/share/vm/opto/graphKit.cpp b/src/share/vm/opto/graphKit.cpp --- a/src/share/vm/opto/graphKit.cpp +++ b/src/share/vm/opto/graphKit.cpp @@ -3749,7 +3749,8 @@ Node* GraphKit::byte_map_base_node() { // Get base of card map - CardTableModRefBS* ct = (CardTableModRefBS*)(Universe::heap()->barrier_set()); + CardTableModRefBS* ct = + barrier_set_cast(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)); diff --git a/src/share/vm/runtime/vmStructs.cpp b/src/share/vm/runtime/vmStructs.cpp --- a/src/share/vm/runtime/vmStructs.cpp +++ b/src/share/vm/runtime/vmStructs.cpp @@ -482,7 +482,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*) \ \ diff --git a/src/share/vm/shark/sharkBuilder.cpp b/src/share/vm/shark/sharkBuilder.cpp --- a/src/share/vm/shark/sharkBuilder.cpp +++ b/src/share/vm/shark/sharkBuilder.cpp @@ -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(bs)->byte_map_base)), CreateLShr( CreatePtrToInt(field, SharkType::intptr_type()), LLVMValue::intptr_constant(CardTableModRefBS::card_shift))), diff --git a/src/share/vm/utilities/fakeRttiSupport.hpp b/src/share/vm/utilities/fakeRttiSupport.hpp new file mode 100644 --- /dev/null +++ b/src/share/vm/utilities/fakeRttiSupport.hpp @@ -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 +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)), _ctag(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), _ctag(validate_tag(concrete_tag)) { } + + // Get the concrete tag. + TagType concrete_tag() const { return _ctag; } + + // 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(_ctag, _tag_set | tbit); + } + +private: + uintx _tag_set; + TagType _ctag; + + 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(tag); + } +}; + +#endif // include guard