Path: blob/master/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp
40957 views
/*1* Copyright (c) 2013, 2021, Red Hat, Inc. 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/shenandoah/shenandoahBarrierSet.hpp"26#include "gc/shenandoah/shenandoahBarrierSetClone.inline.hpp"27#include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"28#include "gc/shenandoah/shenandoahBarrierSetNMethod.hpp"29#include "gc/shenandoah/shenandoahClosures.inline.hpp"30#include "gc/shenandoah/shenandoahHeap.inline.hpp"31#include "gc/shenandoah/shenandoahStackWatermark.hpp"32#ifdef COMPILER133#include "gc/shenandoah/c1/shenandoahBarrierSetC1.hpp"34#endif35#ifdef COMPILER236#include "gc/shenandoah/c2/shenandoahBarrierSetC2.hpp"37#endif3839class ShenandoahBarrierSetC1;40class ShenandoahBarrierSetC2;4142ShenandoahBarrierSet::ShenandoahBarrierSet(ShenandoahHeap* heap) :43BarrierSet(make_barrier_set_assembler<ShenandoahBarrierSetAssembler>(),44make_barrier_set_c1<ShenandoahBarrierSetC1>(),45make_barrier_set_c2<ShenandoahBarrierSetC2>(),46ShenandoahNMethodBarrier ? new ShenandoahBarrierSetNMethod(heap) : NULL,47BarrierSet::FakeRtti(BarrierSet::ShenandoahBarrierSet)),48_heap(heap),49_satb_mark_queue_buffer_allocator("SATB Buffer Allocator", ShenandoahSATBBufferSize),50_satb_mark_queue_set(&_satb_mark_queue_buffer_allocator)51{52}5354ShenandoahBarrierSetAssembler* ShenandoahBarrierSet::assembler() {55BarrierSetAssembler* const bsa = BarrierSet::barrier_set()->barrier_set_assembler();56return reinterpret_cast<ShenandoahBarrierSetAssembler*>(bsa);57}5859void ShenandoahBarrierSet::print_on(outputStream* st) const {60st->print("ShenandoahBarrierSet");61}6263bool ShenandoahBarrierSet::need_load_reference_barrier(DecoratorSet decorators, BasicType type) {64if (!ShenandoahLoadRefBarrier) return false;65// Only needed for references66return is_reference_type(type);67}6869bool ShenandoahBarrierSet::need_keep_alive_barrier(DecoratorSet decorators, BasicType type) {70if (!ShenandoahSATBBarrier) return false;71// Only needed for references72if (!is_reference_type(type)) return false;7374bool keep_alive = (decorators & AS_NO_KEEPALIVE) == 0;75bool unknown = (decorators & ON_UNKNOWN_OOP_REF) != 0;76bool on_weak_ref = (decorators & (ON_WEAK_OOP_REF | ON_PHANTOM_OOP_REF)) != 0;77return (on_weak_ref || unknown) && keep_alive;78}7980void ShenandoahBarrierSet::on_thread_create(Thread* thread) {81// Create thread local data82ShenandoahThreadLocalData::create(thread);83}8485void ShenandoahBarrierSet::on_thread_destroy(Thread* thread) {86// Destroy thread local data87ShenandoahThreadLocalData::destroy(thread);88}8990void ShenandoahBarrierSet::on_thread_attach(Thread *thread) {91assert(!thread->is_Java_thread() || !SafepointSynchronize::is_at_safepoint(),92"We should not be at a safepoint");93SATBMarkQueue& queue = ShenandoahThreadLocalData::satb_mark_queue(thread);94assert(!queue.is_active(), "SATB queue should not be active");95assert(queue.buffer() == nullptr, "SATB queue should not have a buffer");96assert(queue.index() == 0, "SATB queue index should be zero");97queue.set_active(_satb_mark_queue_set.is_active());98if (thread->is_Java_thread()) {99ShenandoahThreadLocalData::set_gc_state(thread, _heap->gc_state());100ShenandoahThreadLocalData::initialize_gclab(thread);101ShenandoahThreadLocalData::set_disarmed_value(thread, ShenandoahCodeRoots::disarmed_value());102103if (ShenandoahStackWatermarkBarrier) {104JavaThread* const jt = thread->as_Java_thread();105StackWatermark* const watermark = new ShenandoahStackWatermark(jt);106StackWatermarkSet::add_watermark(jt, watermark);107}108}109}110111void ShenandoahBarrierSet::on_thread_detach(Thread *thread) {112SATBMarkQueue& queue = ShenandoahThreadLocalData::satb_mark_queue(thread);113_satb_mark_queue_set.flush_queue(queue);114if (thread->is_Java_thread()) {115PLAB* gclab = ShenandoahThreadLocalData::gclab(thread);116if (gclab != NULL) {117gclab->retire();118}119120// SATB protocol requires to keep alive reacheable oops from roots at the beginning of GC121if (ShenandoahStackWatermarkBarrier) {122if (_heap->is_concurrent_mark_in_progress()) {123ShenandoahKeepAliveClosure oops;124StackWatermarkSet::finish_processing(thread->as_Java_thread(), &oops, StackWatermarkKind::gc);125} else if (_heap->is_concurrent_weak_root_in_progress() && _heap->is_evacuation_in_progress()) {126ShenandoahContextEvacuateUpdateRootsClosure oops;127StackWatermarkSet::finish_processing(thread->as_Java_thread(), &oops, StackWatermarkKind::gc);128}129}130}131}132133void ShenandoahBarrierSet::clone_barrier_runtime(oop src) {134if (_heap->has_forwarded_objects() || (ShenandoahIUBarrier && _heap->is_concurrent_mark_in_progress())) {135clone_barrier(src);136}137}138139140