< prev index next >

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

Print this page
*** 22,10 ***
--- 22,13 ---
   *
   */
  
  #include "precompiled.hpp"
  #include "asm/macroAssembler.inline.hpp"
+ #if INCLUDE_CDS
+ #include "code/SCCache.hpp"
+ #endif
  #include "gc/g1/g1BarrierSet.hpp"
  #include "gc/g1/g1BarrierSetAssembler.hpp"
  #include "gc/g1/g1BarrierSetRuntime.hpp"
  #include "gc/g1/g1CardTable.hpp"
  #include "gc/g1/g1HeapRegion.hpp"

*** 281,34 ***
    __ pop_call_clobbered_registers();
  
    __ bind(done);
  }
  
  static void generate_post_barrier_fast_path(MacroAssembler* masm,
                                              const Register store_addr,
                                              const Register new_val,
                                              const Register tmp,
                                              const Register tmp2,
                                              Label& done,
                                              bool new_val_may_be_null) {
    CardTableBarrierSet* ct = barrier_set_cast<CardTableBarrierSet>(BarrierSet::barrier_set());
    // Does store cross heap regions?
!   __ movptr(tmp, store_addr);                                    // tmp := store address
!   __ xorptr(tmp, new_val);                                       // tmp := store address ^ new value
!   __ shrptr(tmp, G1HeapRegion::LogOfHRGrainBytes);               // ((store address ^ new value) >> LogOfHRGrainBytes) == 0?
!   __ jcc(Assembler::equal, done);
    // Crosses regions, storing null?
    if (new_val_may_be_null) {
      __ cmpptr(new_val, NULL_WORD);                               // new value == null?
      __ jcc(Assembler::equal, done);
    }
    // Storing region crossing non-null, is card young?
    __ movptr(tmp, store_addr);                                    // tmp := store address
!   __ shrptr(tmp, CardTable::card_shift());                       // tmp := card address relative to card table base
    // Do not use ExternalAddress to load 'byte_map_base', since 'byte_map_base' is NOT
    // a valid address and therefore is not properly handled by the relocation code.
!   __ movptr(tmp2, (intptr_t)ct->card_table()->byte_map_base());  // tmp2 := card table base address
    __ addptr(tmp, tmp2);                                          // tmp := card address
    __ cmpb(Address(tmp, 0), G1CardTable::g1_young_card_val());    // *(card address) == young_card_val?
  }
  
  static void generate_post_barrier_slow_path(MacroAssembler* masm,
--- 284,91 ---
    __ pop_call_clobbered_registers();
  
    __ bind(done);
  }
  
+ // return a register that differs from reg1, reg2, reg3 and is not rcx
+ 
+ static Register pick_different_reg(Register reg1, Register reg2 = noreg, Register reg3= noreg, Register reg4 = noreg) {
+   RegSet available = (RegSet::of(rscratch1, rscratch2, rax, rbx) + rdx -
+                       RegSet::of(reg1, reg2, reg3, reg4));
+   return *(available.begin());
+ }
+ 
  static void generate_post_barrier_fast_path(MacroAssembler* masm,
                                              const Register store_addr,
                                              const Register new_val,
                                              const Register tmp,
                                              const Register tmp2,
                                              Label& done,
                                              bool new_val_may_be_null) {
    CardTableBarrierSet* ct = barrier_set_cast<CardTableBarrierSet>(BarrierSet::barrier_set());
    // Does store cross heap regions?
! #if INCLUDE_CDS
!   // AOT code needs to load the barrier grain shift from the aot
!   // runtime constants area in the code cache otherwise we can compile
!   // it as an immediate operand
+ 
+   if (SCCache::is_on_for_write()) {
+     address grain_shift_addr = AOTRuntimeConstants::grain_shift_address();
+     Register save = pick_different_reg(rcx, tmp, new_val, store_addr);
+     __ push(save);
+     __ movptr(save, store_addr);
+     __ xorptr(save, new_val);
+     __ push(rcx);
+     __ lea(rcx, ExternalAddress(grain_shift_addr));
+     __ movptr(rcx, Address(rcx, 0));
+     __ shrptr(save);
+     __ pop(rcx);
+     __ mov(tmp, save);
+     __ pop(save);
+     __ jcc(Assembler::equal, done);
+   } else
+ #endif // INCLUDE_CDS
+   {
+     __ movptr(tmp, store_addr);                                    // tmp := store address
+     __ xorptr(tmp, new_val);                                       // tmp := store address ^ new value
+     __ shrptr(tmp, G1HeapRegion::LogOfHRGrainBytes);               // ((store address ^ new value) >> LogOfHRGrainBytes) == 0?
+     __ jcc(Assembler::equal, done);
+   }
+ 
    // Crosses regions, storing null?
    if (new_val_may_be_null) {
      __ cmpptr(new_val, NULL_WORD);                               // new value == null?
      __ jcc(Assembler::equal, done);
    }
    // Storing region crossing non-null, is card young?
    __ movptr(tmp, store_addr);                                    // tmp := store address
! #if INCLUDE_CDS
+   // AOT code needs to load the barrier card shift from the aot
+   // runtime constants area in the code cache otherwise we can compile
+   // it as an immediate operand
+   if (SCCache::is_on_for_write()) {
+     address card_shift_addr = AOTRuntimeConstants::card_shift_address();
+     Register save = pick_different_reg(rcx, tmp);
+     __ push(save);
+     __ mov(save, tmp);
+     __ push(rcx);
+     __ lea(rcx, ExternalAddress(card_shift_addr));
+     __ movptr(rcx, Address(rcx, 0));
+     __ shrptr(save);
+     __ pop(rcx);
+     __ mov(tmp, save);
+     __ pop(save);
+   } else
+ #endif // INCLUDE_CDS
+   {
+     __ shrptr(tmp, CardTable::card_shift());                       // tmp := card address relative to card table base
+   }
    // Do not use ExternalAddress to load 'byte_map_base', since 'byte_map_base' is NOT
    // a valid address and therefore is not properly handled by the relocation code.
!   if (SCCache::is_on_for_write()) {
+     // SCA needs relocation info for this address
+     __ lea(tmp2, ExternalAddress((address)ct->card_table()->byte_map_base()));   // tmp2 := card table base address
+   } else {
+     __ movptr(tmp2, (intptr_t)ct->card_table()->byte_map_base());   // tmp2 := card table base address
+   }
    __ addptr(tmp, tmp2);                                          // tmp := card address
    __ cmpb(Address(tmp, 0), G1CardTable::g1_young_card_val());    // *(card address) == young_card_val?
  }
  
  static void generate_post_barrier_slow_path(MacroAssembler* masm,

*** 655,11 ***
  
    __ load_parameter(0, card_addr);
    __ shrptr(card_addr, CardTable::card_shift());
    // Do not use ExternalAddress to load 'byte_map_base', since 'byte_map_base' is NOT
    // a valid address and therefore is not properly handled by the relocation code.
!   __ movptr(cardtable, (intptr_t)ct->card_table()->byte_map_base());
    __ addptr(card_addr, cardtable);
  
    NOT_LP64(__ get_thread(thread);)
  
    __ cmpb(Address(card_addr, 0), G1CardTable::g1_young_card_val());
--- 715,16 ---
  
    __ load_parameter(0, card_addr);
    __ shrptr(card_addr, CardTable::card_shift());
    // Do not use ExternalAddress to load 'byte_map_base', since 'byte_map_base' is NOT
    // a valid address and therefore is not properly handled by the relocation code.
!   if (SCCache::is_on()) {
+     // SCA needs relocation info for this address
+     __ lea(cardtable, ExternalAddress((address)ct->card_table()->byte_map_base()));
+   } else {
+     __ movptr(cardtable, (intptr_t)ct->card_table()->byte_map_base());
+   }
    __ addptr(card_addr, cardtable);
  
    NOT_LP64(__ get_thread(thread);)
  
    __ cmpb(Address(card_addr, 0), G1CardTable::g1_young_card_val());
< prev index next >