1 /*
   2  * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2015-2018, Azul Systems, Inc. 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 "c1/c1_LIRAssembler.hpp"
  29 #include "c1/c1_MacroAssembler.hpp"
  30 #include "gc/g1/c1/g1BarrierSetC1.hpp"
  31 #include "gc/g1/g1BarrierSet.hpp"
  32 #include "gc/g1/g1BarrierSetAssembler.hpp"
  33 #include "gc/g1/g1BarrierSetRuntime.hpp"
  34 #include "gc/g1/g1CardTable.hpp"
  35 #include "gc/g1/g1ThreadLocalData.hpp"
  36 #include "gc/g1/heapRegion.hpp"
  37 #include "gc/shared/collectedHeap.hpp"
  38 #include "runtime/sharedRuntime.hpp"
  39 #include "runtime/thread.hpp"
  40 #include "interpreter/interp_masm.hpp"
  41 #include "runtime/sharedRuntime.hpp"
  42 
  43 #define __ masm->
  44 
  45 void G1BarrierSetAssembler::gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators,
  46                                                             Register addr, Register count) {
  47   bool dest_uninitialized = (decorators & IS_DEST_UNINITIALIZED) != 0;
  48   // With G1, don't generate the call if we statically know that the target in uninitialized
  49   if (!dest_uninitialized) {
  50     __ push(RegSet::range(r0, r3), sp);
  51     if (count == c_rarg0) {
  52       if (addr == c_rarg1) {
  53         // exactly backwards!!
  54         __ eor(c_rarg0, c_rarg0, c_rarg1);
  55         __ eor(c_rarg1, c_rarg0, c_rarg1);
  56         __ eor(c_rarg0, c_rarg0, c_rarg1);
  57       } else {
  58         __ mov(c_rarg1, count);
  59         __ mov(c_rarg0, addr);
  60       }
  61     } else {
  62       __ mov(c_rarg0, addr);
  63       __ mov(c_rarg1, count);
  64     }
  65     __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_array_pre_oop_entry), 2);
  66     __ pop(RegSet::range(r0, r3), sp);
  67   }
  68 }
  69 
  70 void G1BarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators,
  71                                                              Register start, Register end, Register scratch) {
  72   // must compute element count unless barrier set interface is changed (other platforms supply count)
  73   assert_different_registers(start, end, scratch);
  74   __ lea(scratch, Address(end, BytesPerHeapOop));
  75   __ sub(scratch, scratch, start);               // subtract start to get #bytes
  76   __ lsr(scratch, scratch, LogBytesPerHeapOop);  // convert to element count
  77   __ mov(c_rarg0, start);
  78   __ mov(c_rarg1, scratch);
  79   __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_array_post_entry), 2);
  80 }
  81 
  82 
  83 void G1BarrierSetAssembler::g1_write_barrier_pre(MacroAssembler* masm,
  84                                                  Address obj,
  85                                                  Register pre_val,
  86                                                  Register thread,
  87                                                  Register tmp,
  88                                                  bool tosca_live,
  89                                                  bool expand_call) {
  90   // If expand_call is true then we expand the call_VM_leaf macro
  91   // directly to skip generating the check by
  92   // InterpreterMacroAssembler::call_VM_leaf_base that checks _last_sp.
  93 
  94   assert(thread == rthread, "must be");
  95 
  96   Label done;
  97   Label runtime;
  98 
  99   assert(pre_val != noreg, "check this code");
 100 
 101   assert_different_registers(pre_val, tmp);
 102   if (obj.get_mode() != Address::no_mode)
 103     assert(!obj.uses(pre_val) && !obj.uses(tmp), "destroys register");
 104 
 105   Address in_progress(thread, in_bytes(G1ThreadLocalData::satb_mark_queue_active_offset()));
 106   Address index(thread, in_bytes(G1ThreadLocalData::satb_mark_queue_index_offset()));
 107   Address buffer(thread, in_bytes(G1ThreadLocalData::satb_mark_queue_buffer_offset()));
 108 
 109 
 110   // Is marking active?
 111   if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
 112     __ ldr(tmp, in_progress);
 113   } else {
 114     assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
 115     __ ldrb(tmp, in_progress);
 116   }
 117   __ cbz(tmp, done);
 118 
 119   // Do we need to load the previous value?
 120   if (obj.get_mode() != Address::no_mode) {
 121     __ load_heap_oop(pre_val, obj, noreg, noreg, AS_RAW);
 122   }
 123 
 124   // Is the previous value null?
 125   __ cbz(pre_val, done);
 126 
 127   // Can we store original value in the thread's buffer?
 128   // Is index == 0?
 129   // (The index field is typed as size_t.)
 130 
 131   __ ldr(tmp, index);                      // tmp := *index_adr
 132   __ cbz(tmp, runtime);                    // tmp == 0?
 133                                         // If yes, goto runtime
 134 
 135   __ sub(tmp, tmp, wordSize);              // tmp := tmp - wordSize
 136   __ str(tmp, index);                      // *index_adr := tmp
 137   __ ldr(rscratch1, buffer);
 138   __ add(tmp, tmp, rscratch1);             // tmp := tmp + *buffer_adr
 139 
 140   // Record the previous value
 141   __ str(pre_val, Address(tmp));
 142   __ b(done);
 143 
 144   __ bind(runtime);
 145   // save the live input values
 146   __ push(r0->bit(tosca_live) | obj.reg_bits() | pre_val->bit(true) | lr->bit(true), sp);
 147 
 148   // Calling the runtime using the regular call_VM_leaf mechanism generates
 149   // code (generated by InterpreterMacroAssember::call_VM_leaf_base)
 150   // that checks that the *(rfp+frame::interpreter_frame_last_sp) == NULL.
 151   //
 152   // If we care generating the pre-barrier without a frame (e.g. in the
 153   // intrinsified Reference.get() routine) then ebp might be pointing to
 154   // the caller frame and so this check will most likely fail at runtime.
 155   //
 156   // Expanding the call directly bypasses the generation of the check.
 157   // So when we do not have have a full interpreter frame on the stack
 158   // expand_call should be passed true.
 159 
 160   if (expand_call) {
 161     assert(pre_val != c_rarg1, "smashed arg");
 162     __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_field_pre_entry), pre_val, thread);
 163   } else {
 164     __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_field_pre_entry), pre_val, thread);
 165   }
 166 
 167   __ pop(r0->bit(tosca_live) | obj.reg_bits() | pre_val->bit(true) | lr->bit(true), sp);
 168 
 169   __ bind(done);
 170 }
 171 
 172 void G1BarrierSetAssembler::g1_write_barrier_post(MacroAssembler* masm,
 173                                                   Address store_addr,
 174                                                   Register new_val,
 175                                                   Register thread,
 176                                                   Register tmp,
 177                                                   Register tmp2) {
 178   assert(thread == rthread, "must be");
 179 
 180   Address queue_index(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_index_offset()));
 181   Address buffer(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_buffer_offset()));
 182 
 183   BarrierSet* bs = BarrierSet::barrier_set();
 184   CardTableBarrierSet* ctbs = barrier_set_cast<CardTableBarrierSet>(bs);
 185   CardTable* ct = ctbs->card_table();
 186   assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
 187 
 188   Label done;
 189   Label runtime;
 190 
 191   // Does store cross heap regions?
 192 
 193   __ lea(tmp2, store_addr);
 194   __ eor(tmp, tmp2, new_val);
 195   __ lsrs(tmp, tmp, HeapRegion::LogOfHRGrainBytes);
 196   __ b(done, Assembler::EQ);
 197 
 198   // crosses regions, storing NULL?
 199 
 200   __ cbz(new_val, done);
 201 
 202   // storing region crossing non-NULL, is card already dirty?
 203 
 204   assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
 205   const Register card_addr = tmp;
 206 
 207   __ lsr(card_addr, tmp2, CardTable::card_shift);
 208 
 209   //ExternalAddress cardtable((address) ct->byte_map_base());
 210   __ mov(tmp2, (unsigned)ct->byte_map_base());
 211 
 212   // get the address of the card
 213   __ add(card_addr, card_addr, tmp2);
 214   __ ldrb(tmp2, Address(card_addr));
 215   __ cmp(tmp2, (int)G1CardTable::g1_young_card_val());
 216   __ b(done, Assembler::EQ);
 217 
 218   assert((int)CardTable::dirty_card_val() == 0, "must be 0");
 219 
 220   __ membar(Assembler::StoreLoad);
 221 
 222   __ ldrb(tmp2, Address(card_addr));
 223   __ cbz(tmp2, done);
 224 
 225   // storing a region crossing, non-NULL oop, card is clean.
 226   // dirty card and log.
 227   __ mov(rscratch1, 0);
 228   __ strb(rscratch1, Address(card_addr));
 229 
 230   __ ldr(rscratch1, queue_index);
 231   __ cbz(rscratch1, runtime);
 232   __ sub(rscratch1, rscratch1, wordSize);
 233   __ str(rscratch1, queue_index);
 234 
 235   __ ldr(tmp2, buffer);
 236   __ str(card_addr, Address(tmp2, rscratch1));
 237   __ b(done);
 238 
 239   __ bind(runtime);
 240   // save the live input values
 241   __ push(store_addr.reg_bits() | new_val->bit(true), sp);
 242   __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_field_post_entry), card_addr, thread);
 243   __ pop(store_addr.reg_bits() | new_val->bit(true), sp);
 244 
 245   __ bind(done);
 246 }
 247 
 248 void G1BarrierSetAssembler::load_word_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
 249                                          Register dst, Address src, Register tmp1, Register tmp_thread) {
 250   bool on_oop = type == T_OBJECT || type == T_ARRAY;
 251   bool on_weak = (decorators & ON_WEAK_OOP_REF) != 0;
 252   bool on_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0;
 253   bool on_reference = on_weak || on_phantom;
 254   ModRefBarrierSetAssembler::load_word_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
 255   if (on_oop && on_reference) {
 256     // LR is live.  It must be saved around calls.
 257     // Generate the G1 pre-barrier code to log the value of
 258     // the referent field in an SATB buffer.
 259     g1_write_barrier_pre(masm /* masm */,
 260                          Address() /* obj */,
 261                          dst /* pre_val */,
 262                          rthread /* thread */,
 263                          tmp1 /* tmp */,
 264                          true /* tosca_live */,
 265                          true /* expand_call */);
 266   }
 267 }
 268 
 269 void G1BarrierSetAssembler::load_tos_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
 270                                         Address src, Register tmp1, Register tmp_thread) {
 271   bool on_oop = type == T_OBJECT || type == T_ARRAY;
 272   bool on_weak = (decorators & ON_WEAK_OOP_REF) != 0;
 273   bool on_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0;
 274   bool on_reference = on_weak || on_phantom;
 275   ModRefBarrierSetAssembler::load_tos_at(masm, decorators, type, src, tmp1, tmp_thread);
 276   if (on_oop && on_reference) {
 277     // Generate the G1 pre-barrier code to log the value of
 278     // the referent field in an SATB buffer.
 279     g1_write_barrier_pre(masm /* masm */,
 280                          Address() /* obj */,
 281                          r0 /* pre_val */, // atos is in r0
 282                          rthread /* thread */,
 283                          tmp1 /* tmp */,
 284                          true /* tosca_live */,
 285                          true /* expand_call */);
 286   }
 287 }
 288 
 289 void G1BarrierSetAssembler::oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
 290                                          Address dst, Register val, Register tmp1, Register tmp2) {
 291   g1_write_barrier_pre(masm,
 292                        dst /* obj */,
 293                        tmp2 /* pre_val */,
 294                        rthread /* thread */,
 295                        tmp1  /* tmp */,
 296                        val != noreg /* tosca_live */,
 297                        false /* expand_call */);
 298 
 299   if (val == noreg) {
 300     BarrierSetAssembler::store_word_at(masm, decorators, type, dst, noreg, tmp1, noreg);
 301   } else {
 302     BarrierSetAssembler::store_word_at(masm, decorators, type, dst, val, noreg, noreg);
 303     g1_write_barrier_post(masm,
 304                           dst /* store_adr */,
 305                           val /* new_val */,
 306                           rthread /* thread */,
 307                           tmp1 /* tmp */,
 308                           tmp2 /* tmp2 */);
 309   }
 310 
 311 }
 312 
 313 #ifdef COMPILER1
 314 
 315 #undef __
 316 #define __ ce->masm()->
 317 
 318 void G1BarrierSetAssembler::gen_pre_barrier_stub(LIR_Assembler* ce, G1PreBarrierStub* stub) {
 319   G1BarrierSetC1* bs = (G1BarrierSetC1*)BarrierSet::barrier_set()->barrier_set_c1();
 320   // At this point we know that marking is in progress.
 321   // If do_load() is true then we have to emit the
 322   // load of the previous value; otherwise it has already
 323   // been loaded into _pre_val.
 324 
 325   __ bind(*stub->entry());
 326 
 327   assert(stub->pre_val()->is_register(), "Precondition.");
 328 
 329   Register pre_val_reg = stub->pre_val()->as_register();
 330 
 331   if (stub->do_load()) {
 332     ce->mem2reg(stub->addr(), stub->pre_val(), T_OBJECT, stub->patch_code(), stub->info(), false /*wide*/, false /*unaligned*/);
 333   }
 334   __ cbz(pre_val_reg, *stub->continuation());
 335   ce->store_parameter(stub->pre_val()->as_register(), 0);
 336   __ far_call(RuntimeAddress(bs->pre_barrier_c1_runtime_code_blob()->code_begin()));
 337   __ b(*stub->continuation());
 338 }
 339 
 340 void G1BarrierSetAssembler::gen_post_barrier_stub(LIR_Assembler* ce, G1PostBarrierStub* stub) {
 341   G1BarrierSetC1* bs = (G1BarrierSetC1*)BarrierSet::barrier_set()->barrier_set_c1();
 342   __ bind(*stub->entry());
 343   assert(stub->addr()->is_register(), "Precondition.");
 344   assert(stub->new_val()->is_register(), "Precondition.");
 345   Register new_val_reg = stub->new_val()->as_register();
 346   __ cbz(new_val_reg, *stub->continuation());
 347   ce->store_parameter(stub->addr()->as_pointer_register(), 0);
 348   __ far_call(RuntimeAddress(bs->post_barrier_c1_runtime_code_blob()->code_begin()));
 349   __ b(*stub->continuation());
 350 }
 351 
 352 #undef __
 353 
 354 #define __ sasm->
 355 
 356 void G1BarrierSetAssembler::generate_c1_pre_barrier_runtime_stub(StubAssembler* sasm) {
 357   __ prologue("g1_pre_barrier", false);
 358 
 359   // arg0 : previous value of memory
 360 
 361   BarrierSet* bs = BarrierSet::barrier_set();
 362 
 363   const Register pre_val = r0;
 364   const Register thread = rthread;
 365   const Register tmp = rscratch1;
 366 
 367   Address in_progress(thread, in_bytes(G1ThreadLocalData::satb_mark_queue_active_offset()));
 368   Address queue_index(thread, in_bytes(G1ThreadLocalData::satb_mark_queue_index_offset()));
 369   Address buffer(thread, in_bytes(G1ThreadLocalData::satb_mark_queue_buffer_offset()));
 370 
 371   Label done;
 372   Label runtime;
 373 
 374   // Is marking still active?
 375   if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
 376     __ ldr(tmp, in_progress);
 377   } else {
 378     assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
 379     __ ldrb(tmp, in_progress);
 380   }
 381   __ cbz(tmp, done);
 382 
 383   // Can we store original value in the thread's buffer?
 384   __ ldr(tmp, queue_index);
 385   __ cbz(tmp, runtime);
 386 
 387   __ sub(tmp, tmp, wordSize);
 388   __ str(tmp, queue_index);
 389   __ ldr(rscratch2, buffer);
 390   __ add(tmp, tmp, rscratch2);
 391   __ load_parameter(0, rscratch2);
 392   __ str(rscratch2, Address(tmp, 0));
 393   __ b(done);
 394 
 395   __ bind(runtime);
 396   __ push_call_clobbered_registers();
 397   __ load_parameter(0, pre_val);
 398   __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_field_pre_entry), pre_val, thread);
 399   __ pop_call_clobbered_registers();
 400   __ bind(done);
 401 
 402   __ epilogue();
 403 }
 404 
 405 void G1BarrierSetAssembler::generate_c1_post_barrier_runtime_stub(StubAssembler* sasm) {
 406   __ prologue("g1_post_barrier", false);
 407 
 408   // arg0: store_address
 409   Address store_addr(rfp, 2*BytesPerWord);
 410 
 411   BarrierSet* bs = BarrierSet::barrier_set();
 412   CardTableBarrierSet* ctbs = barrier_set_cast<CardTableBarrierSet>(bs);
 413   CardTable* ct = ctbs->card_table();
 414   assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
 415 
 416   Label done;
 417   Label runtime;
 418 
 419   // At this point we know new_value is non-NULL and the new_value crosses regions.
 420   // Must check to see if card is already dirty
 421 
 422   const Register thread = rthread;
 423 
 424   Address queue_index(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_index_offset()));
 425   Address buffer(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_buffer_offset()));
 426 
 427   const Register card_addr = rscratch2;
 428   ExternalAddress cardtable((address) ct->byte_map_base());
 429 
 430   __ load_parameter(0, card_addr);
 431   __ lsr(card_addr, card_addr, CardTable::card_shift);
 432   __ mov(rscratch1, cardtable);
 433   __ add(card_addr, card_addr, rscratch1);
 434   __ ldrb(rscratch1, Address(card_addr));
 435   __ cmp(rscratch1, (int)G1CardTable::g1_young_card_val());
 436   __ b(done, Assembler::EQ);
 437 
 438   assert((int)CardTable::dirty_card_val() == 0, "must be 0");
 439 
 440   __ membar(Assembler::StoreLoad);
 441   __ ldrb(rscratch1, Address(card_addr));
 442   __ cbz(rscratch1, done);
 443 
 444   // storing region crossing non-NULL, card is clean.
 445   // dirty card and log.
 446   __ mov(rscratch1, 0);
 447   __ strb(rscratch1, Address(card_addr));
 448 
 449   __ ldr(rscratch1, queue_index);
 450   __ cbz(rscratch1, runtime);
 451   __ sub(rscratch1, rscratch1, wordSize);
 452   __ str(rscratch1, queue_index);
 453 
 454   // Reuse LR to hold buffer_addr
 455   const Register buffer_addr = lr;
 456 
 457   __ ldr(buffer_addr, buffer);
 458   __ str(card_addr, Address(buffer_addr, rscratch1));
 459   __ b(done);
 460 
 461   __ bind(runtime);
 462   __ push_call_clobbered_registers();
 463   __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_field_post_entry), card_addr, thread);
 464   __ pop_call_clobbered_registers();
 465   __ bind(done);
 466   __ epilogue();
 467 }
 468 
 469 #undef __
 470 
 471 #endif // COMPILER1