Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.cpp
38920 views
/*1* Copyright (c) 2013, 2018, Red Hat, Inc. All rights reserved.2*3* This code is free software; you can redistribute it and/or modify it4* under the terms of the GNU General Public License version 2 only, as5* published by the Free Software Foundation.6*7* This code is distributed in the hope that it will be useful, but WITHOUT8* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or9* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License10* version 2 for more details (a copy is included in the LICENSE file that11* accompanied this code).12*13* You should have received a copy of the GNU General Public License version14* 2 along with this work; if not, write to the Free Software Foundation,15* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.16*17* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA18* or visit www.oracle.com if you need additional information or have any19* questions.20*21*/2223#include "precompiled.hpp"24#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"25#include "gc_implementation/shenandoah/shenandoahAsserts.hpp"26#include "gc_implementation/shenandoah/shenandoahBarrierSet.hpp"27#include "gc_implementation/shenandoah/shenandoahBarrierSetClone.inline.hpp"28#include "gc_implementation/shenandoah/shenandoahCollectorPolicy.hpp"29#include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp"30#include "gc_implementation/shenandoah/heuristics/shenandoahHeuristics.hpp"31#include "runtime/interfaceSupport.hpp"32#include "utilities/macros.hpp"3334#ifdef COMPILER135#include "gc_implementation/shenandoah/c1/shenandoahBarrierSetC1.hpp"36#endif37#ifdef COMPILER238#include "gc_implementation/shenandoah/c2/shenandoahBarrierSetC2.hpp"39#endif4041#if defined(TARGET_ARCH_aarch64)42#include "shenandoahBarrierSetAssembler_aarch64.hpp"43#elif defined(TARGET_ARCH_x86)44#include "shenandoahBarrierSetAssembler_x86.hpp"45#else46#include "shenandoahBarrierSetAssembler_stub.hpp"47#endif4849ShenandoahBarrierSet::ShenandoahBarrierSet(ShenandoahHeap* heap) :50BarrierSet(),51_heap(heap),52_bsasm(new ShenandoahBarrierSetAssembler()),53_bsc1(COMPILER1_PRESENT(new ShenandoahBarrierSetC1()) NOT_COMPILER1(NULL)),54_bsc2(COMPILER2_PRESENT(new ShenandoahBarrierSetC2()) NOT_COMPILER2(NULL))55{56_kind = BarrierSet::ShenandoahBarrierSet;57}5859ShenandoahBarrierSetAssembler* ShenandoahBarrierSet::bsasm() const {60return _bsasm;61}6263ShenandoahBarrierSetC1* ShenandoahBarrierSet::bsc1() const {64return _bsc1;65}6667ShenandoahBarrierSetC2* ShenandoahBarrierSet::bsc2() const {68return _bsc2;69}7071void ShenandoahBarrierSet::print_on(outputStream* st) const {72st->print("ShenandoahBarrierSet");73}7475bool ShenandoahBarrierSet::is_a(BarrierSet::Name bsn) {76return bsn == BarrierSet::ShenandoahBarrierSet;77}7879bool ShenandoahBarrierSet::has_read_prim_array_opt() {80return true;81}8283bool ShenandoahBarrierSet::has_read_prim_barrier() {84return false;85}8687bool ShenandoahBarrierSet::has_read_ref_array_opt() {88return true;89}9091bool ShenandoahBarrierSet::has_read_ref_barrier() {92return false;93}9495bool ShenandoahBarrierSet::has_read_region_opt() {96return true;97}9899bool ShenandoahBarrierSet::has_write_prim_array_opt() {100return true;101}102103bool ShenandoahBarrierSet::has_write_prim_barrier() {104return false;105}106107bool ShenandoahBarrierSet::has_write_ref_array_opt() {108return true;109}110111bool ShenandoahBarrierSet::has_write_ref_barrier() {112return true;113}114115bool ShenandoahBarrierSet::has_write_ref_pre_barrier() {116return true;117}118119bool ShenandoahBarrierSet::has_write_region_opt() {120return true;121}122123bool ShenandoahBarrierSet::is_aligned(HeapWord* hw) {124return true;125}126127bool ShenandoahBarrierSet::read_prim_needs_barrier(HeapWord* hw, size_t s) {128return false;129}130131void ShenandoahBarrierSet::read_ref_field(void* v) {132// tty->print_cr("read_ref_field: v = "PTR_FORMAT, v);133// return *v;134}135136template <class T>137inline void ShenandoahBarrierSet::inline_write_ref_field_pre(T* field, oop newVal) {138newVal = load_reference_barrier(newVal);139storeval_barrier(newVal);140if (ShenandoahSATBBarrier && _heap->is_concurrent_mark_in_progress()) {141T heap_oop = oopDesc::load_heap_oop(field);142shenandoah_assert_not_in_cset_loc_except(field, ShenandoahHeap::heap()->cancelled_gc());143if (!oopDesc::is_null(heap_oop)) {144ShenandoahBarrierSet::barrier_set()->enqueue(oopDesc::decode_heap_oop(heap_oop));145}146}147}148149// These are the more general virtual versions.150void ShenandoahBarrierSet::write_ref_field_pre_work(oop* field, oop new_val) {151inline_write_ref_field_pre(field, new_val);152}153154void ShenandoahBarrierSet::write_ref_field_pre_work(narrowOop* field, oop new_val) {155inline_write_ref_field_pre(field, new_val);156}157158void ShenandoahBarrierSet::write_ref_field_work(void* v, oop o, bool release) {159shenandoah_assert_not_in_cset_loc_except(v, _heap->cancelled_gc());160shenandoah_assert_not_forwarded_except (v, o, o == NULL || _heap->cancelled_gc() || !_heap->is_concurrent_mark_in_progress());161shenandoah_assert_not_in_cset_except (v, o, o == NULL || _heap->cancelled_gc() || !_heap->is_concurrent_mark_in_progress());162}163164oop ShenandoahBarrierSet::load_reference_barrier_not_null(oop obj) {165assert(obj != NULL, "");166if (ShenandoahLoadRefBarrier && _heap->has_forwarded_objects()) {167return load_reference_barrier_impl(obj);168} else {169return obj;170}171}172173oop ShenandoahBarrierSet::load_reference_barrier(oop obj) {174if (obj != NULL) {175return load_reference_barrier_not_null(obj);176} else {177return obj;178}179}180181182oop ShenandoahBarrierSet::load_reference_barrier_impl(oop obj) {183assert(ShenandoahLoadRefBarrier, "should be enabled");184if (!oopDesc::is_null(obj)) {185oop fwd = resolve_forwarded_not_null(obj);186if (_heap->is_evacuation_in_progress() &&187_heap->in_collection_set(obj) &&188obj == fwd) {189Thread *t = Thread::current();190ShenandoahEvacOOMScope oom_evac_scope;191return _heap->evacuate_object(obj, t);192} else {193return fwd;194}195} else {196return obj;197}198}199200void ShenandoahBarrierSet::storeval_barrier(oop obj) {201if (ShenandoahStoreValEnqueueBarrier && !oopDesc::is_null(obj) && _heap->is_concurrent_mark_in_progress()) {202enqueue(obj);203}204}205206void ShenandoahBarrierSet::keep_alive_barrier(oop obj) {207if (_heap->is_concurrent_mark_in_progress()) {208enqueue(obj);209}210}211212void ShenandoahBarrierSet::enqueue(oop obj) {213assert(JavaThread::satb_mark_queue_set().shared_satb_queue()->is_active(), "only get here when SATB active");214215// Filter marked objects before hitting the SATB queues. The same predicate would216// be used by SATBMQ::filter to eliminate already marked objects downstream, but217// filtering here helps to avoid wasteful SATB queueing work to begin with.218if (!_heap->requires_marking(obj)) return;219220Thread* thr = Thread::current();221if (thr->is_Java_thread()) {222JavaThread* jt = (JavaThread*)thr;223jt->satb_mark_queue().enqueue_known_active(obj);224} else {225MutexLockerEx x(Shared_SATB_Q_lock, Mutex::_no_safepoint_check_flag);226JavaThread::satb_mark_queue_set().shared_satb_queue()->enqueue_known_active(obj);227}228}229230oop ShenandoahBarrierSet::atomic_compare_exchange_oop(oop exchange_value,231volatile HeapWord *dest,232oop compare_value) {233if (UseCompressedOops) {234// encode exchange and compare value from oop to T235narrowOop val = oopDesc::encode_heap_oop(exchange_value);236narrowOop cmp = oopDesc::encode_heap_oop(compare_value);237238narrowOop old = (narrowOop) Atomic::cmpxchg(val, (narrowOop*)dest, cmp);239// decode old from T to oop240return oopDesc::decode_heap_oop(old);241} else {242return (oop)Atomic::cmpxchg_ptr(exchange_value, (oop*)dest, compare_value);243}244}245246oop ShenandoahBarrierSet::oop_atomic_cmpxchg_in_heap(oop new_value, volatile HeapWord* dest, oop compare_value) {247oop expected;248bool success;249do {250expected = compare_value;251compare_value = atomic_compare_exchange_oop(new_value, dest, expected);252success = (compare_value == expected);253} while ((! success) && resolve_forwarded(compare_value) == resolve_forwarded(expected));254oop result = load_reference_barrier(compare_value);255if (ShenandoahSATBBarrier && success && result != NULL &&256ShenandoahHeap::heap()->is_concurrent_mark_in_progress()) {257enqueue(result);258}259if (new_value != NULL) {260storeval_barrier(new_value);261}262return result;263}264265void ShenandoahBarrierSet::clone_barrier_runtime(oop src) {266if (_heap->has_forwarded_objects() || (ShenandoahStoreValEnqueueBarrier && _heap->is_concurrent_mark_in_progress())) {267clone_barrier(src);268}269}270271272