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 "classfile/classLoaderData.hpp"
26 #include "gc/shared/barrierSet.hpp"
27 #include "gc/shared/barrierSetAssembler.hpp"
28 #include "gc/shared/barrierSetNMethod.hpp"
29 #include "gc/shared/collectedHeap.hpp"
30 #include "interpreter/interp_masm.hpp"
31 #include "memory/universe.hpp"
32 #include "runtime/javaThread.hpp"
33 #include "runtime/jniHandles.hpp"
34 #include "runtime/sharedRuntime.hpp"
35 #include "runtime/stubRoutines.hpp"
36 #ifdef COMPILER2
37 #include "code/vmreg.inline.hpp"
38 #include "gc/shared/c2/barrierSetC2.hpp"
39 #endif // COMPILER2
40
41
42 #define __ masm->
43
44 void BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
45 Register dst, Address src, Register tmp1, Register tmp2) {
46
47 // LR is live. It must be saved around calls.
48
49 bool in_heap = (decorators & IN_HEAP) != 0;
50 bool in_native = (decorators & IN_NATIVE) != 0;
51 bool is_not_null = (decorators & IS_NOT_NULL) != 0;
52 switch (type) {
53 case T_OBJECT:
54 case T_ARRAY: {
55 if (in_heap) {
56 if (UseCompressedOops) {
57 __ ldrw(dst, src);
58 if (is_not_null) {
59 __ decode_heap_oop_not_null(dst);
60 } else {
61 __ decode_heap_oop(dst);
62 }
63 } else {
64 __ ldr(dst, src);
65 }
66 } else {
67 assert(in_native, "why else?");
68 __ ldr(dst, src);
69 }
70 break;
71 }
72 case T_BOOLEAN: __ load_unsigned_byte (dst, src); break;
73 case T_BYTE: __ load_signed_byte (dst, src); break;
74 case T_CHAR: __ load_unsigned_short(dst, src); break;
75 case T_SHORT: __ load_signed_short (dst, src); break;
76 case T_INT: __ ldrw (dst, src); break;
77 case T_LONG: __ ldr (dst, src); break;
78 case T_ADDRESS: __ ldr (dst, src); break;
79 case T_FLOAT: __ ldrs (v0, src); break;
80 case T_DOUBLE: __ ldrd (v0, src); break;
81 default: Unimplemented();
82 }
83 }
84
85 void BarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
86 Address dst, Register val, Register tmp1, Register tmp2, Register tmp3) {
87 bool in_heap = (decorators & IN_HEAP) != 0;
88 bool in_native = (decorators & IN_NATIVE) != 0;
89 switch (type) {
90 case T_OBJECT:
91 case T_ARRAY: {
92 val = val == noreg ? zr : val;
93 if (in_heap) {
94 if (UseCompressedOops) {
95 assert(!dst.uses(val), "not enough registers");
96 if (val != zr) {
97 __ encode_heap_oop(val);
98 }
99 __ strw(val, dst);
100 } else {
101 __ str(val, dst);
102 }
103 } else {
104 assert(in_native, "why else?");
105 __ str(val, dst);
106 }
107 break;
108 }
109 case T_BOOLEAN:
110 __ andw(val, val, 0x1); // boolean is true if LSB is 1
111 __ strb(val, dst);
112 break;
113 case T_BYTE: __ strb(val, dst); break;
114 case T_CHAR: __ strh(val, dst); break;
115 case T_SHORT: __ strh(val, dst); break;
116 case T_INT: __ strw(val, dst); break;
117 case T_LONG: __ str (val, dst); break;
118 case T_ADDRESS: __ str (val, dst); break;
119 case T_FLOAT: __ strs(v0, dst); break;
120 case T_DOUBLE: __ strd(v0, dst); break;
121 default: Unimplemented();
122 }
123 }
124
125 void BarrierSetAssembler::copy_load_at(MacroAssembler* masm,
126 DecoratorSet decorators,
127 BasicType type,
128 size_t bytes,
129 Register dst1,
130 Register dst2,
131 Address src,
132 Register tmp) {
133 if (bytes == 1) {
134 assert(dst2 == noreg, "invariant");
135 __ ldrb(dst1, src);
136 } else if (bytes == 2) {
137 assert(dst2 == noreg, "invariant");
138 __ ldrh(dst1, src);
139 } else if (bytes == 4) {
140 assert(dst2 == noreg, "invariant");
141 __ ldrw(dst1, src);
142 } else if (bytes == 8) {
143 assert(dst2 == noreg, "invariant");
144 __ ldr(dst1, src);
|
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 "classfile/classLoaderData.hpp"
26 #include "gc/shared/barrierSet.hpp"
27 #include "gc/shared/barrierSetAssembler.hpp"
28 #include "gc/shared/barrierSetNMethod.hpp"
29 #include "gc/shared/barrierSetRuntime.hpp"
30 #include "gc/shared/collectedHeap.hpp"
31 #include "interpreter/interp_masm.hpp"
32 #include "memory/universe.hpp"
33 #include "runtime/javaThread.hpp"
34 #include "runtime/jniHandles.hpp"
35 #include "runtime/sharedRuntime.hpp"
36 #include "runtime/stubRoutines.hpp"
37 #ifdef COMPILER2
38 #include "code/vmreg.inline.hpp"
39 #include "gc/shared/c2/barrierSetC2.hpp"
40 #endif // COMPILER2
41
42
43 #define __ masm->
44
45 void BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
46 Register dst, Address src, Register tmp1, Register tmp2) {
47
48 // LR is live. It must be saved around calls.
49
50 bool in_heap = (decorators & IN_HEAP) != 0;
51 bool in_native = (decorators & IN_NATIVE) != 0;
52 bool is_not_null = (decorators & IS_NOT_NULL) != 0;
53
54 switch (type) {
55 case T_OBJECT:
56 case T_ARRAY: {
57 if (in_heap) {
58 if (UseCompressedOops) {
59 __ ldrw(dst, src);
60 if (is_not_null) {
61 __ decode_heap_oop_not_null(dst);
62 } else {
63 __ decode_heap_oop(dst);
64 }
65 } else {
66 __ ldr(dst, src);
67 }
68 } else {
69 assert(in_native, "why else?");
70 __ ldr(dst, src);
71 }
72 break;
73 }
74 case T_BOOLEAN: __ load_unsigned_byte (dst, src); break;
75 case T_BYTE: __ load_signed_byte (dst, src); break;
76 case T_CHAR: __ load_unsigned_short(dst, src); break;
77 case T_SHORT: __ load_signed_short (dst, src); break;
78 case T_INT: __ ldrw (dst, src); break;
79 case T_LONG: __ ldr (dst, src); break;
80 case T_ADDRESS: __ ldr (dst, src); break;
81 case T_FLOAT: __ ldrs (v0, src); break;
82 case T_DOUBLE: __ ldrd (v0, src); break;
83 default: Unimplemented();
84 }
85 }
86
87 void BarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
88 Address dst, Register val, Register tmp1, Register tmp2, Register tmp3) {
89 bool in_heap = (decorators & IN_HEAP) != 0;
90 bool in_native = (decorators & IN_NATIVE) != 0;
91 bool is_not_null = (decorators & IS_NOT_NULL) != 0;
92
93 switch (type) {
94 case T_OBJECT:
95 case T_ARRAY: {
96 if (in_heap) {
97 if (val == noreg) {
98 assert(!is_not_null, "inconsistent access");
99 if (UseCompressedOops) {
100 __ strw(zr, dst);
101 } else {
102 __ str(zr, dst);
103 }
104 } else {
105 if (UseCompressedOops) {
106 assert(!dst.uses(val), "not enough registers");
107 if (is_not_null) {
108 __ encode_heap_oop_not_null(val);
109 } else {
110 __ encode_heap_oop(val);
111 }
112 __ strw(val, dst);
113 } else {
114 __ str(val, dst);
115 }
116 }
117 } else {
118 assert(in_native, "why else?");
119 assert(val != noreg, "not supported");
120 __ str(val, dst);
121 }
122 break;
123 }
124 case T_BOOLEAN:
125 __ andw(val, val, 0x1); // boolean is true if LSB is 1
126 __ strb(val, dst);
127 break;
128 case T_BYTE: __ strb(val, dst); break;
129 case T_CHAR: __ strh(val, dst); break;
130 case T_SHORT: __ strh(val, dst); break;
131 case T_INT: __ strw(val, dst); break;
132 case T_LONG: __ str (val, dst); break;
133 case T_ADDRESS: __ str (val, dst); break;
134 case T_FLOAT: __ strs(v0, dst); break;
135 case T_DOUBLE: __ strd(v0, dst); break;
136 default: Unimplemented();
137 }
138 }
139
140 void BarrierSetAssembler::flat_field_copy(MacroAssembler* masm, DecoratorSet decorators,
141 Register src, Register dst, Register inline_layout_info) {
142 // flat_field_copy implementation is fairly complex, and there are not any
143 // "short-cuts" to be made from asm. What there is, appears to have the same
144 // cost in C++, so just "call_VM_leaf" for now rather than maintain hundreds
145 // of hand-rolled instructions...
146 if (decorators & IS_DEST_UNINITIALIZED) {
147 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSetRuntime::value_copy_is_dest_uninitialized), src, dst, inline_layout_info);
148 } else {
149 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSetRuntime::value_copy), src, dst, inline_layout_info);
150 }
151 }
152
153 void BarrierSetAssembler::copy_load_at(MacroAssembler* masm,
154 DecoratorSet decorators,
155 BasicType type,
156 size_t bytes,
157 Register dst1,
158 Register dst2,
159 Address src,
160 Register tmp) {
161 if (bytes == 1) {
162 assert(dst2 == noreg, "invariant");
163 __ ldrb(dst1, src);
164 } else if (bytes == 2) {
165 assert(dst2 == noreg, "invariant");
166 __ ldrh(dst1, src);
167 } else if (bytes == 4) {
168 assert(dst2 == noreg, "invariant");
169 __ ldrw(dst1, src);
170 } else if (bytes == 8) {
171 assert(dst2 == noreg, "invariant");
172 __ ldr(dst1, src);
|