1 /*
 2  * Copyright (c) 2018, 2019, 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  *
23  */
24 
25 #include "precompiled.hpp"
26 #include "asm/macroAssembler.inline.hpp"
27 #include "gc/shared/modRefBarrierSetAssembler.hpp"
28 
29 #define __ masm->
30 
31 void ModRefBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
32                                                    Register src, Register dst, Register count) {
33   bool checkcast = (decorators & ARRAYCOPY_CHECKCAST) != 0;
34   bool disjoint = (decorators & ARRAYCOPY_DISJOINT) != 0;
35   bool obj_int = type == T_OBJECT LP64_ONLY(&& UseCompressedOops);
36 
37   if (is_reference_type(type)) {
38 #ifdef _LP64
39     if (!checkcast) {
40       if (!obj_int) {
41         // Save count for barrier
42         __ movptr(r11, count);
43       } else if (disjoint) {
44         // Save dst in r11 in the disjoint case
45         __ movq(r11, dst);
46       }
47     }
48 #else
49     if (disjoint) {
50       __ mov(rdx, dst);          // save 'to'
51     }
52 #endif
53     gen_write_ref_array_pre_barrier(masm, decorators, dst, count);
54   }
55 }
56 
57 void ModRefBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
58                                                    Register src, Register dst, Register count) {
59   bool checkcast = (decorators & ARRAYCOPY_CHECKCAST) != 0;
60   bool disjoint = (decorators & ARRAYCOPY_DISJOINT) != 0;
61   bool obj_int = type == T_OBJECT LP64_ONLY(&& UseCompressedOops);
62   Register tmp = rax;
63 
64   if (is_reference_type(type)) {
65 #ifdef _LP64
66     if (!checkcast) {
67       if (!obj_int) {
68         // Save count for barrier
69         count = r11;
70       } else if (disjoint) {
71         // Use the saved dst in the disjoint case
72         dst = r11;
73       }
74     } else {
75       tmp = rscratch1;
76     }
77 #else
78     if (disjoint) {
79       __ mov(dst, rdx); // restore 'to'
80     }
81 #endif
82     gen_write_ref_array_post_barrier(masm, decorators, dst, count, tmp);
83   }
84 }
85 
86 void ModRefBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
87                                          Address dst, Register val, Register tmp1, Register tmp2) {
88   if (is_reference_type(type)) {
89     oop_store_at(masm, decorators, type, dst, val, tmp1, tmp2);
90   } else {
91     BarrierSetAssembler::store_at(masm, decorators, type, dst, val, tmp1, tmp2);
92   }
93 }