/* * Copyright (c) 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_INLINE_HPP #define SHARE_VM_GC_G1_G1BARRIERSET_INLINE_HPP #include "gc/shared/modRefBarrierSet.inline.hpp" #include "gc/g1/g1CardTable.inline.hpp" #include "gc/g1/g1BarrierSet.hpp" #include "runtime/orderAccess.inline.hpp" template inline void G1BarrierSet::write_ref_field_pre(void* field) { if (DecoratorTest::HAS_DEST_NOT_INITIALIZED) { return; } typedef typename EncodedOopType::type Encoded; Encoded *addr = (Encoded*)field; Encoded heap_oop = oopDesc::load_heap_oop(addr); if (!oopDesc::is_null(heap_oop)) { satb_enqueue(oopDesc::decode_heap_oop_not_null(heap_oop)); } } // This barrier is used by G1 to remember the old oop values, so // that we don't forget any objects that were live at the snapshot at // the beginning. This function is only used when we write oops into Klasses. inline void G1BarrierSet::klass_update_barrier_set_pre(Klass* klass, oop* p) { oop obj = *p; if (!oopDesc::is_null(obj)) { satb_enqueue(obj); } } template inline void G1BarrierSet::write_ref_field_post(void* field, oop new_val) { volatile jbyte* byte = _card_table->byte_for(field); if (*byte == G1CardTable::g1_young_card_val()) { return; } OrderAccess::storeload(); if (*byte != G1CardTable::dirty_card_val()) { *byte = G1CardTable::dirty_card_val(); card_enqueue(byte); } } template inline oop G1BarrierSet::AccessBarrier::oop_load(void* addr) { oop value = ModRef::oop_load(addr); if (DecoratorTest::IS_ON_REFERENCE && !DecoratorTest::HAS_ACCESS_WEAK && !oopDesc::is_null(value)) { satb_enqueue(value); } return value; } template inline oop G1BarrierSet::AccessBarrier::oop_load_at(oop base, ptrdiff_t offset) { oop load_val = ModRef::oop_load_at(base, offset); if (!DecoratorTest::HAS_ACCESS_WEAK && (DecoratorTest::IS_ON_REFERENCE || (DecoratorTest::HAS_ACCESS_ON_ANONYMOUS && load_val != NULL && !oopDesc::is_null(base) && is_referent_field(base, offset)))) { satb_enqueue(load_val); } return load_val; } template inline void G1BarrierSet::AccessBarrier::oop_store_at(nmethod* base, ptrdiff_t offset, oop new_value) { G1BarrierSet *bs = barrier_set_cast(oopDesc::bs()); bs->write_ref_nmethod_pre(base, offset); Basic::oop_store_at(base, offset, new_value); bs->write_ref_nmethod_post(base, new_value); } #endif // SHARE_VM_GC_G1_G1BARRIERSET_INLINE_HPP