1 /*
2 * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
459 }
460
461 void InterpreterMacroAssembler::set_card(Register card_table_base, Address card_table_addr, Register tmp) {
462 #ifdef AARCH64
463 strb(ZR, card_table_addr);
464 #else
465 CardTableModRefBS* ct = barrier_set_cast<CardTableModRefBS>(Universe::heap()->barrier_set());
466 if ((((uintptr_t)ct->byte_map_base & 0xff) == 0)) {
467 // Card table is aligned so the lowest byte of the table address base is zero.
468 // This works only if the code is not saved for later use, possibly
469 // in a context where the base would no longer be aligned.
470 strb(card_table_base, card_table_addr);
471 } else {
472 mov(tmp, 0);
473 strb(tmp, card_table_addr);
474 }
475 #endif // AARCH64
476 }
477
478 //////////////////////////////////////////////////////////////////////////////////
479
480
481 // Java Expression Stack
482
483 void InterpreterMacroAssembler::pop_ptr(Register r) {
484 assert(r != Rstack_top, "unpredictable instruction");
485 ldr(r, Address(Rstack_top, wordSize, post_indexed));
486 }
487
488 void InterpreterMacroAssembler::pop_i(Register r) {
489 assert(r != Rstack_top, "unpredictable instruction");
490 ldr_s32(r, Address(Rstack_top, wordSize, post_indexed));
491 zap_high_non_significant_bits(r);
492 }
493
494 #ifdef AARCH64
495 void InterpreterMacroAssembler::pop_l(Register r) {
496 assert(r != Rstack_top, "unpredictable instruction");
497 ldr(r, Address(Rstack_top, 2*wordSize, post_indexed));
498 }
|
1 /*
2 * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
459 }
460
461 void InterpreterMacroAssembler::set_card(Register card_table_base, Address card_table_addr, Register tmp) {
462 #ifdef AARCH64
463 strb(ZR, card_table_addr);
464 #else
465 CardTableModRefBS* ct = barrier_set_cast<CardTableModRefBS>(Universe::heap()->barrier_set());
466 if ((((uintptr_t)ct->byte_map_base & 0xff) == 0)) {
467 // Card table is aligned so the lowest byte of the table address base is zero.
468 // This works only if the code is not saved for later use, possibly
469 // in a context where the base would no longer be aligned.
470 strb(card_table_base, card_table_addr);
471 } else {
472 mov(tmp, 0);
473 strb(tmp, card_table_addr);
474 }
475 #endif // AARCH64
476 }
477
478 //////////////////////////////////////////////////////////////////////////////////
479 #if INCLUDE_ALL_GCS
480
481 // G1 pre-barrier.
482 // Blows all volatile registers (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR).
483 // If store_addr != noreg, then previous value is loaded from [store_addr];
484 // in such case store_addr and new_val registers are preserved;
485 // otherwise pre_val register is preserved.
486 void InterpreterMacroAssembler::g1_write_barrier_pre(Register store_addr,
487 Register new_val,
488 Register pre_val,
489 Register tmp1,
490 Register tmp2) {
491 Label done;
492 Label runtime;
493
494 if (store_addr != noreg) {
495 assert_different_registers(store_addr, new_val, pre_val, tmp1, tmp2, noreg);
496 } else {
497 assert (new_val == noreg, "should be");
498 assert_different_registers(pre_val, tmp1, tmp2, noreg);
499 }
500
501 Address in_progress(Rthread, in_bytes(JavaThread::satb_mark_queue_offset() +
502 SATBMarkQueue::byte_offset_of_active()));
503 Address index(Rthread, in_bytes(JavaThread::satb_mark_queue_offset() +
504 SATBMarkQueue::byte_offset_of_index()));
505 Address buffer(Rthread, in_bytes(JavaThread::satb_mark_queue_offset() +
506 SATBMarkQueue::byte_offset_of_buf()));
507
508 // Is marking active?
509 assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "adjust this code");
510 ldrb(tmp1, in_progress);
511 cbz(tmp1, done);
512
513 // Do we need to load the previous value?
514 if (store_addr != noreg) {
515 load_heap_oop(pre_val, Address(store_addr, 0));
516 }
517
518 // Is the previous value null?
519 cbz(pre_val, done);
520
521 // Can we store original value in the thread's buffer?
522 // Is index == 0?
523 // (The index field is typed as size_t.)
524
525 ldr(tmp1, index); // tmp1 := *index_adr
526 ldr(tmp2, buffer);
527
528 subs(tmp1, tmp1, wordSize); // tmp1 := tmp1 - wordSize
529 b(runtime, lt); // If negative, goto runtime
530
531 str(tmp1, index); // *index_adr := tmp1
532
533 // Record the previous value
534 str(pre_val, Address(tmp2, tmp1));
535 b(done);
536
537 bind(runtime);
538
539 // save the live input values
540 #ifdef AARCH64
541 if (store_addr != noreg) {
542 raw_push(store_addr, new_val);
543 } else {
544 raw_push(pre_val, ZR);
545 }
546 #else
547 if (store_addr != noreg) {
548 // avoid raw_push to support any ordering of store_addr and new_val
549 push(RegisterSet(store_addr) | RegisterSet(new_val));
550 } else {
551 push(pre_val);
552 }
553 #endif // AARCH64
554
555 if (pre_val != R0) {
556 mov(R0, pre_val);
557 }
558 mov(R1, Rthread);
559
560 call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), R0, R1);
561
562 #ifdef AARCH64
563 if (store_addr != noreg) {
564 raw_pop(store_addr, new_val);
565 } else {
566 raw_pop(pre_val, ZR);
567 }
568 #else
569 if (store_addr != noreg) {
570 pop(RegisterSet(store_addr) | RegisterSet(new_val));
571 } else {
572 pop(pre_val);
573 }
574 #endif // AARCH64
575
576 bind(done);
577 }
578
579 // G1 post-barrier.
580 // Blows all volatile registers (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR).
581 void InterpreterMacroAssembler::g1_write_barrier_post(Register store_addr,
582 Register new_val,
583 Register tmp1,
584 Register tmp2,
585 Register tmp3) {
586
587 Address queue_index(Rthread, in_bytes(JavaThread::dirty_card_queue_offset() +
588 DirtyCardQueue::byte_offset_of_index()));
589 Address buffer(Rthread, in_bytes(JavaThread::dirty_card_queue_offset() +
590 DirtyCardQueue::byte_offset_of_buf()));
591
592 BarrierSet* bs = Universe::heap()->barrier_set();
593 CardTableModRefBS* ct = (CardTableModRefBS*)bs;
594 Label done;
595 Label runtime;
596
597 // Does store cross heap regions?
598
599 eor(tmp1, store_addr, new_val);
600 #ifdef AARCH64
601 logical_shift_right(tmp1, tmp1, HeapRegion::LogOfHRGrainBytes);
602 cbz(tmp1, done);
603 #else
604 movs(tmp1, AsmOperand(tmp1, lsr, HeapRegion::LogOfHRGrainBytes));
605 b(done, eq);
606 #endif
607
608 // crosses regions, storing NULL?
609
610 cbz(new_val, done);
611
612 // storing region crossing non-NULL, is card already dirty?
613 const Register card_addr = tmp1;
614 assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
615
616 mov_address(tmp2, (address)ct->byte_map_base, symbolic_Relocation::card_table_reference);
617 add(card_addr, tmp2, AsmOperand(store_addr, lsr, CardTableModRefBS::card_shift));
618
619 ldrb(tmp2, Address(card_addr));
620 cmp(tmp2, (int)G1SATBCardTableModRefBS::g1_young_card_val());
621 b(done, eq);
622
623 membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreLoad), tmp2);
624
625 assert(CardTableModRefBS::dirty_card_val() == 0, "adjust this code");
626 ldrb(tmp2, Address(card_addr));
627 cbz(tmp2, done);
628
629 // storing a region crossing, non-NULL oop, card is clean.
630 // dirty card and log.
631
632 strb(zero_register(tmp2), Address(card_addr));
633
634 ldr(tmp2, queue_index);
635 ldr(tmp3, buffer);
636
637 subs(tmp2, tmp2, wordSize);
638 b(runtime, lt); // go to runtime if now negative
639
640 str(tmp2, queue_index);
641
642 str(card_addr, Address(tmp3, tmp2));
643 b(done);
644
645 bind(runtime);
646
647 if (card_addr != R0) {
648 mov(R0, card_addr);
649 }
650 mov(R1, Rthread);
651 call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), R0, R1);
652
653 bind(done);
654 }
655
656 #endif // INCLUDE_ALL_GCS
657 //////////////////////////////////////////////////////////////////////////////////
658
659
660 // Java Expression Stack
661
662 void InterpreterMacroAssembler::pop_ptr(Register r) {
663 assert(r != Rstack_top, "unpredictable instruction");
664 ldr(r, Address(Rstack_top, wordSize, post_indexed));
665 }
666
667 void InterpreterMacroAssembler::pop_i(Register r) {
668 assert(r != Rstack_top, "unpredictable instruction");
669 ldr_s32(r, Address(Rstack_top, wordSize, post_indexed));
670 zap_high_non_significant_bits(r);
671 }
672
673 #ifdef AARCH64
674 void InterpreterMacroAssembler::pop_l(Register r) {
675 assert(r != Rstack_top, "unpredictable instruction");
676 ldr(r, Address(Rstack_top, 2*wordSize, post_indexed));
677 }
|