102 103 CardTableBarrierSet* ctbs = barrier_set_cast<CardTableBarrierSet>(bs); 104 CardTable* ct = ctbs->card_table(); 105 assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "Adjust store check code"); 106 107 // Load card table base address. 108 109 /* Performance note. 110 111 There is an alternative way of loading card table base address 112 from thread descriptor, which may look more efficient: 113 114 ldr(card_table_base, Address(Rthread, JavaThread::card_table_base_offset())); 115 116 However, performance measurements of micro benchmarks and specJVM98 117 showed that loading of card table base from thread descriptor is 118 7-18% slower compared to loading of literal embedded into the code. 119 Possible cause is a cache miss (card table base address resides in a 120 rarely accessed area of thread descriptor). 121 */ 122 // TODO-AARCH64 Investigate if mov_slow is faster than ldr from Rthread on AArch64 123 __ mov_address(card_table_base, (address)ct->byte_map_base(), symbolic_Relocation::card_table_reference); 124 } 125 126 // The 2nd part of the store check. 127 void CardTableBarrierSetAssembler::store_check_part2(MacroAssembler* masm, Register obj, Register card_table_base, Register tmp) { 128 assert_different_registers(obj, card_table_base, tmp); 129 130 BarrierSet* bs = BarrierSet::barrier_set(); 131 assert(bs->kind() == BarrierSet::CardTableBarrierSet, 132 "Wrong barrier set kind"); 133 134 CardTableBarrierSet* ctbs = barrier_set_cast<CardTableBarrierSet>(bs); 135 CardTable* ct = ctbs->card_table(); 136 assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "Adjust store check code"); 137 138 assert(CardTable::dirty_card_val() == 0, "Dirty card value must be 0 due to optimizations."); 139 #ifdef AARCH64 140 add(card_table_base, card_table_base, AsmOperand(obj, lsr, CardTable::card_shift)); 141 Address card_table_addr(card_table_base); 142 #else 143 Address card_table_addr(card_table_base, obj, lsr, CardTable::card_shift); 144 #endif 145 146 if (UseCondCardMark) { 147 if (ct->scanned_concurrently()) { 148 __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreLoad), noreg); 149 } 150 Label already_dirty; 151 152 __ ldrb(tmp, card_table_addr); 153 __ cbz(tmp, already_dirty); 154 155 set_card(masm, card_table_base, card_table_addr, tmp); 156 __ bind(already_dirty); 157 158 } else { 159 if (ct->scanned_concurrently()) { 160 __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore), noreg); 161 } 162 set_card(masm, card_table_base, card_table_addr, tmp); 163 } 164 } 165 166 void CardTableBarrierSetAssembler::set_card(MacroAssembler* masm, Register card_table_base, Address card_table_addr, Register tmp) { 167 #ifdef AARCH64 168 strb(ZR, card_table_addr); 169 #else 170 CardTableBarrierSet* ctbs = barrier_set_cast<CardTableBarrierSet>(BarrierSet::barrier_set()); 171 CardTable* ct = ctbs->card_table(); 172 if ((((uintptr_t)ct->byte_map_base() & 0xff) == 0)) { 173 // Card table is aligned so the lowest byte of the table address base is zero. 174 // This works only if the code is not saved for later use, possibly 175 // in a context where the base would no longer be aligned. 176 __ strb(card_table_base, card_table_addr); 177 } else { 178 __ mov(tmp, 0); 179 __ strb(tmp, card_table_addr); 180 } 181 #endif // AARCH64 182 } | 102 103 CardTableBarrierSet* ctbs = barrier_set_cast<CardTableBarrierSet>(bs); 104 CardTable* ct = ctbs->card_table(); 105 assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "Adjust store check code"); 106 107 // Load card table base address. 108 109 /* Performance note. 110 111 There is an alternative way of loading card table base address 112 from thread descriptor, which may look more efficient: 113 114 ldr(card_table_base, Address(Rthread, JavaThread::card_table_base_offset())); 115 116 However, performance measurements of micro benchmarks and specJVM98 117 showed that loading of card table base from thread descriptor is 118 7-18% slower compared to loading of literal embedded into the code. 119 Possible cause is a cache miss (card table base address resides in a 120 rarely accessed area of thread descriptor). 121 */ 122 __ mov_address(card_table_base, (address)ct->byte_map_base(), symbolic_Relocation::card_table_reference); 123 } 124 125 // The 2nd part of the store check. 126 void CardTableBarrierSetAssembler::store_check_part2(MacroAssembler* masm, Register obj, Register card_table_base, Register tmp) { 127 assert_different_registers(obj, card_table_base, tmp); 128 129 BarrierSet* bs = BarrierSet::barrier_set(); 130 assert(bs->kind() == BarrierSet::CardTableBarrierSet, 131 "Wrong barrier set kind"); 132 133 CardTableBarrierSet* ctbs = barrier_set_cast<CardTableBarrierSet>(bs); 134 CardTable* ct = ctbs->card_table(); 135 assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "Adjust store check code"); 136 137 assert(CardTable::dirty_card_val() == 0, "Dirty card value must be 0 due to optimizations."); 138 Address card_table_addr(card_table_base, obj, lsr, CardTable::card_shift); 139 140 if (UseCondCardMark) { 141 if (ct->scanned_concurrently()) { 142 __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreLoad), noreg); 143 } 144 Label already_dirty; 145 146 __ ldrb(tmp, card_table_addr); 147 __ cbz(tmp, already_dirty); 148 149 set_card(masm, card_table_base, card_table_addr, tmp); 150 __ bind(already_dirty); 151 152 } else { 153 if (ct->scanned_concurrently()) { 154 __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore), noreg); 155 } 156 set_card(masm, card_table_base, card_table_addr, tmp); 157 } 158 } 159 160 void CardTableBarrierSetAssembler::set_card(MacroAssembler* masm, Register card_table_base, Address card_table_addr, Register tmp) { 161 CardTableBarrierSet* ctbs = barrier_set_cast<CardTableBarrierSet>(BarrierSet::barrier_set()); 162 CardTable* ct = ctbs->card_table(); 163 if ((((uintptr_t)ct->byte_map_base() & 0xff) == 0)) { 164 // Card table is aligned so the lowest byte of the table address base is zero. 165 // This works only if the code is not saved for later use, possibly 166 // in a context where the base would no longer be aligned. 167 __ strb(card_table_base, card_table_addr); 168 } else { 169 __ mov(tmp, 0); 170 __ strb(tmp, card_table_addr); 171 } 172 } |