< prev index next >

src/hotspot/cpu/x86/gc/g1/g1BarrierSetAssembler_x86.cpp

Print this page

  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 
 25 #include "precompiled.hpp"
 26 #include "asm/macroAssembler.inline.hpp"

 27 #include "gc/g1/g1BarrierSet.hpp"
 28 #include "gc/g1/g1BarrierSetAssembler.hpp"
 29 #include "gc/g1/g1BarrierSetRuntime.hpp"
 30 #include "gc/g1/g1CardTable.hpp"
 31 #include "gc/g1/g1HeapRegion.hpp"
 32 #include "gc/g1/g1ThreadLocalData.hpp"
 33 #include "interpreter/interp_masm.hpp"
 34 #include "runtime/sharedRuntime.hpp"
 35 #include "utilities/debug.hpp"
 36 #include "utilities/macros.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 addr, Register count) {

286 
287   __ movptr(tmp, store_addr);
288   __ xorptr(tmp, new_val);
289   __ shrptr(tmp, HeapRegion::LogOfHRGrainBytes);
290   __ jcc(Assembler::equal, done);
291 
292   // crosses regions, storing null?
293 
294   __ cmpptr(new_val, NULL_WORD);
295   __ jcc(Assembler::equal, done);
296 
297   // storing region crossing non-null, is card already dirty?
298 
299   const Register card_addr = tmp;
300   const Register cardtable = tmp2;
301 
302   __ movptr(card_addr, store_addr);
303   __ shrptr(card_addr, CardTable::card_shift());
304   // Do not use ExternalAddress to load 'byte_map_base', since 'byte_map_base' is NOT
305   // a valid address and therefore is not properly handled by the relocation code.
306   __ movptr(cardtable, (intptr_t)ct->card_table()->byte_map_base());





307   __ addptr(card_addr, cardtable);
308 
309   __ cmpb(Address(card_addr, 0), G1CardTable::g1_young_card_val());
310   __ jcc(Assembler::equal, done);
311 
312   __ membar(Assembler::Membar_mask_bits(Assembler::StoreLoad));
313   __ cmpb(Address(card_addr, 0), G1CardTable::dirty_card_val());
314   __ jcc(Assembler::equal, done);
315 
316 
317   // storing a region crossing, non-null oop, card is clean.
318   // dirty card and log.
319 
320   __ movb(Address(card_addr, 0), G1CardTable::dirty_card_val());
321 
322   // The code below assumes that buffer index is pointer sized.
323   STATIC_ASSERT(in_bytes(G1DirtyCardQueue::byte_width_of_index()) == sizeof(intptr_t));
324 
325   __ movptr(tmp2, queue_index);
326   __ testptr(tmp2, tmp2);

521   Label runtime;
522 
523   // At this point we know new_value is non-null and the new_value crosses regions.
524   // Must check to see if card is already dirty
525 
526   const Register thread = NOT_LP64(rax) LP64_ONLY(r15_thread);
527 
528   Address queue_index(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_index_offset()));
529   Address buffer(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_buffer_offset()));
530 
531   __ push(rax);
532   __ push(rcx);
533 
534   const Register cardtable = rax;
535   const Register card_addr = rcx;
536 
537   __ load_parameter(0, card_addr);
538   __ shrptr(card_addr, CardTable::card_shift());
539   // Do not use ExternalAddress to load 'byte_map_base', since 'byte_map_base' is NOT
540   // a valid address and therefore is not properly handled by the relocation code.
541   __ movptr(cardtable, (intptr_t)ct->card_table()->byte_map_base());





542   __ addptr(card_addr, cardtable);
543 
544   NOT_LP64(__ get_thread(thread);)
545 
546   __ cmpb(Address(card_addr, 0), G1CardTable::g1_young_card_val());
547   __ jcc(Assembler::equal, done);
548 
549   __ membar(Assembler::Membar_mask_bits(Assembler::StoreLoad));
550   __ cmpb(Address(card_addr, 0), CardTable::dirty_card_val());
551   __ jcc(Assembler::equal, done);
552 
553   // storing region crossing non-null, card is clean.
554   // dirty card and log.
555 
556   __ movb(Address(card_addr, 0), CardTable::dirty_card_val());
557 
558   const Register tmp = rdx;
559   __ push(rdx);
560 
561   __ movptr(tmp, queue_index);

  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 
 25 #include "precompiled.hpp"
 26 #include "asm/macroAssembler.inline.hpp"
 27 #include "code/SCCache.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/g1HeapRegion.hpp"
 33 #include "gc/g1/g1ThreadLocalData.hpp"
 34 #include "interpreter/interp_masm.hpp"
 35 #include "runtime/sharedRuntime.hpp"
 36 #include "utilities/debug.hpp"
 37 #include "utilities/macros.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 addr, Register count) {

287 
288   __ movptr(tmp, store_addr);
289   __ xorptr(tmp, new_val);
290   __ shrptr(tmp, HeapRegion::LogOfHRGrainBytes);
291   __ jcc(Assembler::equal, done);
292 
293   // crosses regions, storing null?
294 
295   __ cmpptr(new_val, NULL_WORD);
296   __ jcc(Assembler::equal, done);
297 
298   // storing region crossing non-null, is card already dirty?
299 
300   const Register card_addr = tmp;
301   const Register cardtable = tmp2;
302 
303   __ movptr(card_addr, store_addr);
304   __ shrptr(card_addr, CardTable::card_shift());
305   // Do not use ExternalAddress to load 'byte_map_base', since 'byte_map_base' is NOT
306   // a valid address and therefore is not properly handled by the relocation code.
307   if (SCCache::is_on_for_write()) {
308     // SCA needs relocation info for this address
309     __ lea(cardtable, ExternalAddress((address)ct->card_table()->byte_map_base()));
310   } else {
311     __ movptr(cardtable, (intptr_t)ct->card_table()->byte_map_base());
312   }
313   __ addptr(card_addr, cardtable);
314 
315   __ cmpb(Address(card_addr, 0), G1CardTable::g1_young_card_val());
316   __ jcc(Assembler::equal, done);
317 
318   __ membar(Assembler::Membar_mask_bits(Assembler::StoreLoad));
319   __ cmpb(Address(card_addr, 0), G1CardTable::dirty_card_val());
320   __ jcc(Assembler::equal, done);
321 
322 
323   // storing a region crossing, non-null oop, card is clean.
324   // dirty card and log.
325 
326   __ movb(Address(card_addr, 0), G1CardTable::dirty_card_val());
327 
328   // The code below assumes that buffer index is pointer sized.
329   STATIC_ASSERT(in_bytes(G1DirtyCardQueue::byte_width_of_index()) == sizeof(intptr_t));
330 
331   __ movptr(tmp2, queue_index);
332   __ testptr(tmp2, tmp2);

527   Label runtime;
528 
529   // At this point we know new_value is non-null and the new_value crosses regions.
530   // Must check to see if card is already dirty
531 
532   const Register thread = NOT_LP64(rax) LP64_ONLY(r15_thread);
533 
534   Address queue_index(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_index_offset()));
535   Address buffer(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_buffer_offset()));
536 
537   __ push(rax);
538   __ push(rcx);
539 
540   const Register cardtable = rax;
541   const Register card_addr = rcx;
542 
543   __ load_parameter(0, card_addr);
544   __ shrptr(card_addr, CardTable::card_shift());
545   // Do not use ExternalAddress to load 'byte_map_base', since 'byte_map_base' is NOT
546   // a valid address and therefore is not properly handled by the relocation code.
547   if (SCCache::is_on()) {
548     // SCA needs relocation info for this address
549     __ lea(cardtable, ExternalAddress((address)ct->card_table()->byte_map_base()));
550   } else {
551     __ movptr(cardtable, (intptr_t)ct->card_table()->byte_map_base());
552   }
553   __ addptr(card_addr, cardtable);
554 
555   NOT_LP64(__ get_thread(thread);)
556 
557   __ cmpb(Address(card_addr, 0), G1CardTable::g1_young_card_val());
558   __ jcc(Assembler::equal, done);
559 
560   __ membar(Assembler::Membar_mask_bits(Assembler::StoreLoad));
561   __ cmpb(Address(card_addr, 0), CardTable::dirty_card_val());
562   __ jcc(Assembler::equal, done);
563 
564   // storing region crossing non-null, card is clean.
565   // dirty card and log.
566 
567   __ movb(Address(card_addr, 0), CardTable::dirty_card_val());
568 
569   const Register tmp = rdx;
570   __ push(rdx);
571 
572   __ movptr(tmp, queue_index);
< prev index next >