< prev index next >

src/hotspot/cpu/arm/templateTable_arm.cpp

Print this page




 176 }
 177 
 178 //----------------------------------------------------------------------------------------------------
 179 // Miscelaneous helper routines
 180 
 181 // Store an oop (or NULL) at the address described by obj.
 182 // Blows all volatile registers (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR).
 183 // Also destroys new_val and obj.base().
 184 static void do_oop_store(InterpreterMacroAssembler* _masm,
 185                          Address obj,
 186                          Register new_val,
 187                          Register tmp1,
 188                          Register tmp2,
 189                          Register tmp3,
 190                          BarrierSet::Name barrier,
 191                          bool precise,
 192                          bool is_null) {
 193 
 194   assert_different_registers(obj.base(), new_val, tmp1, tmp2, tmp3, noreg);
 195   switch (barrier) {
 196 #if INCLUDE_ALL_GCS
 197     case BarrierSet::G1BarrierSet:
 198       {
 199         // flatten object address if needed
 200         assert (obj.mode() == basic_offset, "pre- or post-indexing is not supported here");
 201 
 202         const Register store_addr = obj.base();
 203         if (obj.index() != noreg) {
 204           assert (obj.disp() == 0, "index or displacement, not both");
 205 #ifdef AARCH64
 206           __ add(store_addr, obj.base(), obj.index(), obj.extend(), obj.shift_imm());
 207 #else
 208           assert(obj.offset_op() == add_offset, "addition is expected");
 209           __ add(store_addr, obj.base(), AsmOperand(obj.index(), obj.shift(), obj.shift_imm()));
 210 #endif // AARCH64
 211         } else if (obj.disp() != 0) {
 212           __ add(store_addr, obj.base(), obj.disp());
 213         }
 214 
 215         __ g1_write_barrier_pre(store_addr, new_val, tmp1, tmp2, tmp3);
 216         if (is_null) {
 217           __ store_heap_oop_null(new_val, Address(store_addr));
 218         } else {
 219           // G1 barrier needs uncompressed oop for region cross check.
 220           Register val_to_store = new_val;
 221           if (UseCompressedOops) {
 222             val_to_store = tmp1;
 223             __ mov(val_to_store, new_val);
 224           }
 225           __ store_heap_oop(val_to_store, Address(store_addr)); // blows val_to_store:
 226           val_to_store = noreg;
 227           __ g1_write_barrier_post(store_addr, new_val, tmp1, tmp2, tmp3);
 228         }
 229       }
 230       break;
 231 #endif // INCLUDE_ALL_GCS
 232     case BarrierSet::CardTableBarrierSet:
 233       {
 234         if (is_null) {
 235           __ store_heap_oop_null(new_val, obj);
 236         } else {
 237           assert (!precise || (obj.index() == noreg && obj.disp() == 0),
 238                   "store check address should be calculated beforehand");
 239 
 240           __ store_check_part1(tmp1);
 241           __ store_heap_oop(new_val, obj); // blows new_val:
 242           new_val = noreg;
 243           __ store_check_part2(obj.base(), tmp1, tmp2);
 244         }
 245       }
 246       break;
 247     case BarrierSet::ModRef:
 248       ShouldNotReachHere();
 249       break;
 250     default:
 251       ShouldNotReachHere();




 176 }
 177 
 178 //----------------------------------------------------------------------------------------------------
 179 // Miscelaneous helper routines
 180 
 181 // Store an oop (or NULL) at the address described by obj.
 182 // Blows all volatile registers (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR).
 183 // Also destroys new_val and obj.base().
 184 static void do_oop_store(InterpreterMacroAssembler* _masm,
 185                          Address obj,
 186                          Register new_val,
 187                          Register tmp1,
 188                          Register tmp2,
 189                          Register tmp3,
 190                          BarrierSet::Name barrier,
 191                          bool precise,
 192                          bool is_null) {
 193 
 194   assert_different_registers(obj.base(), new_val, tmp1, tmp2, tmp3, noreg);
 195   switch (barrier) {
 196 #if INCLUDE_G1GC
 197     case BarrierSet::G1BarrierSet:
 198       {
 199         // flatten object address if needed
 200         assert (obj.mode() == basic_offset, "pre- or post-indexing is not supported here");
 201 
 202         const Register store_addr = obj.base();
 203         if (obj.index() != noreg) {
 204           assert (obj.disp() == 0, "index or displacement, not both");
 205 #ifdef AARCH64
 206           __ add(store_addr, obj.base(), obj.index(), obj.extend(), obj.shift_imm());
 207 #else
 208           assert(obj.offset_op() == add_offset, "addition is expected");
 209           __ add(store_addr, obj.base(), AsmOperand(obj.index(), obj.shift(), obj.shift_imm()));
 210 #endif // AARCH64
 211         } else if (obj.disp() != 0) {
 212           __ add(store_addr, obj.base(), obj.disp());
 213         }
 214 
 215         __ g1_write_barrier_pre(store_addr, new_val, tmp1, tmp2, tmp3);
 216         if (is_null) {
 217           __ store_heap_oop_null(new_val, Address(store_addr));
 218         } else {
 219           // G1 barrier needs uncompressed oop for region cross check.
 220           Register val_to_store = new_val;
 221           if (UseCompressedOops) {
 222             val_to_store = tmp1;
 223             __ mov(val_to_store, new_val);
 224           }
 225           __ store_heap_oop(val_to_store, Address(store_addr)); // blows val_to_store:
 226           val_to_store = noreg;
 227           __ g1_write_barrier_post(store_addr, new_val, tmp1, tmp2, tmp3);
 228         }
 229       }
 230       break;
 231 #endif // INCLUDE_G1GC
 232     case BarrierSet::CardTableBarrierSet:
 233       {
 234         if (is_null) {
 235           __ store_heap_oop_null(new_val, obj);
 236         } else {
 237           assert (!precise || (obj.index() == noreg && obj.disp() == 0),
 238                   "store check address should be calculated beforehand");
 239 
 240           __ store_check_part1(tmp1);
 241           __ store_heap_oop(new_val, obj); // blows new_val:
 242           new_val = noreg;
 243           __ store_check_part2(obj.base(), tmp1, tmp2);
 244         }
 245       }
 246       break;
 247     case BarrierSet::ModRef:
 248       ShouldNotReachHere();
 249       break;
 250     default:
 251       ShouldNotReachHere();


< prev index next >