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/g1/g1BarrierSet.hpp"
28 #include "gc/g1/g1CardTable.hpp"
29 #include "gc/g1/g1BSCodeGen.hpp"
30 #include "gc/g1/heapRegion.hpp"
31 #include "gc/shared/collectedHeap.hpp"
32 #include "runtime/thread.hpp"
33 #include "interpreter/interp_masm.hpp"
34 
35 #define __ masm->
36 
37 void G1BSCodeGen::gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators,
38                                                   Register addr, Register count, RegSet saved_regs) {
39   bool dest_uninitialized = (decorators & AS_DEST_NOT_INITIALIZED) != 0;
40   if (!dest_uninitialized) {
41     __ push(saved_regs, sp);
42     if (count == c_rarg0) {
43       if (addr == c_rarg1) {
44         // exactly backwards!!
45         __ mov(rscratch1, c_rarg0);
46         __ mov(c_rarg0, c_rarg1);
47         __ mov(c_rarg1, rscratch1);
48       } else {
49         __ mov(c_rarg1, count);
50         __ mov(c_rarg0, addr);
51       }
52     } else {
53       __ mov(c_rarg0, addr);
54       __ mov(c_rarg1, count);
55     }
56     if (UseCompressedOops) {
57       __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSet::write_ref_array_pre_narrow_oop_entry), 2);
58     } else {
59       __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSet::write_ref_array_pre_oop_entry), 2);
60     }
61     __ pop(saved_regs, sp);
62   }
63 }
64 
65 void G1BSCodeGen::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators,
66                                                    Register start, Register end, Register scratch, RegSet saved_regs) {
67   __ push(saved_regs, sp);
68   // must compute element count unless barrier set interface is changed (other platforms supply count)
69   assert_different_registers(start, end, scratch);
70   __ lea(scratch, Address(end, BytesPerHeapOop));
71   __ sub(scratch, scratch, start);               // subtract start to get #bytes
72   __ lsr(scratch, scratch, LogBytesPerHeapOop);  // convert to element count
73   __ mov(c_rarg0, start);
74   __ mov(c_rarg1, scratch);
75   __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSet::write_ref_array_post_entry), 2);
76   __ pop(saved_regs, sp);
77 }