< prev index next >

src/hotspot/cpu/ppc/gc/g1/g1BarrierSetAssembler_ppc.cpp

Print this page
rev 53582 : imported patch rename
   1 /*
   2  * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2018, 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 "precompiled.hpp"
  27 #include "asm/macroAssembler.inline.hpp"
  28 #include "gc/g1/g1BarrierSet.hpp"
  29 #include "gc/g1/g1BarrierSetAssembler.hpp"
  30 #include "gc/g1/g1BarrierSetRuntime.hpp"
  31 #include "gc/g1/g1CardTable.hpp"

  32 #include "gc/g1/g1SATBMarkQueueSet.hpp"
  33 #include "gc/g1/g1ThreadLocalData.hpp"
  34 #include "gc/g1/heapRegion.hpp"
  35 #include "interpreter/interp_masm.hpp"
  36 #include "runtime/sharedRuntime.hpp"
  37 #ifdef COMPILER1
  38 #include "c1/c1_LIRAssembler.hpp"
  39 #include "c1/c1_MacroAssembler.hpp"
  40 #include "gc/g1/c1/g1BarrierSetC1.hpp"
  41 #endif
  42 
  43 #define __ masm->
  44 
  45 void G1BarrierSetAssembler::gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators,
  46                                                             Register from, Register to, Register count,
  47                                                             Register preserve1, Register preserve2) {
  48   bool dest_uninitialized = (decorators & IS_DEST_UNINITIALIZED) != 0;
  49   // With G1, don't generate the call if we statically know that the target in uninitialized
  50   if (!dest_uninitialized) {
  51     int spill_slots = 3;


 495   __ beq(CCR0, ret);
 496 
 497   // Return if sequential consistent value is already dirty.
 498   __ membar(Assembler::StoreLoad);
 499   __ lbz(tmp, 0, addr); // tmp := [addr + cardtable]
 500 
 501   __ cmpwi(CCR0, tmp, G1CardTable::dirty_card_val());
 502   __ beq(CCR0, ret);
 503 
 504   // Not dirty.
 505 
 506   // First, dirty it.
 507   __ li(tmp, G1CardTable::dirty_card_val());
 508   __ stb(tmp, 0, addr);
 509 
 510   int dirty_card_q_index_byte_offset = in_bytes(G1ThreadLocalData::dirty_card_queue_index_offset());
 511   int dirty_card_q_buf_byte_offset = in_bytes(G1ThreadLocalData::dirty_card_queue_buffer_offset());
 512 
 513   __ bind(restart);
 514 
 515   // Get the index into the update buffer. DirtyCardQueue::_index is
 516   // a size_t so ld_ptr is appropriate here.
 517   __ ld(tmp2, dirty_card_q_index_byte_offset, R16_thread);
 518 
 519   // index == 0?
 520   __ cmpdi(CCR0, tmp2, 0);
 521   __ beq(CCR0, refill);
 522 
 523   __ ld(tmp, dirty_card_q_buf_byte_offset, R16_thread);
 524   __ addi(tmp2, tmp2, -oopSize);
 525 
 526   __ std(tmp2, dirty_card_q_index_byte_offset, R16_thread);
 527   __ add(tmp2, tmp, tmp2);
 528   __ std(addr, 0, tmp2); // [_buf + index] := <address_of_card>
 529 
 530   // Restore temp registers and return-from-leaf.
 531   __ bind(ret);
 532   __ ld(tmp2, -16, R1_SP);
 533   __ ld(addr, -8, R1_SP);
 534   __ blr();
 535 
 536   __ bind(refill);
 537   const int nbytes_save = (MacroAssembler::num_volatile_regs + stack_slots) * BytesPerWord;
 538   __ save_volatile_gprs(R1_SP, -nbytes_save); // except R0
 539   __ mflr(R0);
 540   __ std(R0, _abi(lr), R1_SP);
 541   __ push_frame_reg_args(nbytes_save, R0); // dummy frame for C call
 542   __ call_VM_leaf(CAST_FROM_FN_PTR(address, DirtyCardQueueSet::handle_zero_index_for_thread), R16_thread);
 543   __ pop_frame();
 544   __ ld(R0, _abi(lr), R1_SP);
 545   __ mtlr(R0);
 546   __ restore_volatile_gprs(R1_SP, -nbytes_save); // except R0
 547   __ b(restart);
 548 }
 549 
 550 #undef __
 551 
 552 #endif // COMPILER1
   1 /*
   2  * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2018, 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 "precompiled.hpp"
  27 #include "asm/macroAssembler.inline.hpp"
  28 #include "gc/g1/g1BarrierSet.hpp"
  29 #include "gc/g1/g1BarrierSetAssembler.hpp"
  30 #include "gc/g1/g1BarrierSetRuntime.hpp"
  31 #include "gc/g1/g1CardTable.hpp"
  32 #include "gc/g1/g1DirtyCardQueue.hpp"
  33 #include "gc/g1/g1SATBMarkQueueSet.hpp"
  34 #include "gc/g1/g1ThreadLocalData.hpp"
  35 #include "gc/g1/heapRegion.hpp"
  36 #include "interpreter/interp_masm.hpp"
  37 #include "runtime/sharedRuntime.hpp"
  38 #ifdef COMPILER1
  39 #include "c1/c1_LIRAssembler.hpp"
  40 #include "c1/c1_MacroAssembler.hpp"
  41 #include "gc/g1/c1/g1BarrierSetC1.hpp"
  42 #endif
  43 
  44 #define __ masm->
  45 
  46 void G1BarrierSetAssembler::gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators,
  47                                                             Register from, Register to, Register count,
  48                                                             Register preserve1, Register preserve2) {
  49   bool dest_uninitialized = (decorators & IS_DEST_UNINITIALIZED) != 0;
  50   // With G1, don't generate the call if we statically know that the target in uninitialized
  51   if (!dest_uninitialized) {
  52     int spill_slots = 3;


 496   __ beq(CCR0, ret);
 497 
 498   // Return if sequential consistent value is already dirty.
 499   __ membar(Assembler::StoreLoad);
 500   __ lbz(tmp, 0, addr); // tmp := [addr + cardtable]
 501 
 502   __ cmpwi(CCR0, tmp, G1CardTable::dirty_card_val());
 503   __ beq(CCR0, ret);
 504 
 505   // Not dirty.
 506 
 507   // First, dirty it.
 508   __ li(tmp, G1CardTable::dirty_card_val());
 509   __ stb(tmp, 0, addr);
 510 
 511   int dirty_card_q_index_byte_offset = in_bytes(G1ThreadLocalData::dirty_card_queue_index_offset());
 512   int dirty_card_q_buf_byte_offset = in_bytes(G1ThreadLocalData::dirty_card_queue_buffer_offset());
 513 
 514   __ bind(restart);
 515 
 516   // Get the index into the update buffer. G1DirtyCardQueue::_index is
 517   // a size_t so ld_ptr is appropriate here.
 518   __ ld(tmp2, dirty_card_q_index_byte_offset, R16_thread);
 519 
 520   // index == 0?
 521   __ cmpdi(CCR0, tmp2, 0);
 522   __ beq(CCR0, refill);
 523 
 524   __ ld(tmp, dirty_card_q_buf_byte_offset, R16_thread);
 525   __ addi(tmp2, tmp2, -oopSize);
 526 
 527   __ std(tmp2, dirty_card_q_index_byte_offset, R16_thread);
 528   __ add(tmp2, tmp, tmp2);
 529   __ std(addr, 0, tmp2); // [_buf + index] := <address_of_card>
 530 
 531   // Restore temp registers and return-from-leaf.
 532   __ bind(ret);
 533   __ ld(tmp2, -16, R1_SP);
 534   __ ld(addr, -8, R1_SP);
 535   __ blr();
 536 
 537   __ bind(refill);
 538   const int nbytes_save = (MacroAssembler::num_volatile_regs + stack_slots) * BytesPerWord;
 539   __ save_volatile_gprs(R1_SP, -nbytes_save); // except R0
 540   __ mflr(R0);
 541   __ std(R0, _abi(lr), R1_SP);
 542   __ push_frame_reg_args(nbytes_save, R0); // dummy frame for C call
 543   __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1DirtyCardQueueSet::handle_zero_index_for_thread), R16_thread);
 544   __ pop_frame();
 545   __ ld(R0, _abi(lr), R1_SP);
 546   __ mtlr(R0);
 547   __ restore_volatile_gprs(R1_SP, -nbytes_save); // except R0
 548   __ b(restart);
 549 }
 550 
 551 #undef __
 552 
 553 #endif // COMPILER1
< prev index next >