< prev index next >

src/hotspot/cpu/ppc/gc/shenandoah/shenandoahBarrierSetAssembler_ppc.cpp

Print this page

   1 /*
   2  * Copyright (c) 2018, 2021, Red Hat, Inc. All rights reserved.
   3  * Copyright (c) 2012, 2021 SAP SE. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *
  24  */
  25 
  26 #include "gc/shared/gcArguments.hpp"
  27 #include "gc/shared/gc_globals.hpp"
  28 #include "macroAssembler_ppc.hpp"
  29 #include "precompiled.hpp"
  30 #include "asm/macroAssembler.inline.hpp"
  31 #include "gc/shenandoah/shenandoahBarrierSet.hpp"
  32 #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"
  33 #include "gc/shenandoah/shenandoahForwarding.hpp"
  34 #include "gc/shenandoah/shenandoahHeap.hpp"
  35 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
  36 #include "gc/shenandoah/shenandoahHeapRegion.hpp"
  37 #include "gc/shenandoah/shenandoahRuntime.hpp"
  38 #include "gc/shenandoah/shenandoahThreadLocalData.hpp"
  39 #include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp"

  40 #include "interpreter/interpreter.hpp"
  41 #include "runtime/javaThread.hpp"
  42 #include "runtime/sharedRuntime.hpp"
  43 #include "utilities/globalDefinitions.hpp"
  44 #include "vm_version_ppc.hpp"
  45 #ifdef COMPILER1
  46 #include "c1/c1_LIRAssembler.hpp"
  47 #include "c1/c1_MacroAssembler.hpp"
  48 #include "gc/shenandoah/c1/shenandoahBarrierSetC1.hpp"
  49 #endif
  50 
  51 #define __ masm->
  52 
  53 void ShenandoahBarrierSetAssembler::satb_write_barrier(MacroAssembler *masm,
  54                                                        Register base, RegisterOrConstant ind_or_offs,
  55                                                        Register tmp1, Register tmp2, Register tmp3,
  56                                                        MacroAssembler::PreservationLevel preservation_level) {
  57   if (ShenandoahSATBBarrier) {
  58     __ block_comment("satb_write_barrier (shenandoahgc) {");
  59     satb_write_barrier_impl(masm, 0, base, ind_or_offs, tmp1, tmp2, tmp3, preservation_level);

  73     satb_write_barrier_impl(masm, decorators, noreg, noreg, val, tmp1, tmp2, preservation_level);
  74     __ block_comment("} iu_barrier (shenandoahgc)");
  75   }
  76 }
  77 
  78 void ShenandoahBarrierSetAssembler::load_reference_barrier(MacroAssembler *masm, DecoratorSet decorators,
  79                                                            Register base, RegisterOrConstant ind_or_offs,
  80                                                            Register dst,
  81                                                            Register tmp1, Register tmp2,
  82                                                            MacroAssembler::PreservationLevel preservation_level) {
  83   if (ShenandoahLoadRefBarrier) {
  84     __ block_comment("load_reference_barrier (shenandoahgc) {");
  85     load_reference_barrier_impl(masm, decorators, base, ind_or_offs, dst, tmp1, tmp2, preservation_level);
  86     __ block_comment("} load_reference_barrier (shenandoahgc)");
  87   }
  88 }
  89 
  90 void ShenandoahBarrierSetAssembler::arraycopy_prologue(MacroAssembler *masm, DecoratorSet decorators, BasicType type,
  91                                                        Register src, Register dst, Register count,
  92                                                        Register preserve1, Register preserve2) {
  93   __ block_comment("arraycopy_prologue (shenandoahgc) {");
  94 
  95   Register R11_tmp = R11_scratch1;
  96 
  97   assert_different_registers(src, dst, count, R11_tmp, noreg);
  98   if (preserve1 != noreg) {
  99     // Technically not required, but likely to indicate an error.
 100     assert_different_registers(preserve1, preserve2);
 101   }
 102 
 103   /* ==== Check whether barrier is required (optimizations) ==== */
 104   // Fast path: Component type of array is not a reference type.
 105   if (!is_reference_type(type)) {
 106     return;
 107   }
 108 
 109   bool dest_uninitialized = (decorators & IS_DEST_UNINITIALIZED) != 0;
 110 
 111   // Fast path: No barrier required if for every barrier type, it is either disabled or would not store
 112   // any useful information.
 113   if ((!ShenandoahSATBBarrier || dest_uninitialized) && !ShenandoahIUBarrier && !ShenandoahLoadRefBarrier) {
 114     return;
 115   }
 116 

 117   Label skip_prologue;
 118 
 119   // Fast path: Array is of length zero.
 120   __ cmpdi(CCR0, count, 0);
 121   __ beq(CCR0, skip_prologue);
 122 
 123   /* ==== Check whether barrier is required (gc state) ==== */
 124   __ lbz(R11_tmp, in_bytes(ShenandoahThreadLocalData::gc_state_offset()),
 125          R16_thread);
 126 
 127   // The set of garbage collection states requiring barriers depends on the available barrier types and the
 128   // type of the reference in question.
 129   // For instance, satb barriers may be skipped if it is certain that the overridden values are not relevant
 130   // for the garbage collector.
 131   const int required_states = ShenandoahSATBBarrier && dest_uninitialized
 132                               ? ShenandoahHeap::HAS_FORWARDED
 133                               : ShenandoahHeap::HAS_FORWARDED | ShenandoahHeap::MARKING;
 134 
 135   __ andi_(R11_tmp, R11_tmp, required_states);
 136   __ beq(CCR0, skip_prologue);

 170   {
 171     __ pop_frame();
 172     __ restore_LR_CR(R11_tmp);
 173 
 174     __ ld(count, -BytesPerWord * highest_preserve_register_index--, R1_SP);
 175     __ ld(dst, -BytesPerWord * highest_preserve_register_index--, R1_SP);
 176     __ ld(src, -BytesPerWord * highest_preserve_register_index--, R1_SP);
 177 
 178     if (preserve2 != noreg && preserve2 != preserve1 && preserve2->is_volatile()) {
 179       __ ld(preserve2, -BytesPerWord * highest_preserve_register_index--, R1_SP);
 180     }
 181     if (preserve1 != noreg && preserve1->is_volatile()) {
 182       __ ld(preserve1, -BytesPerWord * highest_preserve_register_index--, R1_SP);
 183     }
 184   }
 185 
 186   __ bind(skip_prologue);
 187   __ block_comment("} arraycopy_prologue (shenandoahgc)");
 188 }
 189 










 190 // The to-be-enqueued value can either be determined
 191 // - dynamically by passing the reference's address information (load mode) or
 192 // - statically by passing a register the value is stored in (preloaded mode)
 193 //   - for performance optimizations in cases where the previous value is known (currently not implemented) and
 194 //   - for incremental-update barriers.
 195 //
 196 // decorators:  The previous value's decorator set.
 197 //              In "load mode", the value must equal '0'.
 198 // base:        Base register of the reference's address (load mode).
 199 //              In "preloaded mode", the register must equal 'noreg'.
 200 // ind_or_offs: Index or offset of the reference's address (load mode).
 201 //              If 'base' equals 'noreg' (preloaded mode), the passed value is ignored.
 202 // pre_val:     Register holding the to-be-stored value (preloaded mode).
 203 //              In "load mode", this register acts as a temporary register and must
 204 //              thus not be 'noreg'.  In "preloaded mode", its content will be sustained.
 205 // tmp1/tmp2:   Temporary registers, one of which must be non-volatile in "preloaded mode".
 206 void ShenandoahBarrierSetAssembler::satb_write_barrier_impl(MacroAssembler *masm, DecoratorSet decorators,
 207                                                             Register base, RegisterOrConstant ind_or_offs,
 208                                                             Register pre_val,
 209                                                             Register tmp1, Register tmp2,

 569                            base, ind_or_offs,
 570                            intermediate_dst,
 571                            tmp1, R0,
 572                            preservation_level);
 573 
 574     __ mr_if_needed(dst, intermediate_dst);
 575   } else {
 576     BarrierSetAssembler::load_at(masm, decorators, type,
 577                                  base, ind_or_offs,
 578                                  dst,
 579                                  tmp1, tmp2,
 580                                  preservation_level, L_handle_null);
 581   }
 582 
 583   /* ==== Apply keep-alive barrier, if required (e.g., to inhibit weak reference resurrection) ==== */
 584   if (ShenandoahBarrierSet::need_keep_alive_barrier(decorators, type)) {
 585     iu_barrier(masm, dst, tmp1, tmp2, preservation_level);
 586   }
 587 }
 588 



















 589 // base:        Base register of the reference's address.
 590 // ind_or_offs: Index or offset of the reference's address.
 591 // val:         To-be-stored value/reference's new value.
 592 void ShenandoahBarrierSetAssembler::store_at(MacroAssembler *masm, DecoratorSet decorators, BasicType type,
 593                                              Register base, RegisterOrConstant ind_or_offs, Register val,
 594                                              Register tmp1, Register tmp2, Register tmp3,
 595                                              MacroAssembler::PreservationLevel preservation_level) {
 596   if (is_reference_type(type)) {
 597     if (ShenandoahSATBBarrier) {
 598       satb_write_barrier(masm, base, ind_or_offs, tmp1, tmp2, tmp3, preservation_level);
 599     }
 600 
 601     if (ShenandoahIUBarrier && val != noreg) {
 602       iu_barrier(masm, val, tmp1, tmp2, preservation_level, decorators);
 603     }
 604   }
 605 
 606   BarrierSetAssembler::store_at(masm, decorators, type,
 607                                 base, ind_or_offs,
 608                                 val,
 609                                 tmp1, tmp2, tmp3,
 610                                 preservation_level);





 611 }
 612 
 613 void ShenandoahBarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler *masm,
 614                                                                   Register dst, Register jni_env, Register obj,
 615                                                                   Register tmp, Label &slowpath) {
 616   __ block_comment("try_resolve_jobject_in_native (shenandoahgc) {");
 617 
 618   assert_different_registers(jni_env, obj, tmp);
 619 
 620   Label done;
 621 
 622   // Fast path: Reference is null (JNI tags are zero for null pointers).
 623   __ cmpdi(CCR0, obj, 0);
 624   __ beq(CCR0, done);
 625 
 626   // Resolve jobject using standard implementation.
 627   BarrierSetAssembler::try_resolve_jobject_in_native(masm, dst, jni_env, obj, tmp, slowpath);
 628 
 629   // Check whether heap is stable.
 630   __ lbz(tmp,

 740   // unlikely case should be handled by the smallest possible code.  Instead of emitting a third,
 741   // explicit CAS operation, the code jumps back and reuses the first CAS operation (step 1)
 742   // (passed arguments are identical).
 743   //
 744   // A failure of the CAS operation in step 1 would imply that the overall CAS operation is supposed
 745   // to fail.  Jumping back to step 1 requires, however, that step 2 and step 3 are re-executed as well.
 746   // It is thus important to ensure that a re-execution of those steps does not put program correctness
 747   // at risk:
 748   // - Step 2: Either terminates in failure (desired result) or falls through to step 3.
 749   // - Step 3: Terminates if the comparison between the forwarded, fetched pointer and the expected value
 750   //           fails.  Unless the reference has been updated in the meanwhile once again, this is
 751   //           guaranteed to be the case.
 752   //           In case of a concurrent update, the CAS would be retried again. This is legitimate
 753   //           in terms of program correctness (even though it is not desired).
 754   __ bne(CCR0, step_four);
 755 
 756   __ bind(done);
 757   __ block_comment("} cmpxchg_oop (shenandoahgc)");
 758 }
 759 


































 760 #undef __
 761 
 762 #ifdef COMPILER1
 763 
 764 #define __ ce->masm()->
 765 
 766 void ShenandoahBarrierSetAssembler::gen_pre_barrier_stub(LIR_Assembler *ce, ShenandoahPreBarrierStub *stub) {
 767   __ block_comment("gen_pre_barrier_stub (shenandoahgc) {");
 768 
 769   ShenandoahBarrierSetC1 *bs = (ShenandoahBarrierSetC1*) BarrierSet::barrier_set()->barrier_set_c1();
 770   __ bind(*stub->entry());
 771 
 772   // GC status has already been verified by 'ShenandoahBarrierSetC1::pre_barrier'.
 773   // This stub is the slowpath of that function.
 774 
 775   assert(stub->pre_val()->is_register(), "pre_val must be a register");
 776   Register pre_val = stub->pre_val()->as_register();
 777 
 778   // If 'do_load()' returns false, the to-be-stored value is already available in 'stub->pre_val()'
 779   // ("preloaded mode" of the store barrier).

   1 /*
   2  * Copyright (c) 2018, 2021, Red Hat, Inc. All rights reserved.
   3  * Copyright (c) 2012, 2022 SAP SE. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *
  24  */
  25 
  26 #include "gc/shared/gcArguments.hpp"
  27 #include "gc/shared/gc_globals.hpp"
  28 #include "macroAssembler_ppc.hpp"
  29 #include "precompiled.hpp"
  30 #include "asm/macroAssembler.inline.hpp"
  31 #include "gc/shenandoah/shenandoahBarrierSet.hpp"
  32 #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"
  33 #include "gc/shenandoah/shenandoahForwarding.hpp"
  34 #include "gc/shenandoah/shenandoahHeap.hpp"
  35 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
  36 #include "gc/shenandoah/shenandoahHeapRegion.hpp"
  37 #include "gc/shenandoah/shenandoahRuntime.hpp"
  38 #include "gc/shenandoah/shenandoahThreadLocalData.hpp"
  39 #include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp"
  40 #include "gc/shenandoah/mode/shenandoahMode.hpp"
  41 #include "interpreter/interpreter.hpp"
  42 #include "runtime/javaThread.hpp"
  43 #include "runtime/sharedRuntime.hpp"
  44 #include "utilities/globalDefinitions.hpp"
  45 #include "vm_version_ppc.hpp"
  46 #ifdef COMPILER1
  47 #include "c1/c1_LIRAssembler.hpp"
  48 #include "c1/c1_MacroAssembler.hpp"
  49 #include "gc/shenandoah/c1/shenandoahBarrierSetC1.hpp"
  50 #endif
  51 
  52 #define __ masm->
  53 
  54 void ShenandoahBarrierSetAssembler::satb_write_barrier(MacroAssembler *masm,
  55                                                        Register base, RegisterOrConstant ind_or_offs,
  56                                                        Register tmp1, Register tmp2, Register tmp3,
  57                                                        MacroAssembler::PreservationLevel preservation_level) {
  58   if (ShenandoahSATBBarrier) {
  59     __ block_comment("satb_write_barrier (shenandoahgc) {");
  60     satb_write_barrier_impl(masm, 0, base, ind_or_offs, tmp1, tmp2, tmp3, preservation_level);

  74     satb_write_barrier_impl(masm, decorators, noreg, noreg, val, tmp1, tmp2, preservation_level);
  75     __ block_comment("} iu_barrier (shenandoahgc)");
  76   }
  77 }
  78 
  79 void ShenandoahBarrierSetAssembler::load_reference_barrier(MacroAssembler *masm, DecoratorSet decorators,
  80                                                            Register base, RegisterOrConstant ind_or_offs,
  81                                                            Register dst,
  82                                                            Register tmp1, Register tmp2,
  83                                                            MacroAssembler::PreservationLevel preservation_level) {
  84   if (ShenandoahLoadRefBarrier) {
  85     __ block_comment("load_reference_barrier (shenandoahgc) {");
  86     load_reference_barrier_impl(masm, decorators, base, ind_or_offs, dst, tmp1, tmp2, preservation_level);
  87     __ block_comment("} load_reference_barrier (shenandoahgc)");
  88   }
  89 }
  90 
  91 void ShenandoahBarrierSetAssembler::arraycopy_prologue(MacroAssembler *masm, DecoratorSet decorators, BasicType type,
  92                                                        Register src, Register dst, Register count,
  93                                                        Register preserve1, Register preserve2) {


  94   Register R11_tmp = R11_scratch1;
  95 
  96   assert_different_registers(src, dst, count, R11_tmp, noreg);
  97   if (preserve1 != noreg) {
  98     // Technically not required, but likely to indicate an error.
  99     assert_different_registers(preserve1, preserve2);
 100   }
 101 
 102   /* ==== Check whether barrier is required (optimizations) ==== */
 103   // Fast path: Component type of array is not a reference type.
 104   if (!is_reference_type(type)) {
 105     return;
 106   }
 107 
 108   bool dest_uninitialized = (decorators & IS_DEST_UNINITIALIZED) != 0;
 109 
 110   // Fast path: No barrier required if for every barrier type, it is either disabled or would not store
 111   // any useful information.
 112   if ((!ShenandoahSATBBarrier || dest_uninitialized) && !ShenandoahIUBarrier && !ShenandoahLoadRefBarrier) {
 113     return;
 114   }
 115 
 116   __ block_comment("arraycopy_prologue (shenandoahgc) {");
 117   Label skip_prologue;
 118 
 119   // Fast path: Array is of length zero.
 120   __ cmpdi(CCR0, count, 0);
 121   __ beq(CCR0, skip_prologue);
 122 
 123   /* ==== Check whether barrier is required (gc state) ==== */
 124   __ lbz(R11_tmp, in_bytes(ShenandoahThreadLocalData::gc_state_offset()),
 125          R16_thread);
 126 
 127   // The set of garbage collection states requiring barriers depends on the available barrier types and the
 128   // type of the reference in question.
 129   // For instance, satb barriers may be skipped if it is certain that the overridden values are not relevant
 130   // for the garbage collector.
 131   const int required_states = ShenandoahSATBBarrier && dest_uninitialized
 132                               ? ShenandoahHeap::HAS_FORWARDED
 133                               : ShenandoahHeap::HAS_FORWARDED | ShenandoahHeap::MARKING;
 134 
 135   __ andi_(R11_tmp, R11_tmp, required_states);
 136   __ beq(CCR0, skip_prologue);

 170   {
 171     __ pop_frame();
 172     __ restore_LR_CR(R11_tmp);
 173 
 174     __ ld(count, -BytesPerWord * highest_preserve_register_index--, R1_SP);
 175     __ ld(dst, -BytesPerWord * highest_preserve_register_index--, R1_SP);
 176     __ ld(src, -BytesPerWord * highest_preserve_register_index--, R1_SP);
 177 
 178     if (preserve2 != noreg && preserve2 != preserve1 && preserve2->is_volatile()) {
 179       __ ld(preserve2, -BytesPerWord * highest_preserve_register_index--, R1_SP);
 180     }
 181     if (preserve1 != noreg && preserve1->is_volatile()) {
 182       __ ld(preserve1, -BytesPerWord * highest_preserve_register_index--, R1_SP);
 183     }
 184   }
 185 
 186   __ bind(skip_prologue);
 187   __ block_comment("} arraycopy_prologue (shenandoahgc)");
 188 }
 189 
 190 void ShenandoahBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
 191                                                        Register dst, Register count,
 192                                                        Register preserve) {
 193   if (ShenandoahCardBarrier && is_reference_type(type)) {
 194     __ block_comment("arraycopy_epilogue (shenandoahgc) {");
 195     gen_write_ref_array_post_barrier(masm, decorators, dst, count, preserve);
 196     __ block_comment("} arraycopy_epilogue (shenandoahgc)");
 197   }
 198 }
 199 
 200 // The to-be-enqueued value can either be determined
 201 // - dynamically by passing the reference's address information (load mode) or
 202 // - statically by passing a register the value is stored in (preloaded mode)
 203 //   - for performance optimizations in cases where the previous value is known (currently not implemented) and
 204 //   - for incremental-update barriers.
 205 //
 206 // decorators:  The previous value's decorator set.
 207 //              In "load mode", the value must equal '0'.
 208 // base:        Base register of the reference's address (load mode).
 209 //              In "preloaded mode", the register must equal 'noreg'.
 210 // ind_or_offs: Index or offset of the reference's address (load mode).
 211 //              If 'base' equals 'noreg' (preloaded mode), the passed value is ignored.
 212 // pre_val:     Register holding the to-be-stored value (preloaded mode).
 213 //              In "load mode", this register acts as a temporary register and must
 214 //              thus not be 'noreg'.  In "preloaded mode", its content will be sustained.
 215 // tmp1/tmp2:   Temporary registers, one of which must be non-volatile in "preloaded mode".
 216 void ShenandoahBarrierSetAssembler::satb_write_barrier_impl(MacroAssembler *masm, DecoratorSet decorators,
 217                                                             Register base, RegisterOrConstant ind_or_offs,
 218                                                             Register pre_val,
 219                                                             Register tmp1, Register tmp2,

 579                            base, ind_or_offs,
 580                            intermediate_dst,
 581                            tmp1, R0,
 582                            preservation_level);
 583 
 584     __ mr_if_needed(dst, intermediate_dst);
 585   } else {
 586     BarrierSetAssembler::load_at(masm, decorators, type,
 587                                  base, ind_or_offs,
 588                                  dst,
 589                                  tmp1, tmp2,
 590                                  preservation_level, L_handle_null);
 591   }
 592 
 593   /* ==== Apply keep-alive barrier, if required (e.g., to inhibit weak reference resurrection) ==== */
 594   if (ShenandoahBarrierSet::need_keep_alive_barrier(decorators, type)) {
 595     iu_barrier(masm, dst, tmp1, tmp2, preservation_level);
 596   }
 597 }
 598 
 599 void ShenandoahBarrierSetAssembler::store_check(MacroAssembler* masm, Register base, RegisterOrConstant ind_or_offs, Register tmp) {
 600   assert(ShenandoahCardBarrier, "Should have been checked by caller");
 601 
 602   ShenandoahBarrierSet* ctbs = ShenandoahBarrierSet::barrier_set();
 603   CardTable* ct = ctbs->card_table();
 604   assert_different_registers(base, tmp, R0);
 605 
 606   if (ind_or_offs.is_constant()) {
 607     __ add_const_optimized(base, base, ind_or_offs.as_constant(), tmp);
 608   } else {
 609     __ add(base, ind_or_offs.as_register(), base);
 610   }
 611 
 612   __ load_const_optimized(tmp, (address)ct->byte_map_base(), R0);
 613   __ srdi(base, base, CardTable::card_shift());
 614   __ li(R0, CardTable::dirty_card_val());
 615   __ stbx(R0, tmp, base);
 616 }
 617 
 618 // base:        Base register of the reference's address.
 619 // ind_or_offs: Index or offset of the reference's address.
 620 // val:         To-be-stored value/reference's new value.
 621 void ShenandoahBarrierSetAssembler::store_at(MacroAssembler *masm, DecoratorSet decorators, BasicType type,
 622                                              Register base, RegisterOrConstant ind_or_offs, Register val,
 623                                              Register tmp1, Register tmp2, Register tmp3,
 624                                              MacroAssembler::PreservationLevel preservation_level) {
 625   if (is_reference_type(type)) {
 626     if (ShenandoahSATBBarrier) {
 627       satb_write_barrier(masm, base, ind_or_offs, tmp1, tmp2, tmp3, preservation_level);
 628     }
 629 
 630     if (ShenandoahIUBarrier && val != noreg) {
 631       iu_barrier(masm, val, tmp1, tmp2, preservation_level, decorators);
 632     }
 633   }
 634 
 635   BarrierSetAssembler::store_at(masm, decorators, type,
 636                                 base, ind_or_offs,
 637                                 val,
 638                                 tmp1, tmp2, tmp3,
 639                                 preservation_level);
 640 
 641   // No need for post barrier if storing NULL
 642   if (ShenandoahCardBarrier && is_reference_type(type) && val != noreg) {
 643     store_check(masm, base, ind_or_offs, tmp1);
 644   }
 645 }
 646 
 647 void ShenandoahBarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler *masm,
 648                                                                   Register dst, Register jni_env, Register obj,
 649                                                                   Register tmp, Label &slowpath) {
 650   __ block_comment("try_resolve_jobject_in_native (shenandoahgc) {");
 651 
 652   assert_different_registers(jni_env, obj, tmp);
 653 
 654   Label done;
 655 
 656   // Fast path: Reference is null (JNI tags are zero for null pointers).
 657   __ cmpdi(CCR0, obj, 0);
 658   __ beq(CCR0, done);
 659 
 660   // Resolve jobject using standard implementation.
 661   BarrierSetAssembler::try_resolve_jobject_in_native(masm, dst, jni_env, obj, tmp, slowpath);
 662 
 663   // Check whether heap is stable.
 664   __ lbz(tmp,

 774   // unlikely case should be handled by the smallest possible code.  Instead of emitting a third,
 775   // explicit CAS operation, the code jumps back and reuses the first CAS operation (step 1)
 776   // (passed arguments are identical).
 777   //
 778   // A failure of the CAS operation in step 1 would imply that the overall CAS operation is supposed
 779   // to fail.  Jumping back to step 1 requires, however, that step 2 and step 3 are re-executed as well.
 780   // It is thus important to ensure that a re-execution of those steps does not put program correctness
 781   // at risk:
 782   // - Step 2: Either terminates in failure (desired result) or falls through to step 3.
 783   // - Step 3: Terminates if the comparison between the forwarded, fetched pointer and the expected value
 784   //           fails.  Unless the reference has been updated in the meanwhile once again, this is
 785   //           guaranteed to be the case.
 786   //           In case of a concurrent update, the CAS would be retried again. This is legitimate
 787   //           in terms of program correctness (even though it is not desired).
 788   __ bne(CCR0, step_four);
 789 
 790   __ bind(done);
 791   __ block_comment("} cmpxchg_oop (shenandoahgc)");
 792 }
 793 
 794 void ShenandoahBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators,
 795                                                                      Register addr, Register count, Register preserve) {
 796   assert(ShenandoahCardBarrier, "Should have been checked by caller");
 797 
 798   ShenandoahBarrierSet* bs = ShenandoahBarrierSet::barrier_set();
 799   CardTable* ct = bs->card_table();
 800   assert_different_registers(addr, count, R0);
 801 
 802   Label L_skip_loop, L_store_loop;
 803 
 804   __ sldi_(count, count, LogBytesPerHeapOop);
 805 
 806   // Zero length? Skip.
 807   __ beq(CCR0, L_skip_loop);
 808 
 809   __ addi(count, count, -BytesPerHeapOop);
 810   __ add(count, addr, count);
 811   // Use two shifts to clear out those low order two bits! (Cannot opt. into 1.)
 812   __ srdi(addr, addr, CardTable::card_shift());
 813   __ srdi(count, count, CardTable::card_shift());
 814   __ subf(count, addr, count);
 815   __ add_const_optimized(addr, addr, (address)ct->byte_map_base(), R0);
 816   __ addi(count, count, 1);
 817   __ li(R0, 0);
 818   __ mtctr(count);
 819 
 820   // Byte store loop
 821   __ bind(L_store_loop);
 822   __ stb(R0, 0, addr);
 823   __ addi(addr, addr, 1);
 824   __ bdnz(L_store_loop);
 825   __ bind(L_skip_loop);
 826 }
 827 
 828 #undef __
 829 
 830 #ifdef COMPILER1
 831 
 832 #define __ ce->masm()->
 833 
 834 void ShenandoahBarrierSetAssembler::gen_pre_barrier_stub(LIR_Assembler *ce, ShenandoahPreBarrierStub *stub) {
 835   __ block_comment("gen_pre_barrier_stub (shenandoahgc) {");
 836 
 837   ShenandoahBarrierSetC1 *bs = (ShenandoahBarrierSetC1*) BarrierSet::barrier_set()->barrier_set_c1();
 838   __ bind(*stub->entry());
 839 
 840   // GC status has already been verified by 'ShenandoahBarrierSetC1::pre_barrier'.
 841   // This stub is the slowpath of that function.
 842 
 843   assert(stub->pre_val()->is_register(), "pre_val must be a register");
 844   Register pre_val = stub->pre_val()->as_register();
 845 
 846   // If 'do_load()' returns false, the to-be-stored value is already available in 'stub->pre_val()'
 847   // ("preloaded mode" of the store barrier).
< prev index next >