Path: blob/master/src/hotspot/share/gc/g1/g1BarrierSet.cpp
40957 views
/*1* Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "gc/g1/g1BarrierSet.inline.hpp"26#include "gc/g1/g1BarrierSetAssembler.hpp"27#include "gc/g1/g1CardTable.inline.hpp"28#include "gc/g1/g1CollectedHeap.inline.hpp"29#include "gc/g1/g1SATBMarkQueueSet.hpp"30#include "gc/g1/g1ThreadLocalData.hpp"31#include "gc/g1/heapRegion.hpp"32#include "gc/shared/satbMarkQueue.hpp"33#include "logging/log.hpp"34#include "oops/access.inline.hpp"35#include "oops/compressedOops.inline.hpp"36#include "oops/oop.inline.hpp"37#include "runtime/interfaceSupport.inline.hpp"38#include "runtime/orderAccess.hpp"39#include "runtime/thread.inline.hpp"40#include "utilities/macros.hpp"41#ifdef COMPILER142#include "gc/g1/c1/g1BarrierSetC1.hpp"43#endif44#ifdef COMPILER245#include "gc/g1/c2/g1BarrierSetC2.hpp"46#endif4748class G1BarrierSetC1;49class G1BarrierSetC2;5051G1BarrierSet::G1BarrierSet(G1CardTable* card_table) :52CardTableBarrierSet(make_barrier_set_assembler<G1BarrierSetAssembler>(),53make_barrier_set_c1<G1BarrierSetC1>(),54make_barrier_set_c2<G1BarrierSetC2>(),55card_table,56BarrierSet::FakeRtti(BarrierSet::G1BarrierSet)),57_satb_mark_queue_buffer_allocator("SATB Buffer Allocator", G1SATBBufferSize),58_dirty_card_queue_buffer_allocator("DC Buffer Allocator", G1UpdateBufferSize),59_satb_mark_queue_set(&_satb_mark_queue_buffer_allocator),60_dirty_card_queue_set(&_dirty_card_queue_buffer_allocator),61_shared_dirty_card_queue(&_dirty_card_queue_set)62{}6364void G1BarrierSet::enqueue(oop pre_val) {65// Nulls should have been already filtered.66assert(oopDesc::is_oop(pre_val, true), "Error");67SATBMarkQueue& queue = G1ThreadLocalData::satb_mark_queue(Thread::current());68G1BarrierSet::satb_mark_queue_set().enqueue(queue, pre_val);69}7071template <class T> void72G1BarrierSet::write_ref_array_pre_work(T* dst, size_t count) {73if (!_satb_mark_queue_set.is_active()) return;74T* elem_ptr = dst;75for (size_t i = 0; i < count; i++, elem_ptr++) {76T heap_oop = RawAccess<>::oop_load(elem_ptr);77if (!CompressedOops::is_null(heap_oop)) {78enqueue(CompressedOops::decode_not_null(heap_oop));79}80}81}8283void G1BarrierSet::write_ref_array_pre(oop* dst, size_t count, bool dest_uninitialized) {84if (!dest_uninitialized) {85write_ref_array_pre_work(dst, count);86}87}8889void G1BarrierSet::write_ref_array_pre(narrowOop* dst, size_t count, bool dest_uninitialized) {90if (!dest_uninitialized) {91write_ref_array_pre_work(dst, count);92}93}9495void G1BarrierSet::write_ref_field_post_slow(volatile CardValue* byte) {96// In the slow path, we know a card is not young97assert(*byte != G1CardTable::g1_young_card_val(), "slow path invoked without filtering");98OrderAccess::storeload();99if (*byte != G1CardTable::dirty_card_val()) {100*byte = G1CardTable::dirty_card_val();101Thread* thr = Thread::current();102G1DirtyCardQueue& queue = G1ThreadLocalData::dirty_card_queue(thr);103G1BarrierSet::dirty_card_queue_set().enqueue(queue, byte);104}105}106107void G1BarrierSet::invalidate(MemRegion mr) {108if (mr.is_empty()) {109return;110}111volatile CardValue* byte = _card_table->byte_for(mr.start());112CardValue* last_byte = _card_table->byte_for(mr.last());113// skip initial young cards114for (; byte <= last_byte && *byte == G1CardTable::g1_young_card_val(); byte++);115116if (byte <= last_byte) {117OrderAccess::storeload();118// Enqueue if necessary.119Thread* thr = Thread::current();120G1DirtyCardQueueSet& qset = G1BarrierSet::dirty_card_queue_set();121G1DirtyCardQueue& queue = G1ThreadLocalData::dirty_card_queue(thr);122for (; byte <= last_byte; byte++) {123CardValue bv = *byte;124if ((bv != G1CardTable::g1_young_card_val()) &&125(bv != G1CardTable::dirty_card_val())) {126*byte = G1CardTable::dirty_card_val();127qset.enqueue(queue, byte);128}129}130}131}132133void G1BarrierSet::on_thread_create(Thread* thread) {134// Create thread local data135G1ThreadLocalData::create(thread);136}137138void G1BarrierSet::on_thread_destroy(Thread* thread) {139// Destroy thread local data140G1ThreadLocalData::destroy(thread);141}142143void G1BarrierSet::on_thread_attach(Thread* thread) {144SATBMarkQueue& queue = G1ThreadLocalData::satb_mark_queue(thread);145assert(!queue.is_active(), "SATB queue should not be active");146assert(queue.buffer() == nullptr, "SATB queue should not have a buffer");147assert(queue.index() == 0, "SATB queue index should be zero");148// Can't assert that the DCQ is empty. There is early execution on149// the main thread, before it gets added to the threads list, which150// is where this is called. That execution may enqueue dirty cards.151152// If we are creating the thread during a marking cycle, we should153// set the active field of the SATB queue to true. That involves154// copying the global is_active value to this thread's queue.155queue.set_active(_satb_mark_queue_set.is_active());156}157158void G1BarrierSet::on_thread_detach(Thread* thread) {159// Flush any deferred card marks.160CardTableBarrierSet::on_thread_detach(thread);161{162SATBMarkQueue& queue = G1ThreadLocalData::satb_mark_queue(thread);163G1BarrierSet::satb_mark_queue_set().flush_queue(queue);164}165{166G1DirtyCardQueue& queue = G1ThreadLocalData::dirty_card_queue(thread);167G1DirtyCardQueueSet& qset = G1BarrierSet::dirty_card_queue_set();168qset.flush_queue(queue);169qset.record_detached_refinement_stats(queue.refinement_stats());170}171}172173174