1/*
2 * Copyright (c) 2018, 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
31void 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 (type == T_OBJECT || type == T_ARRAY) {
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
57void 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 (type == T_OBJECT || type == T_ARRAY) {
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
86void ModRefBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
87 Address dst, Register val, Register tmp1, Register tmp2) {
88 if (type == T_OBJECT || type == T_ARRAY) {
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}
94