1 /*
2 * Copyright (c) 2018, 2020, Red Hat, Inc. All rights reserved.
3 * Copyright (c) 2020, 2021, Huawei Technologies Co., Ltd. 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 *
47 void ShenandoahBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop,
48 Register src, Register dst, Register count, RegSet saved_regs) {
49 if (is_oop) {
50 bool dest_uninitialized = (decorators & IS_DEST_UNINITIALIZED) != 0;
51 if ((ShenandoahSATBBarrier && !dest_uninitialized) || ShenandoahIUBarrier || ShenandoahLoadRefBarrier) {
52
53 Label done;
54
55 // Avoid calling runtime if count == 0
56 __ beqz(count, done);
57
58 // Is GC active?
59 Address gc_state(xthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
60 assert_different_registers(src, dst, count, t0);
61
62 __ lbu(t0, gc_state);
63 if (ShenandoahSATBBarrier && dest_uninitialized) {
64 __ test_bit(t0, t0, ShenandoahHeap::HAS_FORWARDED_BITPOS);
65 __ beqz(t0, done);
66 } else {
67 __ andi(t0, t0, ShenandoahHeap::HAS_FORWARDED | ShenandoahHeap::MARKING);
68 __ beqz(t0, done);
69 }
70
71 __ push_reg(saved_regs, sp);
72 if (UseCompressedOops) {
73 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::arraycopy_barrier_narrow_oop_entry),
74 src, dst, count);
75 } else {
76 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::arraycopy_barrier_oop_entry), src, dst, count);
77 }
78 __ pop_reg(saved_regs, sp);
79 __ bind(done);
80 }
81 }
82 }
83
84 void ShenandoahBarrierSetAssembler::shenandoah_write_barrier_pre(MacroAssembler* masm,
85 Register obj,
86 Register pre_val,
87 Register thread,
625 void ShenandoahBarrierSetAssembler::generate_c1_pre_barrier_runtime_stub(StubAssembler* sasm) {
626 __ prologue("shenandoah_pre_barrier", false);
627
628 // arg0 : previous value of memory
629
630 BarrierSet* bs = BarrierSet::barrier_set();
631
632 const Register pre_val = x10;
633 const Register thread = xthread;
634 const Register tmp = t0;
635
636 Address queue_index(thread, in_bytes(ShenandoahThreadLocalData::satb_mark_queue_index_offset()));
637 Address buffer(thread, in_bytes(ShenandoahThreadLocalData::satb_mark_queue_buffer_offset()));
638
639 Label done;
640 Label runtime;
641
642 // Is marking still active?
643 Address gc_state(thread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
644 __ lb(tmp, gc_state);
645 __ test_bit(tmp, tmp, ShenandoahHeap::MARKING_BITPOS);
646 __ beqz(tmp, done);
647
648 // Can we store original value in the thread's buffer?
649 __ ld(tmp, queue_index);
650 __ beqz(tmp, runtime);
651
652 __ sub(tmp, tmp, wordSize);
653 __ sd(tmp, queue_index);
654 __ ld(t1, buffer);
655 __ add(tmp, tmp, t1);
656 __ load_parameter(0, t1);
657 __ sd(t1, Address(tmp, 0));
658 __ j(done);
659
660 __ bind(runtime);
661 __ push_call_clobbered_registers();
662 __ load_parameter(0, pre_val);
663 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_field_pre_entry), pre_val, thread);
664 __ pop_call_clobbered_registers();
665 __ bind(done);
|
1 /*
2 * Copyright (c) 2018, 2020, Red Hat, Inc. All rights reserved.
3 * Copyright (c) 2020, 2021, Huawei Technologies Co., Ltd. All rights reserved.
4 * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
5 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 *
7 * This code is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 only, as
9 * published by the Free Software Foundation.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 *
48 void ShenandoahBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop,
49 Register src, Register dst, Register count, RegSet saved_regs) {
50 if (is_oop) {
51 bool dest_uninitialized = (decorators & IS_DEST_UNINITIALIZED) != 0;
52 if ((ShenandoahSATBBarrier && !dest_uninitialized) || ShenandoahIUBarrier || ShenandoahLoadRefBarrier) {
53
54 Label done;
55
56 // Avoid calling runtime if count == 0
57 __ beqz(count, done);
58
59 // Is GC active?
60 Address gc_state(xthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
61 assert_different_registers(src, dst, count, t0);
62
63 __ lbu(t0, gc_state);
64 if (ShenandoahSATBBarrier && dest_uninitialized) {
65 __ test_bit(t0, t0, ShenandoahHeap::HAS_FORWARDED_BITPOS);
66 __ beqz(t0, done);
67 } else {
68 __ andi(t0, t0, ShenandoahHeap::HAS_FORWARDED | ShenandoahHeap::YOUNG_MARKING | ShenandoahHeap::OLD_MARKING);
69 __ beqz(t0, done);
70 }
71
72 __ push_reg(saved_regs, sp);
73 if (UseCompressedOops) {
74 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::arraycopy_barrier_narrow_oop_entry),
75 src, dst, count);
76 } else {
77 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::arraycopy_barrier_oop_entry), src, dst, count);
78 }
79 __ pop_reg(saved_regs, sp);
80 __ bind(done);
81 }
82 }
83 }
84
85 void ShenandoahBarrierSetAssembler::shenandoah_write_barrier_pre(MacroAssembler* masm,
86 Register obj,
87 Register pre_val,
88 Register thread,
626 void ShenandoahBarrierSetAssembler::generate_c1_pre_barrier_runtime_stub(StubAssembler* sasm) {
627 __ prologue("shenandoah_pre_barrier", false);
628
629 // arg0 : previous value of memory
630
631 BarrierSet* bs = BarrierSet::barrier_set();
632
633 const Register pre_val = x10;
634 const Register thread = xthread;
635 const Register tmp = t0;
636
637 Address queue_index(thread, in_bytes(ShenandoahThreadLocalData::satb_mark_queue_index_offset()));
638 Address buffer(thread, in_bytes(ShenandoahThreadLocalData::satb_mark_queue_buffer_offset()));
639
640 Label done;
641 Label runtime;
642
643 // Is marking still active?
644 Address gc_state(thread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
645 __ lb(tmp, gc_state);
646 __ andi(tmp, tmp, ShenandoahHeap::YOUNG_MARKING | ShenandoahHeap::OLD_MARKING);
647 __ beqz(tmp, done);
648
649 // Can we store original value in the thread's buffer?
650 __ ld(tmp, queue_index);
651 __ beqz(tmp, runtime);
652
653 __ sub(tmp, tmp, wordSize);
654 __ sd(tmp, queue_index);
655 __ ld(t1, buffer);
656 __ add(tmp, tmp, t1);
657 __ load_parameter(0, t1);
658 __ sd(t1, Address(tmp, 0));
659 __ j(done);
660
661 __ bind(runtime);
662 __ push_call_clobbered_registers();
663 __ load_parameter(0, pre_val);
664 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_field_pre_entry), pre_val, thread);
665 __ pop_call_clobbered_registers();
666 __ bind(done);
|