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 "asm/macroAssembler.inline.hpp"
27 #include "classfile/classLoaderData.hpp"
28 #include "gc/shared/barrierSetAssembler.hpp"
29 #include "gc/shared/barrierSetNMethod.hpp"
30 #include "interpreter/interp_masm.hpp"
31 #include "oops/compressedOops.hpp"
32 #include "runtime/jniHandles.hpp"
33 #include "runtime/sharedRuntime.hpp"
34 #include "runtime/stubRoutines.hpp"
35 #include "utilities/macros.hpp"
36 #ifdef COMPILER2
37 #include "gc/shared/c2/barrierSetC2.hpp"
38 #endif // COMPILER2
39
40 #define __ masm->
41
42 void BarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
43 Register base, RegisterOrConstant ind_or_offs, Register val,
44 Register tmp1, Register tmp2, Register tmp3,
45 MacroAssembler::PreservationLevel preservation_level) {
46 bool in_heap = (decorators & IN_HEAP) != 0;
47 bool in_native = (decorators & IN_NATIVE) != 0;
48 bool not_null = (decorators & IS_NOT_NULL) != 0;
49 assert(in_heap || in_native, "where?");
50 assert_different_registers(base, val, tmp1, tmp2, R0);
51
52 switch (type) {
53 case T_ARRAY:
54 case T_OBJECT: {
55 if (UseCompressedOops && in_heap) {
56 Register co = tmp1;
57 if (val == noreg) {
58 __ li(co, 0);
59 } else {
60 co = not_null ? __ encode_heap_oop_not_null(tmp1, val) : __ encode_heap_oop(tmp1, val);
61 }
62 __ stw(co, ind_or_offs, base, tmp2);
63 } else {
64 if (val == noreg) {
65 val = tmp1;
66 __ li(val, 0);
67 }
68 __ std(val, ind_or_offs, base, tmp2);
69 }
70 break;
71 }
72 default: Unimplemented();
73 }
74 }
75
76 void BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
77 Register base, RegisterOrConstant ind_or_offs, Register dst,
78 Register tmp1, Register tmp2,
79 MacroAssembler::PreservationLevel preservation_level, Label *L_handle_null) {
80 bool in_heap = (decorators & IN_HEAP) != 0;
81 bool in_native = (decorators & IN_NATIVE) != 0;
82 bool not_null = (decorators & IS_NOT_NULL) != 0;
83 assert(in_heap || in_native, "where?");
84 assert_different_registers(ind_or_offs.register_or_noreg(), dst, R0);
96 Register narrowOop = (tmp1 != noreg && CompressedOops::base_disjoint()) ? tmp1 : dst;
97 __ lwz(narrowOop, ind_or_offs, base);
98 __ decode_heap_oop_not_null(dst, narrowOop);
99 } else { // Any oop.
100 __ lwz(dst, ind_or_offs, base);
101 __ decode_heap_oop(dst);
102 }
103 } else {
104 __ ld(dst, ind_or_offs, base);
105 if (L_handle_null != nullptr) {
106 __ cmpdi(CR0, dst, 0);
107 __ beq(CR0, *L_handle_null);
108 }
109 }
110 break;
111 }
112 default: Unimplemented();
113 }
114 }
115
116 // Generic implementation. GCs can provide an optimized one.
117 void BarrierSetAssembler::resolve_jobject(MacroAssembler* masm, Register value,
118 Register tmp1, Register tmp2,
119 MacroAssembler::PreservationLevel preservation_level) {
120 Label done, tagged, weak_tagged, verify;
121 __ cmpdi(CR0, value, 0);
122 __ beq(CR0, done); // Use null as-is.
123
124 __ andi_(tmp1, value, JNIHandles::tag_mask);
125 __ bne(CR0, tagged); // Test for tag.
126
127 __ access_load_at(T_OBJECT, IN_NATIVE | AS_RAW, // no uncoloring
128 value, (intptr_t)0, value, tmp1, tmp2, preservation_level);
129 __ b(verify);
130
131 __ bind(tagged);
132 __ andi_(tmp1, value, JNIHandles::TypeTag::weak_global);
133 __ clrrdi(value, value, JNIHandles::tag_size); // Untag.
134 __ bne(CR0, weak_tagged); // Test for jweak tag.
135
|
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 "asm/macroAssembler.inline.hpp"
27 #include "classfile/classLoaderData.hpp"
28 #include "gc/shared/barrierSetAssembler.hpp"
29 #include "gc/shared/barrierSetNMethod.hpp"
30 #include "gc/shared/barrierSetRuntime.hpp"
31 #include "interpreter/interp_masm.hpp"
32 #include "oops/compressedOops.hpp"
33 #include "runtime/jniHandles.hpp"
34 #include "runtime/sharedRuntime.hpp"
35 #include "runtime/stubRoutines.hpp"
36 #include "utilities/macros.hpp"
37 #ifdef COMPILER2
38 #include "gc/shared/c2/barrierSetC2.hpp"
39 #endif // COMPILER2
40
41 #define __ masm->
42
43 void BarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
44 Register base, RegisterOrConstant ind_or_offs, Register val,
45 Register tmp1, Register tmp2, Register tmp3,
46 MacroAssembler::PreservationLevel preservation_level) {
47 bool in_heap = (decorators & IN_HEAP) != 0;
48 bool in_native = (decorators & IN_NATIVE) != 0;
49 bool not_null = (decorators & IS_NOT_NULL) != 0;
50 assert(in_heap || in_native, "where?");
51 assert_different_registers(base, val, tmp1, tmp2, R0);
52
53 switch (type) {
54 case T_ARRAY:
55 case T_OBJECT: {
56 if (UseCompressedOops && in_heap) {
57 Register co = tmp1;
58 if (val == noreg) {
59 assert(!not_null, "inconsistent access");
60 __ li(co, 0);
61 } else {
62 co = not_null ? __ encode_heap_oop_not_null(tmp1, val) : __ encode_heap_oop(tmp1, val);
63 }
64 __ stw(co, ind_or_offs, base, tmp2);
65 } else {
66 if (val == noreg) {
67 assert(!not_null, "inconsistent access");
68 val = tmp1;
69 __ li(val, 0);
70 }
71 __ std(val, ind_or_offs, base, tmp2);
72 }
73 break;
74 }
75 default: Unimplemented();
76 }
77 }
78
79 void BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
80 Register base, RegisterOrConstant ind_or_offs, Register dst,
81 Register tmp1, Register tmp2,
82 MacroAssembler::PreservationLevel preservation_level, Label *L_handle_null) {
83 bool in_heap = (decorators & IN_HEAP) != 0;
84 bool in_native = (decorators & IN_NATIVE) != 0;
85 bool not_null = (decorators & IS_NOT_NULL) != 0;
86 assert(in_heap || in_native, "where?");
87 assert_different_registers(ind_or_offs.register_or_noreg(), dst, R0);
99 Register narrowOop = (tmp1 != noreg && CompressedOops::base_disjoint()) ? tmp1 : dst;
100 __ lwz(narrowOop, ind_or_offs, base);
101 __ decode_heap_oop_not_null(dst, narrowOop);
102 } else { // Any oop.
103 __ lwz(dst, ind_or_offs, base);
104 __ decode_heap_oop(dst);
105 }
106 } else {
107 __ ld(dst, ind_or_offs, base);
108 if (L_handle_null != nullptr) {
109 __ cmpdi(CR0, dst, 0);
110 __ beq(CR0, *L_handle_null);
111 }
112 }
113 break;
114 }
115 default: Unimplemented();
116 }
117 }
118
119 void BarrierSetAssembler::flat_field_copy(MacroAssembler* masm, DecoratorSet decorators,
120 Register src, Register dst, Register inline_layout_info) {
121 // flat_field_copy implementation is fairly complex, and there are not any
122 // "short-cuts" to be made from asm. What there is, appears to have the same
123 // cost in C++, so just "call_VM_leaf" for now rather than maintain hundreds
124 // of hand-rolled instructions...
125 if (decorators & IS_DEST_UNINITIALIZED) {
126 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSetRuntime::value_copy_is_dest_uninitialized), src, dst, inline_layout_info);
127 } else {
128 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSetRuntime::value_copy), src, dst, inline_layout_info);
129 }
130 }
131
132 // Generic implementation. GCs can provide an optimized one.
133 void BarrierSetAssembler::resolve_jobject(MacroAssembler* masm, Register value,
134 Register tmp1, Register tmp2,
135 MacroAssembler::PreservationLevel preservation_level) {
136 Label done, tagged, weak_tagged, verify;
137 __ cmpdi(CR0, value, 0);
138 __ beq(CR0, done); // Use null as-is.
139
140 __ andi_(tmp1, value, JNIHandles::tag_mask);
141 __ bne(CR0, tagged); // Test for tag.
142
143 __ access_load_at(T_OBJECT, IN_NATIVE | AS_RAW, // no uncoloring
144 value, (intptr_t)0, value, tmp1, tmp2, preservation_level);
145 __ b(verify);
146
147 __ bind(tagged);
148 __ andi_(tmp1, value, JNIHandles::TypeTag::weak_global);
149 __ clrrdi(value, value, JNIHandles::tag_size); // Untag.
150 __ bne(CR0, weak_tagged); // Test for jweak tag.
151
|