/* * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. * */ #ifndef SHARE_VM_GC_G1_G1BARRIERSET_HPP #define SHARE_VM_GC_G1_G1BARRIERSET_HPP #include "gc/shared/cardTableModRefBS.hpp" class CardTable; class DirtyCardQueueSet; class G1CardTable; class SATBMarkQueueSet; // This barrier is specialized to use a logging barrier to support // snapshot-at-the-beginning marking. class G1BarrierSet: public CardTableModRefBS { friend class VMStructs; private: void write_ref_nmethod_pre(nmethod* nm, ptrdiff_t offset); void write_ref_nmethod_post(nmethod* nm, oop new_value); static bool is_referent_field(oop base, ptrdiff_t offset); public: G1BarrierSet(CardTable* table); ~G1BarrierSet() { } static SATBMarkQueueSet& satb_mark_queue_set(); static DirtyCardQueueSet& dirty_card_queue_set(); // Add "pre_val" to a set of objects that may have been disconnected from the // pre-marking object graph. static void satb_enqueue(oop pre_val); static void card_enqueue(volatile jbyte* card); template void write_ref_field_pre(void* field); template void write_ref_field_post(void* field, oop new_val); void klass_update_barrier_set_pre(Klass* klass, oop* p); template void write_ref_array_pre_work(T* dst, int count); virtual void write_ref_array_pre(oop* dst, int count, bool dest_uninitialized); virtual void write_ref_array_pre(narrowOop* dst, int count, bool dest_uninitialized); // NB: if you do a whole-heap invalidation, the "usual invariant" defined // above no longer applies. void invalidate(MemRegion mr); virtual void write_region(MemRegion mr) { invalidate(mr); } virtual void write_ref_array_region(MemRegion mr) { invalidate(mr); } // This method initializes the SATB and dirty card queues before a // JavaThread is added to the Java thread list. Right now, we don't // have to do anything to the dirty card queue (it should have been // activated when the thread was created), but we have to activate // the SATB queue if the thread is created while a marking cycle is // in progress. The activation / de-activation of the SATB queues at // the beginning / end of a marking cycle is done during safepoints // so we have to make sure this method is called outside one to be // able to safely read the active field of the SATB queue set. Right // now, it is called just before the thread is added to the Java // thread list in the Threads::add() method. That method is holding // the Threads_lock which ensures we are outside a safepoint. We // cannot do the obvious and set the active field of the SATB queue // when the thread is created given that, in some cases, safepoints // might happen between the JavaThread constructor being called and the // thread being added to the Java thread list (an example of this is // when the structure for the DestroyJavaVM thread is created). virtual void on_add_thread(JavaThread* thread); virtual void on_destroy_thread(JavaThread* thread); virtual BarrierSetCodeGen *make_code_gen(); virtual C1BarrierSetCodeGen* make_c1_code_gen(); virtual C2BarrierSetCodeGen* make_c2_code_gen(); // Runtime calls for generated code static void g1_wb_pre(oopDesc* orig, JavaThread *thread); static void g1_wb_post(void* card_addr, JavaThread* thread); // Callbacks for runtime accesses. template class AccessBarrier: public ModRefBarrierSet::AccessBarrier { typedef ModRefBarrierSet::AccessBarrier ModRef; typedef BarrierSet::AccessBarrier Basic; public: typedef ModRef SuperAccessBarrier; // Needed for loads on weak references static oop oop_load(void* addr); // Needed for anonymous weak references static oop oop_load_at(oop base, ptrdiff_t offset); // Needed for stores in nmethods static void oop_store_at(nmethod* base, ptrdiff_t offset, oop new_value); }; }; template<> struct BSTypeToName { static const BarrierSet::Name value = BarrierSet::G1BarrierSet; }; template<> struct BSNameToType { typedef G1BarrierSet type; }; #endif // SHARE_VM_GC_G1_G1BARRIERSET_HPP