6 * published by the Free Software Foundation.
7 *
8 * This code is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * version 2 for more details (a copy is included in the LICENSE file that
12 * accompanied this code).
13 *
14 * You should have received a copy of the GNU General Public License version
15 * 2 along with this work; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19 * or visit www.oracle.com if you need additional information or have any
20 * questions.
21 *
22 */
23
24 #include "precompiled.hpp"
25 #include "asm/macroAssembler.inline.hpp"
26 #include "gc/g1/g1BarrierSet.hpp"
27 #include "gc/g1/g1BarrierSetAssembler.hpp"
28 #include "gc/g1/g1CardTable.hpp"
29 #include "gc/g1/g1ThreadLocalData.hpp"
30 #include "gc/g1/heapRegion.hpp"
31 #include "interpreter/interp_masm.hpp"
32 #include "runtime/sharedRuntime.hpp"
33 #include "utilities/macros.hpp"
34
35 #define __ masm->
36
37 void G1BarrierSetAssembler::gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators,
38 Register addr, Register count) {
39 bool dest_uninitialized = (decorators & AS_DEST_NOT_INITIALIZED) != 0;
40
41 if (!dest_uninitialized) {
42 Register thread = NOT_LP64(rax) LP64_ONLY(r15_thread);
43 #ifndef _LP64
44 __ push(thread);
|
6 * published by the Free Software Foundation.
7 *
8 * This code is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * version 2 for more details (a copy is included in the LICENSE file that
12 * accompanied this code).
13 *
14 * You should have received a copy of the GNU General Public License version
15 * 2 along with this work; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19 * or visit www.oracle.com if you need additional information or have any
20 * questions.
21 *
22 */
23
24 #include "precompiled.hpp"
25 #include "asm/macroAssembler.inline.hpp"
26 #include "c1/c1_LIRAssembler.hpp"
27 #include "c1/c1_MacroAssembler.hpp"
28 #include "gc/g1/c1/g1BarrierSetC1.hpp"
29 #include "gc/g1/g1BarrierSet.hpp"
30 #include "gc/g1/g1BarrierSetAssembler.hpp"
31 #include "gc/g1/g1CardTable.hpp"
32 #include "gc/g1/g1ThreadLocalData.hpp"
33 #include "gc/g1/heapRegion.hpp"
34 #include "interpreter/interp_masm.hpp"
35 #include "runtime/sharedRuntime.hpp"
36 #include "utilities/macros.hpp"
37
38 #define __ masm->
39
40 void G1BarrierSetAssembler::gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators,
41 Register addr, Register count) {
42 bool dest_uninitialized = (decorators & AS_DEST_NOT_INITIALIZED) != 0;
43
44 if (!dest_uninitialized) {
45 Register thread = NOT_LP64(rax) LP64_ONLY(r15_thread);
46 #ifndef _LP64
47 __ push(thread);
|
381 Register new_val = val;
382 if (needs_post_barrier) {
383 // G1 barrier needs uncompressed oop for region cross check.
384 if (UseCompressedOops) {
385 new_val = tmp2;
386 __ movptr(new_val, val);
387 }
388 }
389 BarrierSetAssembler::store_at(masm, decorators, type, Address(tmp1, 0), val, noreg, noreg);
390 if (needs_post_barrier) {
391 g1_write_barrier_post(masm /*masm*/,
392 tmp1 /* store_adr */,
393 new_val /* new_val */,
394 rthread /* thread */,
395 tmp3 /* tmp */,
396 tmp2 /* tmp2 */);
397 }
398 }
399 NOT_LP64(imasm->restore_bcp());
400 }
|
384 Register new_val = val;
385 if (needs_post_barrier) {
386 // G1 barrier needs uncompressed oop for region cross check.
387 if (UseCompressedOops) {
388 new_val = tmp2;
389 __ movptr(new_val, val);
390 }
391 }
392 BarrierSetAssembler::store_at(masm, decorators, type, Address(tmp1, 0), val, noreg, noreg);
393 if (needs_post_barrier) {
394 g1_write_barrier_post(masm /*masm*/,
395 tmp1 /* store_adr */,
396 new_val /* new_val */,
397 rthread /* thread */,
398 tmp3 /* tmp */,
399 tmp2 /* tmp2 */);
400 }
401 }
402 NOT_LP64(imasm->restore_bcp());
403 }
404
405 #undef __
406 #define __ ce->masm()->
407
408 void G1BarrierSetAssembler::gen_g1_pre_barrier_stub(LIR_Assembler* ce, G1PreBarrierStub* stub) {
409 G1BarrierSetC1* bs = (G1BarrierSetC1*)BarrierSet::barrier_set()->barrier_set_c1();
410 // At this point we know that marking is in progress.
411 // If do_load() is true then we have to emit the
412 // load of the previous value; otherwise it has already
413 // been loaded into _pre_val.
414
415 __ bind(*stub->entry());
416 assert(stub->pre_val()->is_register(), "Precondition.");
417
418 Register pre_val_reg = stub->pre_val()->as_register();
419
420 if (stub->do_load()) {
421 ce->mem2reg(stub->addr(), stub->pre_val(), T_OBJECT, stub->patch_code(), stub->info(), false /*wide*/, false /*unaligned*/);
422 }
423
424 __ cmpptr(pre_val_reg, (int32_t)NULL_WORD);
425 __ jcc(Assembler::equal, *stub->continuation());
426 ce->store_parameter(stub->pre_val()->as_register(), 0);
427 __ call(RuntimeAddress(bs->pre_barrier_c1_runtime_code_blob()->code_begin()));
428 __ jmp(*stub->continuation());
429
430 }
431
432 void G1BarrierSetAssembler::gen_g1_post_barrier_stub(LIR_Assembler* ce, G1PostBarrierStub* stub) {
433 G1BarrierSetC1* bs = (G1BarrierSetC1*)BarrierSet::barrier_set()->barrier_set_c1();
434 __ bind(*stub->entry());
435 assert(stub->addr()->is_register(), "Precondition.");
436 assert(stub->new_val()->is_register(), "Precondition.");
437 Register new_val_reg = stub->new_val()->as_register();
438 __ cmpptr(new_val_reg, (int32_t) NULL_WORD);
439 __ jcc(Assembler::equal, *stub->continuation());
440 ce->store_parameter(stub->addr()->as_pointer_register(), 0);
441 __ call(RuntimeAddress(bs->post_barrier_c1_runtime_code_blob()->code_begin()));
442 __ jmp(*stub->continuation());
443 }
444
445 #undef __
446
447 #define __ sasm->
448
449 void G1BarrierSetAssembler::generate_c1_pre_barrier_runtime_stub(StubAssembler* sasm) {
450 __ prologue("g1_pre_barrier", false);
451 // arg0 : previous value of memory
452
453 BarrierSet* bs = BarrierSet::barrier_set();
454 __ push(rax);
455 __ push(rdx);
456
457 const Register pre_val = rax;
458 const Register thread = NOT_LP64(rax) LP64_ONLY(r15_thread);
459 const Register tmp = rdx;
460
461 NOT_LP64(__ get_thread(thread);)
462
463 Address queue_active(thread, in_bytes(G1ThreadLocalData::satb_mark_queue_active_offset()));
464 Address queue_index(thread, in_bytes(G1ThreadLocalData::satb_mark_queue_index_offset()));
465 Address buffer(thread, in_bytes(G1ThreadLocalData::satb_mark_queue_buffer_offset()));
466
467 Label done;
468 Label runtime;
469
470 // Is marking still active?
471 if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
472 __ cmpl(queue_active, 0);
473 } else {
474 assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
475 __ cmpb(queue_active, 0);
476 }
477 __ jcc(Assembler::equal, done);
478
479 // Can we store original value in the thread's buffer?
480
481 __ movptr(tmp, queue_index);
482 __ testptr(tmp, tmp);
483 __ jcc(Assembler::zero, runtime);
484 __ subptr(tmp, wordSize);
485 __ movptr(queue_index, tmp);
486 __ addptr(tmp, buffer);
487
488 // prev_val (rax)
489 __ load_parameter(0, pre_val);
490 __ movptr(Address(tmp, 0), pre_val);
491 __ jmp(done);
492
493 __ bind(runtime);
494
495 __ save_live_registers_no_oop_map(3, true);
496
497 // load the pre-value
498 __ load_parameter(0, rcx);
499 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), rcx, thread);
500
501 __ restore_live_registers(true);
502
503 __ bind(done);
504
505 __ pop(rdx);
506 __ pop(rax);
507
508 __ epilogue();
509 }
510
511 void G1BarrierSetAssembler::generate_c1_post_barrier_runtime_stub(StubAssembler* sasm) {
512 __ prologue("g1_post_barrier", false);
513
514 // arg0: store_address
515 Address store_addr(rbp, 2*BytesPerWord);
516
517 CardTableBarrierSet* ct =
518 barrier_set_cast<CardTableBarrierSet>(BarrierSet::barrier_set());
519 assert(sizeof(*ct->card_table()->byte_map_base()) == sizeof(jbyte), "adjust this code");
520
521 Label done;
522 Label enqueued;
523 Label runtime;
524
525 // At this point we know new_value is non-NULL and the new_value crosses regions.
526 // Must check to see if card is already dirty
527
528 const Register thread = NOT_LP64(rax) LP64_ONLY(r15_thread);
529
530 Address queue_index(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_index_offset()));
531 Address buffer(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_buffer_offset()));
532
533 __ push(rax);
534 __ push(rcx);
535
536 const Register cardtable = rax;
537 const Register card_addr = rcx;
538
539 __ load_parameter(0, card_addr);
540 __ shrptr(card_addr, CardTable::card_shift);
541 // Do not use ExternalAddress to load 'byte_map_base', since 'byte_map_base' is NOT
542 // a valid address and therefore is not properly handled by the relocation code.
543 __ movptr(cardtable, (intptr_t)ct->card_table()->byte_map_base());
544 __ addptr(card_addr, cardtable);
545
546 NOT_LP64(__ get_thread(thread);)
547
548 __ cmpb(Address(card_addr, 0), (int)G1CardTable::g1_young_card_val());
549 __ jcc(Assembler::equal, done);
550
551 __ membar(Assembler::Membar_mask_bits(Assembler::StoreLoad));
552 __ cmpb(Address(card_addr, 0), (int)CardTable::dirty_card_val());
553 __ jcc(Assembler::equal, done);
554
555 // storing region crossing non-NULL, card is clean.
556 // dirty card and log.
557
558 __ movb(Address(card_addr, 0), (int)CardTable::dirty_card_val());
559
560 const Register tmp = rdx;
561 __ push(rdx);
562
563 __ movptr(tmp, queue_index);
564 __ testptr(tmp, tmp);
565 __ jcc(Assembler::zero, runtime);
566 __ subptr(tmp, wordSize);
567 __ movptr(queue_index, tmp);
568 __ addptr(tmp, buffer);
569 __ movptr(Address(tmp, 0), card_addr);
570 __ jmp(enqueued);
571
572 __ bind(runtime);
573
574 __ save_live_registers_no_oop_map(3, true);
575
576 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), card_addr, thread);
577
578 __ restore_live_registers(true);
579
580 __ bind(enqueued);
581 __ pop(rdx);
582
583 __ bind(done);
584 __ pop(rcx);
585 __ pop(rax);
586
587 __ epilogue();
588 }
589
590 #undef __
|