1 /*
2  * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
3  * Copyright (c) 2018, SAP SE. 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  *
24  */
25 
26 #include "precompiled.hpp"
27 #include "asm/macroAssembler.inline.hpp"
28 #include "gc/shared/barrierSetAssembler.hpp"
29 #include "interpreter/interp_masm.hpp"
30 
31 #define __ masm->
32 
arraycopy_epilogue(MacroAssembler * masm,DecoratorSet decorators,BasicType type,Register dst,Register count,bool do_return)33 void BarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
34                                              Register dst, Register count, bool do_return) {
35   if (do_return) { __ z_br(Z_R14); }
36 }
37 
load_at(MacroAssembler * masm,DecoratorSet decorators,BasicType type,const Address & addr,Register dst,Register tmp1,Register tmp2,Label * L_handle_null)38 void BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
39                                   const Address& addr, Register dst, Register tmp1, Register tmp2, Label *L_handle_null) {
40   bool in_heap = (decorators & IN_HEAP) != 0;
41   bool in_native = (decorators & IN_NATIVE) != 0;
42   bool not_null = (decorators & IS_NOT_NULL) != 0;
43   assert(in_heap || in_native, "where?");
44 
45   switch (type) {
46   case T_ARRAY:
47   case T_OBJECT: {
48     if (UseCompressedOops && in_heap) {
49       __ z_llgf(dst, addr);
50       if (L_handle_null != NULL) { // Label provided.
51         __ compareU32_and_branch(dst, (intptr_t)0, Assembler::bcondEqual, *L_handle_null);
52         __ oop_decoder(dst, dst, false);
53       } else {
54         __ oop_decoder(dst, dst, !not_null);
55       }
56     } else {
57       __ z_lg(dst, addr);
58       if (L_handle_null != NULL) {
59         __ compareU64_and_branch(dst, (intptr_t)0, Assembler::bcondEqual, *L_handle_null);
60       }
61     }
62     break;
63   }
64   default: Unimplemented();
65   }
66 }
67 
store_at(MacroAssembler * masm,DecoratorSet decorators,BasicType type,const Address & addr,Register val,Register tmp1,Register tmp2,Register tmp3)68 void BarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
69                                    const Address& addr, Register val, Register tmp1, Register tmp2, Register tmp3) {
70   bool in_heap = (decorators & IN_HEAP) != 0;
71   bool in_native = (decorators & IN_NATIVE) != 0;
72   bool not_null = (decorators & IS_NOT_NULL) != 0;
73   assert(in_heap || in_native, "where?");
74   assert_different_registers(val, tmp1, tmp2);
75 
76   switch (type) {
77   case T_ARRAY:
78   case T_OBJECT: {
79     if (UseCompressedOops && in_heap) {
80       if (val == noreg) {
81         __ clear_mem(addr, 4);
82       } else if (Universe::narrow_oop_mode() == Universe::UnscaledNarrowOop) {
83         __ z_st(val, addr);
84       } else {
85         Register tmp = (tmp1 != Z_R1) ? tmp1 : tmp2; // Avoid tmp == Z_R1 (see oop_encoder).
86         __ oop_encoder(tmp, val, !not_null);
87         __ z_st(tmp, addr);
88       }
89     } else {
90       if (val == noreg) {
91         __ clear_mem(addr, 8);
92       } else {
93         __ z_stg(val, addr);
94       }
95     }
96     break;
97   }
98   default: Unimplemented();
99   }
100 }
101 
resolve_jobject(MacroAssembler * masm,Register value,Register tmp1,Register tmp2)102 void BarrierSetAssembler::resolve_jobject(MacroAssembler* masm, Register value, Register tmp1, Register tmp2) {
103   NearLabel Ldone;
104   __ z_ltgr(tmp1, value);
105   __ z_bre(Ldone);          // Use NULL result as-is.
106 
107   __ z_nill(value, ~JNIHandles::weak_tag_mask);
108   __ z_lg(value, 0, value); // Resolve (untagged) jobject.
109 
110   __ verify_oop(value);
111   __ bind(Ldone);
112 }
113