1 // 2 // Copyright (c) 2018, Red Hat, Inc. 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 source %{ 26 #include "gc/shenandoah/shenandoahBarrierSet.hpp" 27 #include "gc/shenandoah/shenandoahBarrierSetAssembler_x86.hpp" 28 #include "gc/shenandoah/c2/shenandoahBarrierSetC2.hpp" 29 %} 30 31 instruct storeP_shenandoah(memory mem, any_RegP src, rRegP tmp, rFlagsReg cr) 32 %{ 33 match(Set mem (StoreP mem src)); 34 predicate(UseShenandoahGC && n->as_Store()->barrier_data() != 0); 35 effect(TEMP tmp, KILL cr); 36 ins_cost(125); // XXX 37 format %{ "movq $mem, $src\t# ptr" %} 38 ins_encode %{ 39 ShenandoahBarrierSet::assembler()->store_c2(this, masm, 40 $mem$$Address, /* dst_narrow = */ false, 41 $src$$Register, /* src_narrow = */ false, 42 $tmp$$Register); 43 %} 44 ins_pipe(ialu_mem_reg); 45 %} 46 47 instruct storeN_shenandoah(memory mem, rRegN src, rRegP tmp, rFlagsReg cr) 48 %{ 49 match(Set mem (StoreN mem src)); 50 predicate(UseShenandoahGC && n->as_Store()->barrier_data() != 0); 51 effect(TEMP tmp, KILL cr); 52 ins_cost(125); // XXX 53 format %{ "movl $mem, $src\t# ptr" %} 54 ins_encode %{ 55 ShenandoahBarrierSet::assembler()->store_c2(this, masm, 56 $mem$$Address, /* dst_narrow = */ true, 57 $src$$Register, /* src_narrow = */ true, 58 $tmp$$Register); 59 %} 60 ins_pipe(ialu_mem_reg); 61 %} 62 63 instruct encodePAndStoreN_shenandoah(memory mem, any_RegP src, rRegP tmp, rFlagsReg cr) 64 %{ 65 match(Set mem (StoreN mem (EncodeP src))); 66 predicate(UseShenandoahGC && n->as_Store()->barrier_data() != 0); 67 effect(TEMP tmp, KILL cr); 68 ins_cost(125); // XXX 69 format %{ "encode_heap_oop $src\n\t" 70 "movl $mem, $src\t# ptr" %} 71 ins_encode %{ 72 ShenandoahBarrierSet::assembler()->store_c2(this, masm, 73 $mem$$Address, /* dst_narrow = */ true, 74 $src$$Register, /* src_narrow = */ false, 75 $tmp$$Register); 76 %} 77 ins_pipe(ialu_mem_reg); 78 %} 79 80 instruct compareAndSwapP_shenandoah(rRegI res, 81 indirect mem, 82 rRegP tmp1, rRegP tmp2, 83 rax_RegP oldval, rRegP newval, 84 rFlagsReg cr) 85 %{ 86 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 87 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 88 predicate(UseShenandoahGC && n->as_LoadStore()->barrier_data() != 0); 89 effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr, KILL oldval); 90 91 format %{ "shenandoah_cas_oop $mem,$newval" %} 92 93 ins_encode %{ 94 guarantee(!UseCompressedOops, "must not be compressed oops"); 95 if (ShenandoahSATBBarrierStubC2::needs_barrier(this)) { 96 __ movptr($tmp1$$Register, $oldval$$Register); 97 ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm, 98 noreg /* addr */, 99 $tmp1$$Register /* pre_val */, 100 $tmp2$$Register /* tmp */); 101 } 102 ShenandoahBarrierSet::assembler()->cmpxchg_oop_c2(this, masm, 103 $res$$Register, $mem$$Address, $oldval$$Register, $newval$$Register, $tmp1$$Register, $tmp2$$Register, 104 /*exchange*/ false); 105 ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm, 106 $mem$$Register /* addr */, 107 $tmp1$$Register /* addr_tmp */, 108 $tmp2$$Register /* tmp */); 109 %} 110 ins_pipe( pipe_cmpxchg ); 111 %} 112 113 instruct compareAndSwapN_shenandoah(rRegI res, 114 indirect mem, 115 rRegP tmp1, rRegP tmp2, 116 rax_RegN oldval, rRegN newval, 117 rFlagsReg cr) %{ 118 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 119 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 120 predicate(UseShenandoahGC && n->as_LoadStore()->barrier_data() != 0); 121 effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr, KILL oldval); 122 123 format %{ "shenandoah_cas_oop $mem,$newval" %} 124 125 ins_encode %{ 126 guarantee(UseCompressedOops, "must be compressed oops"); 127 if (ShenandoahSATBBarrierStubC2::needs_barrier(this)) { 128 __ movl($tmp1$$Register, $oldval$$Register); 129 __ decode_heap_oop($tmp1$$Register); 130 ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm, 131 noreg /* addr */, 132 $tmp1$$Register /* pre_val */, 133 $tmp2$$Register /* tmp */); 134 } 135 ShenandoahBarrierSet::assembler()->cmpxchg_oop_c2(this, masm, 136 $res$$Register, $mem$$Address, $oldval$$Register, $newval$$Register, $tmp1$$Register, $tmp2$$Register, 137 /*exchange*/ false); 138 ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm, 139 $mem$$Register /* addr */, 140 $tmp1$$Register /* addr_tmp */, 141 $tmp2$$Register /* tmp */); 142 %} 143 ins_pipe( pipe_cmpxchg ); 144 %} 145 146 instruct compareAndExchangeN_shenandoah(indirect mem, 147 rax_RegN oldval, rRegN newval, 148 rRegP tmp1, rRegP tmp2, rRegP tmp3, 149 rFlagsReg cr) %{ 150 match(Set oldval (CompareAndExchangeN mem (Binary oldval newval))); 151 predicate(UseShenandoahGC && n->as_LoadStore()->barrier_data() != 0); 152 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 153 154 format %{ "shenandoah_cas_oop $mem,$newval" %} 155 156 ins_encode %{ 157 guarantee(UseCompressedOops, "must be compressed oops"); 158 if (ShenandoahSATBBarrierStubC2::needs_barrier(this)) { 159 __ movl($tmp1$$Register, $oldval$$Register); 160 __ decode_heap_oop($tmp1$$Register); 161 ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm, 162 noreg /* addr */, 163 $tmp1$$Register /* pre_val */, 164 $tmp2$$Register /* tmp */); 165 } 166 ShenandoahBarrierSet::assembler()->cmpxchg_oop_c2(this, masm, 167 noreg, $mem$$Address, $oldval$$Register, $newval$$Register, $tmp1$$Register, $tmp2$$Register, 168 /*exchange*/ true); 169 ShenandoahBarrierSet::assembler()->load_ref_barrier_c2(this, masm, 170 $oldval$$Register /* obj */, 171 $mem$$Register /* addr */, 172 $tmp1$$Register /* tmp1 */, 173 $tmp2$$Register /* tmp2 */, 174 $tmp3$$Register /* tmp3 */, 175 true /* narrow */); 176 ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm, 177 $mem$$Register /* addr */, 178 $tmp1$$Register /* addr_tmp */, 179 $tmp2$$Register /* tmp */); 180 %} 181 ins_pipe( pipe_cmpxchg ); 182 %} 183 184 instruct compareAndExchangeP_shenandoah(indirect mem, 185 rax_RegP oldval, rRegP newval, 186 rRegP tmp1, rRegP tmp2, 187 rFlagsReg cr) 188 %{ 189 match(Set oldval (CompareAndExchangeP mem (Binary oldval newval))); 190 predicate(UseShenandoahGC && n->as_LoadStore()->barrier_data() != 0); 191 effect(KILL cr, TEMP tmp1, TEMP tmp2); 192 ins_cost(1000); 193 194 format %{ "shenandoah_cas_oop $mem,$newval" %} 195 196 ins_encode %{ 197 ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm, 198 noreg /* addr */, 199 $oldval$$Register /* pre_val */, 200 $tmp2$$Register /* tmp */); 201 ShenandoahBarrierSet::assembler()->cmpxchg_oop_c2(this, masm, 202 noreg, $mem$$Address, $oldval$$Register, $newval$$Register, $tmp1$$Register, $tmp2$$Register, 203 /*exchange*/ true); 204 ShenandoahBarrierSet::assembler()->load_ref_barrier_c2(this, masm, 205 $oldval$$Register /* obj */, 206 $mem$$Register /* addr */, 207 noreg /* tmp1 */, 208 $tmp1$$Register /* tmp2 */, 209 $tmp2$$Register /* tmp3 */, 210 false /* narrow */); 211 ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm, 212 $mem$$Register /* addr */, 213 $tmp1$$Register /* addr_tmp */, 214 $tmp2$$Register /* tmp */); 215 %} 216 ins_pipe( pipe_cmpxchg ); 217 %} 218 219 instruct getAndSetP_shenandoah(indirect mem, rRegP newval, rRegP tmp1, rRegP tmp2, rFlagsReg cr) 220 %{ 221 match(Set newval (GetAndSetP mem newval)); 222 predicate(UseShenandoahGC && n->as_LoadStore()->barrier_data() != 0); 223 effect(TEMP tmp1, TEMP tmp2, KILL cr); 224 format %{ "xchgq $newval, $mem" %} 225 ins_encode %{ 226 assert_different_registers($mem$$Register, $newval$$Register); 227 __ xchgq($newval$$Register, Address($mem$$Register, 0)); 228 ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm, 229 noreg /* addr */, 230 $newval$$Register /* pre_val */, 231 $tmp1$$Register /* tmp */); 232 ShenandoahBarrierSet::assembler()->load_ref_barrier_c2(this, masm, 233 $newval$$Register /* obj */, 234 $mem$$Register /* addr */, 235 noreg /* tmp1 */, 236 $tmp1$$Register /* tmp2 */, 237 $tmp2$$Register /* tmp3 */, 238 false /* narrow */); 239 ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm, 240 $mem$$Register /* addr */, 241 $tmp1$$Register /* addr_tmp */, 242 $tmp2$$Register /* tmp */); 243 %} 244 ins_pipe(pipe_cmpxchg); 245 %} 246 247 instruct getAndSetN_shenandoah(indirect mem, rRegN newval, rRegP tmp1, rRegP tmp2, rRegP tmp3, rFlagsReg cr) 248 %{ 249 match(Set newval (GetAndSetN mem newval)); 250 predicate(UseShenandoahGC && n->as_LoadStore()->barrier_data() != 0); 251 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 252 format %{ "xchgq $newval, $mem" %} 253 ins_encode %{ 254 assert_different_registers($mem$$Register, $newval$$Register); 255 __ xchgl($newval$$Register, Address($mem$$Register, 0)); 256 if (ShenandoahSATBBarrierStubC2::needs_barrier(this)) { 257 __ movl($tmp1$$Register, $newval$$Register); 258 __ decode_heap_oop($tmp1$$Register); 259 ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm, 260 noreg /* addr */, 261 $tmp1$$Register /* pre_val */, 262 $tmp2$$Register /* tmp */); 263 } 264 ShenandoahBarrierSet::assembler()->load_ref_barrier_c2(this, masm, 265 $newval$$Register /* obj */, 266 $mem$$Register /* addr */, 267 $tmp1$$Register /* tmp1 */, 268 $tmp2$$Register /* tmp2 */, 269 $tmp3$$Register /* tmp3 */, 270 true /* narrow */); 271 ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm, 272 $mem$$Register /* addr */, 273 $tmp1$$Register /* addr_tmp */, 274 $tmp2$$Register /* tmp */); 275 %} 276 ins_pipe(pipe_cmpxchg); 277 %} 278 279 instruct loadP_shenandaoh(rRegP dst, memory mem, rRegP tmp1, rRegP tmp2, rRegP tmp3, rFlagsReg cr) 280 %{ 281 match(Set dst (LoadP mem)); 282 predicate(UseShenandoahGC && n->as_Load()->barrier_data() != 0); 283 effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 284 ins_cost(125); // XXX 285 format %{ "movq $dst, $mem\t# ptr" %} 286 ins_encode %{ 287 __ movq($dst$$Register, $mem$$Address); 288 ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm, 289 noreg /* addr */, 290 $dst$$Register /* pre_val */, 291 $tmp1$$Register /* tmp */); 292 __ lea($tmp3$$Register, $mem$$Address); 293 ShenandoahBarrierSet::assembler()->load_ref_barrier_c2(this, masm, 294 $dst$$Register /* obj */, 295 $tmp3$$Register /* addr */, 296 noreg /* tmp1 */, 297 $tmp1$$Register /* tmp2 */, 298 $tmp2$$Register /* tmp3 */, 299 false /* narrow */); 300 %} 301 ins_pipe(ialu_reg_mem); // XXX 302 %} 303 304 instruct loadN_shenandoah(rRegN dst, indirect mem, rRegP tmp1, rRegP tmp2, rRegP tmp3, rFlagsReg cr) 305 %{ 306 match(Set dst (LoadN mem)); 307 predicate(UseShenandoahGC && n->as_Load()->barrier_data() != 0); 308 effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 309 ins_cost(125); // XXX 310 format %{ "movl $dst, $mem\t# compressed ptr" %} 311 ins_encode %{ 312 __ movl($dst$$Register, $mem$$Address); 313 if (ShenandoahSATBBarrierStubC2::needs_barrier(this)) { 314 __ movl($tmp1$$Register, $dst$$Register); 315 __ decode_heap_oop($tmp1$$Register); 316 ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm, 317 noreg /* addr */, 318 $tmp1$$Register /* pre_val */, 319 $tmp2$$Register /* tmp */); 320 } 321 ShenandoahBarrierSet::assembler()->load_ref_barrier_c2(this, masm, 322 $dst$$Register /* obj */, 323 $mem$$Register /* addr */, 324 $tmp1$$Register /* tmp1 */, 325 $tmp2$$Register /* tmp2 */, 326 $tmp3$$Register /* tmp3 */, 327 true /* narrow */); 328 %} 329 ins_pipe(ialu_reg_mem); // XXX 330 %} --- EOF ---