/* * Copyright (c) 2018, Red Hat, Inc. and/or its affiliates. * * 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. * */ #include "gc/shenandoah/c1/shenandoahLRBBarrierSetC1.hpp" #ifdef ASSERT #define __ gen->lir(__FILE__, __LINE__)-> #else #define __ gen->lir()-> #endif void ShenandoahLRBBarrierSetC1::store_at_resolved(LIRAccess& access, LIR_Opr value) { if (access.is_oop()) { if (ShenandoahSATBBarrier) { pre_barrier(access.gen(), access.access_emit_info(), access.decorators(), access.resolved_addr(), LIR_OprFact::illegalOpr /* pre_val */); } enqueue_barrier(access.gen(), value, access.access_emit_info(), access.decorators()); } ShenandoahBaseBarrierSetC1::store_at_resolved(access, value); } void ShenandoahLRBBarrierSetC1::load_at_resolved(LIRAccess& access, LIR_Opr result) { if (access.is_oop()) { LIRGenerator* gen = access.gen(); LIR_Opr result_tmp = gen->new_register(T_OBJECT); ShenandoahBaseBarrierSetC1::load_at_resolved(access, result_tmp); result_tmp = write_barrier(access.gen(), result_tmp, access.access_emit_info(), true /*access.needs_null_check()*/); gen->lir()->move(result_tmp, result); } else { ShenandoahBaseBarrierSetC1::load_at_resolved(access, result); } if (ShenandoahKeepAliveBarrier) { DecoratorSet decorators = access.decorators(); bool is_weak = (decorators & ON_WEAK_OOP_REF) != 0; bool is_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0; bool is_anonymous = (decorators & ON_UNKNOWN_OOP_REF) != 0; LIRGenerator *gen = access.gen(); if (access.is_oop() && (is_weak || is_phantom || is_anonymous)) { // Register the value in the referent field with the pre-barrier LabelObj *Lcont_anonymous; if (is_anonymous) { Lcont_anonymous = new LabelObj(); generate_referent_check(access, Lcont_anonymous); } pre_barrier(access.gen(), access.access_emit_info(), access.decorators(), LIR_OprFact::illegalOpr /* addr_opr */, result /* pre_val */); if (is_anonymous) { __ branch_destination(Lcont_anonymous->label()); } } } } LIR_Opr ShenandoahLRBBarrierSetC1::atomic_cmpxchg_at_resolved(LIRAccess& access, LIRItem& cmp_value, LIRItem& new_value) { if (access.is_oop()) { if (ShenandoahSATBBarrier) { pre_barrier(access.gen(), access.access_emit_info(), access.decorators(), access.resolved_addr(), LIR_OprFact::illegalOpr /* pre_val */); } enqueue_barrier(access.gen(), new_value.result(), access.access_emit_info(), access.decorators()); } return ShenandoahBaseBarrierSetC1::atomic_cmpxchg_at_resolved(access, cmp_value, new_value); } LIR_Opr ShenandoahLRBBarrierSetC1::atomic_xchg_at_resolved(LIRAccess& access, LIRItem& value) { if (access.is_oop()) { if (ShenandoahSATBBarrier) { pre_barrier(access.gen(), access.access_emit_info(), access.decorators(), access.resolved_addr(), LIR_OprFact::illegalOpr /* pre_val */); } enqueue_barrier(access.gen(), value.result(), access.access_emit_info(), access.decorators()); } LIR_Opr result = ShenandoahBaseBarrierSetC1::atomic_xchg_at_resolved(access, value); if (access.is_oop()) { result = write_barrier(access.gen(), result, access.access_emit_info(), true); } return result; }