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